diff options
author | Guy Harris <guy@alum.mit.edu> | 2001-07-02 07:11:40 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2001-07-02 07:11:40 +0000 |
commit | db5e1b8c857e1b4866547efce72f6a09af9a3076 (patch) | |
tree | 90b42bb9849ef3e3ebf9768c307afb601d97d14a /packet-nbns.c | |
parent | e78964cea031762e6c7cae3334fcd21eff7091fd (diff) |
Tvbuffify the DNS, NBNS, NBDS, and NBSS dissectors.
Add a "tvb_memeql()" routine, for doing "memcmp()"-style equality
comparisons.
svn path=/trunk/; revision=3631
Diffstat (limited to 'packet-nbns.c')
-rw-r--r-- | packet-nbns.c | 762 |
1 files changed, 319 insertions, 443 deletions
diff --git a/packet-nbns.c b/packet-nbns.c index 763828e9ea..86fa3ca743 100644 --- a/packet-nbns.c +++ b/packet-nbns.c @@ -4,12 +4,11 @@ * Gilbert Ramirez <gram@xiexie.org> * Much stuff added by Guy Harris <guy@alum.mit.edu> * - * $Id: packet-nbns.c,v 1.52 2001/06/18 02:17:49 guy Exp $ + * $Id: packet-nbns.c,v 1.53 2001/07/02 07:11:39 guy Exp $ * * Ethereal - Network traffic analyzer - * By Gerald Combs <gerald@zing.org> + * By Gerald Combs <gerald@ethereal.com> * Copyright 1998 Gerald Combs - * * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -197,7 +196,7 @@ nbns_type_name (int type) #define NBNAME_BUF_LEN 128 static int -get_nbns_name(const u_char *pd, int offset, int nbns_data_offset, +get_nbns_name(tvbuff_t *tvb, int offset, int nbns_data_offset, char *name_ret, int *name_type_ret) { int name_len; @@ -206,7 +205,7 @@ get_nbns_name(const u_char *pd, int offset, int nbns_data_offset, char *pname, *pnbname, cname, cnbname; int name_type; - name_len = get_dns_name(pd, offset, nbns_data_offset, name, + name_len = get_dns_name(tvb, offset, nbns_data_offset, name, sizeof(name)); /* OK, now undo the first-level encoding. */ @@ -290,7 +289,7 @@ bad: static int -get_nbns_name_type_class(const u_char *pd, int offset, int nbns_data_offset, +get_nbns_name_type_class(tvbuff_t *tvb, int offset, int nbns_data_offset, char *name_ret, int *name_len_ret, int *name_type_ret, int *type_ret, int *class_ret) { @@ -298,22 +297,14 @@ get_nbns_name_type_class(const u_char *pd, int offset, int nbns_data_offset, int type; int class; - name_len = get_nbns_name(pd, offset, nbns_data_offset, name_ret, + name_len = get_nbns_name(tvb, offset, nbns_data_offset, name_ret, name_type_ret); offset += name_len; - if (!BYTES_ARE_IN_FRAME(offset, 2)) { - /* We ran past the end of the captured data in the packet. */ - return -1; - } - type = pntohs(&pd[offset]); + type = tvb_get_ntohs(tvb, offset); offset += 2; - if (!BYTES_ARE_IN_FRAME(offset, 2)) { - /* We ran past the end of the captured data in the packet. */ - return -1; - } - class = pntohs(&pd[offset]); + class = tvb_get_ntohs(tvb, offset); *type_ret = type; *class_ret = class; @@ -323,20 +314,20 @@ get_nbns_name_type_class(const u_char *pd, int offset, int nbns_data_offset, } static void -add_name_and_type(proto_tree *tree, int offset, int len, char *tag, - char *name, int name_type) +add_name_and_type(proto_tree *tree, tvbuff_t *tvb, int offset, int len, + char *tag, char *name, int name_type) { if (name_type != -1) { - proto_tree_add_text(tree, NullTVB, offset, len, "%s: %s (%s)", + proto_tree_add_text(tree, tvb, offset, len, "%s: %s (%s)", tag, name, netbios_name_type_descr(name_type)); } else { - proto_tree_add_text(tree, NullTVB, offset, len, "%s: %s", + proto_tree_add_text(tree, tvb, offset, len, "%s: %s", tag, name); } } static int -dissect_nbns_query(const u_char *pd, int offset, int nbns_data_offset, +dissect_nbns_query(tvbuff_t *tvb, int offset, int nbns_data_offset, frame_data *fd, proto_tree *nbns_tree) { int len; @@ -347,20 +338,16 @@ dissect_nbns_query(const u_char *pd, int offset, int nbns_data_offset, int class; char *class_name; char *type_name; - const u_char *dptr; - const u_char *data_start; + int data_offset; + int data_start; proto_tree *q_tree; proto_item *tq; - data_start = dptr = pd + offset; + data_start = data_offset = offset; - len = get_nbns_name_type_class(pd, offset, nbns_data_offset, name, + len = get_nbns_name_type_class(tvb, offset, nbns_data_offset, name, &name_len, &name_type, &type, &class); - if (len < 0) { - /* We ran past the end of the data in the packet. */ - return 0; - } - dptr += len; + data_offset += len; type_name = nbns_type_name(type); class_name = dns_class_name(class); @@ -368,27 +355,27 @@ dissect_nbns_query(const u_char *pd, int offset, int nbns_data_offset, if (fd != NULL) col_append_fstr(fd, COL_INFO, " %s %s", type_name, name); if (nbns_tree != NULL) { - tq = proto_tree_add_text(nbns_tree, NullTVB, offset, len, + tq = proto_tree_add_text(nbns_tree, tvb, offset, len, "%s: type %s, class %s", name, type_name, class_name); q_tree = proto_item_add_subtree(tq, ett_nbns_qd); - add_name_and_type(q_tree, offset, name_len, "Name", name, + add_name_and_type(q_tree, tvb, offset, name_len, "Name", name, name_type); offset += name_len; - proto_tree_add_text(q_tree, NullTVB, offset, 2, "Type: %s", type_name); + proto_tree_add_text(q_tree, tvb, offset, 2, "Type: %s", type_name); offset += 2; - proto_tree_add_text(q_tree, NullTVB, offset, 2, "Class: %s", class_name); + proto_tree_add_text(q_tree, tvb, offset, 2, "Class: %s", class_name); offset += 2; } - return dptr - data_start; + return data_offset - data_start; } static void -nbns_add_nbns_flags(proto_tree *nbns_tree, int offset, u_short flags, - int is_wack) +nbns_add_nbns_flags(proto_tree *nbns_tree, tvbuff_t *tvb, int offset, + u_short flags, int is_wack) { char buf[128+1]; proto_tree *field_tree; @@ -413,48 +400,48 @@ nbns_add_nbns_flags(proto_tree *nbns_tree, int offset, u_short flags, strcat(buf, val_to_str(flags & F_RCODE, rcode_vals, "Unknown error")); } - tf = proto_tree_add_text(nbns_tree, NullTVB, offset, 2, + tf = proto_tree_add_text(nbns_tree, tvb, offset, 2, "Flags: 0x%04x (%s)", flags, buf); field_tree = proto_item_add_subtree(tf, ett_nbns_flags); - proto_tree_add_text(field_tree, NullTVB, offset, 2, "%s", + proto_tree_add_text(field_tree, tvb, offset, 2, "%s", decode_boolean_bitfield(flags, F_RESPONSE, 2*8, "Response", "Query")); - proto_tree_add_text(field_tree, NullTVB, offset, 2, "%s", + proto_tree_add_text(field_tree, tvb, offset, 2, "%s", decode_enumerated_bitfield(flags, F_OPCODE, 2*8, opcode_vals, "%s")); if (flags & F_RESPONSE) { - proto_tree_add_text(field_tree, NullTVB, offset, 2, + proto_tree_add_text(field_tree, tvb, offset, 2, "%s", decode_boolean_bitfield(flags, F_AUTHORITATIVE, 2*8, "Server is an authority for domain", "Server isn't an authority for domain")); } - proto_tree_add_text(field_tree, NullTVB, offset, 2, "%s", + proto_tree_add_text(field_tree, tvb, offset, 2, "%s", decode_boolean_bitfield(flags, F_TRUNCATED, 2*8, "Message is truncated", "Message is not truncated")); - proto_tree_add_text(field_tree, NullTVB, offset, 2, "%s", + proto_tree_add_text(field_tree, tvb, offset, 2, "%s", decode_boolean_bitfield(flags, F_RECDESIRED, 2*8, "Do query recursively", "Don't do query recursively")); if (flags & F_RESPONSE) { - proto_tree_add_text(field_tree, NullTVB, offset, 2, + proto_tree_add_text(field_tree, tvb, offset, 2, "%s", decode_boolean_bitfield(flags, F_RECAVAIL, 2*8, "Server can do recursive queries", "Server can't do recursive queries")); } - proto_tree_add_text(field_tree, NullTVB, offset, 2, "%s", + proto_tree_add_text(field_tree, tvb, offset, 2, "%s", decode_boolean_bitfield(flags, F_BROADCAST, 2*8, "Broadcast packet", "Not a broadcast packet")); if (flags & F_RESPONSE && !is_wack) { - proto_tree_add_text(field_tree, NullTVB, offset, 2, + proto_tree_add_text(field_tree, tvb, offset, 2, "%s", decode_enumerated_bitfield(flags, F_RCODE, 2*8, @@ -463,7 +450,7 @@ nbns_add_nbns_flags(proto_tree *nbns_tree, int offset, u_short flags, } static void -nbns_add_nb_flags(proto_tree *rr_tree, int offset, u_short flags) +nbns_add_nb_flags(proto_tree *rr_tree, tvbuff_t *tvb, int offset, u_short flags) { char buf[128+1]; proto_tree *field_tree; @@ -483,21 +470,22 @@ nbns_add_nb_flags(proto_tree *rr_tree, int offset, u_short flags) strcat(buf, "group"); else strcat(buf, "unique"); - tf = proto_tree_add_text(rr_tree, NullTVB, offset, 2, "Flags: 0x%x (%s)", flags, + tf = proto_tree_add_text(rr_tree, tvb, offset, 2, "Flags: 0x%x (%s)", flags, buf); field_tree = proto_item_add_subtree(tf, ett_nbns_nb_flags); - proto_tree_add_text(field_tree, NullTVB, offset, 2, "%s", + proto_tree_add_text(field_tree, tvb, offset, 2, "%s", decode_boolean_bitfield(flags, NB_FLAGS_G, 2*8, "Group name", "Unique name")); - proto_tree_add_text(field_tree, NullTVB, offset, 2, "%s", + proto_tree_add_text(field_tree, tvb, offset, 2, "%s", decode_enumerated_bitfield(flags, NB_FLAGS_ONT, 2*8, nb_flags_ont_vals, "%s")); } static void -nbns_add_name_flags(proto_tree *rr_tree, int offset, u_short flags) +nbns_add_name_flags(proto_tree *rr_tree, tvbuff_t *tvb, int offset, + u_short flags) { char buf[128+1]; proto_item *field_tree; @@ -524,33 +512,33 @@ nbns_add_name_flags(proto_tree *rr_tree, int offset, u_short flags) strcat(buf, ", active"); if (flags & NAME_FLAGS_PRM) strcat(buf, ", permanent node name"); - tf = proto_tree_add_text(rr_tree, NullTVB, offset, 2, "Name flags: 0x%x (%s)", + tf = proto_tree_add_text(rr_tree, tvb, offset, 2, "Name flags: 0x%x (%s)", flags, buf); field_tree = proto_item_add_subtree(tf, ett_nbns_name_flags); - proto_tree_add_text(field_tree, NullTVB, offset, 2, "%s", + proto_tree_add_text(field_tree, tvb, offset, 2, "%s", decode_boolean_bitfield(flags, NAME_FLAGS_G, 2*8, "Group name", "Unique name")); - proto_tree_add_text(field_tree, NullTVB, offset, 2, "%s", + proto_tree_add_text(field_tree, tvb, offset, 2, "%s", decode_enumerated_bitfield(flags, NAME_FLAGS_ONT, 2*8, name_flags_ont_vals, "%s")); - proto_tree_add_text(field_tree, NullTVB, offset, 2, "%s", + proto_tree_add_text(field_tree, tvb, offset, 2, "%s", decode_boolean_bitfield(flags, NAME_FLAGS_DRG, 2*8, "Name is being deregistered", "Name is not being deregistered")); - proto_tree_add_text(field_tree, NullTVB, offset, 2, "%s", + proto_tree_add_text(field_tree, tvb, offset, 2, "%s", decode_boolean_bitfield(flags, NAME_FLAGS_CNF, 2*8, "Name is in conflict", "Name is not in conflict")); - proto_tree_add_text(field_tree, NullTVB, offset, 2, "%s", + proto_tree_add_text(field_tree, tvb, offset, 2, "%s", decode_boolean_bitfield(flags, NAME_FLAGS_ACT, 2*8, "Name is active", "Name is not active")); - proto_tree_add_text(field_tree, NullTVB, offset, 2, "%s", + proto_tree_add_text(field_tree, tvb, offset, 2, "%s", decode_boolean_bitfield(flags, NAME_FLAGS_PRM, 2*8, "Permanent node name", @@ -558,7 +546,7 @@ nbns_add_name_flags(proto_tree *rr_tree, int offset, u_short flags) } static int -dissect_nbns_answer(const u_char *pd, int offset, int nbns_data_offset, +dissect_nbns_answer(tvbuff_t *tvb, int offset, int nbns_data_offset, frame_data *fd, proto_tree *nbns_tree, int opcode) { int len; @@ -569,9 +557,9 @@ dissect_nbns_answer(const u_char *pd, int offset, int nbns_data_offset, int class; char *class_name; char *type_name; - const u_char *dptr; + int data_offset; int cur_offset; - const u_char *data_start; + int data_start; u_int ttl; u_short data_len; u_short flags; @@ -582,35 +570,23 @@ dissect_nbns_answer(const u_char *pd, int offset, int nbns_data_offset, char nbname[16+4+1]; /* 4 for [<last char>] */ u_short name_flags; - data_start = dptr = pd + offset; + data_start = data_offset = offset; cur_offset = offset; - len = get_nbns_name_type_class(pd, offset, nbns_data_offset, name, + len = get_nbns_name_type_class(tvb, offset, nbns_data_offset, name, &name_len, &name_type, &type, &class); - if (len < 0) { - /* We ran past the end of the data in the packet. */ - return 0; - } - dptr += len; + data_offset += len; cur_offset += len; type_name = nbns_type_name(type); class_name = dns_class_name(class); - if (!BYTES_ARE_IN_FRAME(cur_offset, 4)) { - /* We ran past the end of the captured data in the packet. */ - return 0; - } - ttl = pntohl(dptr); - dptr += 4; + ttl = tvb_get_ntohl(tvb, data_offset); + data_offset += 4; cur_offset += 4; - if (!BYTES_ARE_IN_FRAME(cur_offset, 2)) { - /* We ran past the end of the captured data in the packet. */ - return 0; - } - data_len = pntohs(dptr); - dptr += 2; + data_len = tvb_get_ntohs(tvb, data_offset); + data_offset += 2; cur_offset += 2; switch (type) { @@ -618,72 +594,56 @@ dissect_nbns_answer(const u_char *pd, int offset, int nbns_data_offset, if (fd != NULL) { if (opcode != OPCODE_WACK) { col_append_fstr(fd, COL_INFO, " %s %s", - type_name, ip_to_str((guint8 *)(dptr + 2))); + type_name, + ip_to_str(tvb_get_ptr(tvb, data_offset+2, 4))); } } if (nbns_tree == NULL) break; - trr = proto_tree_add_text(nbns_tree, NullTVB, offset, - (dptr - data_start) + data_len, + trr = proto_tree_add_text(nbns_tree, tvb, offset, + (data_offset - data_start) + data_len, "%s: type %s, class %s", name, type_name, class_name); strcat(name, " ("); strcat(name, netbios_name_type_descr(name_type)); strcat(name, ")"); - rr_tree = add_rr_to_tree(trr, ett_nbns_rr, offset, name, + rr_tree = add_rr_to_tree(trr, ett_nbns_rr, tvb, offset, name, name_len, type_name, class_name, ttl, data_len); while (data_len > 0) { if (opcode == OPCODE_WACK) { /* WACK response. This doesn't contain the * same type of RR data as other T_NB * responses. */ - if (!BYTES_ARE_IN_FRAME(cur_offset, 2)) { - /* We ran past the end of the captured - data in the packet. */ - return 0; - } if (data_len < 2) { - proto_tree_add_text(rr_tree, NullTVB, cur_offset, + proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "(incomplete entry)"); break; } - flags = pntohs(dptr); - dptr += 2; - nbns_add_nbns_flags(rr_tree, cur_offset, + flags = tvb_get_ntohs(tvb, cur_offset); + nbns_add_nbns_flags(rr_tree, tvb, cur_offset, flags, 1); cur_offset += 2; data_len -= 2; } else { - if (!BYTES_ARE_IN_FRAME(cur_offset, 2)) { - /* We ran past the end of the captured - data in the packet. */ - return 0; - } if (data_len < 2) { - proto_tree_add_text(rr_tree, NullTVB, cur_offset, + proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "(incomplete entry)"); break; } - flags = pntohs(dptr); - dptr += 2; - nbns_add_nb_flags(rr_tree, cur_offset, flags); + flags = tvb_get_ntohs(tvb, cur_offset); + nbns_add_nb_flags(rr_tree, tvb, cur_offset, + flags); cur_offset += 2; data_len -= 2; - if (!BYTES_ARE_IN_FRAME(cur_offset, 4)) { - /* We ran past the end of the captured - data in the packet. */ - return 0; - } if (data_len < 4) { - proto_tree_add_text(rr_tree, NullTVB, cur_offset, + proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "(incomplete entry)"); break; } - proto_tree_add_text(rr_tree, NullTVB, cur_offset, 4, + proto_tree_add_text(rr_tree, tvb, cur_offset, 4, "Addr: %s", - ip_to_str((guint8 *)dptr)); - dptr += 4; + ip_to_str(tvb_get_ptr(tvb, cur_offset, 4))); cur_offset += 4; data_len -= 4; } @@ -695,354 +655,240 @@ dissect_nbns_answer(const u_char *pd, int offset, int nbns_data_offset, col_append_fstr(fd, COL_INFO, " %s", type_name); if (nbns_tree == NULL) break; - trr = proto_tree_add_text(nbns_tree, NullTVB, offset, - (dptr - data_start) + data_len, + trr = proto_tree_add_text(nbns_tree, tvb, offset, + (data_offset - data_start) + data_len, "%s: type %s, class %s", name, type_name, class_name); - rr_tree = add_rr_to_tree(trr, ett_nbns_rr, offset, name, + rr_tree = add_rr_to_tree(trr, ett_nbns_rr, tvb, offset, name, name_len, type_name, class_name, ttl, data_len); - if (!BYTES_ARE_IN_FRAME(cur_offset, 1)) { - /* We ran past the end of the captured - data in the packet. */ - return 0; - } if (data_len < 1) { - proto_tree_add_text(rr_tree, NullTVB, cur_offset, + proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "(incomplete entry)"); break; } - num_names = *dptr; - dptr += 1; - proto_tree_add_text(rr_tree, NullTVB, cur_offset, 2, + num_names = tvb_get_guint8(tvb, cur_offset); + proto_tree_add_text(rr_tree, tvb, cur_offset, 1, "Number of names: %u", num_names); cur_offset += 1; while (num_names != 0) { - if (!BYTES_ARE_IN_FRAME(cur_offset, NETBIOS_NAME_LEN)) { - /* We ran past the end of the captured - data in the packet. */ - return 0; - } if (data_len < NETBIOS_NAME_LEN) { - proto_tree_add_text(rr_tree, NullTVB, cur_offset, + proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "(incomplete entry)"); goto out; } - memcpy(nbname, dptr, NETBIOS_NAME_LEN); - dptr += NETBIOS_NAME_LEN; + tvb_memcpy(tvb, (guint8 *)nbname, cur_offset, + NETBIOS_NAME_LEN); name_type = process_netbios_name(nbname, name_str); - proto_tree_add_text(rr_tree, NullTVB, cur_offset, + proto_tree_add_text(rr_tree, tvb, cur_offset, NETBIOS_NAME_LEN, "Name: %s<%02x> (%s)", name_str, name_type, netbios_name_type_descr(name_type)); cur_offset += NETBIOS_NAME_LEN; data_len -= NETBIOS_NAME_LEN; - if (!BYTES_ARE_IN_FRAME(cur_offset, 2)) { - /* We ran past the end of the captured - data in the packet. */ - return 0; - } if (data_len < 2) { - proto_tree_add_text(rr_tree, NullTVB, cur_offset, + proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "(incomplete entry)"); goto out; } - name_flags = pntohs(dptr); - dptr += 2; - nbns_add_name_flags(rr_tree, cur_offset, name_flags); + name_flags = tvb_get_ntohs(tvb, cur_offset); + nbns_add_name_flags(rr_tree, tvb, cur_offset, + name_flags); cur_offset += 2; data_len -= 2; num_names--; } - if (!BYTES_ARE_IN_FRAME(cur_offset, 6)) { - /* We ran past the end of the captured - data in the packet. */ - return 0; - } if (data_len < 6) { - proto_tree_add_text(rr_tree, NullTVB, cur_offset, + proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "(incomplete entry)"); break; } - proto_tree_add_text(rr_tree, NullTVB, cur_offset, 6, + proto_tree_add_text(rr_tree, tvb, cur_offset, 6, "Unit ID: %s", - ether_to_str((guint8 *)dptr)); - dptr += 6; + ether_to_str(tvb_get_ptr(tvb, cur_offset, 6))); cur_offset += 6; data_len -= 6; - if (!BYTES_ARE_IN_FRAME(cur_offset, 1)) { - /* We ran past the end of the captured - data in the packet. */ - return 0; - } if (data_len < 1) { - proto_tree_add_text(rr_tree, NullTVB, cur_offset, + proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "(incomplete entry)"); break; } - proto_tree_add_text(rr_tree, NullTVB, cur_offset, 1, - "Jumpers: 0x%x", *dptr); - dptr += 1; + proto_tree_add_text(rr_tree, tvb, cur_offset, 1, + "Jumpers: 0x%x", tvb_get_guint8(tvb, cur_offset)); cur_offset += 1; data_len -= 1; - if (!BYTES_ARE_IN_FRAME(cur_offset, 1)) { - /* We ran past the end of the captured - data in the packet. */ - return 0; - } if (data_len < 1) { - proto_tree_add_text(rr_tree, NullTVB, cur_offset, + proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "(incomplete entry)"); break; } - proto_tree_add_text(rr_tree, NullTVB, cur_offset, 1, - "Test result: 0x%x", *dptr); - dptr += 1; + proto_tree_add_text(rr_tree, tvb, cur_offset, 1, + "Test result: 0x%x", tvb_get_guint8(tvb, cur_offset)); cur_offset += 1; data_len -= 1; - if (!BYTES_ARE_IN_FRAME(cur_offset, 2)) { - /* We ran past the end of the captured - data in the packet. */ - return 0; - } if (data_len < 2) { - proto_tree_add_text(rr_tree, NullTVB, cur_offset, + proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "(incomplete entry)"); break; } - proto_tree_add_text(rr_tree, NullTVB, cur_offset, 2, - "Version number: 0x%x", pntohs(dptr)); - dptr += 2; + proto_tree_add_text(rr_tree, tvb, cur_offset, 2, + "Version number: 0x%x", tvb_get_ntohs(tvb, cur_offset)); cur_offset += 2; data_len -= 2; - if (!BYTES_ARE_IN_FRAME(cur_offset, 2)) { - /* We ran past the end of the captured - data in the packet. */ - return 0; - } if (data_len < 2) { - proto_tree_add_text(rr_tree, NullTVB, cur_offset, + proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "(incomplete entry)"); break; } - proto_tree_add_text(rr_tree, NullTVB, cur_offset, 2, - "Period of statistics: 0x%x", pntohs(dptr)); - dptr += 2; + proto_tree_add_text(rr_tree, tvb, cur_offset, 2, + "Period of statistics: 0x%x", + tvb_get_ntohs(tvb, cur_offset)); cur_offset += 2; data_len -= 2; - if (!BYTES_ARE_IN_FRAME(cur_offset, 2)) { - /* We ran past the end of the captured - data in the packet. */ - return 0; - } if (data_len < 2) { - proto_tree_add_text(rr_tree, NullTVB, cur_offset, + proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "(incomplete entry)"); break; } - proto_tree_add_text(rr_tree, NullTVB, cur_offset, 2, - "Number of CRCs: %u", pntohs(dptr)); - dptr += 2; + proto_tree_add_text(rr_tree, tvb, cur_offset, 2, + "Number of CRCs: %u", tvb_get_ntohs(tvb, cur_offset)); cur_offset += 2; data_len -= 2; - if (!BYTES_ARE_IN_FRAME(cur_offset, 2)) { - /* We ran past the end of the captured - data in the packet. */ - return 0; - } if (data_len < 2) { - proto_tree_add_text(rr_tree, NullTVB, cur_offset, + proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "(incomplete entry)"); break; } - proto_tree_add_text(rr_tree, NullTVB, cur_offset, 2, - "Number of alignment errors: %u", pntohs(dptr)); - dptr += 2; + proto_tree_add_text(rr_tree, tvb, cur_offset, 2, + "Number of alignment errors: %u", + tvb_get_ntohs(tvb, cur_offset)); cur_offset += 2; data_len -= 2; - if (!BYTES_ARE_IN_FRAME(cur_offset, 2)) { - /* We ran past the end of the captured - data in the packet. */ - return 0; - } if (data_len < 2) { - proto_tree_add_text(rr_tree, NullTVB, cur_offset, + proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "(incomplete entry)"); break; } - proto_tree_add_text(rr_tree, NullTVB, cur_offset, 2, - "Number of collisions: %u", pntohs(dptr)); - dptr += 2; + proto_tree_add_text(rr_tree, tvb, cur_offset, 2, + "Number of collisions: %u", tvb_get_ntohs(tvb, cur_offset)); cur_offset += 2; data_len -= 2; - if (!BYTES_ARE_IN_FRAME(cur_offset, 2)) { - /* We ran past the end of the captured - data in the packet. */ - return 0; - } if (data_len < 2) { - proto_tree_add_text(rr_tree, NullTVB, cur_offset, + proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "(incomplete entry)"); break; } - proto_tree_add_text(rr_tree, NullTVB, cur_offset, 2, - "Number of send aborts: %u", pntohs(dptr)); - dptr += 2; + proto_tree_add_text(rr_tree, tvb, cur_offset, 2, + "Number of send aborts: %u", tvb_get_ntohs(tvb, cur_offset)); cur_offset += 2; data_len -= 2; - if (!BYTES_ARE_IN_FRAME(cur_offset, 4)) { - /* We ran past the end of the captured - data in the packet. */ - return 0; - } if (data_len < 4) { - proto_tree_add_text(rr_tree, NullTVB, cur_offset, + proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "(incomplete entry)"); break; } - proto_tree_add_text(rr_tree, NullTVB, cur_offset, 4, - "Number of good sends: %u", pntohl(dptr)); - dptr += 4; + proto_tree_add_text(rr_tree, tvb, cur_offset, 4, + "Number of good sends: %u", tvb_get_ntohl(tvb, cur_offset)); cur_offset += 4; data_len -= 4; - if (!BYTES_ARE_IN_FRAME(cur_offset, 4)) { - /* We ran past the end of the captured - data in the packet. */ - return 0; - } if (data_len < 4) { - proto_tree_add_text(rr_tree, NullTVB, cur_offset, + proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "(incomplete entry)"); break; } - proto_tree_add_text(rr_tree, NullTVB, cur_offset, 4, - "Number of good receives: %u", pntohl(dptr)); - dptr += 4; + proto_tree_add_text(rr_tree, tvb, cur_offset, 4, + "Number of good receives: %u", + tvb_get_ntohl(tvb, cur_offset)); cur_offset += 4; data_len -= 4; - if (!BYTES_ARE_IN_FRAME(cur_offset, 2)) { - /* We ran past the end of the captured - data in the packet. */ - return 0; - } if (data_len < 2) { - proto_tree_add_text(rr_tree, NullTVB, cur_offset, + proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "(incomplete entry)"); break; } - proto_tree_add_text(rr_tree, NullTVB, cur_offset, 2, - "Number of retransmits: %u", pntohs(dptr)); - dptr += 2; + proto_tree_add_text(rr_tree, tvb, cur_offset, 2, + "Number of retransmits: %u", tvb_get_ntohs(tvb, cur_offset)); cur_offset += 2; data_len -= 2; - if (!BYTES_ARE_IN_FRAME(cur_offset, 2)) { - /* We ran past the end of the captured - data in the packet. */ - return 0; - } if (data_len < 2) { - proto_tree_add_text(rr_tree, NullTVB, cur_offset, + proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "(incomplete entry)"); break; } - proto_tree_add_text(rr_tree, NullTVB, cur_offset, 2, - "Number of no resource conditions: %u", pntohs(dptr)); - dptr += 2; + proto_tree_add_text(rr_tree, tvb, cur_offset, 2, + "Number of no resource conditions: %u", + tvb_get_ntohs(tvb, cur_offset)); cur_offset += 2; data_len -= 2; - if (!BYTES_ARE_IN_FRAME(cur_offset, 2)) { - /* We ran past the end of the captured - data in the packet. */ - return 0; - } if (data_len < 2) { - proto_tree_add_text(rr_tree, NullTVB, cur_offset, + proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "(incomplete entry)"); break; } - proto_tree_add_text(rr_tree, NullTVB, cur_offset, 2, - "Number of command blocks: %u", pntohs(dptr)); - dptr += 2; + proto_tree_add_text(rr_tree, tvb, cur_offset, 2, + "Number of command blocks: %u", + tvb_get_ntohs(tvb, cur_offset)); cur_offset += 2; data_len -= 2; - if (!BYTES_ARE_IN_FRAME(cur_offset, 2)) { - /* We ran past the end of the captured - data in the packet. */ - return 0; - } if (data_len < 2) { - proto_tree_add_text(rr_tree, NullTVB, cur_offset, + proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "(incomplete entry)"); break; } - proto_tree_add_text(rr_tree, NullTVB, cur_offset, 2, - "Number of pending sessions: %u", pntohs(dptr)); - dptr += 2; + proto_tree_add_text(rr_tree, tvb, cur_offset, 2, + "Number of pending sessions: %u", + tvb_get_ntohs(tvb, cur_offset)); cur_offset += 2; data_len -= 2; - if (!BYTES_ARE_IN_FRAME(cur_offset, 2)) { - /* We ran past the end of the captured - data in the packet. */ - return 0; - } if (data_len < 2) { - proto_tree_add_text(rr_tree, NullTVB, cur_offset, + proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "(incomplete entry)"); break; } - proto_tree_add_text(rr_tree, NullTVB, cur_offset, 2, - "Max number of pending sessions: %u", pntohs(dptr)); - dptr += 2; + proto_tree_add_text(rr_tree, tvb, cur_offset, 2, + "Max number of pending sessions: %u", + tvb_get_ntohs(tvb, cur_offset)); cur_offset += 2; + data_len -= 2; - if (!BYTES_ARE_IN_FRAME(cur_offset, 2)) { - /* We ran past the end of the captured - data in the packet. */ - return 0; - } if (data_len < 2) { - proto_tree_add_text(rr_tree, NullTVB, cur_offset, + proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "(incomplete entry)"); break; } - proto_tree_add_text(rr_tree, NullTVB, cur_offset, 2, - "Max total sessions possible: %u", pntohs(dptr)); - dptr += 2; + proto_tree_add_text(rr_tree, tvb, cur_offset, 2, + "Max total sessions possible: %u", + tvb_get_ntohs(tvb, cur_offset)); cur_offset += 2; data_len -= 2; - if (!BYTES_ARE_IN_FRAME(cur_offset, 2)) { - /* We ran past the end of the captured - data in the packet. */ - return 0; - } if (data_len < 2) { - proto_tree_add_text(rr_tree, NullTVB, cur_offset, + proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "(incomplete entry)"); break; } - proto_tree_add_text(rr_tree, NullTVB, cur_offset, 2, - "Session data packet size: %u", pntohs(dptr)); - dptr += 2; + proto_tree_add_text(rr_tree, tvb, cur_offset, 2, + "Session data packet size: %u", + tvb_get_ntohs(tvb, cur_offset)); cur_offset += 2; data_len -= 2; out: @@ -1053,22 +899,22 @@ dissect_nbns_answer(const u_char *pd, int offset, int nbns_data_offset, col_append_fstr(fd, COL_INFO, " %s", type_name); if (nbns_tree == NULL) break; - trr = proto_tree_add_text(nbns_tree, NullTVB, offset, - (dptr - data_start) + data_len, + trr = proto_tree_add_text(nbns_tree, tvb, offset, + (data_offset - data_start) + data_len, "%s: type %s, class %s", name, type_name, class_name); - rr_tree = add_rr_to_tree(trr, ett_nbns_rr, offset, name, + rr_tree = add_rr_to_tree(trr, ett_nbns_rr, tvb, offset, name, name_len, type_name, class_name, ttl, data_len); - proto_tree_add_text(rr_tree, NullTVB, cur_offset, data_len, "Data"); + proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "Data"); + cur_offset += data_len; break; } - dptr += data_len; - return dptr - data_start; + return cur_offset - data_start; } static int -dissect_query_records(const u_char *pd, int cur_off, int nbns_data_offset, +dissect_query_records(tvbuff_t *tvb, int cur_off, int nbns_data_offset, int count, frame_data *fd, proto_tree *nbns_tree) { int start_off, add_off; @@ -1077,11 +923,11 @@ dissect_query_records(const u_char *pd, int cur_off, int nbns_data_offset, start_off = cur_off; if (nbns_tree != NULL) { - ti = proto_tree_add_text(nbns_tree, NullTVB, start_off, 0, "Queries"); + ti = proto_tree_add_text(nbns_tree, tvb, start_off, 0, "Queries"); qatree = proto_item_add_subtree(ti, ett_nbns_qry); } while (count-- > 0) { - add_off = dissect_nbns_query(pd, cur_off, nbns_data_offset, + add_off = dissect_nbns_query(tvb, cur_off, nbns_data_offset, fd, qatree); if (add_off <= 0) { /* We ran past the end of the captured data in the @@ -1099,7 +945,7 @@ dissect_query_records(const u_char *pd, int cur_off, int nbns_data_offset, static int -dissect_answer_records(const u_char *pd, int cur_off, int nbns_data_offset, +dissect_answer_records(tvbuff_t *tvb, int cur_off, int nbns_data_offset, int count, frame_data *fd, proto_tree *nbns_tree, int opcode, char *name) { int start_off, add_off; @@ -1108,11 +954,11 @@ dissect_answer_records(const u_char *pd, int cur_off, int nbns_data_offset, start_off = cur_off; if (nbns_tree != NULL) { - ti = proto_tree_add_text(nbns_tree, NullTVB, start_off, 0, name); + ti = proto_tree_add_text(nbns_tree, tvb, start_off, 0, name); qatree = proto_item_add_subtree(ti, ett_nbns_ans); } while (count-- > 0) { - add_off = dissect_nbns_answer(pd, cur_off, nbns_data_offset, + add_off = dissect_nbns_answer(tvb, cur_off, nbns_data_offset, fd, qatree, opcode); if (add_off <= 0) { /* We ran past the end of the captured data in the @@ -1127,9 +973,11 @@ dissect_answer_records(const u_char *pd, int cur_off, int nbns_data_offset, } static void -dissect_nbns(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) +dissect_nbns(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { + int offset = 0; int nbns_data_offset; + frame_data *fd; proto_tree *nbns_tree = NULL; proto_item *ti; guint16 id, flags, quest, ans, auth, add; @@ -1137,32 +985,21 @@ dissect_nbns(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) nbns_data_offset = offset; - if (check_col(fd, COL_PROTOCOL)) - col_set_str(fd, COL_PROTOCOL, "NBNS"); - if (check_col(fd, COL_INFO)) - col_clear(fd, COL_INFO); - - if (pi.captured_len < NBNS_HDRLEN) { - if (check_col(fd, COL_INFO)) { - col_set_str(fd, COL_INFO, "Short NBNS packet"); - } - old_dissect_data(pd, offset, fd, tree); - return; - } + if (check_col(pinfo->fd, COL_PROTOCOL)) + col_set_str(pinfo->fd, COL_PROTOCOL, "NBNS"); + if (check_col(pinfo->fd, COL_INFO)) + col_clear(pinfo->fd, COL_INFO); /* To do: check for runts, errs, etc. */ - id = pntohs(&pd[offset + NBNS_ID]); - flags = pntohs(&pd[offset + NBNS_FLAGS]); - quest = pntohs(&pd[offset + NBNS_QUEST]); - ans = pntohs(&pd[offset + NBNS_ANS]); - auth = pntohs(&pd[offset + NBNS_AUTH]); - add = pntohs(&pd[offset + NBNS_ADD]); - - if (check_col(fd, COL_INFO)) { - col_add_fstr(fd, COL_INFO, "%s%s", + id = tvb_get_ntohs(tvb, offset + NBNS_ID); + flags = tvb_get_ntohs(tvb, offset + NBNS_FLAGS); + + if (check_col(pinfo->fd, COL_INFO)) { + col_add_fstr(pinfo->fd, COL_INFO, "%s%s", val_to_str(flags & F_OPCODE, opcode_vals, "Unknown operation (%x)"), (flags & F_RESPONSE) ? " response" : ""); + fd = pinfo->fd; } else { /* Set "fd" to NULL; we pass a NULL "fd" to the query and answer dissectors, as a way of saying that they shouldn't @@ -1173,28 +1010,42 @@ dissect_nbns(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) } if (tree) { - ti = proto_tree_add_item(tree, proto_nbns, NullTVB, offset, END_OF_FRAME, FALSE); + ti = proto_tree_add_item(tree, proto_nbns, tvb, offset, + tvb_length(tvb), FALSE); nbns_tree = proto_item_add_subtree(ti, ett_nbns); if (flags & F_RESPONSE) { - proto_tree_add_boolean_hidden(nbns_tree, hf_nbns_response, NullTVB, + proto_tree_add_boolean_hidden(nbns_tree, hf_nbns_response, tvb, 0, 0, TRUE); } else { - proto_tree_add_boolean_hidden(nbns_tree, hf_nbns_query, NullTVB, + proto_tree_add_boolean_hidden(nbns_tree, hf_nbns_query, tvb, 0, 0, TRUE); } - proto_tree_add_uint(nbns_tree, hf_nbns_transaction_id, NullTVB, + proto_tree_add_uint(nbns_tree, hf_nbns_transaction_id, tvb, offset + NBNS_ID, 2, id); - nbns_add_nbns_flags(nbns_tree, offset + NBNS_FLAGS, flags, 0); - proto_tree_add_uint(nbns_tree, hf_nbns_count_questions, NullTVB, + nbns_add_nbns_flags(nbns_tree, tvb, offset + NBNS_FLAGS, + flags, 0); + } + quest = tvb_get_ntohs(tvb, offset + NBNS_QUEST); + if (tree) { + proto_tree_add_uint(nbns_tree, hf_nbns_count_questions, tvb, offset + NBNS_QUEST, 2, quest); - proto_tree_add_uint(nbns_tree, hf_nbns_count_answers, NullTVB, + } + ans = tvb_get_ntohs(tvb, offset + NBNS_ANS); + if (tree) { + proto_tree_add_uint(nbns_tree, hf_nbns_count_answers, tvb, offset + NBNS_ANS, 2, ans); - proto_tree_add_uint(nbns_tree, hf_nbns_count_auth_rr, NullTVB, + } + auth = tvb_get_ntohs(tvb, offset + NBNS_AUTH); + if (tree) { + proto_tree_add_uint(nbns_tree, hf_nbns_count_auth_rr, tvb, offset + NBNS_AUTH, 2, auth); - proto_tree_add_uint(nbns_tree, hf_nbns_count_add_rr, NullTVB, + } + add = tvb_get_ntohs(tvb, offset + NBNS_ADD); + if (tree) { + proto_tree_add_uint(nbns_tree, hf_nbns_count_add_rr, tvb, offset + NBNS_ADD, 2, add); } @@ -1204,7 +1055,7 @@ dissect_nbns(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) /* If this is a response, don't add information about the queries to the summary, just add information about the answers. */ - cur_off += dissect_query_records(pd, cur_off, + cur_off += dissect_query_records(tvb, cur_off, nbns_data_offset, quest, (!(flags & F_RESPONSE) ? fd : NULL), nbns_tree); } @@ -1213,7 +1064,7 @@ dissect_nbns(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) /* If this is a request, don't add information about the answers to the summary, just add information about the queries. */ - cur_off += dissect_answer_records(pd, cur_off, + cur_off += dissect_answer_records(tvb, cur_off, nbns_data_offset, ans, ((flags & F_RESPONSE) ? fd : NULL), nbns_tree, flags & F_OPCODE, "Answers"); @@ -1223,14 +1074,14 @@ dissect_nbns(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) /* Don't add information about the authoritative name servers, or the additional records, to the summary. */ if (auth > 0) - cur_off += dissect_answer_records(pd, cur_off, + cur_off += dissect_answer_records(tvb, cur_off, nbns_data_offset, auth, NULL, nbns_tree, flags & F_OPCODE, "Authoritative nameservers"); if (add > 0) - cur_off += dissect_answer_records(pd, cur_off, + cur_off += dissect_answer_records(tvb, cur_off, nbns_data_offset, add, NULL, nbns_tree, flags & F_OPCODE, @@ -1259,14 +1110,15 @@ struct nbdgm_header { }; static void -dissect_nbdgm(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) +dissect_nbdgm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { + int offset = 0; proto_tree *nbdgm_tree = NULL; proto_item *ti; struct nbdgm_header header; int flags; int message_index; - int max_data = pi.captured_len - offset; + int max_data = tvb_length_remaining(tvb, offset); char *message[] = { "Unknown", @@ -1299,29 +1151,29 @@ dissect_nbdgm(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) int name_type; int len; - if (check_col(fd, COL_PROTOCOL)) - col_set_str(fd, COL_PROTOCOL, "NBDS"); - if (check_col(fd, COL_INFO)) - col_clear(fd, COL_INFO); + if (check_col(pinfo->fd, COL_PROTOCOL)) + col_set_str(pinfo->fd, COL_PROTOCOL, "NBDS"); + if (check_col(pinfo->fd, COL_INFO)) + col_clear(pinfo->fd, COL_INFO); - header.msg_type = pd[offset]; + header.msg_type = tvb_get_guint8(tvb, offset); - flags = pd[offset+1]; + flags = tvb_get_guint8(tvb, offset+1); header.flags.more = flags & 1; header.flags.first = (flags & 2) >> 1; header.flags.node_type = (flags & 12) >> 2; - header.dgm_id = pntohs(&pd[offset+2]); - memcpy(&header.src_ip, &pd[offset+4], 4); - header.src_port = pntohs(&pd[offset+8]); + header.dgm_id = tvb_get_ntohs(tvb, offset+2); + tvb_memcpy(tvb, (guint8 *)&header.src_ip, offset+4, 4); + header.src_port = tvb_get_ntohs(tvb, offset+8); if (header.msg_type == 0x10 || header.msg_type == 0x11 || header.msg_type == 0x12) { - header.dgm_length = pntohs(&pd[offset+10]); - header.pkt_offset = pntohs(&pd[offset+12]); + header.dgm_length = tvb_get_ntohs(tvb, offset+10); + header.pkt_offset = tvb_get_ntohs(tvb, offset+12); } else if (header.msg_type == 0x13) { - header.error_code = pntohs(&pd[offset+10]); + header.error_code = tvb_get_ntohs(tvb, offset+10); } message_index = header.msg_type - 0x0f; @@ -1329,40 +1181,40 @@ dissect_nbdgm(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) message_index = 0; } - if (check_col(fd, COL_INFO)) { - col_set_str(fd, COL_INFO, message[message_index]); + if (check_col(pinfo->fd, COL_INFO)) { + col_set_str(pinfo->fd, COL_INFO, message[message_index]); } if (tree) { - ti = proto_tree_add_item(tree, proto_nbdgm, NullTVB, offset, header.dgm_length, FALSE); + ti = proto_tree_add_item(tree, proto_nbdgm, tvb, offset, header.dgm_length, FALSE); nbdgm_tree = proto_item_add_subtree(ti, ett_nbdgm); - proto_tree_add_uint_format(nbdgm_tree, hf_nbdgm_type, NullTVB, + proto_tree_add_uint_format(nbdgm_tree, hf_nbdgm_type, tvb, offset, 1, header.msg_type, "Message Type: %s", message[message_index]); - proto_tree_add_boolean_format(nbdgm_tree, hf_nbdgm_fragment, NullTVB, + proto_tree_add_boolean_format(nbdgm_tree, hf_nbdgm_fragment, tvb, offset+1, 1, header.flags.more, "More fragments follow: %s", yesno[header.flags.more]); - proto_tree_add_boolean_format(nbdgm_tree, hf_nbdgm_first, NullTVB, + proto_tree_add_boolean_format(nbdgm_tree, hf_nbdgm_first, tvb, offset+1, 1, header.flags.first, "This is first fragment: %s", yesno[header.flags.first]); - proto_tree_add_uint_format(nbdgm_tree, hf_nbdgm_node_type, NullTVB, + proto_tree_add_uint_format(nbdgm_tree, hf_nbdgm_node_type, tvb, offset+1, 1, header.flags.node_type, "Node Type: %s", node[header.flags.node_type]); - proto_tree_add_uint(nbdgm_tree, hf_nbdgm_datagram_id, NullTVB, + proto_tree_add_uint(nbdgm_tree, hf_nbdgm_datagram_id, tvb, offset+2, 2, header.dgm_id); - proto_tree_add_ipv4(nbdgm_tree, hf_nbdgm_src_ip, NullTVB, + proto_tree_add_ipv4(nbdgm_tree, hf_nbdgm_src_ip, tvb, offset+4, 4, header.src_ip); - proto_tree_add_uint(nbdgm_tree, hf_nbdgm_src_port, NullTVB, + proto_tree_add_uint(nbdgm_tree, hf_nbdgm_src_port, tvb, offset+8, 2, header.src_port); } @@ -1374,9 +1226,9 @@ dissect_nbdgm(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) header.msg_type == 0x11 || header.msg_type == 0x12) { if (tree) { - proto_tree_add_text(nbdgm_tree, NullTVB, offset, 2, + proto_tree_add_text(nbdgm_tree, tvb, offset, 2, "Datagram length: %d bytes", header.dgm_length); - proto_tree_add_text(nbdgm_tree, NullTVB, offset+2, 2, + proto_tree_add_text(nbdgm_tree, tvb, offset+2, 2, "Packet offset: %d bytes", header.pkt_offset); } @@ -1384,41 +1236,53 @@ dissect_nbdgm(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) max_data -= 4; /* Source name */ - len = get_nbns_name(pd, offset, offset, name, &name_type); + len = get_nbns_name(tvb, offset, offset, name, &name_type); if (tree) { - add_name_and_type(nbdgm_tree, offset, len, + add_name_and_type(nbdgm_tree, tvb, offset, len, "Source name", name, name_type); } offset += len; max_data -= len; /* Destination name */ - len = get_nbns_name(pd, offset, offset, name, &name_type); + len = get_nbns_name(tvb, offset, offset, name, &name_type); if (tree) { - add_name_and_type(nbdgm_tree, offset, len, + add_name_and_type(nbdgm_tree, tvb, offset, len, "Destination name", name, name_type); } offset += len; max_data -= len; - /* here we can pass the packet off to the next protocol */ - dissect_smb(pd, offset, fd, tree, max_data); + /* + * Here we can pass the packet off to the next protocol. + */ + { + 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); + } } else if (header.msg_type == 0x13) { if (tree) { - proto_tree_add_text(nbdgm_tree, NullTVB, offset, 1, "Error code: %s", + proto_tree_add_text(nbdgm_tree, tvb, offset, 1, "Error code: %s", val_to_str(header.error_code, error_codes, "Unknown (0x%x)")); } } else if (header.msg_type == 0x14 || header.msg_type == 0x15 || header.msg_type == 0x16) { /* Destination name */ - len = get_nbns_name(pd, offset, offset, name, &name_type); + len = get_nbns_name(tvb, offset, offset, name, &name_type); if (tree) { - add_name_and_type(nbdgm_tree, offset, len, + add_name_and_type(nbdgm_tree, tvb, offset, len, "Destination name", name, name_type); } } @@ -1473,7 +1337,8 @@ static const value_string error_codes[] = { * (MMM). ] */ static int -dissect_nbss_packet(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int max_data, int is_cifs) +dissect_nbss_packet(tvbuff_t *tvb, int offset, packet_info *pinfo, + proto_tree *tree, int max_data, int is_cifs) { proto_tree *nbss_tree = NULL; proto_item *ti; @@ -1486,23 +1351,23 @@ dissect_nbss_packet(const u_char *pd, int offset, frame_data *fd, proto_tree *tr char name[(NETBIOS_NAME_LEN - 1)*4 + MAXDNAME]; int name_type; - msg_type = pd[offset]; + msg_type = tvb_get_guint8(tvb, offset); if (is_cifs) { flags = 0; - length = pntohl(&pd[offset]) & 0x00FFFFFF; + length = tvb_get_ntoh24(tvb, offset + 1); } else { - flags = pd[offset + 1]; - length = pntohs(&pd[offset + 2]); + flags = tvb_get_guint8(tvb, offset + 1); + length = tvb_get_ntohs(tvb, offset + 2); if (flags & NBSS_FLAGS_E) length += 65536; } if (tree) { - ti = proto_tree_add_item(tree, proto_nbss, NullTVB, offset, length + 4, FALSE); + ti = proto_tree_add_item(tree, proto_nbss, tvb, offset, length + 4, FALSE); nbss_tree = proto_item_add_subtree(ti, ett_nbss); - proto_tree_add_uint_format(nbss_tree, hf_nbss_type, NullTVB, + proto_tree_add_uint_format(nbss_tree, hf_nbss_type, tvb, offset, 1, msg_type, "Message Type: %s", @@ -1514,21 +1379,21 @@ dissect_nbss_packet(const u_char *pd, int offset, frame_data *fd, proto_tree *tr if (is_cifs) { if (tree) { - proto_tree_add_text(nbss_tree, NullTVB, offset, 3, "Length: %u", length); + proto_tree_add_text(nbss_tree, tvb, offset, 3, "Length: %u", length); } offset += 3; } else { if (tree) { - tf = proto_tree_add_uint(nbss_tree, hf_nbss_flags, NullTVB, offset, 1, flags); + tf = proto_tree_add_uint(nbss_tree, hf_nbss_flags, tvb, offset, 1, flags); field_tree = proto_item_add_subtree(tf, ett_nbss_flags); - proto_tree_add_text(field_tree, NullTVB, offset, 1, "%s", + proto_tree_add_text(field_tree, tvb, offset, 1, "%s", decode_boolean_bitfield(flags, NBSS_FLAGS_E, 8, "Add 65536 to length", "Add 0 to length")); } offset += 1; if (tree) { - proto_tree_add_text(nbss_tree, NullTVB, offset, 2, "Length: %u", length); + proto_tree_add_text(nbss_tree, tvb, offset, 2, "Length: %u", length); } offset += 2; @@ -1537,38 +1402,40 @@ dissect_nbss_packet(const u_char *pd, int offset, frame_data *fd, proto_tree *tr switch (msg_type) { case SESSION_REQUEST: - len = get_nbns_name(pd, offset, offset, name, &name_type); + len = get_nbns_name(tvb, offset, offset, name, &name_type); if (tree) - add_name_and_type(nbss_tree, offset, len, + add_name_and_type(nbss_tree, tvb, offset, len, "Called name", name, name_type); offset += len; - len = get_nbns_name(pd, offset, offset, name, &name_type); + len = get_nbns_name(tvb, offset, offset, name, &name_type); if (tree) - add_name_and_type(nbss_tree, offset, len, + add_name_and_type(nbss_tree, tvb, offset, len, "Calling name", name, name_type); break; case NEGATIVE_SESSION_RESPONSE: if (tree) - proto_tree_add_text(nbss_tree, NullTVB, offset, 1, + proto_tree_add_text(nbss_tree, tvb, offset, 1, "Error code: %s", - val_to_str(pd[offset], error_codes, "Unknown (%x)")); + val_to_str(tvb_get_guint8(tvb, offset), + error_codes, "Unknown (%x)")); break; case RETARGET_SESSION_RESPONSE: if (tree) - proto_tree_add_text(nbss_tree, NullTVB, offset, 4, + proto_tree_add_text(nbss_tree, tvb, offset, 4, "Retarget IP address: %s", - ip_to_str((guint8 *)&pd[offset])); + ip_to_str(tvb_get_ptr(tvb, offset, 4))); offset += 4; if (tree) - proto_tree_add_text(nbss_tree, NullTVB, offset, 2, - "Retarget port: %u", pntohs(&pd[offset])); + proto_tree_add_text(nbss_tree, tvb, offset, 2, + "Retarget port: %u", + tvb_get_ntohs(tvb, offset)); break; @@ -1576,9 +1443,17 @@ dissect_nbss_packet(const u_char *pd, int offset, frame_data *fd, proto_tree *tr /* * Here we can pass the packet off to the next protocol. */ + { + tvbuff_t *next_tvb; + const guint8 *next_pd; + int next_offset; - dissect_smb(pd, offset, fd, tree, max_data - 4); + 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); + } break; } @@ -1586,23 +1461,28 @@ dissect_nbss_packet(const u_char *pd, int offset, frame_data *fd, proto_tree *tr } static void -dissect_nbss(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) +dissect_nbss(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { + int offset = 0; guint8 msg_type; - guint8 flags; - guint16 length; - int len; int max_data; - int is_cifs; + int len; + gboolean is_cifs; - if (check_col(fd, COL_PROTOCOL)) - col_set_str(fd, COL_PROTOCOL, "NBSS"); - if (check_col(fd, COL_INFO)) - col_clear(fd, COL_INFO); + if (check_col(pinfo->fd, COL_PROTOCOL)) + col_set_str(pinfo->fd, COL_PROTOCOL, "NBSS"); + if (check_col(pinfo->fd, COL_INFO)) + col_clear(pinfo->fd, COL_INFO); - msg_type = pd[offset]; + msg_type = tvb_get_guint8(tvb, offset); + + /* + * XXX - we should set this based on both the length remaining + * and "length".... + */ + max_data = tvb_length_remaining(tvb, offset); - if (pi.match_port == TCP_PORT_CIFS) { + if (pinfo->match_port == TCP_PORT_CIFS) { /* * Windows 2000 CIFS clients can dispense completely * with the NETBIOS encapsulation and directly use CIFS @@ -1611,23 +1491,11 @@ dissect_nbss(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) * of 17. The only message types used are * SESSION_MESSAGE and SESSION_KEEP_ALIVE. */ - flags = 0; - length = pntohl(&pd[offset]) & 0x00FFFFFF; is_cifs = TRUE; } else { - flags = pd[offset + 1]; - length = pntohs(&pd[offset + 2]); - if (flags & NBSS_FLAGS_E) - length += 65536; is_cifs = FALSE; } - /* - * XXX - we should set this based on both "pi.captured_len" - * and "length".... - */ - max_data = pi.captured_len - offset; - /* Hmmm, it may be a continuation message ... */ #define RJSHACK 1 @@ -1636,32 +1504,40 @@ dissect_nbss(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) (msg_type != POSITIVE_SESSION_RESPONSE) && (msg_type != NEGATIVE_SESSION_RESPONSE) && (msg_type != RETARGET_SESSION_RESPONSE) && + (msg_type != SESSION_KEEP_ALIVE) && (msg_type != SESSION_MESSAGE)) || ((msg_type == SESSION_MESSAGE) && - (memcmp(pd + offset + 4, "\377SMB", 4) != 0))) { + (max_data < 8 || tvb_memeql(tvb, offset + 4, "\377SMB", 4) != 0))) { - if (check_col(fd, COL_INFO)) { - col_add_fstr(fd, COL_INFO, "NBSS Continuation Message"); + /* + * Either the first byte isn't one of the known message types, + * or it's a session message but we either don't have enough + * data in the frame for the NBSS/CIFS header plus an SMB header, + * or we do but the message data doesn't begin with 0xFF S M B. + * Assume it's a continuation message. + */ + if (check_col(pinfo->fd, COL_INFO)) { + col_add_fstr(pinfo->fd, COL_INFO, "NBSS Continuation Message"); } if (tree) - proto_tree_add_text(tree, NullTVB, offset, max_data, "Continuation data"); + proto_tree_add_text(tree, tvb, offset, max_data, "Continuation data"); return; } #endif - if (check_col(fd, COL_INFO)) { - col_add_fstr(fd, COL_INFO, + if (check_col(pinfo->fd, COL_INFO)) { + col_add_fstr(pinfo->fd, COL_INFO, val_to_str(msg_type, message_types, "Unknown (%x)")); } while (max_data > 0) { - len = dissect_nbss_packet(pd, offset, fd, tree, max_data, is_cifs); + len = dissect_nbss_packet(tvb, offset, pinfo, tree, max_data, + is_cifs); offset += len; max_data -= len; } - } void @@ -1771,8 +1647,8 @@ proto_register_nbt(void) void proto_reg_handoff_nbt(void) { - old_dissector_add("udp.port", UDP_PORT_NBNS, dissect_nbns, proto_nbns); - old_dissector_add("udp.port", UDP_PORT_NBDGM, dissect_nbdgm, proto_nbdgm); - old_dissector_add("tcp.port", TCP_PORT_NBSS, dissect_nbss, proto_nbss); - old_dissector_add("tcp.port", TCP_PORT_CIFS, dissect_nbss, proto_nbss); + dissector_add("udp.port", UDP_PORT_NBNS, dissect_nbns, proto_nbns); + dissector_add("udp.port", UDP_PORT_NBDGM, dissect_nbdgm, proto_nbdgm); + dissector_add("tcp.port", TCP_PORT_NBSS, dissect_nbss, proto_nbss); + dissector_add("tcp.port", TCP_PORT_CIFS, dissect_nbss, proto_nbss); } |