2 * Routines for NetBIOS-over-TCP packet disassembly (the name dates back
3 * to when it had only NBNS)
4 * Guy Harris <guy@alum.mit.edu>
6 * $Id: packet-nbns.c,v 1.74 2002/02/28 23:09:03 guy Exp $
8 * Ethereal - Network traffic analyzer
9 * By Gerald Combs <gerald@ethereal.com>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #ifdef HAVE_SYS_TYPES_H
32 # include <sys/types.h>
39 #include <epan/packet.h>
40 #include "packet-dns.h"
41 #include "packet-netbios.h"
42 #include "packet-tcp.h"
43 #include "packet-frame.h"
46 static int proto_nbns = -1;
47 static int hf_nbns_response = -1;
48 static int hf_nbns_query = -1;
49 static int hf_nbns_transaction_id = -1;
50 static int hf_nbns_count_questions = -1;
51 static int hf_nbns_count_answers = -1;
52 static int hf_nbns_count_auth_rr = -1;
53 static int hf_nbns_count_add_rr = -1;
55 static gint ett_nbns = -1;
56 static gint ett_nbns_qd = -1;
57 static gint ett_nbns_flags = -1;
58 static gint ett_nbns_nb_flags = -1;
59 static gint ett_nbns_name_flags = -1;
60 static gint ett_nbns_rr = -1;
61 static gint ett_nbns_qry = -1;
62 static gint ett_nbns_ans = -1;
64 static int proto_nbdgm = -1;
65 static int hf_nbdgm_type = -1;
66 static int hf_nbdgm_fragment = -1;
67 static int hf_nbdgm_first = -1;
68 static int hf_nbdgm_node_type = -1;
69 static int hf_nbdgm_datagram_id = -1;
70 static int hf_nbdgm_src_ip = -1;
71 static int hf_nbdgm_src_port = -1;
73 static gint ett_nbdgm = -1;
75 static int proto_nbss = -1;
76 static int hf_nbss_type = -1;
77 static int hf_nbss_flags = -1;
79 static gint ett_nbss = -1;
80 static gint ett_nbss_flags = -1;
82 /* desegmentation of NBSS over TCP */
83 static gboolean nbss_desegment = TRUE;
85 /* See RFC 1001 and 1002 for information on the first three, and see
87 http://www.cifs.com/specs/draft-leach-cifs-v1-spec-01.txt
89 Appendix B, and various messages on the CIFS mailing list such as
91 http://discuss.microsoft.com/SCRIPTS/WA-MSD.EXE?A2=ind9811A&L=cifs&P=R386
93 for information on the fourth. */
94 #define UDP_PORT_NBNS 137
95 #define UDP_PORT_NBDGM 138
96 #define TCP_PORT_NBSS 139
97 #define TCP_PORT_CIFS 445
99 /* Packet structure taken from RFC 1002. See also RFC 1001.
100 * Opcode, flags, and rcode treated as "flags", similarly to DNS,
101 * to make it easier to lift the dissection code from "packet-dns.c". */
103 /* Offsets of fields in the NBNS header. */
111 /* Length of NBNS header. */
112 #define NBNS_HDRLEN 12
115 #define T_NB 32 /* NetBIOS name service RR */
116 #define T_NBSTAT 33 /* NetBIOS node status RR */
118 /* Bit fields in the flags */
119 #define F_RESPONSE (1<<15) /* packet is response */
120 #define F_OPCODE (0xF<<11) /* query opcode */
121 #define F_AUTHORITATIVE (1<<10) /* response is authoritative */
122 #define F_TRUNCATED (1<<9) /* response is truncated */
123 #define F_RECDESIRED (1<<8) /* recursion desired */
124 #define F_RECAVAIL (1<<7) /* recursion available */
125 #define F_BROADCAST (1<<4) /* broadcast/multicast packet */
126 #define F_RCODE (0xF<<0) /* reply code */
129 #define OPCODE_QUERY (0<<11) /* standard query */
130 #define OPCODE_REGISTRATION (5<<11) /* registration */
131 #define OPCODE_RELEASE (6<<11) /* release name */
132 #define OPCODE_WACK (7<<11) /* wait for acknowledgement */
133 #define OPCODE_REFRESH (8<<11) /* refresh registration */
134 #define OPCODE_REFRESHALT (9<<11) /* refresh registration (alternate opcode) */
135 #define OPCODE_MHREGISTRATION (15<<11) /* multi-homed registration */
138 #define RCODE_NOERROR (0<<0)
139 #define RCODE_FMTERROR (1<<0)
140 #define RCODE_SERVFAIL (2<<0)
141 #define RCODE_NAMEERROR (3<<0)
142 #define RCODE_NOTIMPL (4<<0)
143 #define RCODE_REFUSED (5<<0)
144 #define RCODE_ACTIVE (6<<0)
145 #define RCODE_CONFLICT (7<<0)
147 /* Values for the "NB_FLAGS" field of RR data. From RFC 1001 and 1002,
148 * except for NB_FLAGS_ONT_H_NODE, which was discovered by looking at
150 #define NB_FLAGS_ONT (3<<(15-2)) /* bits for node type */
151 #define NB_FLAGS_ONT_B_NODE (0<<(15-2)) /* B-mode node */
152 #define NB_FLAGS_ONT_P_NODE (1<<(15-2)) /* P-mode node */
153 #define NB_FLAGS_ONT_M_NODE (2<<(15-2)) /* M-mode node */
154 #define NB_FLAGS_ONT_H_NODE (3<<(15-2)) /* H-mode node */
156 #define NB_FLAGS_G (1<<(15-0)) /* group name */
158 /* Values for the "NAME_FLAGS" field of a NODE_NAME entry in T_NBSTAT
159 * RR data. From RFC 1001 and 1002, except for NAME_FLAGS_ONT_H_NODE,
160 * which was discovered by looking at packet traces. */
161 #define NAME_FLAGS_PRM (1<<(15-6)) /* name is permanent node name */
163 #define NAME_FLAGS_ACT (1<<(15-5)) /* name is active */
165 #define NAME_FLAGS_CNF (1<<(15-4)) /* name is in conflict */
167 #define NAME_FLAGS_DRG (1<<(15-3)) /* name is being deregistered */
169 #define NAME_FLAGS_ONT (3<<(15-2)) /* bits for node type */
170 #define NAME_FLAGS_ONT_B_NODE (0<<(15-2)) /* B-mode node */
171 #define NAME_FLAGS_ONT_P_NODE (1<<(15-2)) /* P-mode node */
172 #define NAME_FLAGS_ONT_M_NODE (2<<(15-2)) /* M-mode node */
174 #define NAME_FLAGS_G (1<<(15-0)) /* group name */
176 static const value_string opcode_vals[] = {
177 { OPCODE_QUERY, "Name query" },
178 { OPCODE_REGISTRATION, "Registration" },
179 { OPCODE_RELEASE, "Release" },
180 { OPCODE_WACK, "Wait for acknowledgment" },
181 { OPCODE_REFRESH, "Refresh" },
182 { OPCODE_REFRESHALT, "Refresh (alternate opcode)" },
183 { OPCODE_MHREGISTRATION, "Multi-homed registration" },
188 nbns_type_name (int type)
200 #define NBNAME_BUF_LEN 128
203 get_nbns_name(tvbuff_t *tvb, int offset, int nbns_data_offset,
204 char *name_ret, int *name_type_ret)
208 char nbname[NBNAME_BUF_LEN];
209 char *pname, *pnbname, cname, cnbname;
212 name_len = get_dns_name(tvb, offset, nbns_data_offset, name,
215 /* OK, now undo the first-level encoding. */
217 pnbname = &nbname[0];
219 /* Every two characters of the first level-encoded name
220 * turn into one character in the decoded name. */
223 break; /* no more characters */
225 break; /* scope ID follows */
226 if (cname < 'A' || cname > 'Z') {
229 "Illegal NetBIOS name (character not between A and Z in first-level encoding)");
233 cnbname = cname << 4;
237 if (cname == '\0' || cname == '.') {
238 /* No more characters in the name - but we're in
239 * the middle of a pair. Not legal. */
241 "Illegal NetBIOS name (odd number of bytes)");
244 if (cname < 'A' || cname > 'Z') {
247 "Illegal NetBIOS name (character not between A and Z in first-level encoding)");
254 /* Do we have room to store the character? */
255 if (pnbname < &nbname[NETBIOS_NAME_LEN]) {
256 /* Yes - store the character. */
260 /* We bump the pointer even if it's past the end of the
261 name, so we keep track of how long the name is. */
265 /* NetBIOS names are supposed to be exactly 16 bytes long. */
266 if (pnbname - nbname != NETBIOS_NAME_LEN) {
268 sprintf(nbname, "Illegal NetBIOS name (%ld bytes long)",
269 (long)(pnbname - nbname));
273 /* This one is; make its name printable. */
274 name_type = process_netbios_name(nbname, name_ret);
275 name_ret += strlen(name_ret);
276 sprintf(name_ret, "<%02x>", name_type);
279 /* We have a scope ID, starting at "pname"; append that to
280 * the decoded host name. */
281 strcpy(name_ret, pname);
283 if (name_type_ret != NULL)
284 *name_type_ret = name_type;
288 if (name_type_ret != NULL)
290 strcpy (name_ret, nbname);
296 get_nbns_name_type_class(tvbuff_t *tvb, int offset, int nbns_data_offset,
297 char *name_ret, int *name_len_ret, int *name_type_ret, int *type_ret,
304 name_len = get_nbns_name(tvb, offset, nbns_data_offset, name_ret,
308 type = tvb_get_ntohs(tvb, offset);
311 class = tvb_get_ntohs(tvb, offset);
315 *name_len_ret = name_len;
321 add_name_and_type(proto_tree *tree, tvbuff_t *tvb, int offset, int len,
322 char *tag, char *name, int name_type)
324 if (name_type != -1) {
325 proto_tree_add_text(tree, tvb, offset, len, "%s: %s (%s)",
326 tag, name, netbios_name_type_descr(name_type));
328 proto_tree_add_text(tree, tvb, offset, len, "%s: %s",
334 dissect_nbns_query(tvbuff_t *tvb, int offset, int nbns_data_offset,
335 column_info *cinfo, proto_tree *nbns_tree)
338 char name[(NETBIOS_NAME_LEN - 1)*4 + MAXDNAME];
350 data_start = data_offset = offset;
352 len = get_nbns_name_type_class(tvb, offset, nbns_data_offset, name,
353 &name_len, &name_type, &type, &class);
356 type_name = nbns_type_name(type);
357 class_name = dns_class_name(class);
360 col_append_fstr(cinfo, COL_INFO, " %s %s", type_name, name);
361 if (nbns_tree != NULL) {
362 tq = proto_tree_add_text(nbns_tree, tvb, offset, len,
363 "%s: type %s, class %s", name, type_name, class_name);
364 q_tree = proto_item_add_subtree(tq, ett_nbns_qd);
366 add_name_and_type(q_tree, tvb, offset, name_len, "Name", name,
370 proto_tree_add_text(q_tree, tvb, offset, 2, "Type: %s", type_name);
373 proto_tree_add_text(q_tree, tvb, offset, 2, "Class: %s", class_name);
377 return data_offset - data_start;
381 nbns_add_nbns_flags(proto_tree *nbns_tree, tvbuff_t *tvb, int offset,
382 u_short flags, int is_wack)
385 proto_tree *field_tree;
387 static const value_string rcode_vals[] = {
388 { RCODE_NOERROR, "No error" },
389 { RCODE_FMTERROR, "Request was invalidly formatted" },
390 { RCODE_SERVFAIL, "Server failure" },
391 { RCODE_NAMEERROR, "Requested name does not exist" },
392 { RCODE_NOTIMPL, "Request is not implemented" },
393 { RCODE_REFUSED, "Request was refused" },
394 { RCODE_ACTIVE, "Name is owned by another node" },
395 { RCODE_CONFLICT, "Name is in conflict" },
399 strcpy(buf, val_to_str(flags & F_OPCODE, opcode_vals,
400 "Unknown operation"));
401 if (flags & F_RESPONSE && !is_wack) {
402 strcat(buf, " response");
404 strcat(buf, val_to_str(flags & F_RCODE, rcode_vals,
407 tf = proto_tree_add_text(nbns_tree, tvb, offset, 2,
408 "Flags: 0x%04x (%s)", flags, buf);
409 field_tree = proto_item_add_subtree(tf, ett_nbns_flags);
410 proto_tree_add_text(field_tree, tvb, offset, 2, "%s",
411 decode_boolean_bitfield(flags, F_RESPONSE,
412 2*8, "Response", "Query"));
413 proto_tree_add_text(field_tree, tvb, offset, 2, "%s",
414 decode_enumerated_bitfield(flags, F_OPCODE,
415 2*8, opcode_vals, "%s"));
416 if (flags & F_RESPONSE) {
417 proto_tree_add_text(field_tree, tvb, offset, 2,
419 decode_boolean_bitfield(flags, F_AUTHORITATIVE,
421 "Server is an authority for domain",
422 "Server isn't an authority for domain"));
424 proto_tree_add_text(field_tree, tvb, offset, 2, "%s",
425 decode_boolean_bitfield(flags, F_TRUNCATED,
427 "Message is truncated",
428 "Message is not truncated"));
429 proto_tree_add_text(field_tree, tvb, offset, 2, "%s",
430 decode_boolean_bitfield(flags, F_RECDESIRED,
432 "Do query recursively",
433 "Don't do query recursively"));
434 if (flags & F_RESPONSE) {
435 proto_tree_add_text(field_tree, tvb, offset, 2,
437 decode_boolean_bitfield(flags, F_RECAVAIL,
439 "Server can do recursive queries",
440 "Server can't do recursive queries"));
442 proto_tree_add_text(field_tree, tvb, offset, 2, "%s",
443 decode_boolean_bitfield(flags, F_BROADCAST,
446 "Not a broadcast packet"));
447 if (flags & F_RESPONSE && !is_wack) {
448 proto_tree_add_text(field_tree, tvb, offset, 2,
450 decode_enumerated_bitfield(flags, F_RCODE,
457 nbns_add_nb_flags(proto_tree *rr_tree, tvbuff_t *tvb, int offset, u_short flags)
460 proto_tree *field_tree;
462 static const value_string nb_flags_ont_vals[] = {
463 { NB_FLAGS_ONT_B_NODE, "B-node" },
464 { NB_FLAGS_ONT_P_NODE, "P-node" },
465 { NB_FLAGS_ONT_M_NODE, "M-node" },
466 { NB_FLAGS_ONT_H_NODE, "H-node" },
470 strcpy(buf, val_to_str(flags & NB_FLAGS_ONT, nb_flags_ont_vals,
473 if (flags & NB_FLAGS_G)
474 strcat(buf, "group");
476 strcat(buf, "unique");
477 tf = proto_tree_add_text(rr_tree, tvb, offset, 2, "Flags: 0x%x (%s)", flags,
479 field_tree = proto_item_add_subtree(tf, ett_nbns_nb_flags);
480 proto_tree_add_text(field_tree, tvb, offset, 2, "%s",
481 decode_boolean_bitfield(flags, NB_FLAGS_G,
485 proto_tree_add_text(field_tree, tvb, offset, 2, "%s",
486 decode_enumerated_bitfield(flags, NB_FLAGS_ONT,
487 2*8, nb_flags_ont_vals, "%s"));
491 nbns_add_name_flags(proto_tree *rr_tree, tvbuff_t *tvb, int offset,
495 proto_item *field_tree;
497 static const value_string name_flags_ont_vals[] = {
498 { NAME_FLAGS_ONT_B_NODE, "B-node" },
499 { NAME_FLAGS_ONT_P_NODE, "P-node" },
500 { NAME_FLAGS_ONT_M_NODE, "M-node" },
504 strcpy(buf, val_to_str(flags & NAME_FLAGS_ONT, name_flags_ont_vals,
507 if (flags & NAME_FLAGS_G)
508 strcat(buf, "group");
510 strcat(buf, "unique");
511 if (flags & NAME_FLAGS_DRG)
512 strcat(buf, ", being deregistered");
513 if (flags & NAME_FLAGS_CNF)
514 strcat(buf, ", in conflict");
515 if (flags & NAME_FLAGS_ACT)
516 strcat(buf, ", active");
517 if (flags & NAME_FLAGS_PRM)
518 strcat(buf, ", permanent node name");
519 tf = proto_tree_add_text(rr_tree, tvb, offset, 2, "Name flags: 0x%x (%s)",
521 field_tree = proto_item_add_subtree(tf, ett_nbns_name_flags);
522 proto_tree_add_text(field_tree, tvb, offset, 2, "%s",
523 decode_boolean_bitfield(flags, NAME_FLAGS_G,
527 proto_tree_add_text(field_tree, tvb, offset, 2, "%s",
528 decode_enumerated_bitfield(flags, NAME_FLAGS_ONT,
529 2*8, name_flags_ont_vals, "%s"));
530 proto_tree_add_text(field_tree, tvb, offset, 2, "%s",
531 decode_boolean_bitfield(flags, NAME_FLAGS_DRG,
533 "Name is being deregistered",
534 "Name is not being deregistered"));
535 proto_tree_add_text(field_tree, tvb, offset, 2, "%s",
536 decode_boolean_bitfield(flags, NAME_FLAGS_CNF,
538 "Name is in conflict",
539 "Name is not in conflict"));
540 proto_tree_add_text(field_tree, tvb, offset, 2, "%s",
541 decode_boolean_bitfield(flags, NAME_FLAGS_ACT,
544 "Name is not active"));
545 proto_tree_add_text(field_tree, tvb, offset, 2, "%s",
546 decode_boolean_bitfield(flags, NAME_FLAGS_PRM,
548 "Permanent node name",
549 "Not permanent node name"));
553 dissect_nbns_answer(tvbuff_t *tvb, int offset, int nbns_data_offset,
554 column_info *cinfo, proto_tree *nbns_tree, int opcode)
557 char name[(NETBIOS_NAME_LEN - 1)*4 + MAXDNAME + 64];
572 char name_str[(NETBIOS_NAME_LEN - 1)*4 + 1];
574 char nbname[16+4+1]; /* 4 for [<last char>] */
577 data_start = data_offset = offset;
580 len = get_nbns_name_type_class(tvb, offset, nbns_data_offset, name,
581 &name_len, &name_type, &type, &class);
585 type_name = nbns_type_name(type);
586 class_name = dns_class_name(class);
588 ttl = tvb_get_ntohl(tvb, data_offset);
592 data_len = tvb_get_ntohs(tvb, data_offset);
597 case T_NB: /* "NB" record */
599 if (opcode != OPCODE_WACK) {
600 col_append_fstr(cinfo, COL_INFO, " %s %s",
602 ip_to_str(tvb_get_ptr(tvb, data_offset+2, 4)));
605 if (nbns_tree == NULL)
607 trr = proto_tree_add_text(nbns_tree, tvb, offset,
608 (data_offset - data_start) + data_len,
609 "%s: type %s, class %s",
610 name, type_name, class_name);
612 strcat(name, netbios_name_type_descr(name_type));
614 rr_tree = add_rr_to_tree(trr, ett_nbns_rr, tvb, offset, name,
615 name_len, type_name, class_name, ttl, data_len);
616 while (data_len > 0) {
617 if (opcode == OPCODE_WACK) {
618 /* WACK response. This doesn't contain the
619 * same type of RR data as other T_NB
622 proto_tree_add_text(rr_tree, tvb, cur_offset,
623 data_len, "(incomplete entry)");
626 flags = tvb_get_ntohs(tvb, cur_offset);
627 nbns_add_nbns_flags(rr_tree, tvb, cur_offset,
633 proto_tree_add_text(rr_tree, tvb, cur_offset,
634 data_len, "(incomplete entry)");
637 flags = tvb_get_ntohs(tvb, cur_offset);
638 nbns_add_nb_flags(rr_tree, tvb, cur_offset,
644 proto_tree_add_text(rr_tree, tvb, cur_offset,
645 data_len, "(incomplete entry)");
648 proto_tree_add_text(rr_tree, tvb, cur_offset, 4,
650 ip_to_str(tvb_get_ptr(tvb, cur_offset, 4)));
657 case T_NBSTAT: /* "NBSTAT" record */
659 col_append_fstr(cinfo, COL_INFO, " %s", type_name);
660 if (nbns_tree == NULL)
662 trr = proto_tree_add_text(nbns_tree, tvb, offset,
663 (data_offset - data_start) + data_len,
664 "%s: type %s, class %s",
665 name, type_name, class_name);
666 rr_tree = add_rr_to_tree(trr, ett_nbns_rr, tvb, offset, name,
667 name_len, type_name, class_name, ttl, data_len);
669 proto_tree_add_text(rr_tree, tvb, cur_offset,
670 data_len, "(incomplete entry)");
673 num_names = tvb_get_guint8(tvb, cur_offset);
674 proto_tree_add_text(rr_tree, tvb, cur_offset, 1,
675 "Number of names: %u", num_names);
678 while (num_names != 0) {
679 if (data_len < NETBIOS_NAME_LEN) {
680 proto_tree_add_text(rr_tree, tvb, cur_offset,
681 data_len, "(incomplete entry)");
684 tvb_memcpy(tvb, (guint8 *)nbname, cur_offset,
686 name_type = process_netbios_name(nbname,
688 proto_tree_add_text(rr_tree, tvb, cur_offset,
689 NETBIOS_NAME_LEN, "Name: %s<%02x> (%s)",
691 netbios_name_type_descr(name_type));
692 cur_offset += NETBIOS_NAME_LEN;
693 data_len -= NETBIOS_NAME_LEN;
696 proto_tree_add_text(rr_tree, tvb, cur_offset,
697 data_len, "(incomplete entry)");
700 name_flags = tvb_get_ntohs(tvb, cur_offset);
701 nbns_add_name_flags(rr_tree, tvb, cur_offset,
710 proto_tree_add_text(rr_tree, tvb, cur_offset,
711 data_len, "(incomplete entry)");
714 proto_tree_add_text(rr_tree, tvb, cur_offset, 6,
716 ether_to_str(tvb_get_ptr(tvb, cur_offset, 6)));
721 proto_tree_add_text(rr_tree, tvb, cur_offset,
722 data_len, "(incomplete entry)");
725 proto_tree_add_text(rr_tree, tvb, cur_offset, 1,
726 "Jumpers: 0x%x", tvb_get_guint8(tvb, cur_offset));
731 proto_tree_add_text(rr_tree, tvb, cur_offset,
732 data_len, "(incomplete entry)");
735 proto_tree_add_text(rr_tree, tvb, cur_offset, 1,
736 "Test result: 0x%x", tvb_get_guint8(tvb, cur_offset));
741 proto_tree_add_text(rr_tree, tvb, cur_offset,
742 data_len, "(incomplete entry)");
745 proto_tree_add_text(rr_tree, tvb, cur_offset, 2,
746 "Version number: 0x%x", tvb_get_ntohs(tvb, cur_offset));
751 proto_tree_add_text(rr_tree, tvb, cur_offset,
752 data_len, "(incomplete entry)");
755 proto_tree_add_text(rr_tree, tvb, cur_offset, 2,
756 "Period of statistics: 0x%x",
757 tvb_get_ntohs(tvb, cur_offset));
762 proto_tree_add_text(rr_tree, tvb, cur_offset,
763 data_len, "(incomplete entry)");
766 proto_tree_add_text(rr_tree, tvb, cur_offset, 2,
767 "Number of CRCs: %u", tvb_get_ntohs(tvb, cur_offset));
772 proto_tree_add_text(rr_tree, tvb, cur_offset,
773 data_len, "(incomplete entry)");
776 proto_tree_add_text(rr_tree, tvb, cur_offset, 2,
777 "Number of alignment errors: %u",
778 tvb_get_ntohs(tvb, cur_offset));
783 proto_tree_add_text(rr_tree, tvb, cur_offset,
784 data_len, "(incomplete entry)");
787 proto_tree_add_text(rr_tree, tvb, cur_offset, 2,
788 "Number of collisions: %u", tvb_get_ntohs(tvb, cur_offset));
793 proto_tree_add_text(rr_tree, tvb, cur_offset,
794 data_len, "(incomplete entry)");
797 proto_tree_add_text(rr_tree, tvb, cur_offset, 2,
798 "Number of send aborts: %u", tvb_get_ntohs(tvb, cur_offset));
803 proto_tree_add_text(rr_tree, tvb, cur_offset,
804 data_len, "(incomplete entry)");
807 proto_tree_add_text(rr_tree, tvb, cur_offset, 4,
808 "Number of good sends: %u", tvb_get_ntohl(tvb, cur_offset));
813 proto_tree_add_text(rr_tree, tvb, cur_offset,
814 data_len, "(incomplete entry)");
817 proto_tree_add_text(rr_tree, tvb, cur_offset, 4,
818 "Number of good receives: %u",
819 tvb_get_ntohl(tvb, cur_offset));
824 proto_tree_add_text(rr_tree, tvb, cur_offset,
825 data_len, "(incomplete entry)");
828 proto_tree_add_text(rr_tree, tvb, cur_offset, 2,
829 "Number of retransmits: %u", tvb_get_ntohs(tvb, cur_offset));
834 proto_tree_add_text(rr_tree, tvb, cur_offset,
835 data_len, "(incomplete entry)");
838 proto_tree_add_text(rr_tree, tvb, cur_offset, 2,
839 "Number of no resource conditions: %u",
840 tvb_get_ntohs(tvb, cur_offset));
845 proto_tree_add_text(rr_tree, tvb, cur_offset,
846 data_len, "(incomplete entry)");
849 proto_tree_add_text(rr_tree, tvb, cur_offset, 2,
850 "Number of command blocks: %u",
851 tvb_get_ntohs(tvb, cur_offset));
856 proto_tree_add_text(rr_tree, tvb, cur_offset,
857 data_len, "(incomplete entry)");
860 proto_tree_add_text(rr_tree, tvb, cur_offset, 2,
861 "Number of pending sessions: %u",
862 tvb_get_ntohs(tvb, cur_offset));
867 proto_tree_add_text(rr_tree, tvb, cur_offset,
868 data_len, "(incomplete entry)");
871 proto_tree_add_text(rr_tree, tvb, cur_offset, 2,
872 "Max number of pending sessions: %u",
873 tvb_get_ntohs(tvb, cur_offset));
878 proto_tree_add_text(rr_tree, tvb, cur_offset,
879 data_len, "(incomplete entry)");
882 proto_tree_add_text(rr_tree, tvb, cur_offset, 2,
883 "Max total sessions possible: %u",
884 tvb_get_ntohs(tvb, cur_offset));
889 proto_tree_add_text(rr_tree, tvb, cur_offset,
890 data_len, "(incomplete entry)");
893 proto_tree_add_text(rr_tree, tvb, cur_offset, 2,
894 "Session data packet size: %u",
895 tvb_get_ntohs(tvb, cur_offset));
903 col_append_fstr(cinfo, COL_INFO, " %s", type_name);
904 if (nbns_tree == NULL)
906 trr = proto_tree_add_text(nbns_tree, tvb, offset,
907 (data_offset - data_start) + data_len,
908 "%s: type %s, class %s",
909 name, type_name, class_name);
910 rr_tree = add_rr_to_tree(trr, ett_nbns_rr, tvb, offset, name,
911 name_len, type_name, class_name, ttl, data_len);
912 proto_tree_add_text(rr_tree, tvb, cur_offset, data_len, "Data");
913 cur_offset += data_len;
917 return cur_offset - data_start;
921 dissect_query_records(tvbuff_t *tvb, int cur_off, int nbns_data_offset,
922 int count, column_info *cinfo, proto_tree *nbns_tree)
924 int start_off, add_off;
925 proto_tree *qatree = NULL;
926 proto_item *ti = NULL;
929 if (nbns_tree != NULL) {
930 ti = proto_tree_add_text(nbns_tree, tvb, start_off, -1, "Queries");
931 qatree = proto_item_add_subtree(ti, ett_nbns_qry);
933 while (count-- > 0) {
934 add_off = dissect_nbns_query(tvb, cur_off, nbns_data_offset,
939 proto_item_set_len(ti, cur_off - start_off);
941 return cur_off - start_off;
947 dissect_answer_records(tvbuff_t *tvb, int cur_off, int nbns_data_offset,
948 int count, column_info *cinfo, proto_tree *nbns_tree, int opcode,
951 int start_off, add_off;
952 proto_tree *qatree = NULL;
953 proto_item *ti = NULL;
956 if (nbns_tree != NULL) {
957 ti = proto_tree_add_text(nbns_tree, tvb, start_off, -1, name);
958 qatree = proto_item_add_subtree(ti, ett_nbns_ans);
960 while (count-- > 0) {
961 add_off = dissect_nbns_answer(tvb, cur_off, nbns_data_offset,
962 cinfo, qatree, opcode);
966 proto_item_set_len(ti, cur_off - start_off);
967 return cur_off - start_off;
971 dissect_nbns(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
974 int nbns_data_offset;
976 proto_tree *nbns_tree = NULL;
978 guint16 id, flags, quest, ans, auth, add;
981 nbns_data_offset = offset;
983 if (check_col(pinfo->cinfo, COL_PROTOCOL))
984 col_set_str(pinfo->cinfo, COL_PROTOCOL, "NBNS");
985 if (check_col(pinfo->cinfo, COL_INFO))
986 col_clear(pinfo->cinfo, COL_INFO);
988 /* To do: check for runts, errs, etc. */
989 id = tvb_get_ntohs(tvb, offset + NBNS_ID);
990 flags = tvb_get_ntohs(tvb, offset + NBNS_FLAGS);
992 if (check_col(pinfo->cinfo, COL_INFO)) {
993 col_add_fstr(pinfo->cinfo, COL_INFO, "%s%s",
994 val_to_str(flags & F_OPCODE, opcode_vals,
995 "Unknown operation (%x)"),
996 (flags & F_RESPONSE) ? " response" : "");
997 cinfo = pinfo->cinfo;
999 /* Set "cinfo" to NULL; we pass a NULL "cinfo" to the query
1000 and answer dissectors, as a way of saying that they
1001 shouldn't add stuff to the COL_INFO column (a call to
1002 "check_col(cinfo, COL_INFO)" is more expensive than
1003 a check that a pointer isn't NULL). */
1008 ti = proto_tree_add_item(tree, proto_nbns, tvb, offset, -1,
1010 nbns_tree = proto_item_add_subtree(ti, ett_nbns);
1012 if (flags & F_RESPONSE) {
1013 proto_tree_add_boolean_hidden(nbns_tree, hf_nbns_response, tvb,
1016 proto_tree_add_boolean_hidden(nbns_tree, hf_nbns_query, tvb,
1020 proto_tree_add_uint(nbns_tree, hf_nbns_transaction_id, tvb,
1021 offset + NBNS_ID, 2, id);
1023 nbns_add_nbns_flags(nbns_tree, tvb, offset + NBNS_FLAGS,
1026 quest = tvb_get_ntohs(tvb, offset + NBNS_QUEST);
1028 proto_tree_add_uint(nbns_tree, hf_nbns_count_questions, tvb,
1029 offset + NBNS_QUEST, 2, quest);
1031 ans = tvb_get_ntohs(tvb, offset + NBNS_ANS);
1033 proto_tree_add_uint(nbns_tree, hf_nbns_count_answers, tvb,
1034 offset + NBNS_ANS, 2, ans);
1036 auth = tvb_get_ntohs(tvb, offset + NBNS_AUTH);
1038 proto_tree_add_uint(nbns_tree, hf_nbns_count_auth_rr, tvb,
1039 offset + NBNS_AUTH, 2, auth);
1041 add = tvb_get_ntohs(tvb, offset + NBNS_ADD);
1043 proto_tree_add_uint(nbns_tree, hf_nbns_count_add_rr, tvb,
1044 offset + NBNS_ADD, 2, add);
1047 cur_off = offset + NBNS_HDRLEN;
1050 /* If this is a response, don't add information about the
1051 queries to the summary, just add information about the
1053 cur_off += dissect_query_records(tvb, cur_off,
1054 nbns_data_offset, quest,
1055 (!(flags & F_RESPONSE) ? cinfo : NULL), nbns_tree);
1059 /* If this is a request, don't add information about the
1060 answers to the summary, just add information about the
1062 cur_off += dissect_answer_records(tvb, cur_off,
1063 nbns_data_offset, ans,
1064 ((flags & F_RESPONSE) ? cinfo : NULL), nbns_tree,
1065 flags & F_OPCODE, "Answers");
1069 /* Don't add information about the authoritative name
1070 servers, or the additional records, to the summary. */
1072 cur_off += dissect_answer_records(tvb, cur_off,
1074 auth, NULL, nbns_tree,
1076 "Authoritative nameservers");
1079 cur_off += dissect_answer_records(tvb, cur_off,
1081 add, NULL, nbns_tree,
1083 "Additional records");
1087 /* NetBIOS datagram packet, from RFC 1002, page 32 */
1088 struct nbdgm_header {
1099 /* For packets with data */
1103 /* For error packets */
1108 * NBDS message types.
1110 #define NBDS_DIRECT_UNIQUE 0x10
1111 #define NBDS_DIRECT_GROUP 0x11
1112 #define NBDS_BROADCAST 0x12
1113 #define NBDS_ERROR 0x13
1114 #define NBDS_QUERY_REQUEST 0x14
1115 #define NBDS_POS_QUERY_RESPONSE 0x15
1116 #define NBDS_NEG_QUERY_RESPONSE 0x16
1118 static const value_string nbds_msgtype_vals[] = {
1119 { NBDS_DIRECT_UNIQUE, "Direct_unique datagram" },
1120 { NBDS_DIRECT_GROUP, "Direct_group datagram" },
1121 { NBDS_BROADCAST, "Broadcast datagram" },
1122 { NBDS_ERROR, "Datagram error" },
1123 { NBDS_QUERY_REQUEST, "Datagram query request" },
1124 { NBDS_POS_QUERY_RESPONSE, "Datagram positive query response" },
1125 { NBDS_NEG_QUERY_RESPONSE, "Datagram negative query response" },
1129 static const true_false_string yesno = {
1134 static const value_string node_type_vals[] = {
1143 dissect_nbdgm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1146 proto_tree *nbdgm_tree = NULL;
1147 proto_item *ti = NULL;
1148 struct nbdgm_header header;
1153 static const value_string error_codes[] = {
1154 { 0x82, "Destination name not present" },
1155 { 0x83, "Invalid source name format" },
1156 { 0x84, "Invalid destination name format" },
1160 char name[(NETBIOS_NAME_LEN - 1)*4 + MAXDNAME];
1164 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1165 col_set_str(pinfo->cinfo, COL_PROTOCOL, "NBDS");
1166 if (check_col(pinfo->cinfo, COL_INFO))
1167 col_clear(pinfo->cinfo, COL_INFO);
1169 header.msg_type = tvb_get_guint8(tvb, offset);
1171 flags = tvb_get_guint8(tvb, offset+1);
1172 header.flags.more = flags & 1;
1173 header.flags.first = (flags & 2) >> 1;
1174 header.flags.node_type = (flags & 12) >> 2;
1176 header.dgm_id = tvb_get_ntohs(tvb, offset+2);
1177 tvb_memcpy(tvb, (guint8 *)&header.src_ip, offset+4, 4);
1178 header.src_port = tvb_get_ntohs(tvb, offset+8);
1180 switch (header.msg_type) {
1182 case NBDS_DIRECT_UNIQUE:
1183 case NBDS_DIRECT_GROUP:
1184 case NBDS_BROADCAST:
1185 header.dgm_length = tvb_get_ntohs(tvb, offset+10);
1186 header.pkt_offset = tvb_get_ntohs(tvb, offset+12);
1190 header.error_code = tvb_get_ntohs(tvb, offset+10);
1194 message_index = header.msg_type - 0x0f;
1195 if (message_index < 1 || message_index > 8) {
1199 if (check_col(pinfo->cinfo, COL_INFO)) {
1200 col_add_str(pinfo->cinfo, COL_INFO,
1201 val_to_str(header.msg_type, nbds_msgtype_vals,
1202 "Unknown message type (0x%02X)"));
1206 ti = proto_tree_add_item(tree, proto_nbdgm, tvb, offset, -1,
1208 nbdgm_tree = proto_item_add_subtree(ti, ett_nbdgm);
1210 proto_tree_add_uint(nbdgm_tree, hf_nbdgm_type, tvb,
1213 proto_tree_add_boolean(nbdgm_tree, hf_nbdgm_fragment, tvb,
1216 proto_tree_add_boolean(nbdgm_tree, hf_nbdgm_first, tvb,
1218 header.flags.first);
1219 proto_tree_add_uint(nbdgm_tree, hf_nbdgm_node_type, tvb,
1221 header.flags.node_type);
1223 proto_tree_add_uint(nbdgm_tree, hf_nbdgm_datagram_id, tvb,
1224 offset+2, 2, header.dgm_id);
1225 proto_tree_add_ipv4(nbdgm_tree, hf_nbdgm_src_ip, tvb,
1226 offset+4, 4, header.src_ip);
1227 proto_tree_add_uint(nbdgm_tree, hf_nbdgm_src_port, tvb,
1228 offset+8, 2, header.src_port);
1234 switch (header.msg_type) {
1236 case NBDS_DIRECT_UNIQUE:
1237 case NBDS_DIRECT_GROUP:
1238 case NBDS_BROADCAST:
1240 proto_tree_add_text(nbdgm_tree, tvb, offset, 2,
1241 "Datagram length: %d bytes", header.dgm_length);
1242 proto_tree_add_text(nbdgm_tree, tvb, offset+2, 2,
1243 "Packet offset: %d bytes", header.pkt_offset);
1249 len = get_nbns_name(tvb, offset, offset, name, &name_type);
1252 add_name_and_type(nbdgm_tree, tvb, offset, len,
1253 "Source name", name, name_type);
1257 /* Destination name */
1258 len = get_nbns_name(tvb, offset, offset, name, &name_type);
1261 add_name_and_type(nbdgm_tree, tvb, offset, len,
1262 "Destination name", name, name_type);
1267 * Here we can pass the packet off to the next protocol.
1268 * Set the length of our top-level tree item to include
1271 * XXX - take the datagram length into account?
1273 proto_item_set_len(ti, offset);
1274 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
1275 dissect_netbios_payload(next_tvb, pinfo, tree);
1280 proto_tree_add_text(nbdgm_tree, tvb, offset, 1, "Error code: %s",
1281 val_to_str(header.error_code, error_codes, "Unknown (0x%x)"));
1284 proto_item_set_len(ti, offset);
1287 case NBDS_QUERY_REQUEST:
1288 case NBDS_POS_QUERY_RESPONSE:
1289 case NBDS_NEG_QUERY_RESPONSE:
1290 /* Destination name */
1291 len = get_nbns_name(tvb, offset, offset, name, &name_type);
1294 add_name_and_type(nbdgm_tree, tvb, offset, len,
1295 "Destination name", name, name_type);
1298 proto_item_set_len(ti, offset);
1304 * NetBIOS Session Service message types.
1306 #define SESSION_MESSAGE 0x00
1307 #define SESSION_REQUEST 0x81
1308 #define POSITIVE_SESSION_RESPONSE 0x82
1309 #define NEGATIVE_SESSION_RESPONSE 0x83
1310 #define RETARGET_SESSION_RESPONSE 0x84
1311 #define SESSION_KEEP_ALIVE 0x85
1313 static const value_string message_types[] = {
1314 { SESSION_MESSAGE, "Session message" },
1315 { SESSION_REQUEST, "Session request" },
1316 { POSITIVE_SESSION_RESPONSE, "Positive session response" },
1317 { NEGATIVE_SESSION_RESPONSE, "Negative session response" },
1318 { RETARGET_SESSION_RESPONSE, "Retarget session response" },
1319 { SESSION_KEEP_ALIVE, "Session keep-alive" },
1324 * NetBIOS Session Service flags.
1326 #define NBSS_FLAGS_E 0x1
1328 static const value_string error_codes[] = {
1329 { 0x80, "Not listening on called name" },
1330 { 0x81, "Not listening for called name" },
1331 { 0x82, "Called name not present" },
1332 { 0x83, "Called name present, but insufficient resources" },
1333 { 0x8F, "Unspecified error" },
1338 * Dissect a single NBSS packet (there may be more than one in a given
1341 * [ Hmmm, in my experience, I have never seen more than one NBSS in a
1342 * single segment, since they mostly contain SMBs which are essentially
1343 * a request response type protocol (RJS). ]
1345 * [ However, under heavy load with many requests multiplexed on one
1346 * session it is not unusual to see multiple requests in one TCP
1347 * segment. Unfortunately, in this case a single session message is
1348 * frequently split over multiple segments, which frustrates decoding
1352 dissect_nbss_packet(tvbuff_t *tvb, int offset, packet_info *pinfo,
1353 proto_tree *tree, int max_data, int is_cifs)
1355 proto_tree *nbss_tree = NULL;
1356 proto_item *ti = NULL;
1357 proto_tree *field_tree;
1361 volatile int length;
1362 int length_remaining;
1364 char name[(NETBIOS_NAME_LEN - 1)*4 + MAXDNAME];
1368 const char *saved_proto;
1370 /* Desegmentation */
1371 length_remaining = tvb_length_remaining(tvb, offset);
1374 * Can we do reassembly?
1376 if (nbss_desegment && pinfo->can_desegment) {
1378 * Yes - is the NBSS header split across segment boundaries?
1380 if (length_remaining < 4) {
1382 * Yes. Tell our caller how many more bytes
1385 return -(4 - length_remaining);
1390 * Get the length of the NBSS message.
1394 length = tvb_get_ntoh24(tvb, offset + 1);
1396 flags = tvb_get_guint8(tvb, offset + 1);
1397 length = tvb_get_ntohs(tvb, offset + 2);
1398 if (flags & NBSS_FLAGS_E)
1403 * Can we do reassembly?
1405 if (nbss_desegment && pinfo->can_desegment) {
1407 * Yes - is the NBSS message split across segment boundaries?
1409 if (length_remaining < length + 4) {
1411 * Yes. Tell our caller how many more bytes
1414 return -((length + 4) - length_remaining);
1418 msg_type = tvb_get_guint8(tvb, offset);
1421 ti = proto_tree_add_item(tree, proto_nbss, tvb, offset, length + 4, FALSE);
1422 nbss_tree = proto_item_add_subtree(ti, ett_nbss);
1424 proto_tree_add_uint_format(nbss_tree, hf_nbss_type, tvb,
1428 val_to_str(msg_type, message_types,
1436 proto_tree_add_text(nbss_tree, tvb, offset, 3, "Length: %u", length);
1441 tf = proto_tree_add_uint(nbss_tree, hf_nbss_flags, tvb, offset, 1, flags);
1442 field_tree = proto_item_add_subtree(tf, ett_nbss_flags);
1443 proto_tree_add_text(field_tree, tvb, offset, 1, "%s",
1444 decode_boolean_bitfield(flags, NBSS_FLAGS_E,
1445 8, "Add 65536 to length", "Add 0 to length"));
1450 proto_tree_add_text(nbss_tree, tvb, offset, 2, "Length: %u", length);
1458 case SESSION_REQUEST:
1459 len = get_nbns_name(tvb, offset, offset, name, &name_type);
1461 add_name_and_type(nbss_tree, tvb, offset, len,
1462 "Called name", name, name_type);
1465 len = get_nbns_name(tvb, offset, offset, name, &name_type);
1468 add_name_and_type(nbss_tree, tvb, offset, len,
1469 "Calling name", name, name_type);
1473 case NEGATIVE_SESSION_RESPONSE:
1475 proto_tree_add_text(nbss_tree, tvb, offset, 1,
1477 val_to_str(tvb_get_guint8(tvb, offset),
1478 error_codes, "Unknown (%x)"));
1481 case RETARGET_SESSION_RESPONSE:
1483 proto_tree_add_text(nbss_tree, tvb, offset, 4,
1484 "Retarget IP address: %s",
1485 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
1490 proto_tree_add_text(nbss_tree, tvb, offset, 2,
1491 "Retarget port: %u",
1492 tvb_get_ntohs(tvb, offset));
1496 case SESSION_MESSAGE:
1498 * Here we can pass the message off to the next protocol.
1499 * Set the length of our top-level tree item to include
1502 proto_item_set_len(ti, offset);
1503 len = tvb_length_remaining(tvb, offset);
1504 reported_len = tvb_reported_length_remaining(tvb, offset);
1507 if (reported_len > length)
1508 reported_len = length;
1510 next_tvb = tvb_new_subset(tvb, offset, len, reported_len);
1513 * Catch the ReportedBoundsError exception; if this
1514 * particular message happens to get a ReportedBoundsError
1515 * exception, that doesn't mean that we should stop
1516 * dissecting NetBIOS messages within this frame or chunk
1517 * of reassembled data.
1519 * If it gets a BoundsError, we can stop, as there's nothing
1520 * more to see, so we just re-throw it.
1522 saved_proto = pinfo->current_proto;
1524 dissect_netbios_payload(next_tvb, pinfo, tree);
1526 CATCH(BoundsError) {
1529 CATCH(ReportedBoundsError) {
1530 show_reported_bounds_error(tvb, pinfo, tree);
1531 pinfo->current_proto = saved_proto;
1541 dissect_nbss(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1543 struct tcpinfo *tcpinfo = pinfo->private_data;
1551 proto_tree *nbss_tree;
1554 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1555 col_set_str(pinfo->cinfo, COL_PROTOCOL, "NBSS");
1556 if (check_col(pinfo->cinfo, COL_INFO))
1557 col_clear(pinfo->cinfo, COL_INFO);
1559 max_data = tvb_length(tvb);
1561 msg_type = tvb_get_guint8(tvb, offset);
1563 if (pinfo->match_port == TCP_PORT_CIFS) {
1565 * Windows 2000 CIFS clients can dispense completely
1566 * with the NETBIOS encapsulation and directly use CIFS
1567 * over TCP. As would be expected, the framing is
1568 * identical, except that the length is 24 bits instead
1569 * of 17. The only message types used are
1570 * SESSION_MESSAGE and SESSION_KEEP_ALIVE.
1578 * This might be a continuation of an earlier message.
1579 * (Yes, that might be true even if we're doing TCP reassembly,
1580 * as the first TCP segment in the capture might start in the
1581 * middle of an NBNS message.)
1585 * If this isn't reassembled data, check to see whether it
1586 * looks like a continuation of a message.
1587 * (If it is reassembled data, it shouldn't be a continuation,
1588 * as reassembly should've gathered the continuations together
1591 if (!tcpinfo->is_reassembled) {
1594 * Not enough data for an NBSS header; assume
1595 * it's a continuation of a message.
1597 * XXX - if there's not enough data, we should
1598 * attempt to reassemble the data, if the first byte
1599 * is a valid message type.
1605 * We have enough data for an NBSS header.
1606 * Get the flags and length of the message,
1607 * and see if they're sane.
1611 length = tvb_get_ntoh24(tvb, offset + 1);
1613 flags = tvb_get_guint8(tvb, offset + 1);
1614 length = tvb_get_ntohs(tvb, offset + 2);
1615 if (flags & NBSS_FLAGS_E)
1618 if ((flags & (~NBSS_FLAGS_E)) != 0) {
1620 * A bogus flag was set; assume it's a continuation.
1627 case SESSION_MESSAGE:
1629 * This is variable-length.
1630 * All we know is that it shouldn't be zero.
1631 * (XXX - can we get zero-length messages?
1632 * Not with SMB, but perhaps other NetBIOS-based
1633 * protocols have them.)
1639 case SESSION_REQUEST:
1641 * This is variable-length.
1642 * The names are DNS-encoded 32-byte values;
1643 * we need at least 2 bytes (one for each name;
1644 * actually, we should have more for the first
1645 * name, as there's no name preceding it so
1646 * there should be no compression), and we
1647 * shouldn't have more than 128 bytes (actually,
1648 * we shouldn't have that many).
1650 * XXX - actually, MacOS X 10.1 (yes, that's
1651 * redundant, but that's what Apple calls it,
1652 * not MacOS X.1) puts names longer than 16
1653 * characters into session request messages,
1654 * so we can have more than 32 bytes of
1655 * name value, so we can have more than 128
1658 if (length < 2 || length > 256)
1662 case POSITIVE_SESSION_RESPONSE:
1664 * This has no data, so the length must be zero.
1670 case NEGATIVE_SESSION_RESPONSE:
1672 * This has 1 byte of data.
1678 case RETARGET_SESSION_RESPONSE:
1680 * This has 6 bytes of data.
1686 case SESSION_KEEP_ALIVE:
1688 * This has no data, so the length must be zero.
1696 * Unknown message type; assume it's a continuation.
1702 if (check_col(pinfo->cinfo, COL_INFO)) {
1703 col_add_fstr(pinfo->cinfo, COL_INFO,
1704 val_to_str(msg_type, message_types, "Unknown (%02x)"));
1707 while (max_data > 0) {
1708 len = dissect_nbss_packet(tvb, offset, pinfo, tree, max_data,
1712 * We need more data to dissect this, and
1713 * desegmentation is enabled. "-len" is the
1714 * number of additional bytes of data we need.
1716 * Tell the TCP dissector where the data for this
1717 * message starts in the data it handed us, and
1718 * how many more bytes we need, and return.
1720 pinfo->desegment_offset = offset;
1721 pinfo->desegment_len = -len;
1732 * It looks like a continuation.
1734 if (check_col(pinfo->cinfo, COL_INFO))
1735 col_add_fstr(pinfo->cinfo, COL_INFO, "NBSS Continuation Message");
1738 ti = proto_tree_add_item(tree, proto_nbss, tvb, 0,
1740 nbss_tree = proto_item_add_subtree(ti, ett_nbss);
1741 proto_tree_add_text(nbss_tree, tvb, 0, max_data,
1742 "Continuation data");
1747 proto_register_nbt(void)
1750 static hf_register_info hf_nbns[] = {
1751 { &hf_nbns_response,
1752 { "Response", "nbns.response",
1753 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1754 "TRUE if NBNS response", HFILL }},
1756 { "Query", "nbns.query",
1757 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1758 "TRUE if NBNS query", HFILL }},
1759 { &hf_nbns_transaction_id,
1760 { "Transaction ID", "nbns.id",
1761 FT_UINT16, BASE_HEX, NULL, 0x0,
1762 "Identification of transaction", HFILL }},
1763 { &hf_nbns_count_questions,
1764 { "Questions", "nbns.count.queries",
1765 FT_UINT16, BASE_DEC, NULL, 0x0,
1766 "Number of queries in packet", HFILL }},
1767 { &hf_nbns_count_answers,
1768 { "Answer RRs", "nbns.count.answers",
1769 FT_UINT16, BASE_DEC, NULL, 0x0,
1770 "Number of answers in packet", HFILL }},
1771 { &hf_nbns_count_auth_rr,
1772 { "Authority RRs", "nbns.count.auth_rr",
1773 FT_UINT16, BASE_DEC, NULL, 0x0,
1774 "Number of authoritative records in packet", HFILL }},
1775 { &hf_nbns_count_add_rr,
1776 { "Additional RRs", "nbns.count.add_rr",
1777 FT_UINT16, BASE_DEC, NULL, 0x0,
1778 "Number of additional records in packet", HFILL }}
1781 static hf_register_info hf_nbdgm[] = {
1783 { "Message Type", "nbdgm.type",
1784 FT_UINT8, BASE_DEC, VALS(nbds_msgtype_vals), 0x0,
1785 "NBDGM message type", HFILL }},
1786 { &hf_nbdgm_fragment,
1787 { "More fragments follow", "nbdgm.next",
1788 FT_BOOLEAN, BASE_NONE, TFS(&yesno), 0x0,
1789 "TRUE if more fragments follow", HFILL }},
1791 { "This is first fragment", "nbdgm.first",
1792 FT_BOOLEAN, BASE_NONE, TFS(&yesno), 0x0,
1793 "TRUE if first fragment", HFILL }},
1794 { &hf_nbdgm_node_type,
1795 { "Node Type", "nbdgm.node_type",
1796 FT_UINT8, BASE_DEC, VALS(node_type_vals), 0x0,
1797 "Node type", HFILL }},
1798 { &hf_nbdgm_datagram_id,
1799 { "Datagram ID", "nbdgm.dgram_id",
1800 FT_UINT16, BASE_HEX, NULL, 0x0,
1801 "Datagram identifier", HFILL }},
1803 { "Source IP", "nbdgm.src.ip",
1804 FT_IPv4, BASE_NONE, NULL, 0x0,
1805 "Source IPv4 address", HFILL }},
1806 { &hf_nbdgm_src_port,
1807 { "Source Port", "nbdgm.src.port",
1808 FT_UINT16, BASE_DEC, NULL, 0x0,
1809 "Source port", HFILL }}
1812 static hf_register_info hf_nbss[] = {
1814 { "Message Type", "nbss.type",
1815 FT_UINT8, BASE_DEC, NULL, 0x0,
1816 "NBSS message type", HFILL }},
1818 { "Flags", "nbss.flags",
1819 FT_UINT8, BASE_HEX, NULL, 0x0,
1820 "NBSS message flags", HFILL }}
1822 static gint *ett[] = {
1827 &ett_nbns_name_flags,
1835 module_t *nbss_module;
1837 proto_nbns = proto_register_protocol("NetBIOS Name Service", "NBNS", "nbns");
1838 proto_register_field_array(proto_nbns, hf_nbns, array_length(hf_nbns));
1840 proto_nbdgm = proto_register_protocol("NetBIOS Datagram Service",
1842 proto_register_field_array(proto_nbdgm, hf_nbdgm, array_length(hf_nbdgm));
1844 proto_nbss = proto_register_protocol("NetBIOS Session Service",
1846 proto_register_field_array(proto_nbss, hf_nbss, array_length(hf_nbss));
1848 proto_register_subtree_array(ett, array_length(ett));
1850 nbss_module = prefs_register_protocol(proto_nbss, NULL);
1851 prefs_register_bool_preference(nbss_module, "desegment_nbss_commands",
1852 "Desegment all NBSS packets spanning multiple TCP segments",
1853 "Whether NBSS dissector should desegment all packets spanning multiple TCP segments",
1858 proto_reg_handoff_nbt(void)
1860 dissector_handle_t nbns_handle, nbdgm_handle, nbss_handle;
1862 nbns_handle = create_dissector_handle(dissect_nbns, proto_nbns);
1863 dissector_add("udp.port", UDP_PORT_NBNS, nbns_handle);
1864 nbdgm_handle = create_dissector_handle(dissect_nbdgm, proto_nbdgm);
1865 dissector_add("udp.port", UDP_PORT_NBDGM, nbdgm_handle);
1866 nbss_handle = create_dissector_handle(dissect_nbss, proto_nbss);
1867 dissector_add("tcp.port", TCP_PORT_NBSS, nbss_handle);
1868 dissector_add("tcp.port", TCP_PORT_CIFS, nbss_handle);