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>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32 #include <epan/packet.h>
33 #include <epan/exceptions.h>
34 #include <epan/wmem/wmem.h>
35 #include <epan/prefs.h>
36 #include <epan/strutil.h>
37 #include <epan/show_exception.h>
39 #include "packet-dns.h"
40 #include "packet-netbios.h"
41 #include "packet-tcp.h"
43 static int proto_nbns
= -1;
44 static int hf_nbns_flags
= -1;
45 static int hf_nbns_flags_response
= -1;
46 static int hf_nbns_flags_opcode
= -1;
47 static int hf_nbns_flags_authoritative
= -1;
48 static int hf_nbns_flags_truncated
= -1;
49 static int hf_nbns_flags_recdesired
= -1;
50 static int hf_nbns_flags_recavail
= -1;
51 static int hf_nbns_flags_broadcast
= -1;
52 static int hf_nbns_flags_rcode
= -1;
53 static int hf_nbns_transaction_id
= -1;
54 static int hf_nbns_count_questions
= -1;
55 static int hf_nbns_count_answers
= -1;
56 static int hf_nbns_count_auth_rr
= -1;
57 static int hf_nbns_count_add_rr
= -1;
58 static int hf_nbns_name_flags
= -1;
59 static int hf_nbns_name_flags_group
= -1;
60 static int hf_nbns_name_flags_ont
= -1;
61 static int hf_nbns_name_flags_drg
= -1;
62 static int hf_nbns_name_flags_cnf
= -1;
63 static int hf_nbns_name_flags_act
= -1;
64 static int hf_nbns_name_flags_prm
= -1;
65 static int hf_nbns_nb_flags
= -1;
66 static int hf_nbns_nb_flags_group
= -1;
67 static int hf_nbns_nb_flags_ont
= -1;
69 static gint ett_nbns
= -1;
70 static gint ett_nbns_qd
= -1;
71 static gint ett_nbns_flags
= -1;
72 static gint ett_nbns_nb_flags
= -1;
73 static gint ett_nbns_name_flags
= -1;
74 static gint ett_nbns_rr
= -1;
75 static gint ett_nbns_qry
= -1;
76 static gint ett_nbns_ans
= -1;
78 static int proto_nbdgm
= -1;
79 static int hf_nbdgm_type
= -1;
80 static int hf_nbdgm_fragment
= -1;
81 static int hf_nbdgm_first
= -1;
82 static int hf_nbdgm_node_type
= -1;
83 static int hf_nbdgm_datagram_id
= -1;
84 static int hf_nbdgm_src_ip
= -1;
85 static int hf_nbdgm_src_port
= -1;
87 static gint ett_nbdgm
= -1;
89 static int proto_nbss
= -1;
90 static int hf_nbss_type
= -1;
91 static int hf_nbss_flags
= -1;
92 static int hf_nbss_flags_e
= -1;
93 static int hf_nbss_length
= -1;
94 static int hf_nbss_cifs_length
= -1;
96 static gint ett_nbss
= -1;
97 static gint ett_nbss_flags
= -1;
99 /* desegmentation of NBSS over TCP */
100 static gboolean nbss_desegment
= TRUE
;
102 /* See RFC 1001 and 1002 for information on the first three, and see
104 http://www.cifs.com/specs/draft-leach-cifs-v1-spec-01.txt
106 Appendix B, and various messages on the CIFS mailing list such as
108 http://discuss.microsoft.com/SCRIPTS/WA-MSD.EXE?A2=ind9811A&L=cifs&P=R386
110 for information on the fourth. */
111 #define UDP_PORT_NBNS 137
112 #define UDP_PORT_NBDGM 138
113 #define TCP_PORT_NBSS 139
114 #define TCP_PORT_CIFS 445
116 /* Packet structure taken from RFC 1002. See also RFC 1001.
117 * Opcode, flags, and rcode treated as "flags", similarly to DNS,
118 * to make it easier to lift the dissection code from "packet-dns.c". */
120 /* Offsets of fields in the NBNS header. */
128 /* Length of NBNS header. */
129 #define NBNS_HDRLEN 12
132 #define T_NB 32 /* NetBIOS name service RR */
133 #define T_NBSTAT 33 /* NetBIOS node status RR */
135 /* Bit fields in the flags */
136 #define F_RESPONSE (1<<15) /* packet is response */
137 #define F_OPCODE (0xF<<11) /* query opcode */
138 #define OPCODE_SHIFT 11
139 #define F_AUTHORITATIVE (1<<10) /* response is authoritative */
140 #define F_TRUNCATED (1<<9) /* response is truncated */
141 #define F_RECDESIRED (1<<8) /* recursion desired */
142 #define F_RECAVAIL (1<<7) /* recursion available */
143 #define F_BROADCAST (1<<4) /* broadcast/multicast packet */
144 #define F_RCODE (0xF<<0) /* reply code */
146 static const true_false_string tfs_flags_response
= {
147 "Message is a response",
151 static const true_false_string tfs_flags_authoritative
= {
152 "Server is an authority for domain",
153 "Server is not an authority for domain"
156 static const true_false_string tfs_flags_truncated
= {
157 "Message is truncated",
158 "Message is not truncated"
161 static const true_false_string tfs_flags_recdesired
= {
162 "Do query recursively",
163 "Don't do query recursively"
166 static const true_false_string tfs_flags_recavail
= {
167 "Server can do recursive queries",
168 "Server can't do recursive queries"
171 static const true_false_string tfs_flags_broadcast
= {
173 "Not a broadcast packet"
176 static const true_false_string tfs_nbss_flags_e
= {
177 "Add 65536 to length",
182 #define OPCODE_QUERY 0 /* standard query */
183 #define OPCODE_REGISTRATION 5 /* registration */
184 #define OPCODE_RELEASE 6 /* release name */
185 #define OPCODE_WACK 7 /* wait for acknowledgement */
186 #define OPCODE_REFRESH 8 /* refresh registration */
187 #define OPCODE_REFRESHALT 9 /* refresh registration (alternate opcode) */
188 #define OPCODE_MHREGISTRATION 15 /* multi-homed registration */
190 static const value_string opcode_vals
[] = {
191 { OPCODE_QUERY
, "Name query" },
192 { OPCODE_REGISTRATION
, "Registration" },
193 { OPCODE_RELEASE
, "Release" },
194 { OPCODE_WACK
, "Wait for acknowledgment" },
195 { OPCODE_REFRESH
, "Refresh" },
196 { OPCODE_REFRESHALT
, "Refresh (alternate opcode)" },
197 { OPCODE_MHREGISTRATION
, "Multi-homed registration" },
202 #define RCODE_NOERROR 0
203 #define RCODE_FMTERROR 1
204 #define RCODE_SERVFAIL 2
205 #define RCODE_NAMEERROR 3
206 #define RCODE_NOTIMPL 4
207 #define RCODE_REFUSED 5
208 #define RCODE_ACTIVE 6
209 #define RCODE_CONFLICT 7
211 static const value_string rcode_vals
[] = {
212 { RCODE_NOERROR
, "No error" },
213 { RCODE_FMTERROR
, "Request was invalidly formatted" },
214 { RCODE_SERVFAIL
, "Server failure" },
215 { RCODE_NAMEERROR
, "Requested name does not exist" },
216 { RCODE_NOTIMPL
, "Request is not implemented" },
217 { RCODE_REFUSED
, "Request was refused" },
218 { RCODE_ACTIVE
, "Name is owned by another node" },
219 { RCODE_CONFLICT
, "Name is in conflict" },
223 /* Values for the "NB_FLAGS" field of RR data. From RFC 1001 and 1002,
224 * except for NB_FLAGS_ONT_H_NODE, which was discovered by looking at
226 #define NB_FLAGS_ONT (3<<(15-2)) /* bits for node type */
227 #define NB_FLAGS_ONT_B_NODE (0<<(15-2)) /* B-mode node */
228 #define NB_FLAGS_ONT_P_NODE (1<<(15-2)) /* P-mode node */
229 #define NB_FLAGS_ONT_M_NODE (2<<(15-2)) /* M-mode node */
230 #define NB_FLAGS_ONT_H_NODE (3<<(15-2)) /* H-mode node */
232 #define NB_FLAGS_G (1<<(15-0)) /* group name */
234 /* Values for the "NAME_FLAGS" field of a NODE_NAME entry in T_NBSTAT
235 * RR data. From RFC 1001 and 1002; as I remember, the "NAME_FLAGS"
236 * field doesn't include any special values for H-mode nodes, even
237 * though one can register them (if so, perhaps that was done to
238 * avoid surprising clients that don't know about H-mode nodes). */
239 #define NAME_FLAGS_PRM (1<<(15-6)) /* name is permanent node name */
241 #define NAME_FLAGS_ACT (1<<(15-5)) /* name is active */
243 #define NAME_FLAGS_CNF (1<<(15-4)) /* name is in conflict */
245 #define NAME_FLAGS_DRG (1<<(15-3)) /* name is being deregistered */
247 #define NAME_FLAGS_ONT (3<<(15-2)) /* bits for node type */
248 #define NAME_FLAGS_ONT_B_NODE (0<<(15-2)) /* B-mode node */
249 #define NAME_FLAGS_ONT_P_NODE (1<<(15-2)) /* P-mode node */
250 #define NAME_FLAGS_ONT_M_NODE (2<<(15-2)) /* M-mode node */
252 #define NAME_FLAGS_G (1<<(15-0)) /* group name */
254 static const value_string name_flags_ont_vals
[] = {
255 { NAME_FLAGS_ONT_B_NODE
, "B-node" },
256 { NAME_FLAGS_ONT_P_NODE
, "P-node" },
257 { NAME_FLAGS_ONT_M_NODE
, "M-node" },
261 static const value_string nb_flags_ont_vals
[] = {
262 { NB_FLAGS_ONT_B_NODE
, "B-node" },
263 { NB_FLAGS_ONT_P_NODE
, "P-node" },
264 { NB_FLAGS_ONT_M_NODE
, "M-node" },
265 { NB_FLAGS_ONT_H_NODE
, "H-node" },
270 nbns_type_name (int type
)
282 #define NBNAME_BUF_LEN 128
285 add_rr_to_tree(proto_item
*trr
, int rr_type
, tvbuff_t
*tvb
, int offset
,
286 const char *name
, int namelen
,
287 const char *type_name
, const char *class_description
,
288 guint ttl
, gushort data_len
)
292 rr_tree
= proto_item_add_subtree(trr
, rr_type
);
293 proto_tree_add_text(rr_tree
, tvb
, offset
+1, namelen
-1, "Name: %s", name
);
295 proto_tree_add_text(rr_tree
, tvb
, offset
, 2, "Type: %s", type_name
);
297 proto_tree_add_text(rr_tree
, tvb
, offset
, 2, "Class: %s", class_description
);
299 proto_tree_add_text(rr_tree
, tvb
, offset
, 4, "Time to live: %s",
300 time_secs_to_str(ttl
));
302 proto_tree_add_text(rr_tree
, tvb
, offset
, 2, "Data length: %u", data_len
);
307 get_nbns_name(tvbuff_t
*tvb
, int offset
, int nbns_data_offset
,
308 char *name_ret
, int name_ret_len
, int *name_type_ret
)
312 const guchar
*nbname
;
320 nbname_buf
= (char *)wmem_alloc(wmem_packet_scope(), NBNAME_BUF_LEN
);
322 /* XXX Fix data len */
323 name_len
= get_dns_name(tvb
, offset
, 0, nbns_data_offset
, &name
);
325 /* OK, now undo the first-level encoding. */
327 pname_ret
= name_ret
;
330 /* Every two characters of the first level-encoded name
331 * turn into one character in the decoded name. */
334 break; /* no more characters */
336 break; /* scope ID follows */
337 if (cname
< 'A' || cname
> 'Z') {
339 nbname
= "Illegal NetBIOS name (1st character not between A and Z in first-level encoding)";
343 cnbname
= cname
<< 4;
347 if (cname
== '\0' || cname
== '.') {
348 /* No more characters in the name - but we're in
349 * the middle of a pair. Not legal. */
350 nbname
= "Illegal NetBIOS name (odd number of bytes)";
353 if (cname
< 'A' || cname
> 'Z') {
355 nbname
= "Illegal NetBIOS name (2nd character not between A and Z in first-level encoding)";
362 /* Do we have room to store the character? */
363 if (idx
< NETBIOS_NAME_LEN
) {
364 /* Yes - store the character. */
365 nbname_buf
[idx
++] = cnbname
;
369 /* NetBIOS names are supposed to be exactly 16 bytes long. */
370 if (idx
!= NETBIOS_NAME_LEN
) {
372 g_snprintf(nbname_buf
, NBNAME_BUF_LEN
, "Illegal NetBIOS name (%lu bytes long)",
377 /* This one is; make its name printable. */
378 name_type
= process_netbios_name(nbname
, name_ret
, name_ret_len
);
379 pname_ret
+= MIN(strlen(name_ret
), (size_t) name_ret_len
);
380 pname_ret
+= MIN(name_ret_len
-(pname_ret
-name_ret
),
381 g_snprintf(pname_ret
, name_ret_len
-(gulong
)(pname_ret
-name_ret
), "<%02x>", name_type
));
383 /* We have a scope ID, starting at "pname"; append that to
384 * the decoded host name. */
385 g_snprintf(pname_ret
, name_ret_len
-(gulong
)(pname_ret
-name_ret
), "%s", pname
);
387 if (name_type_ret
!= NULL
)
388 *name_type_ret
= name_type
;
392 if (name_type_ret
!= NULL
)
394 /* This is only valid because nbname is always assigned an error string
395 * before jumping to bad: Otherwise nbname wouldn't be \0 terminated */
396 g_snprintf(pname_ret
, name_ret_len
-(gulong
)(pname_ret
-name_ret
), "%s", nbname
);
402 get_nbns_name_type_class(tvbuff_t
*tvb
, int offset
, int nbns_data_offset
,
403 char *name_ret
, int *name_len_ret
, int *name_type_ret
,
404 int *type_ret
, int *class_ret
)
410 name_len
= get_nbns_name(tvb
, offset
, nbns_data_offset
, name_ret
,
411 *name_len_ret
, name_type_ret
);
414 type
= tvb_get_ntohs(tvb
, offset
);
417 rr_class
= tvb_get_ntohs(tvb
, offset
);
420 *class_ret
= rr_class
;
421 *name_len_ret
= name_len
;
427 add_name_and_type(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
, int len
,
428 const char *tag
, const char *name
, int name_type
)
430 if (name_type
!= -1) {
431 proto_tree_add_text(tree
, tvb
, offset
, len
, "%s: %s (%s)",
432 tag
, name
, netbios_name_type_descr(name_type
));
434 proto_tree_add_text(tree
, tvb
, offset
, len
, "%s: %s",
439 #define MAX_NAME_LEN (NETBIOS_NAME_LEN - 1)*4 + MAXDNAME + 64
442 dissect_nbns_query(tvbuff_t
*tvb
, int offset
, int nbns_data_offset
,
443 column_info
*cinfo
, proto_tree
*nbns_tree
)
451 const char *type_name
;
457 name
= (char *)wmem_alloc(wmem_packet_scope(), MAX_NAME_LEN
);
458 data_start
= data_offset
= offset
;
460 name_len
= MAX_NAME_LEN
;
461 len
= get_nbns_name_type_class(tvb
, offset
, nbns_data_offset
, name
,
462 &name_len
, &name_type
, &type
, &dns_class
);
465 type_name
= nbns_type_name(type
);
468 col_append_fstr(cinfo
, COL_INFO
, " %s %s", type_name
, name
);
470 if (nbns_tree
!= NULL
) {
471 tq
= proto_tree_add_text(nbns_tree
, tvb
, offset
, len
,
472 "%s: type %s, class %s", name
, type_name
,
473 dns_class_name(dns_class
));
474 q_tree
= proto_item_add_subtree(tq
, ett_nbns_qd
);
476 add_name_and_type(q_tree
, tvb
, offset
, name_len
, "Name", name
,
480 proto_tree_add_text(q_tree
, tvb
, offset
, 2, "Type: %s", type_name
);
483 proto_tree_add_text(q_tree
, tvb
, offset
, 2, "Class: %s",
484 dns_class_name(dns_class
));
488 return data_offset
- data_start
;
492 nbns_add_nbns_flags(column_info
*cinfo
, proto_tree
*nbns_tree
, tvbuff_t
*tvb
, int offset
,
493 gushort flags
, int is_wack
)
497 proto_tree
*field_tree
;
500 #define MAX_BUF_SIZE (128+1)
503 if (flags
& F_RESPONSE
&& !is_wack
) {
504 if ((flags
& F_RCODE
))
505 col_append_fstr(cinfo
, COL_INFO
, ", %s",
506 val_to_str_const(flags
& F_RCODE
, rcode_vals
,
514 buf
= (char *)wmem_alloc(wmem_packet_scope(), MAX_BUF_SIZE
);
515 opcode
= (guint16
) ((flags
& F_OPCODE
) >> OPCODE_SHIFT
);
516 g_snprintf(buf
, MAX_BUF_SIZE
, "%s", val_to_str_const(opcode
, opcode_vals
, "Unknown operation"));
517 if (flags
& F_RESPONSE
&& !is_wack
) {
518 g_strlcat(buf
, " response", MAX_BUF_SIZE
);
519 g_strlcat(buf
, ", ", MAX_BUF_SIZE
);
520 g_strlcat(buf
, val_to_str_const(flags
& F_RCODE
, rcode_vals
, "Unknown error"), MAX_BUF_SIZE
);
521 buf
[MAX_BUF_SIZE
-1] = '\0';
523 tf
= proto_tree_add_uint_format_value(nbns_tree
, hf_nbns_flags
,
524 tvb
, offset
, 2, flags
, "0x%04x (%s)", flags
, buf
);
525 field_tree
= proto_item_add_subtree(tf
, ett_nbns_flags
);
526 proto_tree_add_item(field_tree
, hf_nbns_flags_response
,
527 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
528 proto_tree_add_item(field_tree
, hf_nbns_flags_opcode
,
529 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
530 if (flags
& F_RESPONSE
) {
531 proto_tree_add_item(field_tree
, hf_nbns_flags_authoritative
,
532 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
534 proto_tree_add_item(field_tree
, hf_nbns_flags_truncated
,
535 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
536 proto_tree_add_item(field_tree
, hf_nbns_flags_recdesired
,
537 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
538 if (flags
& F_RESPONSE
) {
539 proto_tree_add_item(field_tree
, hf_nbns_flags_recavail
,
540 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
542 proto_tree_add_item(field_tree
, hf_nbns_flags_broadcast
,
543 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
544 if (flags
& F_RESPONSE
&& !is_wack
) {
545 proto_tree_add_item(field_tree
, hf_nbns_flags_rcode
,
546 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
551 nbns_add_nb_flags(proto_tree
*rr_tree
, tvbuff_t
*tvb
, int offset
)
553 proto_tree
*field_tree
;
560 flags
= tvb_get_ntohs(tvb
, offset
);
561 tf
= proto_tree_add_item(rr_tree
, hf_nbns_nb_flags
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
562 field_tree
= proto_item_add_subtree(tf
, ett_nbns_nb_flags
);
563 proto_tree_add_item(field_tree
, hf_nbns_nb_flags_group
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
564 proto_tree_add_item(field_tree
, hf_nbns_nb_flags_ont
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
566 proto_item_append_text(tf
, "(%s, %s",
567 val_to_str_const(flags
& NB_FLAGS_ONT
, nb_flags_ont_vals
, "Unknown"),
568 (flags
& NB_FLAGS_G
) ? "group" : "unique");
572 nbns_add_name_flags(proto_tree
*rr_tree
, tvbuff_t
*tvb
, int offset
)
574 proto_item
*field_tree
;
581 flags
= tvb_get_ntohs(tvb
, offset
);
582 tf
= proto_tree_add_item(rr_tree
, hf_nbns_name_flags
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
583 field_tree
= proto_item_add_subtree(tf
, ett_nbns_name_flags
);
584 proto_tree_add_item(field_tree
, hf_nbns_name_flags_group
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
585 proto_tree_add_item(field_tree
, hf_nbns_name_flags_ont
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
586 proto_tree_add_item(field_tree
, hf_nbns_name_flags_drg
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
587 proto_tree_add_item(field_tree
, hf_nbns_name_flags_cnf
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
588 proto_tree_add_item(field_tree
, hf_nbns_name_flags_act
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
589 proto_tree_add_item(field_tree
, hf_nbns_name_flags_prm
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
591 proto_item_append_text(tf
, "(%s, %s",
592 val_to_str_const(flags
& NAME_FLAGS_ONT
, name_flags_ont_vals
, "Unknown"),
593 (flags
& NAME_FLAGS_G
) ? "group" : "unique");
594 if (flags
& NAME_FLAGS_DRG
)
595 proto_item_append_text(tf
, ", being deregistered");
596 if (flags
& NAME_FLAGS_CNF
)
597 proto_item_append_text(tf
, ", in conflict");
598 if (flags
& NAME_FLAGS_ACT
)
599 proto_item_append_text(tf
, ", active");
600 if (flags
& NAME_FLAGS_PRM
)
601 proto_item_append_text(tf
, ", permanent node name");
602 proto_item_append_text(tf
, ")");
606 dissect_nbns_answer(tvbuff_t
*tvb
, int offset
, int nbns_data_offset
,
607 column_info
*cinfo
, proto_tree
*nbns_tree
, int opcode
)
615 const char *class_name
;
616 const char *type_name
;
621 proto_tree
*rr_tree
= NULL
;
629 name
= (char *)wmem_alloc(wmem_packet_scope(), MAX_NAME_LEN
);
630 name_str
= (char *)wmem_alloc(wmem_packet_scope(), MAX_NAME_LEN
);
631 nbname
= (char *)wmem_alloc(wmem_packet_scope(), 16+4+1); /* 4 for [<last char>] */
633 name_len
= MAX_NAME_LEN
;
634 len
= get_nbns_name_type_class(tvb
, offset
, nbns_data_offset
, name
,
635 &name_len
, &name_type
, &type
, &dns_class
);
638 type_name
= nbns_type_name(type
);
639 class_name
= dns_class_name(dns_class
);
641 ttl
= tvb_get_ntohl(tvb
, cur_offset
);
644 data_len
= tvb_get_ntohs(tvb
, cur_offset
);
647 /* XXX: This code should be simplified */
649 case T_NB
: /* "NB" record */
651 if (opcode
!= OPCODE_WACK
) {
652 col_append_fstr(cinfo
, COL_INFO
, " %s %s",
654 tvb_ip_to_str(tvb
, cur_offset
+2));
659 trr
= proto_tree_add_text(nbns_tree
, tvb
, offset
,
660 (cur_offset
- offset
) + data_len
,
661 "%s: type %s, class %s",
662 name
, type_name
, class_name
);
663 g_strlcat(name
, " (", MAX_NAME_LEN
);
664 g_strlcat(name
, netbios_name_type_descr(name_type
), MAX_NAME_LEN
);
665 g_strlcat(name
, ")", MAX_NAME_LEN
);
666 rr_tree
= add_rr_to_tree(trr
, ett_nbns_rr
, tvb
, offset
, name
,
667 name_len
, type_name
, dns_class_name(dns_class
), ttl
, data_len
);
669 while (data_len
> 0) {
670 if (opcode
== OPCODE_WACK
) {
671 /* WACK response. This doesn't contain the
672 * same type of RR data as other T_NB
675 proto_tree_add_text(rr_tree
, tvb
, cur_offset
,
676 data_len
, "(incomplete entry)");
679 flags
= tvb_get_ntohs(tvb
, cur_offset
);
680 nbns_add_nbns_flags(cinfo
, rr_tree
, tvb
, cur_offset
,
686 proto_tree_add_text(rr_tree
, tvb
, cur_offset
,
687 data_len
, "(incomplete entry)");
690 nbns_add_nb_flags(rr_tree
, tvb
, cur_offset
);
695 proto_tree_add_text(rr_tree
, tvb
, cur_offset
,
696 data_len
, "(incomplete entry)");
699 proto_tree_add_text(rr_tree
, tvb
, cur_offset
, 4,
701 tvb_ip_to_str(tvb
, cur_offset
));
708 case T_NBSTAT
: /* "NBSTAT" record */
710 col_append_fstr(cinfo
, COL_INFO
, " %s", type_name
);
713 trr
= proto_tree_add_text(nbns_tree
, tvb
, offset
,
714 (cur_offset
- offset
) + data_len
,
715 "%s: type %s, class %s",
716 name
, type_name
, class_name
);
717 rr_tree
= add_rr_to_tree(trr
, ett_nbns_rr
, tvb
, offset
, name
,
718 name_len
, type_name
, dns_class_name(dns_class
), ttl
, data_len
);
722 proto_tree_add_text(rr_tree
, tvb
, cur_offset
,
723 data_len
, "(incomplete entry)");
727 num_names
= tvb_get_guint8(tvb
, cur_offset
);
728 proto_tree_add_text(rr_tree
, tvb
, cur_offset
, 1,
729 "Number of names: %u", num_names
);
732 while (num_names
!= 0) {
733 if (data_len
< NETBIOS_NAME_LEN
) {
734 proto_tree_add_text(rr_tree
, tvb
, cur_offset
,
735 data_len
, "(incomplete entry)");
739 tvb_memcpy(tvb
, (guint8
*)nbname
, cur_offset
,
741 name_type
= process_netbios_name(nbname
,
743 proto_tree_add_text(rr_tree
, tvb
, cur_offset
,
744 NETBIOS_NAME_LEN
, "Name: %s<%02x> (%s)",
746 netbios_name_type_descr(name_type
));
748 cur_offset
+= NETBIOS_NAME_LEN
;
749 data_len
-= NETBIOS_NAME_LEN
;
752 proto_tree_add_text(rr_tree
, tvb
, cur_offset
,
753 data_len
, "(incomplete entry)");
757 nbns_add_name_flags(rr_tree
, tvb
, cur_offset
);
766 proto_tree_add_text(rr_tree
, tvb
, cur_offset
,
767 data_len
, "(incomplete entry)");
772 proto_tree_add_text(rr_tree
, tvb
, cur_offset
, 6,
774 tvb_ether_to_str(tvb
, cur_offset
));
780 proto_tree_add_text(rr_tree
, tvb
, cur_offset
,
781 data_len
, "(incomplete entry)");
786 proto_tree_add_text(rr_tree
, tvb
, cur_offset
, 1,
787 "Jumpers: 0x%x", tvb_get_guint8(tvb
, cur_offset
));
793 proto_tree_add_text(rr_tree
, tvb
, cur_offset
,
794 data_len
, "(incomplete entry)");
798 proto_tree_add_text(rr_tree
, tvb
, cur_offset
, 1,
799 "Test result: 0x%x", tvb_get_guint8(tvb
, cur_offset
));
805 proto_tree_add_text(rr_tree
, tvb
, cur_offset
,
806 data_len
, "(incomplete entry)");
810 proto_tree_add_text(rr_tree
, tvb
, cur_offset
, 2,
811 "Version number: 0x%x", tvb_get_ntohs(tvb
, cur_offset
));
817 proto_tree_add_text(rr_tree
, tvb
, cur_offset
,
818 data_len
, "(incomplete entry)");
822 proto_tree_add_text(rr_tree
, tvb
, cur_offset
, 2,
823 "Period of statistics: 0x%x",
824 tvb_get_ntohs(tvb
, cur_offset
));
830 proto_tree_add_text(rr_tree
, tvb
, cur_offset
,
831 data_len
, "(incomplete entry)");
835 proto_tree_add_text(rr_tree
, tvb
, cur_offset
, 2,
836 "Number of CRCs: %u", tvb_get_ntohs(tvb
, cur_offset
));
842 proto_tree_add_text(rr_tree
, tvb
, cur_offset
,
843 data_len
, "(incomplete entry)");
847 proto_tree_add_text(rr_tree
, tvb
, cur_offset
, 2,
848 "Number of alignment errors: %u",
849 tvb_get_ntohs(tvb
, cur_offset
));
855 proto_tree_add_text(rr_tree
, tvb
, cur_offset
,
856 data_len
, "(incomplete entry)");
860 proto_tree_add_text(rr_tree
, tvb
, cur_offset
, 2,
861 "Number of collisions: %u", tvb_get_ntohs(tvb
, cur_offset
));
867 proto_tree_add_text(rr_tree
, tvb
, cur_offset
,
868 data_len
, "(incomplete entry)");
872 proto_tree_add_text(rr_tree
, tvb
, cur_offset
, 2,
873 "Number of send aborts: %u", tvb_get_ntohs(tvb
, cur_offset
));
879 proto_tree_add_text(rr_tree
, tvb
, cur_offset
,
880 data_len
, "(incomplete entry)");
884 proto_tree_add_text(rr_tree
, tvb
, cur_offset
, 4,
885 "Number of good sends: %u", tvb_get_ntohl(tvb
, cur_offset
));
891 proto_tree_add_text(rr_tree
, tvb
, cur_offset
,
892 data_len
, "(incomplete entry)");
896 proto_tree_add_text(rr_tree
, tvb
, cur_offset
, 4,
897 "Number of good receives: %u",
898 tvb_get_ntohl(tvb
, cur_offset
));
904 proto_tree_add_text(rr_tree
, tvb
, cur_offset
,
905 data_len
, "(incomplete entry)");
909 proto_tree_add_text(rr_tree
, tvb
, cur_offset
, 2,
910 "Number of retransmits: %u", tvb_get_ntohs(tvb
, cur_offset
));
916 proto_tree_add_text(rr_tree
, tvb
, cur_offset
,
917 data_len
, "(incomplete entry)");
921 proto_tree_add_text(rr_tree
, tvb
, cur_offset
, 2,
922 "Number of no resource conditions: %u",
923 tvb_get_ntohs(tvb
, cur_offset
));
929 proto_tree_add_text(rr_tree
, tvb
, cur_offset
,
930 data_len
, "(incomplete entry)");
934 proto_tree_add_text(rr_tree
, tvb
, cur_offset
, 2,
935 "Number of command blocks: %u",
936 tvb_get_ntohs(tvb
, cur_offset
));
942 proto_tree_add_text(rr_tree
, tvb
, cur_offset
,
943 data_len
, "(incomplete entry)");
947 proto_tree_add_text(rr_tree
, tvb
, cur_offset
, 2,
948 "Number of pending sessions: %u",
949 tvb_get_ntohs(tvb
, cur_offset
));
955 proto_tree_add_text(rr_tree
, tvb
, cur_offset
,
956 data_len
, "(incomplete entry)");
960 proto_tree_add_text(rr_tree
, tvb
, cur_offset
, 2,
961 "Max number of pending sessions: %u",
962 tvb_get_ntohs(tvb
, cur_offset
));
968 proto_tree_add_text(rr_tree
, tvb
, cur_offset
,
969 data_len
, "(incomplete entry)");
973 proto_tree_add_text(rr_tree
, tvb
, cur_offset
, 2,
974 "Max total sessions possible: %u",
975 tvb_get_ntohs(tvb
, cur_offset
));
981 proto_tree_add_text(rr_tree
, tvb
, cur_offset
,
982 data_len
, "(incomplete entry)");
986 proto_tree_add_text(rr_tree
, tvb
, cur_offset
, 2,
987 "Session data packet size: %u",
988 tvb_get_ntohs(tvb
, cur_offset
));
997 col_append_fstr(cinfo
, COL_INFO
, " %s", type_name
);
1000 trr
= proto_tree_add_text(nbns_tree
, tvb
, offset
,
1001 (cur_offset
- offset
) + data_len
,
1002 "%s: type %s, class %s",
1003 name
, type_name
, class_name
);
1004 rr_tree
= add_rr_to_tree(trr
, ett_nbns_rr
, tvb
, offset
, name
,
1005 name_len
, type_name
, dns_class_name(dns_class
), ttl
, data_len
);
1006 proto_tree_add_text(rr_tree
, tvb
, cur_offset
, data_len
, "Data");
1008 cur_offset
+= data_len
;
1012 return cur_offset
- offset
;
1016 dissect_query_records(tvbuff_t
*tvb
, int cur_off
, int nbns_data_offset
,
1017 int count
, column_info
*cinfo
, proto_tree
*nbns_tree
)
1019 int start_off
, add_off
;
1020 proto_tree
*qatree
= NULL
;
1021 proto_item
*ti
= NULL
;
1023 start_off
= cur_off
;
1024 if (nbns_tree
!= NULL
) {
1025 ti
= proto_tree_add_text(nbns_tree
, tvb
, start_off
, -1, "Queries");
1026 qatree
= proto_item_add_subtree(ti
, ett_nbns_qry
);
1028 while (count
-- > 0) {
1029 add_off
= dissect_nbns_query(tvb
, cur_off
, nbns_data_offset
,
1034 proto_item_set_len(ti
, cur_off
- start_off
);
1036 return cur_off
- start_off
;
1040 dissect_answer_records(tvbuff_t
*tvb
, int cur_off
, int nbns_data_offset
,
1041 int count
, column_info
*cinfo
, proto_tree
*nbns_tree
,
1042 int opcode
, const char *name
)
1044 int start_off
, add_off
;
1045 proto_tree
*qatree
= NULL
;
1046 proto_item
*ti
= NULL
;
1048 start_off
= cur_off
;
1049 if (nbns_tree
!= NULL
) {
1050 ti
= proto_tree_add_text(nbns_tree
, tvb
, start_off
, -1, "%s", name
);
1051 qatree
= proto_item_add_subtree(ti
, ett_nbns_ans
);
1053 while (count
-- > 0) {
1054 add_off
= dissect_nbns_answer(tvb
, cur_off
, nbns_data_offset
,
1055 cinfo
, qatree
, opcode
);
1059 proto_item_set_len(ti
, cur_off
- start_off
);
1060 return cur_off
- start_off
;
1064 dissect_nbns(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
1067 int nbns_data_offset
;
1068 proto_tree
*nbns_tree
= NULL
;
1070 guint16 id
, flags
, opcode
, quest
, ans
, auth
, add
;
1073 nbns_data_offset
= offset
;
1075 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "NBNS");
1076 col_clear(pinfo
->cinfo
, COL_INFO
);
1078 /* To do: check for runts, errs, etc. */
1079 id
= tvb_get_ntohs(tvb
, offset
+ NBNS_ID
);
1080 flags
= tvb_get_ntohs(tvb
, offset
+ NBNS_FLAGS
);
1081 opcode
= (guint16
) ((flags
& F_OPCODE
) >> OPCODE_SHIFT
);
1083 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s%s",
1084 val_to_str(opcode
, opcode_vals
, "Unknown operation (%u)"),
1085 (flags
& F_RESPONSE
) ? " response" : "");
1088 ti
= proto_tree_add_item(tree
, proto_nbns
, tvb
, offset
, -1,
1090 nbns_tree
= proto_item_add_subtree(ti
, ett_nbns
);
1092 proto_tree_add_uint(nbns_tree
, hf_nbns_transaction_id
, tvb
,
1093 offset
+ NBNS_ID
, 2, id
);
1096 nbns_add_nbns_flags(pinfo
->cinfo
, nbns_tree
, tvb
, offset
+ NBNS_FLAGS
,
1099 quest
= tvb_get_ntohs(tvb
, offset
+ NBNS_QUEST
);
1101 proto_tree_add_uint(nbns_tree
, hf_nbns_count_questions
, tvb
,
1102 offset
+ NBNS_QUEST
, 2, quest
);
1104 ans
= tvb_get_ntohs(tvb
, offset
+ NBNS_ANS
);
1106 proto_tree_add_uint(nbns_tree
, hf_nbns_count_answers
, tvb
,
1107 offset
+ NBNS_ANS
, 2, ans
);
1109 auth
= tvb_get_ntohs(tvb
, offset
+ NBNS_AUTH
);
1111 proto_tree_add_uint(nbns_tree
, hf_nbns_count_auth_rr
, tvb
,
1112 offset
+ NBNS_AUTH
, 2, auth
);
1114 add
= tvb_get_ntohs(tvb
, offset
+ NBNS_ADD
);
1116 proto_tree_add_uint(nbns_tree
, hf_nbns_count_add_rr
, tvb
,
1117 offset
+ NBNS_ADD
, 2, add
);
1120 cur_off
= offset
+ NBNS_HDRLEN
;
1123 /* If this is a response, don't add information about the
1124 queries to the summary, just add information about the
1126 cur_off
+= dissect_query_records(tvb
, cur_off
,
1127 nbns_data_offset
, quest
,
1128 (!(flags
& F_RESPONSE
) ? pinfo
->cinfo
: NULL
), nbns_tree
);
1132 /* If this is a request, don't add information about the
1133 answers to the summary, just add information about the
1135 cur_off
+= dissect_answer_records(tvb
, cur_off
,
1136 nbns_data_offset
, ans
,
1137 ((flags
& F_RESPONSE
) ? pinfo
->cinfo
: NULL
), nbns_tree
,
1141 /* Don't add information about the authoritative name
1142 servers, or the additional records, to the summary. */
1144 cur_off
+= dissect_answer_records(tvb
, cur_off
,
1146 auth
, NULL
, nbns_tree
, opcode
,
1147 "Authoritative nameservers");
1150 /*cur_off += */dissect_answer_records(tvb
, cur_off
,
1152 add
, NULL
, nbns_tree
, opcode
,
1153 "Additional records");
1156 /* NetBIOS datagram packet, from RFC 1002, page 32 */
1157 struct nbdgm_header
{
1168 /* For packets with data */
1172 /* For error packets */
1177 * NBDS message types.
1179 #define NBDS_DIRECT_UNIQUE 0x10
1180 #define NBDS_DIRECT_GROUP 0x11
1181 #define NBDS_BROADCAST 0x12
1182 #define NBDS_ERROR 0x13
1183 #define NBDS_QUERY_REQUEST 0x14
1184 #define NBDS_POS_QUERY_RESPONSE 0x15
1185 #define NBDS_NEG_QUERY_RESPONSE 0x16
1187 static const value_string nbds_msgtype_vals
[] = {
1188 { NBDS_DIRECT_UNIQUE
, "Direct_unique datagram" },
1189 { NBDS_DIRECT_GROUP
, "Direct_group datagram" },
1190 { NBDS_BROADCAST
, "Broadcast datagram" },
1191 { NBDS_ERROR
, "Datagram error" },
1192 { NBDS_QUERY_REQUEST
, "Datagram query request" },
1193 { NBDS_POS_QUERY_RESPONSE
, "Datagram positive query response" },
1194 { NBDS_NEG_QUERY_RESPONSE
, "Datagram negative query response" },
1198 static const value_string node_type_vals
[] = {
1207 dissect_nbdgm(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
1210 proto_tree
*nbdgm_tree
= NULL
;
1211 proto_item
*ti
= NULL
;
1212 struct nbdgm_header header
;
1216 static const value_string error_codes
[] = {
1217 { 0x82, "Destination name not present" },
1218 { 0x83, "Invalid source name format" },
1219 { 0x84, "Invalid destination name format" },
1227 name
= (char *)wmem_alloc(wmem_packet_scope(), MAX_NAME_LEN
);
1229 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "NBDS");
1230 col_clear(pinfo
->cinfo
, COL_INFO
);
1232 header
.msg_type
= tvb_get_guint8(tvb
, offset
);
1234 flags
= tvb_get_guint8(tvb
, offset
+1);
1235 header
.flags
.more
= flags
& 1;
1236 header
.flags
.first
= (flags
& 2) >> 1;
1237 header
.flags
.node_type
= (flags
& 12) >> 2;
1239 header
.dgm_id
= tvb_get_ntohs(tvb
, offset
+2);
1240 header
.src_ip
= tvb_get_ipv4( tvb
, offset
+4);
1241 header
.src_port
= tvb_get_ntohs(tvb
, offset
+8);
1243 /* avoid gcc warnings */
1244 header
.dgm_length
= 0;
1245 header
.pkt_offset
= 0;
1246 header
.error_code
= 0;
1247 switch (header
.msg_type
) {
1249 case NBDS_DIRECT_UNIQUE
:
1250 case NBDS_DIRECT_GROUP
:
1251 case NBDS_BROADCAST
:
1252 header
.dgm_length
= tvb_get_ntohs(tvb
, offset
+10);
1253 header
.pkt_offset
= tvb_get_ntohs(tvb
, offset
+12);
1257 header
.error_code
= tvb_get_guint8(tvb
, offset
+10);
1261 col_add_str(pinfo
->cinfo
, COL_INFO
,
1262 val_to_str(header
.msg_type
, nbds_msgtype_vals
,
1263 "Unknown message type (0x%02X)"));
1266 ti
= proto_tree_add_item(tree
, proto_nbdgm
, tvb
, offset
, -1,
1268 nbdgm_tree
= proto_item_add_subtree(ti
, ett_nbdgm
);
1270 proto_tree_add_uint(nbdgm_tree
, hf_nbdgm_type
, tvb
,
1273 proto_tree_add_boolean(nbdgm_tree
, hf_nbdgm_fragment
, tvb
,
1276 proto_tree_add_boolean(nbdgm_tree
, hf_nbdgm_first
, tvb
,
1278 header
.flags
.first
);
1279 proto_tree_add_uint(nbdgm_tree
, hf_nbdgm_node_type
, tvb
,
1281 header
.flags
.node_type
);
1283 proto_tree_add_uint(nbdgm_tree
, hf_nbdgm_datagram_id
, tvb
,
1284 offset
+2, 2, header
.dgm_id
);
1285 proto_tree_add_ipv4(nbdgm_tree
, hf_nbdgm_src_ip
, tvb
,
1286 offset
+4, 4, header
.src_ip
);
1287 proto_tree_add_uint(nbdgm_tree
, hf_nbdgm_src_port
, tvb
,
1288 offset
+8, 2, header
.src_port
);
1294 switch (header
.msg_type
) {
1296 case NBDS_DIRECT_UNIQUE
:
1297 case NBDS_DIRECT_GROUP
:
1298 case NBDS_BROADCAST
:
1300 proto_tree_add_text(nbdgm_tree
, tvb
, offset
, 2,
1301 "Datagram length: %d bytes", header
.dgm_length
);
1302 proto_tree_add_text(nbdgm_tree
, tvb
, offset
+2, 2,
1303 "Packet offset: %d bytes", header
.pkt_offset
);
1309 len
= get_nbns_name(tvb
, offset
, offset
, name
, MAX_NAME_LEN
, &name_type
);
1312 add_name_and_type(nbdgm_tree
, tvb
, offset
, len
,
1313 "Source name", name
, name_type
);
1317 /* Destination name */
1318 len
= get_nbns_name(tvb
, offset
, offset
, name
, MAX_NAME_LEN
, &name_type
);
1321 add_name_and_type(nbdgm_tree
, tvb
, offset
, len
,
1322 "Destination name", name
, name_type
);
1327 * Here we can pass the packet off to the next protocol.
1328 * Set the length of our top-level tree item to include
1331 * XXX - take the datagram length into account?
1334 proto_item_set_len(ti
, offset
);
1335 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
1336 dissect_netbios_payload(next_tvb
, pinfo
, tree
);
1341 proto_tree_add_text(nbdgm_tree
, tvb
, offset
, 1, "Error code: %s",
1342 val_to_str(header
.error_code
, error_codes
, "Unknown (0x%x)"));
1346 proto_item_set_len(ti
, offset
);
1349 case NBDS_QUERY_REQUEST
:
1350 case NBDS_POS_QUERY_RESPONSE
:
1351 case NBDS_NEG_QUERY_RESPONSE
:
1352 /* Destination name */
1353 len
= get_nbns_name(tvb
, offset
, offset
, name
, MAX_NAME_LEN
, &name_type
);
1356 add_name_and_type(nbdgm_tree
, tvb
, offset
, len
,
1357 "Destination name", name
, name_type
);
1361 proto_item_set_len(ti
, offset
);
1367 * NetBIOS Session Service message types (RFC 1002).
1369 #define SESSION_MESSAGE 0x00
1370 #define SESSION_REQUEST 0x81
1371 #define POSITIVE_SESSION_RESPONSE 0x82
1372 #define NEGATIVE_SESSION_RESPONSE 0x83
1373 #define RETARGET_SESSION_RESPONSE 0x84
1374 #define SESSION_KEEP_ALIVE 0x85
1376 static const value_string message_types
[] = {
1377 { SESSION_MESSAGE
, "Session message" },
1378 { SESSION_REQUEST
, "Session request" },
1379 { POSITIVE_SESSION_RESPONSE
, "Positive session response" },
1380 { NEGATIVE_SESSION_RESPONSE
, "Negative session response" },
1381 { RETARGET_SESSION_RESPONSE
, "Retarget session response" },
1382 { SESSION_KEEP_ALIVE
, "Session keep-alive" },
1387 * NetBIOS Session Service flags.
1389 #define NBSS_FLAGS_E 0x1
1391 static const value_string error_codes
[] = {
1392 { 0x80, "Not listening on called name" },
1393 { 0x81, "Not listening for called name" },
1394 { 0x82, "Called name not present" },
1395 { 0x83, "Called name present, but insufficient resources" },
1396 { 0x8F, "Unspecified error" },
1401 * Dissect a single NBSS packet (there may be more than one in a given
1404 * [ Hmmm, in my experience, I have never seen more than one NBSS in a
1405 * single segment, since they mostly contain SMBs which are essentially
1406 * a request response type protocol (RJS). ]
1408 * [ However, under heavy load with many requests multiplexed on one
1409 * session it is not unusual to see multiple requests in one TCP
1410 * segment. Unfortunately, in this case a single session message is
1411 * frequently split over multiple segments, which frustrates decoding
1415 dissect_nbss_packet(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
,
1416 proto_tree
*tree
, int is_cifs
)
1418 proto_tree
*nbss_tree
= NULL
;
1419 proto_item
*ti
= NULL
;
1420 proto_tree
*field_tree
;
1424 volatile int length
;
1425 int length_remaining
;
1431 const char *saved_proto
;
1434 name
= (char *)wmem_alloc(wmem_packet_scope(), MAX_NAME_LEN
);
1436 /* Desegmentation */
1437 length_remaining
= tvb_length_remaining(tvb
, offset
);
1440 * Can we do reassembly?
1442 if (nbss_desegment
&& pinfo
->can_desegment
) {
1444 * Yes - is the NBSS header split across segment boundaries?
1446 if (length_remaining
< 4) {
1448 * Yes. Tell our caller how many more bytes
1451 return -(4 - length_remaining
);
1456 * Get the length of the NBSS message.
1460 length
= tvb_get_ntoh24(tvb
, offset
+ 1);
1462 flags
= tvb_get_guint8(tvb
, offset
+ 1);
1463 length
= tvb_get_ntohs(tvb
, offset
+ 2);
1464 if (flags
& NBSS_FLAGS_E
)
1468 /* give a hint to TCP where the next PDU starts
1469 * so that it can attempt to find it in case it starts
1470 * somewhere in the middle of a segment.
1472 if(!pinfo
->fd
->flags
.visited
){
1473 /* 'Only' SMB is transported ontop of this so make sure
1474 * there is an SMB header there ...
1476 if( ((length
+4)>tvb_reported_length_remaining(tvb
, offset
))
1477 &&(tvb_length_remaining(tvb
, offset
) >= 8)
1478 &&(tvb_get_guint8(tvb
,offset
+5) == 'S')
1479 &&(tvb_get_guint8(tvb
,offset
+6) == 'M')
1480 &&(tvb_get_guint8(tvb
,offset
+7) == 'B') ){
1481 pinfo
->want_pdu_tracking
= 2;
1482 pinfo
->bytes_until_next_pdu
= (length
+4)-tvb_reported_length_remaining(tvb
, offset
);
1487 * Can we do reassembly?
1489 if (nbss_desegment
&& pinfo
->can_desegment
) {
1491 * Yes - is the NBSS message split across segment boundaries?
1493 if (length_remaining
< length
+ 4) {
1495 * Yes. Tell our caller how many more bytes
1498 return -((length
+ 4) - length_remaining
);
1502 msg_type
= tvb_get_guint8(tvb
, offset
);
1504 ti
= proto_tree_add_item(tree
, proto_nbss
, tvb
, offset
, length
+ 4, ENC_NA
);
1505 nbss_tree
= proto_item_add_subtree(ti
, ett_nbss
);
1507 proto_tree_add_item(nbss_tree
, hf_nbss_type
, tvb
, offset
, 1, ENC_NA
);
1512 proto_tree_add_item(nbss_tree
, hf_nbss_cifs_length
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
1516 tf
= proto_tree_add_uint(nbss_tree
, hf_nbss_flags
, tvb
, offset
, 1, flags
);
1517 field_tree
= proto_item_add_subtree(tf
, ett_nbss_flags
);
1518 proto_tree_add_item(field_tree
, hf_nbss_flags_e
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1522 proto_tree_add_uint(nbss_tree
, hf_nbss_length
, tvb
, offset
, 2, length
);
1529 case SESSION_REQUEST
:
1530 len
= get_nbns_name(tvb
, offset
, offset
, name
, MAX_NAME_LEN
, &name_type
);
1532 add_name_and_type(nbss_tree
, tvb
, offset
, len
,
1533 "Called name", name
, name_type
);
1536 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", to %s ", name
);
1538 len
= get_nbns_name(tvb
, offset
, offset
, name
, MAX_NAME_LEN
, &name_type
);
1541 add_name_and_type(nbss_tree
, tvb
, offset
, len
,
1542 "Calling name", name
, name_type
);
1544 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "from %s", name
);
1548 case NEGATIVE_SESSION_RESPONSE
:
1550 proto_tree_add_text(nbss_tree
, tvb
, offset
, 1,
1552 val_to_str(tvb_get_guint8(tvb
, offset
),
1553 error_codes
, "Unknown (%x)"));
1555 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", %s",
1556 val_to_str(tvb_get_guint8(tvb
, offset
),
1557 error_codes
, "Unknown (%x)"));
1561 case RETARGET_SESSION_RESPONSE
:
1563 proto_tree_add_text(nbss_tree
, tvb
, offset
, 4,
1564 "Retarget IP address: %s",
1565 tvb_ip_to_str(tvb
, offset
));
1570 proto_tree_add_text(nbss_tree
, tvb
, offset
, 2,
1571 "Retarget port: %u",
1572 tvb_get_ntohs(tvb
, offset
));
1576 case SESSION_MESSAGE
:
1578 * Here we can pass the message off to the next protocol.
1579 * Set the length of our top-level tree item to include
1582 len
= tvb_length_remaining(tvb
, offset
);
1583 reported_len
= tvb_reported_length_remaining(tvb
, offset
);
1586 if (reported_len
> length
)
1587 reported_len
= length
;
1589 next_tvb
= tvb_new_subset(tvb
, offset
, len
, reported_len
);
1592 * Dissect the message.
1594 * If it gets an error that means there's no point in
1595 * dissecting any more PDUs, rethrow the exception in
1598 * If it gets any other error, report it and continue, as that
1599 * means that PDU got an error, but that doesn't mean we should
1600 * stop dissecting PDUs within this frame or chunk of reassembled
1603 saved_proto
= pinfo
->current_proto
;
1604 pd_save
= pinfo
->private_data
;
1606 dissect_netbios_payload(next_tvb
, pinfo
, tree
);
1608 CATCH_NONFATAL_ERRORS
{
1609 /* Restore the private_data structure in case one of the
1610 * called dissectors modified it (and, due to the exception,
1611 * was unable to restore it).
1613 pinfo
->private_data
= pd_save
;
1614 show_exception(tvb
, pinfo
, tree
, EXCEPT_CODE
, GET_MESSAGE
);
1615 pinfo
->current_proto
= saved_proto
;
1625 dissect_continuation_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
1627 proto_tree
*nbss_tree
;
1631 * It looks like a continuation.
1633 col_set_str(pinfo
->cinfo
, COL_INFO
, "NBSS Continuation Message");
1636 ti
= proto_tree_add_item(tree
, proto_nbss
, tvb
, 0, -1, ENC_NA
);
1637 nbss_tree
= proto_item_add_subtree(ti
, ett_nbss
);
1638 proto_tree_add_text(nbss_tree
, tvb
, 0, -1, "Continuation data");
1641 return tvb_length(tvb
);
1645 dissect_nbss(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data
)
1647 struct tcpinfo
*tcpinfo
= (struct tcpinfo
*)data
;
1656 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "NBSS");
1657 col_clear(pinfo
->cinfo
, COL_INFO
);
1659 max_data
= tvb_length(tvb
);
1661 msg_type
= tvb_get_guint8(tvb
, offset
);
1663 if (pinfo
->match_uint
== TCP_PORT_CIFS
) {
1665 * Windows 2000 CIFS clients can dispense completely
1666 * with the NETBIOS encapsulation and directly use CIFS
1667 * over TCP. As would be expected, the framing is
1668 * identical, except that the length is 24 bits instead
1669 * of 17. The only message types used are
1670 * SESSION_MESSAGE and SESSION_KEEP_ALIVE.
1678 * This might be a continuation of an earlier message.
1679 * (Yes, that might be true even if we're doing TCP reassembly,
1680 * as the first TCP segment in the capture might start in the
1681 * middle of an NBNS message.)
1685 * If this isn't reassembled data, check to see whether it
1686 * looks like a continuation of a message.
1687 * (If it is reassembled data, it shouldn't be a continuation,
1688 * as reassembly should've gathered the continuations together
1691 if (!tcpinfo
->is_reassembled
) {
1694 * Not enough data for an NBSS header; assume
1695 * it's a continuation of a message.
1697 * XXX - if there's not enough data, we should
1698 * attempt to reassemble the data, if the first byte
1699 * is a valid message type.
1701 return dissect_continuation_packet(tvb
, pinfo
, tree
);
1705 * The larged size in for non-SMB NBSS traffic is
1706 * 17 bits (0x1FFFF).
1708 * The SMB1 unix extensions and the SMB2 multi credit
1709 * feature allow more than 17 bits (0x1FFFF), they allow
1710 * 24 bits (0xFFFFFF).
1712 * So if it is a SESSION_MESSAGE and SMB1 or SMB2
1713 * mark it as is_cifs.
1715 if (tvb_length_remaining(tvb
, offset
) >= 8
1716 && tvb_get_guint8(tvb
,offset
+0) == SESSION_MESSAGE
1717 && tvb_get_guint8(tvb
,offset
+5) == 'S'
1718 && tvb_get_guint8(tvb
,offset
+6) == 'M'
1719 && tvb_get_guint8(tvb
,offset
+7) == 'B') {
1726 * We have enough data for an NBSS header.
1727 * Get the flags and length of the message,
1728 * and see if they're sane.
1732 length
= tvb_get_ntoh24(tvb
, offset
+ 1);
1734 flags
= tvb_get_guint8(tvb
, offset
+ 1);
1735 length
= tvb_get_ntohs(tvb
, offset
+ 2);
1736 if (flags
& NBSS_FLAGS_E
)
1739 if ((flags
& (~NBSS_FLAGS_E
)) != 0) {
1741 * A bogus flag was set; assume it's a continuation.
1743 return dissect_continuation_packet(tvb
, pinfo
, tree
);
1748 case SESSION_MESSAGE
:
1750 * This is variable-length.
1751 * All we know is that it shouldn't be zero.
1752 * (XXX - can we get zero-length messages?
1753 * Not with SMB, but perhaps other NetBIOS-based
1754 * protocols have them.)
1757 return dissect_continuation_packet(tvb
, pinfo
, tree
);
1761 case SESSION_REQUEST
:
1763 * This is variable-length.
1764 * The names are DNS-encoded 32-byte values;
1765 * we need at least 2 bytes (one for each name;
1766 * actually, we should have more for the first
1767 * name, as there's no name preceding it so
1768 * there should be no compression), and we
1769 * shouldn't have more than 128 bytes (actually,
1770 * we shouldn't have that many).
1772 * XXX - actually, Mac OS X 10.1 (yes, that's
1773 * redundant, but that's what Apple calls it,
1774 * not Mac OS X.1) puts names longer than 16
1775 * characters into session request messages,
1776 * so we can have more than 32 bytes of
1777 * name value, so we can have more than 128
1780 if (length
< 2 || length
> 256)
1781 return dissect_continuation_packet(tvb
, pinfo
, tree
);
1784 case POSITIVE_SESSION_RESPONSE
:
1786 * This has no data, so the length must be zero.
1789 return dissect_continuation_packet(tvb
, pinfo
, tree
);
1792 case NEGATIVE_SESSION_RESPONSE
:
1794 * This has 1 byte of data.
1797 return dissect_continuation_packet(tvb
, pinfo
, tree
);
1800 case RETARGET_SESSION_RESPONSE
:
1802 * This has 6 bytes of data.
1805 return dissect_continuation_packet(tvb
, pinfo
, tree
);
1808 case SESSION_KEEP_ALIVE
:
1810 * This has no data, so the length must be zero.
1813 return dissect_continuation_packet(tvb
, pinfo
, tree
);
1818 * Unknown message type; assume it's a continuation.
1820 return dissect_continuation_packet(tvb
, pinfo
, tree
);
1824 col_add_str(pinfo
->cinfo
, COL_INFO
,
1825 val_to_str(msg_type
, message_types
, "Unknown (%02x)"));
1827 while (tvb_reported_length_remaining(tvb
, offset
) > 0) {
1828 len
= dissect_nbss_packet(tvb
, offset
, pinfo
, tree
, is_cifs
);
1831 * We need more data to dissect this, and
1832 * desegmentation is enabled. "-len" is the
1833 * number of additional bytes of data we need.
1835 * Tell the TCP dissector where the data for this
1836 * message starts in the data it handed us, and
1837 * how many more bytes we need, and return.
1839 pinfo
->desegment_offset
= offset
;
1840 pinfo
->desegment_len
= -len
;
1841 return tvb_length(tvb
);
1846 return tvb_length(tvb
);
1850 proto_register_nbt(void)
1853 static hf_register_info hf_nbns
[] = {
1855 { "Flags", "nbns.flags",
1856 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1858 { &hf_nbns_flags_response
,
1859 { "Response", "nbns.flags.response",
1860 FT_BOOLEAN
, 16, TFS(&tfs_flags_response
), F_RESPONSE
,
1861 "Is the message a response?", HFILL
}},
1862 { &hf_nbns_flags_opcode
,
1863 { "Opcode", "nbns.flags.opcode",
1864 FT_UINT16
, BASE_DEC
, VALS(opcode_vals
), F_OPCODE
,
1865 "Operation code", HFILL
}},
1866 { &hf_nbns_flags_authoritative
,
1867 { "Authoritative", "nbns.flags.authoritative",
1868 FT_BOOLEAN
, 16, TFS(&tfs_flags_authoritative
), F_AUTHORITATIVE
,
1869 "Is the server is an authority for the domain?", HFILL
}},
1870 { &hf_nbns_flags_truncated
,
1871 { "Truncated", "nbns.flags.truncated",
1872 FT_BOOLEAN
, 16, TFS(&tfs_flags_truncated
), F_TRUNCATED
,
1873 "Is the message truncated?", HFILL
}},
1874 { &hf_nbns_flags_recdesired
,
1875 { "Recursion desired", "nbns.flags.recdesired",
1876 FT_BOOLEAN
, 16, TFS(&tfs_flags_recdesired
), F_RECDESIRED
,
1877 "Do query recursively?", HFILL
}},
1878 { &hf_nbns_flags_recavail
,
1879 { "Recursion available", "nbns.flags.recavail",
1880 FT_BOOLEAN
, 16, TFS(&tfs_flags_recavail
), F_RECAVAIL
,
1881 "Can the server do recursive queries?", HFILL
}},
1882 { &hf_nbns_flags_broadcast
,
1883 { "Broadcast", "nbns.flags.broadcast",
1884 FT_BOOLEAN
, 16, TFS(&tfs_flags_broadcast
), F_BROADCAST
,
1885 "Is this a broadcast packet?", HFILL
}},
1886 { &hf_nbns_flags_rcode
,
1887 { "Reply code", "nbns.flags.rcode",
1888 FT_UINT16
, BASE_DEC
, VALS(rcode_vals
), F_RCODE
,
1890 { &hf_nbns_transaction_id
,
1891 { "Transaction ID", "nbns.id",
1892 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1893 "Identification of transaction", HFILL
}},
1894 { &hf_nbns_count_questions
,
1895 { "Questions", "nbns.count.queries",
1896 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1897 "Number of queries in packet", HFILL
}},
1898 { &hf_nbns_count_answers
,
1899 { "Answer RRs", "nbns.count.answers",
1900 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1901 "Number of answers in packet", HFILL
}},
1902 { &hf_nbns_count_auth_rr
,
1903 { "Authority RRs", "nbns.count.auth_rr",
1904 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1905 "Number of authoritative records in packet", HFILL
}},
1906 { &hf_nbns_count_add_rr
,
1907 { "Additional RRs", "nbns.count.add_rr",
1908 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1909 "Number of additional records in packet", HFILL
}},
1910 { &hf_nbns_name_flags
,
1911 { "Name flags", "nbns.name_flags",
1912 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1914 { &hf_nbns_name_flags_group
,
1915 { "Name type", "nbns.name_flags.group",
1916 FT_BOOLEAN
, 16, TFS(&tfs_group_unique_name
), NAME_FLAGS_G
,
1918 { &hf_nbns_name_flags_ont
,
1919 { "ONT", "nbns.name_flags.ont",
1920 FT_UINT16
, BASE_DEC
, VALS(name_flags_ont_vals
), NAME_FLAGS_ONT
,
1922 { &hf_nbns_name_flags_drg
,
1923 { "Name is being deregistered", "nbns.name_flags.drg",
1924 FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), NAME_FLAGS_DRG
,
1926 { &hf_nbns_name_flags_cnf
,
1927 { "Name is in conflict", "nbns.name_flags.cnf",
1928 FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), NAME_FLAGS_CNF
,
1930 { &hf_nbns_name_flags_act
,
1931 { "Name is active", "nbns.name_flags.act",
1932 FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), NAME_FLAGS_ACT
,
1934 { &hf_nbns_name_flags_prm
,
1935 { "Permanent node name", "nbns.name_flags.prm",
1936 FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), NAME_FLAGS_PRM
,
1938 { &hf_nbns_nb_flags
,
1939 { "Name flags", "nbns.nb_flags",
1940 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1942 { &hf_nbns_nb_flags_group
,
1943 { "Name type", "nbns.nb_flags.group",
1944 FT_BOOLEAN
, 16, TFS(&tfs_group_unique_name
), NB_FLAGS_G
,
1946 { &hf_nbns_nb_flags_ont
,
1947 { "ONT", "nbns.nb_flags.ont",
1948 FT_UINT16
, BASE_DEC
, VALS(nb_flags_ont_vals
), NB_FLAGS_ONT
,
1952 static hf_register_info hf_nbdgm
[] = {
1954 { "Message Type", "nbdgm.type",
1955 FT_UINT8
, BASE_DEC
, VALS(nbds_msgtype_vals
), 0x0,
1956 "NBDGM message type", HFILL
}},
1957 { &hf_nbdgm_fragment
,
1958 { "More fragments follow", "nbdgm.next",
1959 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0x0,
1960 "TRUE if more fragments follow", HFILL
}},
1962 { "This is first fragment", "nbdgm.first",
1963 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_yes_no
), 0x0,
1964 "TRUE if first fragment", HFILL
}},
1965 { &hf_nbdgm_node_type
,
1966 { "Node Type", "nbdgm.node_type",
1967 FT_UINT8
, BASE_DEC
, VALS(node_type_vals
), 0x0,
1969 { &hf_nbdgm_datagram_id
,
1970 { "Datagram ID", "nbdgm.dgram_id",
1971 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1972 "Datagram identifier", HFILL
}},
1974 { "Source IP", "nbdgm.src.ip",
1975 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
1976 "Source IPv4 address", HFILL
}},
1977 { &hf_nbdgm_src_port
,
1978 { "Source Port", "nbdgm.src.port",
1979 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1983 static hf_register_info hf_nbss
[] = {
1985 { "Message Type", "nbss.type",
1986 FT_UINT8
, BASE_HEX
, VALS(message_types
), 0x0,
1987 "NBSS message type", HFILL
}},
1989 { "Flags", "nbss.flags",
1990 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
1991 "NBSS message flags", HFILL
}},
1993 { "Extend", "nbss.flags.e",
1994 FT_BOOLEAN
, 8, TFS(&tfs_nbss_flags_e
), NBSS_FLAGS_E
,
1997 { "Length", "nbss.length",
1998 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1999 "Length of trailer (payload) following this field in bytes", HFILL
}},
2000 { &hf_nbss_cifs_length
,
2001 { "Length", "nbss.length",
2002 FT_UINT24
, BASE_DEC
, NULL
, 0x0,
2003 "Length trailer (payload) following this field in bytes", HFILL
}}
2005 static gint
*ett
[] = {
2010 &ett_nbns_name_flags
,
2018 module_t
*nbss_module
;
2020 proto_nbns
= proto_register_protocol("NetBIOS Name Service", "NBNS", "nbns");
2021 proto_register_field_array(proto_nbns
, hf_nbns
, array_length(hf_nbns
));
2023 proto_nbdgm
= proto_register_protocol("NetBIOS Datagram Service",
2025 proto_register_field_array(proto_nbdgm
, hf_nbdgm
, array_length(hf_nbdgm
));
2027 proto_nbss
= proto_register_protocol("NetBIOS Session Service",
2029 proto_register_field_array(proto_nbss
, hf_nbss
, array_length(hf_nbss
));
2031 proto_register_subtree_array(ett
, array_length(ett
));
2033 nbss_module
= prefs_register_protocol(proto_nbss
, NULL
);
2034 prefs_register_bool_preference(nbss_module
, "desegment_nbss_commands",
2035 "Reassemble NBSS packets spanning multiple TCP segments",
2036 "Whether the NBSS dissector should reassemble packets spanning multiple TCP segments."
2037 " To use this option, you must also enable"
2038 " \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
2043 proto_reg_handoff_nbt(void)
2045 dissector_handle_t nbns_handle
, nbdgm_handle
, nbss_handle
;
2047 nbns_handle
= create_dissector_handle(dissect_nbns
, proto_nbns
);
2048 dissector_add_uint("udp.port", UDP_PORT_NBNS
, nbns_handle
);
2050 nbdgm_handle
= create_dissector_handle(dissect_nbdgm
, proto_nbdgm
);
2051 dissector_add_uint("udp.port", UDP_PORT_NBDGM
, nbdgm_handle
);
2053 nbss_handle
= new_create_dissector_handle(dissect_nbss
, proto_nbss
);
2054 dissector_add_uint("tcp.port", TCP_PORT_NBSS
, nbss_handle
);
2055 dissector_add_uint("tcp.port", TCP_PORT_CIFS
, nbss_handle
);