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):





