Ethereal-dev: [Ethereal-dev] some dcerpc and nbss updates
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Todd Sabin <tas@xxxxxxxxxxx>
Date: 26 Sep 2001 07:46:52 -0400
Hi, The attached diff contains code to do two things. 1. dissect the auth info in connection oriented dcerpc packets. 2. modifies packet-nbns.c to use pass off netbios session packets to heuristic dissectors, and packet-dcerpc.c registers itself there. Most of the time, the layer directly above netbios session is SMB. However, it's possible to do DCE/RPC directly on the netbios session layer, with the ncacn_nb_tcp protseq. That's what this is for. Note that for this to work, I've had to comment out the #define RJSHACK, because it's just, well, wrong. I think the correct solution is to make the SMB dissector a heuristic dissector as well, and then if no dissector claims a nbns packet, do the stuff in the RJSHACK code. For now, though, if no heuristic nbss dissector handles a packet, it's shipped off to dissect_smb directly, as before. Todd
Index: packet-dcerpc.c =================================================================== RCS file: /cvsroot/ethereal/packet-dcerpc.c,v retrieving revision 1.8 diff -u -r1.8 packet-dcerpc.c --- packet-dcerpc.c 2001/09/03 10:33:05 1.8 +++ packet-dcerpc.c 2001/09/26 02:26:08 @@ -102,6 +102,11 @@ 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,7 +447,51 @@ 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 @@ 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 @@ &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 @@ 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 @@ 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 @@ 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 @@ { 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 @@ /* 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 @@ } 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 @@ 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 @@ /* * 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 @@ 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 @@ { "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 @@ proto_reg_handoff_dcerpc (void) { heur_dissector_add ("tcp", dissect_dcerpc_cn, proto_dcerpc); + heur_dissector_add ("nbss", dissect_dcerpc_cn, proto_dcerpc); heur_dissector_add ("udp", dissect_dcerpc_dg, proto_dcerpc); } Index: packet-nbns.c =================================================================== RCS file: /cvsroot/ethereal/packet-nbns.c,v retrieving revision 1.56 diff -u -r1.56 packet-nbns.c --- packet-nbns.c 2001/09/17 02:07:00 1.56 +++ packet-nbns.c 2001/09/26 02:26:14 @@ -43,6 +43,8 @@ #include "packet-smb.h" #include "prefs.h" +static heur_dissector_list_t nbns_heur_subdissector_list; + static int proto_nbns = -1; static int hf_nbns_response = -1; static int hf_nbns_query = -1; @@ -1383,7 +1385,6 @@ int len; char name[(NETBIOS_NAME_LEN - 1)*4 + MAXDNAME]; int name_type; - tvbuff_t *next_tvb; msg_type = tvb_get_guint8(tvb, offset); @@ -1500,14 +1501,18 @@ */ proto_item_set_len(ti, offset); { + tvbuff_t *next_tvb; const guint8 *next_pd; int next_offset; next_tvb = tvb_new_subset(tvb, offset, -1, -1); tvb_compat(next_tvb, &next_pd, &next_offset); - dissect_smb(next_pd, next_offset, pinfo->fd, tree, - max_data - 4); + if (!dissector_try_heuristic (nbns_heur_subdissector_list, + next_tvb, pinfo, tree)) { + dissect_smb(next_pd, next_offset, pinfo->fd, tree, + max_data - 4); + } } break; @@ -1553,7 +1558,7 @@ /* Hmmm, it may be a continuation message ... */ -#define RJSHACK 1 +/*#define RJSHACK 1*/ #ifdef RJSHACK if (((msg_type != SESSION_REQUEST) && (msg_type != POSITIVE_SESSION_RESPONSE) && @@ -1698,6 +1703,8 @@ proto_register_field_array(proto_nbss, hf_nbss, array_length(hf_nbss)); proto_register_subtree_array(ett, array_length(ett)); + + register_heur_dissector_list ("nbss", &nbns_heur_subdissector_list); nbss_module = prefs_register_protocol(proto_nbss, NULL); prefs_register_bool_preference(nbss_module, "desegment_nbss_commands",
- Follow-Ups:
- Re: [Ethereal-dev] some dcerpc and nbss updates
- From: Guy Harris
- Re: [Ethereal-dev] some dcerpc and nbss updates
- From: Guy Harris
- Re: [Ethereal-dev] some dcerpc and nbss updates
- Prev by Date: RE: [ethereal-dev] Bug in packet-tcp: ack value not in tree when RST
- Next by Date: [Ethereal-dev] patch for packet-ip.c
- Previous by thread: RE: [ethereal-dev] Bug in packet-tcp: ack value not in tree when RST
- Next by thread: Re: [Ethereal-dev] some dcerpc and nbss updates
- Index(es):