diff options
author | Guy Harris <guy@alum.mit.edu> | 2001-09-28 22:43:57 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2001-09-28 22:43:57 +0000 |
commit | 44e672ab42e83bf7f1d1926f5e2461e91ec138d2 (patch) | |
tree | 11d3008e5fb57bae3b1ed856e05791447cfffecc /packet-dcerpc.c | |
parent | 434a3ded4cdd018188b3d307d9f056d525d2e22b (diff) | |
download | wireshark-44e672ab42e83bf7f1d1926f5e2461e91ec138d2.tar.gz wireshark-44e672ab42e83bf7f1d1926f5e2461e91ec138d2.tar.bz2 wireshark-44e672ab42e83bf7f1d1926f5e2461e91ec138d2.zip |
From Todd Sabin: dissect the auth info in connection oriented dcerpc
packets.
Make a "dissect_netbios_payload()" routine, called from the
NetBIOS-over-802.2 (NBF), NetBIOS-over-IPX, and NetBIOS-over-TCP
dissectors. Take Todd Sabin's changes to add a heuristic dissector list
to the NBSS dissector, and apply them to "dissect_netbios_payload()"
instead. Make the SMB dissector heuristic, returning FALSE if it
doesn't see 0xFF S M B at the beginning of the packet, and have
"dissect_netbios_payload()" first try the heuristic dissector list, then
try the SMB dissector if no other heuristic dissector claims the packet,
then just dissect the payload as data.
From Todd Sabin: have the DCE/RPC dissector register as a heuristic
dissector for NetBIOS.
svn path=/trunk/; revision=3969
Diffstat (limited to 'packet-dcerpc.c')
-rw-r--r-- | packet-dcerpc.c | 94 |
1 files changed, 89 insertions, 5 deletions
diff --git a/packet-dcerpc.c b/packet-dcerpc.c index 7bc11cb490..95003692ce 100644 --- a/packet-dcerpc.c +++ b/packet-dcerpc.c @@ -2,7 +2,7 @@ * Routines for DCERPC packet disassembly * Copyright 2001, Todd Sabin <tas@webspan.net> * - * $Id: packet-dcerpc.c,v 1.8 2001/09/03 10:33:05 guy Exp $ + * $Id: packet-dcerpc.c,v 1.9 2001/09/28 22:43:56 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -102,6 +102,11 @@ static int hf_dcerpc_cn_num_results = -1; static int hf_dcerpc_cn_ack_result = -1; static int hf_dcerpc_cn_ack_reason = -1; static int hf_dcerpc_cn_cancel_count = -1; +static int hf_dcerpc_auth_type = -1; +static int hf_dcerpc_auth_level = -1; +static int hf_dcerpc_auth_pad_len = -1; +static int hf_dcerpc_auth_rsrvd = -1; +static int hf_dcerpc_auth_ctx_id = -1; static int hf_dcerpc_dg_flags1 = -1; static int hf_dcerpc_dg_flags1_rsrvd_01 = -1; static int hf_dcerpc_dg_flags1_last_frag = -1; @@ -442,6 +447,50 @@ dcerpc_try_handoff (packet_info *pinfo, proto_tree *tree, return 0; } +static int +dissect_dcerpc_cn_auth (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tree, + e_dce_cn_common_hdr_t *hdr) +{ + int offset; + guint8 auth_pad_len; + /* + * If the full packet is here, and we've got an auth len, and it's + * valid, then dissect the auth info + */ + if (tvb_length (tvb) >= hdr->frag_len + && hdr->auth_len + && (hdr->auth_len + 8 <= hdr->frag_len)) { + + offset = hdr->frag_len - (hdr->auth_len + 8); + + offset = dissect_dcerpc_uint8 (tvb, offset, pinfo, dcerpc_tree, hdr->drep, + hf_dcerpc_auth_type, NULL); + offset = dissect_dcerpc_uint8 (tvb, offset, pinfo, dcerpc_tree, hdr->drep, + hf_dcerpc_auth_level, NULL); + offset = dissect_dcerpc_uint8 (tvb, offset, pinfo, dcerpc_tree, hdr->drep, + hf_dcerpc_auth_pad_len, &auth_pad_len); + offset = dissect_dcerpc_uint8 (tvb, offset, pinfo, dcerpc_tree, hdr->drep, + hf_dcerpc_auth_rsrvd, NULL); + offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, dcerpc_tree, hdr->drep, + hf_dcerpc_auth_ctx_id, NULL); + + proto_tree_add_text (dcerpc_tree, tvb, offset, hdr->auth_len, "Auth Data"); + + /* figure out where the auth padding starts */ + offset = hdr->frag_len - (hdr->auth_len + 8 + auth_pad_len); + if (offset > 0 && auth_pad_len) { + proto_tree_add_text (dcerpc_tree, tvb, offset, + auth_pad_len, "Auth padding"); + return hdr->auth_len + 8 + auth_pad_len; + } else { + return hdr->auth_len + 8; + } + } else { + return 0; + } +} + + /* * Connection oriented packet types @@ -525,6 +574,8 @@ dissect_dcerpc_cn_bind (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, dcerpc_tree, hdr->drep, hf_dcerpc_cn_bind_trans_ver, &trans_ver); + dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, hdr); + if (check_col (pinfo->fd, COL_INFO)) { col_add_fstr (pinfo->fd, COL_INFO, "%s: UUID %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x ver %d.%d", hdr->ptype == PDU_BIND ? "Bind" : "Alter Ctx", @@ -597,6 +648,8 @@ dissect_dcerpc_cn_bind_ack (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerp &reason); } + dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, hdr); + if (check_col (pinfo->fd, COL_INFO)) { if (num_results == 1 && result == 0) { col_add_fstr (pinfo->fd, COL_INFO, "%s ack: accept max_xmit: %d max_recv: %d", @@ -621,7 +674,7 @@ dissect_dcerpc_cn_rqst (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr guint16 ctx_id; guint16 opnum; e_uuid_t obj_id; - + int auth_sz = 0; int offset = 16; offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, dcerpc_tree, hdr->drep, @@ -652,6 +705,8 @@ dissect_dcerpc_cn_rqst (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr offset += 16; } + auth_sz = dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, hdr); + if (check_col (pinfo->fd, COL_INFO)) { col_add_fstr (pinfo->fd, COL_INFO, "Request: opnum: %d ctx_id:%d", opnum, ctx_id); @@ -675,7 +730,10 @@ dissect_dcerpc_cn_rqst (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr value->ver, &value->uuid); /* handoff this call */ - dcerpc_try_handoff (pinfo, tree, tvb, offset, + dcerpc_try_handoff (pinfo, tree, + tvb_new_subset (tvb, offset, + hdr->frag_len - offset - auth_sz, + hdr->frag_len - offset - auth_sz), 0, &value->uuid, value->ver, opnum, TRUE); } @@ -688,7 +746,7 @@ dissect_dcerpc_cn_resp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr { conversation_t *conv; guint16 ctx_id; - + int auth_sz = 0; int offset = 16; offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, dcerpc_tree, hdr->drep, @@ -702,6 +760,8 @@ dissect_dcerpc_cn_resp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr /* padding */ offset++; + auth_sz = dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, hdr); + if (check_col (pinfo->fd, COL_INFO)) { col_add_fstr (pinfo->fd, COL_INFO, "Response: call_id: %d ctx_id:%d", hdr->call_id, ctx_id); @@ -714,7 +774,10 @@ dissect_dcerpc_cn_resp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr } else { dcerpc_call_value *value = dcerpc_call_lookup (hdr->call_id, conv); if (value) { - dcerpc_try_handoff (pinfo, tree, tvb, offset, + dcerpc_try_handoff (pinfo, tree, + tvb_new_subset (tvb, offset, + hdr->frag_len - offset - auth_sz, + hdr->frag_len - offset - auth_sz), 0, &value->uuid, value->ver, value->opnum, FALSE); } @@ -727,6 +790,7 @@ dissect_dcerpc_cn_resp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tr static gboolean dissect_dcerpc_cn (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { + static char nulls[4] = { 0 }; proto_item *ti = NULL; proto_item *tf = NULL; proto_tree *dcerpc_tree = NULL; @@ -737,6 +801,13 @@ dissect_dcerpc_cn (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) /* * Check if this looks like a C/O DCERPC call */ + /* + * when done over nbt, dcerpc requests are padded with 4 bytes of null + * data for some reason. + */ + if (tvb_bytes_exist (tvb, 0, 4) && tvb_memeql (tvb, 0, nulls, 4) == 0) { + tvb = tvb_new_subset (tvb, 4, -1, -1); + } if (!tvb_bytes_exist (tvb, 0, sizeof (hdr))) { return FALSE; } @@ -824,6 +895,8 @@ dissect_dcerpc_cn (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) break; default: + /* might as well dissect the auth info */ + dissect_dcerpc_cn_auth (tvb, pinfo, dcerpc_tree, &hdr); break; } return TRUE; @@ -1158,6 +1231,16 @@ proto_register_dcerpc (void) { "Ack reason", "dcerpc.cn_ack_reason", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }}, { &hf_dcerpc_cn_cancel_count, { "Cancel count", "dcerpc.cn_cancel_count", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, + { &hf_dcerpc_auth_type, + { "Auth type", "dcerpc.auth_type", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, + { &hf_dcerpc_auth_level, + { "Auth level", "dcerpc.auth_level", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, + { &hf_dcerpc_auth_pad_len, + { "Auth pad len", "dcerpc.auth_pad_len", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, + { &hf_dcerpc_auth_rsrvd, + { "Auth Rsrvd", "dcerpc.auth_rsrvd", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, + { &hf_dcerpc_auth_ctx_id, + { "Auth Context ID", "dcerpc.auth_ctx_id", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }}, { &hf_dcerpc_dg_flags1, { "Flags1", "dcerpc.dg_flags1", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }}, { &hf_dcerpc_dg_flags1_rsrvd_01, @@ -1244,5 +1327,6 @@ void proto_reg_handoff_dcerpc (void) { heur_dissector_add ("tcp", dissect_dcerpc_cn, proto_dcerpc); + heur_dissector_add ("netbios", dissect_dcerpc_cn, proto_dcerpc); heur_dissector_add ("udp", dissect_dcerpc_dg, proto_dcerpc); } |