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