The length of an NBSS message can be bigger than 64K, so make the
[obnox/wireshark/wip.git] / packet-nbns.c
1 /* packet-nbns.c
2  * Routines for NetBIOS-over-TCP packet disassembly (the name dates back
3  * to when it had only NBNS)
4  * Gilbert Ramirez <gram@xiexie.org>
5  * Much stuff added by Guy Harris <guy@alum.mit.edu>
6  *
7  * $Id: packet-nbns.c,v 1.61 2001/09/30 23:14:43 guy Exp $
8  *
9  * Ethereal - Network traffic analyzer
10  * By Gerald Combs <gerald@ethereal.com>
11  * Copyright 1998 Gerald Combs
12  * 
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  * 
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  * 
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26  */
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #ifdef HAVE_SYS_TYPES_H
33 # include <sys/types.h>
34 #endif
35
36 #include <stdio.h>
37 #include <string.h>
38 #include <glib.h>
39
40 #include "packet.h"
41 #include "packet-dns.h"
42 #include "packet-netbios.h"
43 #include "packet-tcp.h"
44 #include "prefs.h"
45
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;
54
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;
63
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;
72
73 static gint ett_nbdgm = -1;
74
75 static int proto_nbss = -1;
76 static int hf_nbss_type = -1;
77 static int hf_nbss_flags = -1;
78
79 static gint ett_nbss = -1;
80 static gint ett_nbss_flags = -1;
81
82 /* desegmentation of NBSS over TCP */
83 static gboolean nbss_desegment = TRUE;
84
85 /* See RFC 1001 and 1002 for information on the first three, and see
86
87         http://www.cifs.com/specs/draft-leach-cifs-v1-spec-01.txt
88
89    Appendix B, and various messages on the CIFS mailing list such as
90
91         http://discuss.microsoft.com/SCRIPTS/WA-MSD.EXE?A2=ind9811A&L=cifs&P=R386
92
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
98
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". */
102
103 /* Offsets of fields in the NBNS header. */
104 #define NBNS_ID         0
105 #define NBNS_FLAGS      2
106 #define NBNS_QUEST      4
107 #define NBNS_ANS        6
108 #define NBNS_AUTH       8
109 #define NBNS_ADD        10
110
111 /* Length of NBNS header. */
112 #define NBNS_HDRLEN     12
113
114 /* type values  */
115 #define T_NB            32              /* NetBIOS name service RR */
116 #define T_NBSTAT        33              /* NetBIOS node status RR */
117
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 */
127
128 /* Opcodes */
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 */
136
137 /* Reply codes */
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)
146
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
149  * packet traces. */
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 */
155
156 #define NB_FLAGS_G              (1<<(15-0))     /* group name */
157
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 */
162
163 #define NAME_FLAGS_ACT          (1<<(15-5))     /* name is active */
164
165 #define NAME_FLAGS_CNF          (1<<(15-4))     /* name is in conflict */
166
167 #define NAME_FLAGS_DRG          (1<<(15-3))     /* name is being deregistered */
168
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 */
173
174 #define NAME_FLAGS_G            (1<<(15-0))     /* group name */
175
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"   },
184           { 0,                     NULL                         }
185 };
186
187 static char *
188 nbns_type_name (int type)
189 {
190         switch (type) {
191         case T_NB:
192                 return "NB";
193         case T_NBSTAT:
194                 return "NBSTAT";
195         }
196         
197         return "unknown";
198 }
199
200 #define NBNAME_BUF_LEN 128
201
202 static int
203 get_nbns_name(tvbuff_t *tvb, int offset, int nbns_data_offset,
204     char *name_ret, int *name_type_ret)
205 {
206         int name_len;
207         char name[MAXDNAME];
208         char nbname[NBNAME_BUF_LEN];
209         char *pname, *pnbname, cname, cnbname;
210         int name_type;
211
212         name_len = get_dns_name(tvb, offset, nbns_data_offset, name,
213             sizeof(name));
214
215         /* OK, now undo the first-level encoding. */
216         pname = &name[0];
217         pnbname = &nbname[0];
218         for (;;) {
219                 /* Every two characters of the first level-encoded name
220                  * turn into one character in the decoded name. */
221                 cname = *pname;
222                 if (cname == '\0')
223                         break;          /* no more characters */
224                 if (cname == '.')
225                         break;          /* scope ID follows */
226                 if (cname < 'A' || cname > 'Z') {
227                         /* Not legal. */
228                         strcpy(nbname,
229                             "Illegal NetBIOS name (character not between A and Z in first-level encoding)");
230                         goto bad;
231                 }
232                 cname -= 'A';
233                 cnbname = cname << 4;
234                 pname++;
235
236                 cname = *pname;
237                 if (cname == '\0' || cname == '.') {
238                         /* No more characters in the name - but we're in
239                          * the middle of a pair.  Not legal. */
240                         strcpy(nbname,
241                             "Illegal NetBIOS name (odd number of bytes)");
242                         goto bad;
243                 }
244                 if (cname < 'A' || cname > 'Z') {
245                         /* Not legal. */
246                         strcpy(nbname,
247                             "Illegal NetBIOS name (character not between A and Z in first-level encoding)");
248                         goto bad;
249                 }
250                 cname -= 'A';
251                 cnbname |= cname;
252                 pname++;
253
254                 /* Do we have room to store the character? */
255                 if (pnbname < &nbname[NETBIOS_NAME_LEN]) {
256                         /* Yes - store the character. */
257                         *pnbname = cnbname;
258                 }
259
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. */
262                 pnbname++;
263         }
264
265         /* NetBIOS names are supposed to be exactly 16 bytes long. */
266         if (pnbname - nbname != NETBIOS_NAME_LEN) {
267                 /* It's not. */
268                 sprintf(nbname, "Illegal NetBIOS name (%ld bytes long)",
269                     (long)(pnbname - nbname));
270                 goto bad;
271         }
272
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);
277         name_ret += 4;
278         if (cname == '.') {
279                 /* We have a scope ID, starting at "pname"; append that to
280                  * the decoded host name. */
281                 strcpy(name_ret, pname);
282         }
283         if (name_type_ret != NULL)
284                 *name_type_ret = name_type;
285         return name_len;
286
287 bad:
288         if (name_type_ret != NULL)
289                 *name_type_ret = -1;
290         strcpy (name_ret, nbname);
291         return name_len;
292 }
293
294
295 static int
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,
298     int *class_ret)
299 {
300         int name_len;
301         int type;
302         int class;
303
304         name_len = get_nbns_name(tvb, offset, nbns_data_offset, name_ret,
305            name_type_ret);
306         offset += name_len;
307         
308         type = tvb_get_ntohs(tvb, offset);
309         offset += 2;
310
311         class = tvb_get_ntohs(tvb, offset);
312
313         *type_ret = type;
314         *class_ret = class;
315         *name_len_ret = name_len;
316
317         return name_len + 4;
318 }
319
320 static void
321 add_name_and_type(proto_tree *tree, tvbuff_t *tvb, int offset, int len,
322     char *tag, char *name, int name_type)
323 {
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));
327         } else {
328                 proto_tree_add_text(tree, tvb, offset, len, "%s: %s",
329                     tag, name);
330         }
331 }
332
333 static int
334 dissect_nbns_query(tvbuff_t *tvb, int offset, int nbns_data_offset,
335     frame_data *fd, proto_tree *nbns_tree)
336 {
337         int len;
338         char name[(NETBIOS_NAME_LEN - 1)*4 + MAXDNAME];
339         int name_len;
340         int name_type;
341         int type;
342         int class;
343         char *class_name;
344         char *type_name;
345         int data_offset;
346         int data_start;
347         proto_tree *q_tree;
348         proto_item *tq;
349
350         data_start = data_offset = offset;
351
352         len = get_nbns_name_type_class(tvb, offset, nbns_data_offset, name,
353             &name_len, &name_type, &type, &class);
354         data_offset += len;
355
356         type_name = nbns_type_name(type);
357         class_name = dns_class_name(class);
358
359         if (fd != NULL)
360                 col_append_fstr(fd, 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);
365
366                 add_name_and_type(q_tree, tvb, offset, name_len, "Name", name,
367                     name_type);
368                 offset += name_len;
369
370                 proto_tree_add_text(q_tree, tvb, offset, 2, "Type: %s", type_name);
371                 offset += 2;
372
373                 proto_tree_add_text(q_tree, tvb, offset, 2, "Class: %s", class_name);
374                 offset += 2;
375         }
376         
377         return data_offset - data_start;
378 }
379
380 static void
381 nbns_add_nbns_flags(proto_tree *nbns_tree, tvbuff_t *tvb, int offset,
382     u_short flags, int is_wack)
383 {
384         char buf[128+1];
385         proto_tree *field_tree;
386         proto_item *tf;
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"             },
396                   { 0,               NULL                              }
397         };
398
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");
403                 strcat(buf, ", ");
404                 strcat(buf, val_to_str(flags & F_RCODE, rcode_vals,
405                     "Unknown error"));
406         }
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,
418                         "%s",
419                         decode_boolean_bitfield(flags, F_AUTHORITATIVE,
420                                 2*8,
421                                 "Server is an authority for domain",
422                                 "Server isn't an authority for domain"));
423         }
424         proto_tree_add_text(field_tree, tvb, offset, 2, "%s",
425                         decode_boolean_bitfield(flags, F_TRUNCATED,
426                                 2*8,
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,
431                                 2*8,
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,
436                         "%s",
437                         decode_boolean_bitfield(flags, F_RECAVAIL,
438                                 2*8,
439                                 "Server can do recursive queries",
440                                 "Server can't do recursive queries"));
441         }
442         proto_tree_add_text(field_tree, tvb, offset, 2, "%s",
443                         decode_boolean_bitfield(flags, F_BROADCAST,
444                                 2*8,
445                                 "Broadcast packet",
446                                 "Not a broadcast packet"));
447         if (flags & F_RESPONSE && !is_wack) {
448                 proto_tree_add_text(field_tree, tvb, offset, 2,
449                         "%s",
450                         decode_enumerated_bitfield(flags, F_RCODE,
451                                 2*8,
452                                 rcode_vals, "%s"));
453         }
454 }
455
456 static void
457 nbns_add_nb_flags(proto_tree *rr_tree, tvbuff_t *tvb, int offset, u_short flags)
458 {
459         char buf[128+1];
460         proto_tree *field_tree;
461         proto_item *tf;
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" },
467                   { 0,                   NULL     }
468         };
469
470         strcpy(buf, val_to_str(flags & NB_FLAGS_ONT, nb_flags_ont_vals,
471             "Unknown"));
472         strcat(buf, ", ");
473         if (flags & NB_FLAGS_G)
474                 strcat(buf, "group");
475         else
476                 strcat(buf, "unique");
477         tf = proto_tree_add_text(rr_tree, tvb, offset, 2, "Flags: 0x%x (%s)", flags,
478                         buf);
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,
482                                 2*8,
483                                 "Group name",
484                                 "Unique name"));
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"));
488 }
489
490 static void
491 nbns_add_name_flags(proto_tree *rr_tree, tvbuff_t *tvb, int offset,
492     u_short flags)
493 {
494         char buf[128+1];
495         proto_item *field_tree;
496         proto_item *tf;
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" },
501                   { 0,                     NULL     }
502         };
503
504         strcpy(buf, val_to_str(flags & NAME_FLAGS_ONT, name_flags_ont_vals,
505             "Unknown"));
506         strcat(buf, ", ");
507         if (flags & NAME_FLAGS_G)
508                 strcat(buf, "group");
509         else
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)",
520                         flags, buf);
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,
524                                 2*8,
525                                 "Group name",
526                                 "Unique name"));
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,
532                                 2*8,
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,
537                                 2*8,
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,
542                                 2*8,
543                                 "Name is active",
544                                 "Name is not active"));
545         proto_tree_add_text(field_tree, tvb, offset, 2, "%s",
546                         decode_boolean_bitfield(flags, NAME_FLAGS_PRM,
547                                 2*8,
548                                 "Permanent node name",
549                                 "Not permanent node name"));
550 }
551
552 static int
553 dissect_nbns_answer(tvbuff_t *tvb, int offset, int nbns_data_offset,
554     frame_data *fd, proto_tree *nbns_tree, int opcode)
555 {
556         int len;
557         char name[(NETBIOS_NAME_LEN - 1)*4 + MAXDNAME + 64];
558         int name_len;
559         int name_type;
560         int type;
561         int class;
562         char *class_name;
563         char *type_name;
564         int data_offset;
565         int cur_offset;
566         int data_start;
567         u_int ttl;
568         u_short data_len;
569         u_short flags;
570         proto_tree *rr_tree;
571         proto_item *trr;
572         char name_str[(NETBIOS_NAME_LEN - 1)*4 + 1];
573         u_int num_names;
574         char nbname[16+4+1];    /* 4 for [<last char>] */
575         u_short name_flags;
576
577         data_start = data_offset = offset;
578         cur_offset = offset;
579
580         len = get_nbns_name_type_class(tvb, offset, nbns_data_offset, name,
581             &name_len, &name_type, &type, &class);
582         data_offset += len;
583         cur_offset += len;
584
585         type_name = nbns_type_name(type);
586         class_name = dns_class_name(class);
587
588         ttl = tvb_get_ntohl(tvb, data_offset);
589         data_offset += 4;
590         cur_offset += 4;
591
592         data_len = tvb_get_ntohs(tvb, data_offset);
593         data_offset += 2;
594         cur_offset += 2;
595
596         switch (type) {
597         case T_NB:              /* "NB" record */
598                 if (fd != NULL) {
599                         if (opcode != OPCODE_WACK) {
600                                 col_append_fstr(fd, COL_INFO, " %s %s",
601                                     type_name,
602                                     ip_to_str(tvb_get_ptr(tvb, data_offset+2, 4)));
603                         }
604                 }
605                 if (nbns_tree == NULL)
606                         break;
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);
611                 strcat(name, " (");
612                 strcat(name, netbios_name_type_descr(name_type));
613                 strcat(name, ")");
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
620                                  * responses.  */
621                                 if (data_len < 2) {
622                                         proto_tree_add_text(rr_tree, tvb, cur_offset,
623                                             data_len, "(incomplete entry)");
624                                         break;
625                                 }
626                                 flags = tvb_get_ntohs(tvb, cur_offset);
627                                 nbns_add_nbns_flags(rr_tree, tvb, cur_offset,
628                                     flags, 1);
629                                 cur_offset += 2;
630                                 data_len -= 2;
631                         } else {
632                                 if (data_len < 2) {
633                                         proto_tree_add_text(rr_tree, tvb, cur_offset,
634                                             data_len, "(incomplete entry)");
635                                         break;
636                                 }
637                                 flags = tvb_get_ntohs(tvb, cur_offset);
638                                 nbns_add_nb_flags(rr_tree, tvb, cur_offset,
639                                     flags);
640                                 cur_offset += 2;
641                                 data_len -= 2;
642
643                                 if (data_len < 4) {
644                                         proto_tree_add_text(rr_tree, tvb, cur_offset,
645                                             data_len, "(incomplete entry)");
646                                         break;
647                                 }
648                                 proto_tree_add_text(rr_tree, tvb, cur_offset, 4,
649                                     "Addr: %s",
650                                     ip_to_str(tvb_get_ptr(tvb, cur_offset, 4)));
651                                 cur_offset += 4;
652                                 data_len -= 4;
653                         }
654                 }
655                 break;
656
657         case T_NBSTAT:  /* "NBSTAT" record */
658                 if (fd != NULL)
659                         col_append_fstr(fd, COL_INFO, " %s", type_name);
660                 if (nbns_tree == NULL)
661                         break;
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);
668                 if (data_len < 1) {
669                         proto_tree_add_text(rr_tree, tvb, cur_offset,
670                             data_len, "(incomplete entry)");
671                         break;
672                 }
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);
676                 cur_offset += 1;
677
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)");
682                                 goto out;
683                         }
684                         tvb_memcpy(tvb, (guint8 *)nbname, cur_offset,
685                             NETBIOS_NAME_LEN);
686                         name_type = process_netbios_name(nbname,
687                             name_str);
688                         proto_tree_add_text(rr_tree, tvb, cur_offset,
689                             NETBIOS_NAME_LEN, "Name: %s<%02x> (%s)",
690                             name_str, name_type,
691                             netbios_name_type_descr(name_type));
692                         cur_offset += NETBIOS_NAME_LEN;
693                         data_len -= NETBIOS_NAME_LEN;
694
695                         if (data_len < 2) {
696                                 proto_tree_add_text(rr_tree, tvb, cur_offset,
697                                     data_len, "(incomplete entry)");
698                                 goto out;
699                         }
700                         name_flags = tvb_get_ntohs(tvb, cur_offset);
701                         nbns_add_name_flags(rr_tree, tvb, cur_offset,
702                             name_flags);
703                         cur_offset += 2;
704                         data_len -= 2;
705
706                         num_names--;
707                 }
708
709                 if (data_len < 6) {
710                         proto_tree_add_text(rr_tree, tvb, cur_offset,
711                             data_len, "(incomplete entry)");
712                         break;
713                 }
714                 proto_tree_add_text(rr_tree, tvb, cur_offset, 6,
715                     "Unit ID: %s",
716                     ether_to_str(tvb_get_ptr(tvb, cur_offset, 6)));
717                 cur_offset += 6;
718                 data_len -= 6;
719
720                 if (data_len < 1) {
721                         proto_tree_add_text(rr_tree, tvb, cur_offset,
722                             data_len, "(incomplete entry)");
723                         break;
724                 }
725                 proto_tree_add_text(rr_tree, tvb, cur_offset, 1,
726                     "Jumpers: 0x%x", tvb_get_guint8(tvb, cur_offset));
727                 cur_offset += 1;
728                 data_len -= 1;
729
730                 if (data_len < 1) {
731                         proto_tree_add_text(rr_tree, tvb, cur_offset,
732                             data_len, "(incomplete entry)");
733                         break;
734                 }
735                 proto_tree_add_text(rr_tree, tvb, cur_offset, 1,
736                     "Test result: 0x%x", tvb_get_guint8(tvb, cur_offset));
737                 cur_offset += 1;
738                 data_len -= 1;
739
740                 if (data_len < 2) {
741                         proto_tree_add_text(rr_tree, tvb, cur_offset,
742                             data_len, "(incomplete entry)");
743                         break;
744                 }
745                 proto_tree_add_text(rr_tree, tvb, cur_offset, 2,
746                     "Version number: 0x%x", tvb_get_ntohs(tvb, cur_offset));
747                 cur_offset += 2;
748                 data_len -= 2;
749
750                 if (data_len < 2) {
751                         proto_tree_add_text(rr_tree, tvb, cur_offset,
752                             data_len, "(incomplete entry)");
753                         break;
754                 }
755                 proto_tree_add_text(rr_tree, tvb, cur_offset, 2,
756                     "Period of statistics: 0x%x",
757                     tvb_get_ntohs(tvb, cur_offset));
758                 cur_offset += 2;
759                 data_len -= 2;
760
761                 if (data_len < 2) {
762                         proto_tree_add_text(rr_tree, tvb, cur_offset,
763                             data_len, "(incomplete entry)");
764                         break;
765                 }
766                 proto_tree_add_text(rr_tree, tvb, cur_offset, 2,
767                     "Number of CRCs: %u", tvb_get_ntohs(tvb, cur_offset));
768                 cur_offset += 2;
769                 data_len -= 2;
770
771                 if (data_len < 2) {
772                         proto_tree_add_text(rr_tree, tvb, cur_offset,
773                             data_len, "(incomplete entry)");
774                         break;
775                 }
776                 proto_tree_add_text(rr_tree, tvb, cur_offset, 2,
777                     "Number of alignment errors: %u",
778                     tvb_get_ntohs(tvb, cur_offset));
779                 cur_offset += 2;
780                 data_len -= 2;
781
782                 if (data_len < 2) {
783                         proto_tree_add_text(rr_tree, tvb, cur_offset,
784                             data_len, "(incomplete entry)");
785                         break;
786                 }
787                 proto_tree_add_text(rr_tree, tvb, cur_offset, 2,
788                     "Number of collisions: %u", tvb_get_ntohs(tvb, cur_offset));
789                 cur_offset += 2;
790                 data_len -= 2;
791
792                 if (data_len < 2) {
793                         proto_tree_add_text(rr_tree, tvb, cur_offset,
794                             data_len, "(incomplete entry)");
795                         break;
796                 }
797                 proto_tree_add_text(rr_tree, tvb, cur_offset, 2,
798                     "Number of send aborts: %u", tvb_get_ntohs(tvb, cur_offset));
799                 cur_offset += 2;
800                 data_len -= 2;
801
802                 if (data_len < 4) {
803                         proto_tree_add_text(rr_tree, tvb, cur_offset,
804                             data_len, "(incomplete entry)");
805                         break;
806                 }
807                 proto_tree_add_text(rr_tree, tvb, cur_offset, 4,
808                     "Number of good sends: %u", tvb_get_ntohl(tvb, cur_offset));
809                 cur_offset += 4;
810                 data_len -= 4;
811
812                 if (data_len < 4) {
813                         proto_tree_add_text(rr_tree, tvb, cur_offset,
814                             data_len, "(incomplete entry)");
815                         break;
816                 }
817                 proto_tree_add_text(rr_tree, tvb, cur_offset, 4,
818                     "Number of good receives: %u",
819                     tvb_get_ntohl(tvb, cur_offset));
820                 cur_offset += 4;
821                 data_len -= 4;
822
823                 if (data_len < 2) {
824                         proto_tree_add_text(rr_tree, tvb, cur_offset,
825                             data_len, "(incomplete entry)");
826                         break;
827                 }
828                 proto_tree_add_text(rr_tree, tvb, cur_offset, 2,
829                     "Number of retransmits: %u", tvb_get_ntohs(tvb, cur_offset));
830                 cur_offset += 2;
831                 data_len -= 2;
832
833                 if (data_len < 2) {
834                         proto_tree_add_text(rr_tree, tvb, cur_offset,
835                             data_len, "(incomplete entry)");
836                         break;
837                 }
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));
841                 cur_offset += 2;
842                 data_len -= 2;
843
844                 if (data_len < 2) {
845                         proto_tree_add_text(rr_tree, tvb, cur_offset,
846                             data_len, "(incomplete entry)");
847                         break;
848                 }
849                 proto_tree_add_text(rr_tree, tvb, cur_offset, 2,
850                     "Number of command blocks: %u",
851                     tvb_get_ntohs(tvb, cur_offset));
852                 cur_offset += 2;
853                 data_len -= 2;
854
855                 if (data_len < 2) {
856                         proto_tree_add_text(rr_tree, tvb, cur_offset,
857                             data_len, "(incomplete entry)");
858                         break;
859                 }
860                 proto_tree_add_text(rr_tree, tvb, cur_offset, 2,
861                     "Number of pending sessions: %u",
862                     tvb_get_ntohs(tvb, cur_offset));
863                 cur_offset += 2;
864                 data_len -= 2;
865
866                 if (data_len < 2) {
867                         proto_tree_add_text(rr_tree, tvb, cur_offset,
868                             data_len, "(incomplete entry)");
869                         break;
870                 }
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));
874                 cur_offset += 2;
875                 data_len -= 2;
876
877                 if (data_len < 2) {
878                         proto_tree_add_text(rr_tree, tvb, cur_offset,
879                             data_len, "(incomplete entry)");
880                         break;
881                 }
882                 proto_tree_add_text(rr_tree, tvb, cur_offset, 2,
883                     "Max total sessions possible: %u",
884                     tvb_get_ntohs(tvb, cur_offset));
885                 cur_offset += 2;
886                 data_len -= 2;
887
888                 if (data_len < 2) {
889                         proto_tree_add_text(rr_tree, tvb, cur_offset,
890                             data_len, "(incomplete entry)");
891                         break;
892                 }
893                 proto_tree_add_text(rr_tree, tvb, cur_offset, 2,
894                     "Session data packet size: %u",
895                     tvb_get_ntohs(tvb, cur_offset));
896                 cur_offset += 2;
897                 data_len -= 2;
898         out:
899                 break;
900
901         default:
902                 if (fd != NULL)
903                         col_append_fstr(fd, COL_INFO, " %s", type_name);
904                 if (nbns_tree == NULL)
905                         break;
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;
914                 break;
915         }
916         
917         return cur_offset - data_start;
918 }
919
920 static int
921 dissect_query_records(tvbuff_t *tvb, int cur_off, int nbns_data_offset,
922     int count, frame_data *fd, proto_tree *nbns_tree)
923 {
924         int start_off, add_off;
925         proto_tree *qatree = NULL;
926         proto_item *ti = NULL;
927         
928         start_off = cur_off;
929         if (nbns_tree != NULL) {
930                 ti = proto_tree_add_text(nbns_tree, tvb, start_off, 0, "Queries");
931                 qatree = proto_item_add_subtree(ti, ett_nbns_qry);
932         }
933         while (count-- > 0) {
934                 add_off = dissect_nbns_query(tvb, cur_off, nbns_data_offset,
935                     fd, qatree);
936                 if (add_off <= 0) {
937                         /* We ran past the end of the captured data in the
938                            packet. */
939                         break;
940                 }
941                 cur_off += add_off;
942         }
943         if (ti != NULL)
944                 proto_item_set_len(ti, cur_off - start_off);
945
946         return cur_off - start_off;
947 }
948
949
950
951 static int
952 dissect_answer_records(tvbuff_t *tvb, int cur_off, int nbns_data_offset,
953     int count, frame_data *fd, proto_tree *nbns_tree, int opcode, char *name)
954 {
955         int start_off, add_off;
956         proto_tree *qatree = NULL;
957         proto_item *ti = NULL;
958         
959         start_off = cur_off;
960         if (nbns_tree != NULL) {
961                 ti = proto_tree_add_text(nbns_tree, tvb, start_off, 0, name);
962                 qatree = proto_item_add_subtree(ti, ett_nbns_ans);
963         }
964         while (count-- > 0) {
965                 add_off = dissect_nbns_answer(tvb, cur_off, nbns_data_offset,
966                                         fd, qatree, opcode);
967                 if (add_off <= 0) {
968                         /* We ran past the end of the captured data in the
969                            packet. */
970                         break;
971                 }
972                 cur_off += add_off;
973         }
974         if (ti != NULL)
975                 proto_item_set_len(ti, cur_off - start_off);
976         return cur_off - start_off;
977 }
978
979 static void
980 dissect_nbns(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
981 {
982         int                     offset = 0;
983         int                     nbns_data_offset;
984         frame_data              *fd;
985         proto_tree              *nbns_tree = NULL;
986         proto_item              *ti;
987         guint16                 id, flags, quest, ans, auth, add;
988         int                     cur_off;
989
990         nbns_data_offset = offset;
991
992         if (check_col(pinfo->fd, COL_PROTOCOL))
993                 col_set_str(pinfo->fd, COL_PROTOCOL, "NBNS");
994         if (check_col(pinfo->fd, COL_INFO))
995                 col_clear(pinfo->fd, COL_INFO);
996
997         /* To do: check for runts, errs, etc. */
998         id    = tvb_get_ntohs(tvb, offset + NBNS_ID);
999         flags = tvb_get_ntohs(tvb, offset + NBNS_FLAGS);
1000
1001         if (check_col(pinfo->fd, COL_INFO)) {
1002                 col_add_fstr(pinfo->fd, COL_INFO, "%s%s",
1003                     val_to_str(flags & F_OPCODE, opcode_vals,
1004                       "Unknown operation (%x)"),
1005                     (flags & F_RESPONSE) ? " response" : "");
1006                 fd = pinfo->fd;
1007         } else {
1008                 /* Set "fd" to NULL; we pass a NULL "fd" to the query and
1009                    answer dissectors, as a way of saying that they shouldn't
1010                    add stuff to the COL_INFO column (a call to
1011                    "check_col(fd, COL_INFO)" is more expensive than a check
1012                    that a pointer isn't NULL). */
1013                 fd = NULL;
1014         }
1015
1016         if (tree) {
1017                 ti = proto_tree_add_item(tree, proto_nbns, tvb, offset,
1018                     tvb_length(tvb), FALSE);
1019                 nbns_tree = proto_item_add_subtree(ti, ett_nbns);
1020
1021                 if (flags & F_RESPONSE) {
1022                         proto_tree_add_boolean_hidden(nbns_tree, hf_nbns_response, tvb, 
1023                                              0, 0, TRUE);
1024                 } else {
1025                         proto_tree_add_boolean_hidden(nbns_tree, hf_nbns_query, tvb, 
1026                                              0, 0, TRUE);
1027                 }
1028
1029                 proto_tree_add_uint(nbns_tree, hf_nbns_transaction_id, tvb,
1030                                     offset + NBNS_ID, 2, id);
1031
1032                 nbns_add_nbns_flags(nbns_tree, tvb, offset + NBNS_FLAGS,
1033                                     flags, 0);
1034         }
1035         quest = tvb_get_ntohs(tvb, offset + NBNS_QUEST);
1036         if (tree) {
1037                 proto_tree_add_uint(nbns_tree, hf_nbns_count_questions, tvb,
1038                                     offset + NBNS_QUEST, 2, quest);
1039         }
1040         ans = tvb_get_ntohs(tvb, offset + NBNS_ANS);
1041         if (tree) {
1042                 proto_tree_add_uint(nbns_tree, hf_nbns_count_answers, tvb,
1043                                     offset + NBNS_ANS, 2, ans);
1044         }
1045         auth = tvb_get_ntohs(tvb, offset + NBNS_AUTH);
1046         if (tree) {
1047                 proto_tree_add_uint(nbns_tree, hf_nbns_count_auth_rr, tvb,
1048                                     offset + NBNS_AUTH, 2, auth);
1049         }
1050         add = tvb_get_ntohs(tvb, offset + NBNS_ADD);
1051         if (tree) {
1052                 proto_tree_add_uint(nbns_tree, hf_nbns_count_add_rr, tvb,
1053                                     offset + NBNS_ADD, 2, add);
1054         }
1055
1056         cur_off = offset + NBNS_HDRLEN;
1057     
1058         if (quest > 0) {
1059                 /* If this is a response, don't add information about the
1060                    queries to the summary, just add information about the
1061                    answers. */
1062                 cur_off += dissect_query_records(tvb, cur_off,
1063                     nbns_data_offset, quest,
1064                     (!(flags & F_RESPONSE) ? fd : NULL), nbns_tree);
1065         }
1066
1067         if (ans > 0) {
1068                 /* If this is a request, don't add information about the
1069                    answers to the summary, just add information about the
1070                    queries. */
1071                 cur_off += dissect_answer_records(tvb, cur_off,
1072                         nbns_data_offset, ans,
1073                         ((flags & F_RESPONSE) ? fd : NULL), nbns_tree,
1074                         flags & F_OPCODE, "Answers");
1075         }
1076
1077         if (tree) {
1078                 /* Don't add information about the authoritative name
1079                    servers, or the additional records, to the summary. */
1080                 if (auth > 0)
1081                         cur_off += dissect_answer_records(tvb, cur_off,
1082                                         nbns_data_offset,
1083                                         auth, NULL, nbns_tree,
1084                                         flags & F_OPCODE,
1085                                         "Authoritative nameservers");
1086
1087                 if (add > 0)
1088                         cur_off += dissect_answer_records(tvb, cur_off,
1089                                         nbns_data_offset,
1090                                         add, NULL, nbns_tree,
1091                                         flags & F_OPCODE,
1092                                         "Additional records");
1093         }
1094 }
1095
1096 /* NetBIOS datagram packet, from RFC 1002, page 32 */
1097 struct nbdgm_header {
1098         guint8          msg_type;
1099         struct {
1100                 guint8  more;
1101                 guint8  first;
1102                 guint8  node_type;
1103         } flags;
1104         guint16         dgm_id;
1105         guint32         src_ip;
1106         guint16         src_port;
1107
1108         /* For packets with data */
1109         guint16         dgm_length;
1110         guint16         pkt_offset;
1111
1112         /* For error packets */
1113         guint8          error_code;
1114 };
1115
1116 /*
1117  * NBDS message types.
1118  */
1119 #define NBDS_DIRECT_UNIQUE      0x10
1120 #define NBDS_DIRECT_GROUP       0x11
1121 #define NBDS_BROADCAST          0x12
1122 #define NBDS_ERROR              0x13
1123 #define NBDS_QUERY_REQUEST      0x14
1124 #define NBDS_POS_QUERY_RESPONSE 0x15
1125 #define NBDS_NEG_QUERY_RESPONSE 0x16
1126
1127 static const value_string nbds_msgtype_vals[] = {
1128         { NBDS_DIRECT_UNIQUE,      "Direct_unique datagram" },
1129         { NBDS_DIRECT_GROUP,       "Direct_group datagram" },
1130         { NBDS_BROADCAST,          "Broadcast datagram" },
1131         { NBDS_ERROR,              "Datagram error" },
1132         { NBDS_QUERY_REQUEST,      "Datagram query request" },
1133         { NBDS_POS_QUERY_RESPONSE, "Datagram positive query response" },
1134         { NBDS_NEG_QUERY_RESPONSE, "Datagram negative query response" },
1135         { 0,                       NULL }
1136 };
1137
1138 static const true_false_string yesno = {  
1139         "Yes",
1140         "No"
1141 };
1142
1143 static const value_string node_type_vals[] = {
1144         { 0, "B node" },
1145         { 1, "P node" },
1146         { 2, "M node" },
1147         { 3, "NBDD" },
1148         { 0, NULL }
1149 };
1150
1151 static void
1152 dissect_nbdgm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1153 {
1154         int                     offset = 0;
1155         proto_tree              *nbdgm_tree = NULL;
1156         proto_item              *ti = NULL;
1157         struct nbdgm_header     header;
1158         int                     msglen;
1159         int                     flags;
1160         int                     message_index;
1161         tvbuff_t                *next_tvb;
1162
1163         static const value_string error_codes[] = {
1164                 { 0x82, "Destination name not present" },
1165                 { 0x83, "Invalid source name format" },
1166                 { 0x84, "Invalid destination name format" },
1167                 { 0x00, NULL }
1168         };
1169
1170         char name[(NETBIOS_NAME_LEN - 1)*4 + MAXDNAME];
1171         int name_type;
1172         int len;
1173
1174         if (check_col(pinfo->fd, COL_PROTOCOL))
1175                 col_set_str(pinfo->fd, COL_PROTOCOL, "NBDS");
1176         if (check_col(pinfo->fd, COL_INFO))
1177                 col_clear(pinfo->fd, COL_INFO);
1178
1179         header.msg_type = tvb_get_guint8(tvb, offset);
1180         
1181         flags = tvb_get_guint8(tvb, offset+1);
1182         header.flags.more = flags & 1;
1183         header.flags.first = (flags & 2) >> 1;
1184         header.flags.node_type = (flags & 12) >> 2;
1185
1186         header.dgm_id = tvb_get_ntohs(tvb, offset+2);
1187         tvb_memcpy(tvb, (guint8 *)&header.src_ip, offset+4, 4);
1188         header.src_port = tvb_get_ntohs(tvb, offset+8);
1189
1190         switch (header.msg_type) {
1191
1192         case NBDS_DIRECT_UNIQUE:
1193         case NBDS_DIRECT_GROUP:
1194         case NBDS_BROADCAST:
1195                 header.dgm_length = tvb_get_ntohs(tvb, offset+10);
1196                 header.pkt_offset = tvb_get_ntohs(tvb, offset+12);
1197                 break;
1198
1199         case NBDS_ERROR:
1200                 header.error_code = tvb_get_ntohs(tvb, offset+10);
1201                 break;
1202         }
1203
1204         message_index = header.msg_type - 0x0f;
1205         if (message_index < 1 || message_index > 8) {
1206                 message_index = 0;
1207         }
1208
1209         if (check_col(pinfo->fd, COL_INFO)) {
1210                 col_add_str(pinfo->fd, COL_INFO,
1211                     val_to_str(header.msg_type, nbds_msgtype_vals,
1212                       "Unknown message type (0x%02X)"));
1213         }
1214
1215         if (tree) {
1216                 ti = proto_tree_add_item(tree, proto_nbdgm, tvb, offset,
1217                     tvb_length_remaining(tvb, offset), FALSE);
1218                 nbdgm_tree = proto_item_add_subtree(ti, ett_nbdgm);
1219
1220                 proto_tree_add_uint(nbdgm_tree, hf_nbdgm_type, tvb,
1221                                      offset, 1, 
1222                                      header.msg_type);
1223                 proto_tree_add_boolean(nbdgm_tree, hf_nbdgm_fragment, tvb,
1224                                        offset+1, 1, 
1225                                        header.flags.more);
1226                 proto_tree_add_boolean(nbdgm_tree, hf_nbdgm_first, tvb,
1227                                        offset+1, 1, 
1228                                        header.flags.first);
1229                 proto_tree_add_uint(nbdgm_tree, hf_nbdgm_node_type, tvb,
1230                                      offset+1, 1, 
1231                                      header.flags.node_type);
1232
1233                 proto_tree_add_uint(nbdgm_tree, hf_nbdgm_datagram_id, tvb,
1234                                     offset+2, 2, header.dgm_id);
1235                 proto_tree_add_ipv4(nbdgm_tree, hf_nbdgm_src_ip, tvb,
1236                                     offset+4, 4, header.src_ip);
1237                 proto_tree_add_uint(nbdgm_tree, hf_nbdgm_src_port, tvb,
1238                                     offset+8, 2, header.src_port);
1239
1240         }
1241
1242         offset += 10;
1243
1244         switch (header.msg_type) {
1245
1246         case NBDS_DIRECT_UNIQUE:
1247         case NBDS_DIRECT_GROUP:
1248         case NBDS_BROADCAST:
1249                 if (tree) {
1250                         proto_tree_add_text(nbdgm_tree, tvb, offset, 2,
1251                                         "Datagram length: %d bytes", header.dgm_length);
1252                         proto_tree_add_text(nbdgm_tree, tvb, offset+2, 2,
1253                                         "Packet offset: %d bytes", header.pkt_offset);
1254                 }
1255
1256                 offset += 4;
1257
1258                 /* Source name */
1259                 len = get_nbns_name(tvb, offset, offset, name, &name_type);
1260
1261                 if (tree) {
1262                         add_name_and_type(nbdgm_tree, tvb, offset, len,
1263                             "Source name", name, name_type);
1264                 }
1265                 offset += len;
1266
1267                 /* Destination name */
1268                 len = get_nbns_name(tvb, offset, offset, name, &name_type);
1269
1270                 if (tree) {
1271                         add_name_and_type(nbdgm_tree, tvb, offset, len,
1272                             "Destination name", name, name_type);
1273                 }
1274                 offset += len;
1275
1276                 /*
1277                  * Here we can pass the packet off to the next protocol.
1278                  * Set the length of our top-level tree item to include
1279                  * only our stuff.
1280                  */
1281                 proto_item_set_len(ti, offset);
1282                 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
1283                 dissect_netbios_payload(next_tvb, pinfo, tree);
1284                 break;
1285
1286         case NBDS_ERROR:
1287                 if (tree) {
1288                         proto_tree_add_text(nbdgm_tree, tvb, offset, 1, "Error code: %s",
1289                                 val_to_str(header.error_code, error_codes, "Unknown (0x%x)"));
1290                 }
1291                 offset += 1;
1292                 proto_item_set_len(ti, offset);
1293                 break;
1294
1295         case NBDS_QUERY_REQUEST:
1296         case NBDS_POS_QUERY_RESPONSE:
1297         case NBDS_NEG_QUERY_RESPONSE:
1298                 /* Destination name */
1299                 len = get_nbns_name(tvb, offset, offset, name, &name_type);
1300
1301                 if (tree) {
1302                         add_name_and_type(nbdgm_tree, tvb, offset, len,
1303                             "Destination name", name, name_type);
1304                 }
1305                 offset += len;
1306                 proto_item_set_len(ti, offset);
1307                 break;
1308         }
1309 }
1310
1311 /*
1312  * NetBIOS Session Service message types.
1313  */
1314 #define SESSION_MESSAGE                 0x00
1315 #define SESSION_REQUEST                 0x81
1316 #define POSITIVE_SESSION_RESPONSE       0x82
1317 #define NEGATIVE_SESSION_RESPONSE       0x83
1318 #define RETARGET_SESSION_RESPONSE       0x84
1319 #define SESSION_KEEP_ALIVE              0x85
1320
1321 static const value_string message_types[] = {
1322         { SESSION_MESSAGE,           "Session message" },
1323         { SESSION_REQUEST,           "Session request" },
1324         { POSITIVE_SESSION_RESPONSE, "Positive session response" },
1325         { NEGATIVE_SESSION_RESPONSE, "Negative session response" },
1326         { RETARGET_SESSION_RESPONSE, "Retarget session response" },
1327         { SESSION_KEEP_ALIVE,        "Session keep-alive" },
1328         { 0x0,                       NULL }
1329 };
1330
1331 /*
1332  * NetBIOS Session Service flags.
1333  */
1334 #define NBSS_FLAGS_E                    0x1
1335
1336 static const value_string error_codes[] = {
1337         { 0x80, "Not listening on called name" },
1338         { 0x81, "Not listening for called name" },
1339         { 0x82, "Called name not present" },
1340         { 0x83, "Called name present, but insufficient resources" },
1341         { 0x8F, "Unspecified error" },
1342         { 0x0,  NULL }
1343 };
1344
1345 /*
1346  * Dissect a single NBSS packet (there may be more than one in a given
1347  * TCP segment).
1348  *
1349  * [ Hmmm, in my experience, I have never seen more than one NBSS in a
1350  * single segment, since they mostly contain SMBs which are essentially
1351  * a request response type protocol (RJS). ]
1352  *
1353  * [ However, under heavy load with many requests multiplexed on one
1354  * session it is not unusual to see multiple requests in one TCP
1355  * segment. Unfortunately, in this case a single session message is
1356  * frequently split over multiple segments, which frustrates decoding
1357  * (MMM). ]
1358  */
1359 static int
1360 dissect_nbss_packet(tvbuff_t *tvb, int offset, packet_info *pinfo,
1361     proto_tree *tree, int max_data, int is_cifs)
1362 {
1363         proto_tree      *nbss_tree = NULL;
1364         proto_item      *ti = NULL;
1365         proto_tree      *field_tree;
1366         proto_item      *tf;
1367         guint8          msg_type;
1368         guint8          flags;
1369         int             length;
1370         int             len;
1371         char            name[(NETBIOS_NAME_LEN - 1)*4 + MAXDNAME];
1372         int             name_type;
1373         gint            reported_len;
1374         tvbuff_t        *next_tvb;
1375
1376         msg_type = tvb_get_guint8(tvb, offset);
1377
1378         if (is_cifs) {
1379                 flags = 0;
1380                 length = tvb_get_ntoh24(tvb, offset + 1);
1381         } else {
1382                 flags = tvb_get_guint8(tvb, offset + 1);
1383                 length = tvb_get_ntohs(tvb, offset + 2);
1384                 if (flags & NBSS_FLAGS_E)
1385                         length += 65536;
1386         }
1387
1388         /*Desegmentation */
1389         if (nbss_desegment) {
1390                 if (pinfo->can_desegment
1391                     && length > tvb_length_remaining(tvb, offset+4)) {
1392                         /*
1393                          * This frame doesn't have all of the data for
1394                          * this message, but we can do reassembly on it.
1395                          *
1396                          * Tell the TCP dissector where the data for this
1397                          * message starts in the data it handed us, and
1398                          * how many more bytes we need, and return.
1399                          */
1400                         pinfo->desegment_offset = offset;
1401                         pinfo->desegment_len =
1402                             length - tvb_length_remaining(tvb, offset+4);
1403                         return max_data;
1404                 }
1405         }
1406
1407         if (tree) {
1408           ti = proto_tree_add_item(tree, proto_nbss, tvb, offset, length + 4, FALSE);
1409           nbss_tree = proto_item_add_subtree(ti, ett_nbss);
1410           
1411           proto_tree_add_uint_format(nbss_tree, hf_nbss_type, tvb,
1412                                      offset, 1, 
1413                                      msg_type,
1414                                      "Message Type: %s",
1415                                      val_to_str(msg_type, message_types, 
1416                                                 "Unknown (%x)"));
1417         }
1418
1419         offset += 1;
1420
1421         if (is_cifs) {
1422                 if (tree) {
1423                   proto_tree_add_text(nbss_tree, tvb, offset, 3, "Length: %u", length);
1424                 }
1425                 offset += 3;
1426         } else {
1427                 if (tree) {
1428                   tf = proto_tree_add_uint(nbss_tree, hf_nbss_flags, tvb, offset, 1, flags);
1429                   field_tree = proto_item_add_subtree(tf, ett_nbss_flags);
1430                   proto_tree_add_text(field_tree, tvb, offset, 1, "%s",
1431                               decode_boolean_bitfield(flags, NBSS_FLAGS_E,
1432                                                               8, "Add 65536 to length", "Add 0 to length"));
1433                 }
1434                 offset += 1;
1435
1436                 if (tree) {
1437                   proto_tree_add_text(nbss_tree, tvb, offset, 2, "Length: %u", length);
1438                 }
1439
1440                 offset += 2;
1441         }
1442
1443         switch (msg_type) {
1444
1445         case SESSION_REQUEST:
1446           len = get_nbns_name(tvb, offset, offset, name, &name_type);
1447           if (tree)
1448             add_name_and_type(nbss_tree, tvb, offset, len,
1449                                 "Called name", name, name_type);
1450           offset += len;
1451
1452           len = get_nbns_name(tvb, offset, offset, name, &name_type);
1453           
1454           if (tree)
1455             add_name_and_type(nbss_tree, tvb, offset, len,
1456                                 "Calling name", name, name_type);
1457
1458           break;
1459
1460         case NEGATIVE_SESSION_RESPONSE:
1461           if (tree) 
1462             proto_tree_add_text(nbss_tree, tvb, offset, 1,
1463                                 "Error code: %s",
1464                                 val_to_str(tvb_get_guint8(tvb, offset),
1465                                            error_codes, "Unknown (%x)"));
1466           break;
1467
1468         case RETARGET_SESSION_RESPONSE:
1469           if (tree)
1470             proto_tree_add_text(nbss_tree, tvb, offset, 4,
1471                                 "Retarget IP address: %s",
1472                                 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
1473           
1474           offset += 4;
1475
1476           if (tree)
1477             proto_tree_add_text(nbss_tree, tvb, offset, 2,
1478                                 "Retarget port: %u",
1479                                 tvb_get_ntohs(tvb, offset));
1480
1481           break;
1482
1483         case SESSION_MESSAGE:
1484           /*
1485            * Here we can pass the message off to the next protocol.
1486            * Set the length of our top-level tree item to include
1487            * only our stuff.
1488            */
1489           proto_item_set_len(ti, offset);
1490           len = tvb_length_remaining(tvb, offset);
1491           reported_len = tvb_reported_length_remaining(tvb, offset);
1492           if (len > length)
1493             len = length;
1494           if (reported_len > length)
1495             reported_len = length;
1496           next_tvb = tvb_new_subset(tvb, offset, len, reported_len);
1497           dissect_netbios_payload(next_tvb, pinfo, tree);
1498           break;
1499
1500         }
1501         return length + 4;
1502 }
1503
1504 static void
1505 dissect_nbss(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1506 {
1507         struct tcpinfo  *tcpinfo = pinfo->private;
1508         int             offset = 0;
1509         int             max_data;
1510         guint8          msg_type;
1511         guint8          flags;
1512         guint32         length;
1513         int             len;
1514         gboolean        is_cifs;
1515         proto_tree      *nbss_tree;
1516         proto_item      *ti;
1517
1518         if (check_col(pinfo->fd, COL_PROTOCOL))
1519                 col_set_str(pinfo->fd, COL_PROTOCOL, "NBSS");
1520         if (check_col(pinfo->fd, COL_INFO))
1521                 col_clear(pinfo->fd, COL_INFO);
1522
1523         max_data = tvb_length(tvb);
1524
1525         msg_type = tvb_get_guint8(tvb, offset);
1526
1527         if (pinfo->match_port == TCP_PORT_CIFS) {
1528                 /*
1529                  * Windows 2000 CIFS clients can dispense completely
1530                  * with the NETBIOS encapsulation and directly use CIFS
1531                  * over TCP. As would be expected, the framing is
1532                  * identical, except that the length is 24 bits instead
1533                  * of 17. The only message types used are
1534                  * SESSION_MESSAGE and SESSION_KEEP_ALIVE.
1535                  */
1536                 is_cifs = TRUE;
1537         } else {
1538                 is_cifs = FALSE;
1539         }
1540
1541         /*
1542          * This might be a continuation of an earlier message.
1543          * (Yes, that might be true even if we're doing TCP reassembly,
1544          * as the first TCP segment in the capture might start in the
1545          * middle of an NBNS message.)
1546          */
1547
1548         /*
1549          * If this isn't reassembled data, check to see whether it
1550          * looks like a continuation of a message.
1551          * (If it is reassembled data, it shouldn't be a continuation,
1552          * as reassembly should've gathered the continuations together
1553          * into a message.)
1554          */
1555         if (!tcpinfo->is_reassembled) {
1556                 if (max_data < 4) {
1557                         /*
1558                          * Not enough data for an NBSS header; assume
1559                          * it's a continuation of a message.
1560                          *
1561                          * XXX - if there's not enough data, we should
1562                          * attempt to reassemble the data, if the first byte
1563                          * is a valid message type.
1564                          */
1565                         goto continuation;
1566                 }
1567
1568                 /*
1569                  * We have enough data for an NBSS header.
1570                  * Get the flags and length of the message,
1571                  * and see if they're sane.
1572                  */
1573                 if (is_cifs) {
1574                         flags = 0;
1575                         length = tvb_get_ntoh24(tvb, offset + 1);
1576                 } else {
1577                         flags = tvb_get_guint8(tvb, offset + 1);
1578                         length = tvb_get_ntohs(tvb, offset + 2);
1579                         if (flags & NBSS_FLAGS_E)
1580                                 length += 65536;
1581                 }
1582                 if ((flags & (~NBSS_FLAGS_E)) != 0) {
1583                         /*
1584                          * A bogus flag was set; assume it's a continuation.
1585                          */
1586                         goto continuation;
1587                 }
1588
1589                 switch (msg_type) {
1590
1591                 case SESSION_MESSAGE:
1592                         /*
1593                          * This is variable-length.
1594                          * All we know is that it shouldn't be zero.
1595                          * (XXX - can we get zero-length messages?
1596                          * Not with SMB, but perhaps other NetBIOS-based
1597                          * protocols have them.)
1598                          */
1599                         if (length == 0)
1600                                 goto continuation;
1601                         break;
1602
1603                 case SESSION_REQUEST:
1604                         /*
1605                          * This is variable-length.
1606                          * The names are DNS-encoded 32-byte values;
1607                          * we need at least 2 bytes (one for each name;
1608                          * actually, we should have more for the first
1609                          * name, as there's no name preceding it so
1610                          * there should be no compression), and we
1611                          * shouldn't have more than 128 bytes (actually,
1612                          * we shouldn't have that many).
1613                          */
1614                         if (length < 2 || length > 128)
1615                                 goto continuation;
1616                         break;
1617
1618                 case POSITIVE_SESSION_RESPONSE:
1619                         /*
1620                          * This has no data, so the length must be zero.
1621                          */
1622                         if (length != 0)
1623                                 goto continuation;
1624                         break;
1625
1626                 case NEGATIVE_SESSION_RESPONSE:
1627                         /*
1628                          * This has 1 byte of data.
1629                          */
1630                         if (length != 1)
1631                                 goto continuation;
1632                         break;
1633
1634                 case RETARGET_SESSION_RESPONSE:
1635                         /*
1636                          * This has 6 bytes of data.
1637                          */
1638                         if (length != 6)
1639                                 goto continuation;
1640                         break;
1641
1642                 case SESSION_KEEP_ALIVE:
1643                         /*
1644                          * This has no data, so the length must be zero.
1645                          */
1646                         if (length != 0)
1647                                 goto continuation;
1648                         break;
1649
1650                 default:
1651                         /*
1652                          * Unknown message type; assume it's a continuation.
1653                          */
1654                         goto continuation;
1655                 }
1656         }
1657  
1658         if (check_col(pinfo->fd, COL_INFO)) {
1659                 col_add_fstr(pinfo->fd, COL_INFO,
1660                     val_to_str(msg_type, message_types, "Unknown (%02x)"));
1661         }
1662
1663         while (max_data > 0) {
1664                 len = dissect_nbss_packet(tvb, offset, pinfo, tree, max_data,
1665                     is_cifs);
1666                 offset += len;
1667                 max_data -= len;
1668         }
1669
1670         return;
1671
1672 continuation:
1673         /*
1674          * It looks like a continuation.
1675          */
1676         if (check_col(pinfo->fd, COL_INFO))
1677                 col_add_fstr(pinfo->fd, COL_INFO, "NBSS Continuation Message");
1678
1679         if (tree) {
1680                 ti = proto_tree_add_item(tree, proto_nbss, tvb, 0,
1681                     max_data, FALSE);
1682                 nbss_tree = proto_item_add_subtree(ti, ett_nbss);
1683                 proto_tree_add_text(nbss_tree, tvb, 0, max_data,
1684                     "Continuation data");
1685         }
1686 }
1687
1688 void
1689 proto_register_nbt(void)
1690 {
1691
1692   static hf_register_info hf_nbns[] = {
1693     { &hf_nbns_response,
1694       { "Response",             "nbns.response",  
1695         FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1696         "TRUE if NBNS response", HFILL }},
1697     { &hf_nbns_query,
1698       { "Query",                "nbns.query",  
1699         FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1700         "TRUE if NBNS query", HFILL }},
1701     { &hf_nbns_transaction_id,
1702       { "Transaction ID",       "nbns.id",  
1703         FT_UINT16, BASE_HEX, NULL, 0x0,
1704         "Identification of transaction", HFILL }},
1705     { &hf_nbns_count_questions,
1706       { "Questions",            "nbns.count.queries",  
1707         FT_UINT16, BASE_DEC, NULL, 0x0,
1708         "Number of queries in packet", HFILL }},
1709     { &hf_nbns_count_answers,
1710       { "Answer RRs",           "nbns.count.answers",  
1711         FT_UINT16, BASE_DEC, NULL, 0x0,
1712         "Number of answers in packet", HFILL }},
1713     { &hf_nbns_count_auth_rr,
1714       { "Authority RRs",        "nbns.count.auth_rr",  
1715         FT_UINT16, BASE_DEC, NULL, 0x0,
1716         "Number of authoritative records in packet", HFILL }},
1717     { &hf_nbns_count_add_rr,
1718       { "Additional RRs",       "nbns.count.add_rr",  
1719         FT_UINT16, BASE_DEC, NULL, 0x0,
1720         "Number of additional records in packet", HFILL }}
1721   };
1722
1723   static hf_register_info hf_nbdgm[] = {
1724     { &hf_nbdgm_type,
1725       { "Message Type",         "nbdgm.type",  
1726         FT_UINT8, BASE_DEC, VALS(nbds_msgtype_vals), 0x0,
1727         "NBDGM message type", HFILL }},
1728     { &hf_nbdgm_fragment,
1729       { "More fragments follow",        "nbdgm.next",  
1730         FT_BOOLEAN, BASE_NONE, TFS(&yesno), 0x0,
1731         "TRUE if more fragments follow", HFILL }},
1732     { &hf_nbdgm_first,
1733       { "This is first fragment",       "nbdgm.first",  
1734         FT_BOOLEAN, BASE_NONE, TFS(&yesno), 0x0,
1735         "TRUE if first fragment", HFILL }},
1736     { &hf_nbdgm_node_type,
1737       { "Node Type",            "nbdgm.node_type",  
1738         FT_UINT8, BASE_DEC, VALS(node_type_vals), 0x0,
1739         "Node type", HFILL }},
1740     { &hf_nbdgm_datagram_id,
1741       { "Datagram ID",          "nbdgm.dgram_id",  
1742         FT_UINT16, BASE_HEX, NULL, 0x0,
1743         "Datagram identifier", HFILL }},
1744     { &hf_nbdgm_src_ip,
1745       { "Source IP",            "nbdgm.src.ip",  
1746         FT_IPv4, BASE_NONE, NULL, 0x0,
1747         "Source IPv4 address", HFILL }},
1748     { &hf_nbdgm_src_port,
1749       { "Source Port",          "nbdgm.src.port",
1750         FT_UINT16, BASE_DEC, NULL, 0x0,
1751         "Source port", HFILL }}
1752   };
1753
1754   static hf_register_info hf_nbss[] = {
1755     { &hf_nbss_type,
1756       { "Message Type",         "nbss.type",  
1757         FT_UINT8, BASE_DEC, NULL, 0x0,
1758         "NBSS message type", HFILL }},
1759     { &hf_nbss_flags,
1760       { "Flags",                "nbss.flags",  
1761         FT_UINT8, BASE_HEX, NULL, 0x0,
1762         "NBSS message flags", HFILL }}
1763   };
1764   static gint *ett[] = {
1765     &ett_nbns,
1766     &ett_nbns_qd,
1767     &ett_nbns_flags,
1768     &ett_nbns_nb_flags,
1769     &ett_nbns_name_flags,
1770     &ett_nbns_rr,
1771     &ett_nbns_qry,
1772     &ett_nbns_ans,
1773     &ett_nbdgm,
1774     &ett_nbss,
1775     &ett_nbss_flags,
1776   };
1777   module_t *nbss_module;
1778
1779   proto_nbns = proto_register_protocol("NetBIOS Name Service", "NBNS", "nbns");
1780   proto_register_field_array(proto_nbns, hf_nbns, array_length(hf_nbns));
1781   
1782   proto_nbdgm = proto_register_protocol("NetBIOS Datagram Service",
1783                                         "NBDS", "nbdgm");
1784   proto_register_field_array(proto_nbdgm, hf_nbdgm, array_length(hf_nbdgm));
1785
1786   proto_nbss = proto_register_protocol("NetBIOS Session Service",
1787                                        "NBSS", "nbss");
1788   proto_register_field_array(proto_nbss, hf_nbss, array_length(hf_nbss));
1789
1790   proto_register_subtree_array(ett, array_length(ett));
1791
1792   nbss_module = prefs_register_protocol(proto_nbss, NULL);
1793   prefs_register_bool_preference(nbss_module, "desegment_nbss_commands",
1794     "Desegment all NBSS packets spanning multiple TCP segments",
1795     "Whether NBSS dissector should desegment all packets spanning multiple TCP segments",
1796     &nbss_desegment);
1797 }
1798
1799 void
1800 proto_reg_handoff_nbt(void)
1801 {
1802   dissector_add("udp.port", UDP_PORT_NBNS, dissect_nbns, proto_nbns);
1803   dissector_add("udp.port", UDP_PORT_NBDGM, dissect_nbdgm, proto_nbdgm);
1804   dissector_add("tcp.port", TCP_PORT_NBSS, dissect_nbss, proto_nbss);
1805   dissector_add("tcp.port", TCP_PORT_CIFS, dissect_nbss, proto_nbss);
1806 }