As we may return an error message, rather than a NetBIOS name, from
[obnox/wireshark/wip.git] / packet-nbns.c
1 /* packet-nbns.c
2  * Routines for NetBIOS Name Service, Datagram Service, and Session Service
3  * packet disassembly (the name dates back to when it had only NBNS)
4  * Gilbert Ramirez <gram@verdict.uthscsa.edu>
5  * Much stuff added by Guy Harris <guy@netapp.com>
6  *
7  * $Id: packet-nbns.c,v 1.21 1999/06/01 20:40:34 guy Exp $
8  *
9  * Ethereal - Network traffic analyzer
10  * By Gerald Combs <gerald@zing.org>
11  * Copyright 1998 Gerald Combs
12  *
13  * 
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  * 
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  * 
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27  */
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #ifdef HAVE_SYS_TYPES_H
34 # include <sys/types.h>
35 #endif
36
37 #include <stdio.h>
38 #include <string.h>
39 #include <glib.h>
40 #include "packet.h"
41 #include "packet-dns.h"
42 #include "util.h"
43
44 /* Packet structure taken from RFC 1002. See also RFC 1001.
45  * Opcode, flags, and rcode treated as "flags", similarly to DNS,
46  * to make it easier to lift the dissection code from "packet-dns.c". */
47
48 /* Offsets of fields in the NBNS header. */
49 #define NBNS_ID         0
50 #define NBNS_FLAGS      2
51 #define NBNS_QUEST      4
52 #define NBNS_ANS        6
53 #define NBNS_AUTH       8
54 #define NBNS_ADD        10
55
56 /* Length of NBNS header. */
57 #define NBNS_HDRLEN     12
58
59 /* type values  */
60 #define T_NB            32              /* NetBIOS name service RR */
61 #define T_NBSTAT        33              /* NetBIOS node status RR */
62
63 /* Bit fields in the flags */
64 #define F_RESPONSE      (1<<15)         /* packet is response */
65 #define F_OPCODE        (0xF<<11)       /* query opcode */
66 #define F_AUTHORITATIVE (1<<10)         /* response is authoritative */
67 #define F_TRUNCATED     (1<<9)          /* response is truncated */
68 #define F_RECDESIRED    (1<<8)          /* recursion desired */
69 #define F_RECAVAIL      (1<<7)          /* recursion available */
70 #define F_BROADCAST     (1<<4)          /* broadcast/multicast packet */
71 #define F_RCODE         (0xF<<0)        /* reply code */
72
73 /* Opcodes */
74 #define OPCODE_QUERY          (0<<11)    /* standard query */
75 #define OPCODE_REGISTRATION   (5<<11)    /* registration */
76 #define OPCODE_RELEASE        (6<<11)    /* release name */
77 #define OPCODE_WACK           (7<<11)    /* wait for acknowledgement */
78 #define OPCODE_REFRESH        (8<<11)    /* refresh registration */
79 #define OPCODE_REFRESHALT     (9<<11)    /* refresh registration (alternate opcode) */
80 #define OPCODE_MHREGISTRATION (15<<11)   /* multi-homed registration */
81
82 /* Reply codes */
83 #define RCODE_NOERROR   (0<<0)
84 #define RCODE_FMTERROR  (1<<0)
85 #define RCODE_SERVFAIL  (2<<0)
86 #define RCODE_NAMEERROR (3<<0)
87 #define RCODE_NOTIMPL   (4<<0)
88 #define RCODE_REFUSED   (5<<0)
89 #define RCODE_ACTIVE    (6<<0)
90 #define RCODE_CONFLICT  (7<<0)
91
92 /* Values for the "NB_FLAGS" field of RR data.  From RFC 1001 and 1002,
93  * except for NB_FLAGS_ONT_H_NODE, which was discovered by looking at
94  * packet traces. */
95 #define NB_FLAGS_ONT            (3<<(15-2))     /* bits for node type */
96 #define NB_FLAGS_ONT_B_NODE     (0<<(15-2))     /* B-mode node */
97 #define NB_FLAGS_ONT_P_NODE     (1<<(15-2))     /* P-mode node */
98 #define NB_FLAGS_ONT_M_NODE     (2<<(15-2))     /* M-mode node */
99 #define NB_FLAGS_ONT_H_NODE     (3<<(15-2))     /* H-mode node */
100
101 #define NB_FLAGS_G              (1<<(15-0))     /* group name */
102
103 /* Values for the "NAME_FLAGS" field of a NODE_NAME entry in T_NBSTAT
104  * RR data.  From RFC 1001 and 1002, except for NAME_FLAGS_ONT_H_NODE,
105  * which was discovered by looking at packet traces. */
106 #define NAME_FLAGS_PRM          (1<<(15-6))     /* name is permanent node name */
107
108 #define NAME_FLAGS_ACT          (1<<(15-5))     /* name is active */
109
110 #define NAME_FLAGS_CNF          (1<<(15-4))     /* name is in conflict */
111
112 #define NAME_FLAGS_DRG          (1<<(15-3))     /* name is being deregistered */
113
114 #define NAME_FLAGS_ONT          (3<<(15-2))     /* bits for node type */
115 #define NAME_FLAGS_ONT_B_NODE   (0<<(15-2))     /* B-mode node */
116 #define NAME_FLAGS_ONT_P_NODE   (1<<(15-2))     /* P-mode node */
117 #define NAME_FLAGS_ONT_M_NODE   (2<<(15-2))     /* M-mode node */
118
119 #define NAME_FLAGS_G            (1<<(15-0))     /* group name */
120
121 static const value_string opcode_vals[] = {
122           { OPCODE_QUERY,          "Name query"                 },
123           { OPCODE_REGISTRATION,   "Registration"               },
124           { OPCODE_RELEASE,        "Release"                    },
125           { OPCODE_WACK,           "Wait for acknowledgment"    },
126           { OPCODE_REFRESH,        "Refresh"                    },
127           { OPCODE_REFRESHALT,     "Refresh (alternate opcode)" },
128           { OPCODE_MHREGISTRATION, "Multi-homed registration"   },
129           { 0,                     NULL                         }
130 };
131
132 static char *
133 nbns_type_name (int type)
134 {
135         switch (type) {
136         case T_NB:
137                 return "NB";
138         case T_NBSTAT:
139                 return "NBSTAT";
140         }
141         
142         return "unknown";
143 }
144
145 /* "Canonicalize" a 16-character NetBIOS name by:
146  *
147  *      removing and saving the last byte;
148  *
149  *      stripping trailing blanks;
150  *
151  *      appending the trailing byte, as a hex number, in square brackets. */
152 static char *
153 canonicalize_netbios_name(char *nbname)
154 {
155         char *pnbname;
156         u_char lastchar;
157
158         /* Get the last character of the name, as it's a special number
159          * indicating the type of the name, rather than part of the name
160          * *per se*. */
161         pnbname = nbname + 15;  /* point to the 16th character */
162         lastchar = *(unsigned char *)pnbname;
163
164         /* Now strip off any trailing blanks used to pad it to
165          * 16 bytes. */
166         while (pnbname > &nbname[0]) {
167                 if (*(pnbname - 1) != ' ')
168                         break;          /* found non-blank character */
169                 pnbname--;              /* blank - skip over it */
170         }
171
172         /* Replace the last character with its hex value, in square
173          * brackets, to make it easier to tell what it is. */
174         sprintf(pnbname, "[%02X]", lastchar);
175         pnbname += 4;
176         return pnbname;
177 }
178
179 static int
180 get_nbns_name(const u_char *nbns_data_ptr, const u_char *pd,
181     int offset, char *name_ret)
182 {
183         int name_len;
184         char name[MAXDNAME];
185         char nbname[MAXDNAME+4];        /* 4 for [<last char>] */
186         char *pname, *pnbname, cname, cnbname;
187
188         name_len = get_dns_name(nbns_data_ptr, pd + offset, name, sizeof(name));
189         
190         /* OK, now undo the first-level encoding. */
191         pname = &name[0];
192         pnbname = &nbname[0];
193         for (;;) {
194                 /* Every two characters of the first level-encoded name
195                  * turn into one character in the decoded name. */
196                 cname = *pname;
197                 if (cname == '\0')
198                         break;          /* no more characters */
199                 if (cname == '.')
200                         break;          /* scope ID follows */
201                 if (cname < 'A' || cname > 'Z') {
202                         /* Not legal. */
203                         strcpy(nbname,
204                             "Illegal NetBIOS name (character not between A and Z in first-level encoding)");
205                         goto bad;
206                 }
207                 cname -= 'A';
208                 cnbname = cname << 4;
209                 pname++;
210
211                 cname = *pname;
212                 if (cname == '\0' || cname == '.') {
213                         /* No more characters in the name - but we're in
214                          * the middle of a pair.  Not legal. */
215                         strcpy(nbname,
216                             "Illegal NetBIOS name (odd number of bytes)");
217                         goto bad;
218                 }
219                 if (cname < 'A' || cname > 'Z') {
220                         /* Not legal. */
221                         strcpy(nbname,
222                             "Illegal NetBIOS name (character not between A and Z in first-level encoding)");
223                         goto bad;
224                 }
225                 cname -= 'A';
226                 cnbname |= cname;
227                 pname++;
228
229                 /* Store the character. */
230                 *pnbname++ = cnbname;
231         }
232
233         /* NetBIOS names are supposed to be exactly 16 bytes long. */
234         if (pnbname - nbname == 16) {
235                 /* This one is; canonicalize its name. */
236                 pnbname = canonicalize_netbios_name(nbname);
237         } else {
238                 sprintf(nbname, "Illegal NetBIOS name (%ld bytes long)",
239                     (long)(pnbname - nbname));
240                 goto bad;
241         }
242         if (cname == '.') {
243                 /* We have a scope ID, starting at "pname"; append that to
244                  * the decoded host name. */
245                 strcpy(pnbname, pname);
246         } else {
247                 /* Terminate the decoded host name. */
248                 *pnbname = '\0';
249         }
250
251 bad:
252         strcpy (name_ret, nbname);
253         return name_len;
254 }
255
256
257 static int
258 get_nbns_name_type_class(const u_char *nbns_data_ptr, const u_char *pd,
259     int offset, char *name_ret, int *name_len_ret, int *type_ret,
260     int *class_ret)
261 {
262         int name_len;
263         int type;
264         int class;
265
266         name_len = get_nbns_name(nbns_data_ptr, pd, offset, name_ret);
267         offset += name_len;
268         
269         type = pntohs(&pd[offset]);
270         offset += 2;
271         class = pntohs(&pd[offset]);
272
273         *type_ret = type;
274         *class_ret = class;
275         *name_len_ret = name_len;
276
277         return name_len + 4;
278 }
279
280
281 static int
282 dissect_nbns_query(const u_char *nbns_data_ptr, const u_char *pd, int offset,
283     proto_tree *nbns_tree)
284 {
285         int len;
286         char name[MAXDNAME];
287         int name_len;
288         int type;
289         int class;
290         char *class_name;
291         char *type_name;
292         const u_char *dptr;
293         const u_char *data_start;
294         proto_tree *q_tree;
295         proto_item *tq;
296
297         data_start = dptr = pd + offset;
298
299         len = get_nbns_name_type_class(nbns_data_ptr, pd, offset, name,
300             &name_len, &type, &class);
301         dptr += len;
302
303         type_name = nbns_type_name(type);
304         class_name = dns_class_name(class);
305
306         tq = proto_tree_add_item(nbns_tree, offset, len, "%s: type %s, class %s", 
307             name, type_name, class_name);
308         q_tree = proto_tree_new();
309         proto_item_add_subtree(tq, q_tree, ETT_NBNS_QD);
310
311         proto_tree_add_item(q_tree, offset, name_len, "Name: %s", name);
312         offset += name_len;
313
314         proto_tree_add_item(q_tree, offset, 2, "Type: %s", type_name);
315         offset += 2;
316
317         proto_tree_add_item(q_tree, offset, 2, "Class: %s", class_name);
318         offset += 2;
319         
320         return dptr - data_start;
321 }
322
323 static void
324 nbns_add_nbns_flags(proto_tree *nbns_tree, int offset, u_short flags,
325     int is_wack)
326 {
327         char buf[128+1];
328         proto_tree *field_tree;
329         proto_item *tf;
330         static const value_string rcode_vals[] = {
331                   { RCODE_NOERROR,   "No error"                        },
332                   { RCODE_FMTERROR,  "Request was invalidly formatted" },
333                   { RCODE_SERVFAIL,  "Server failure"                  },
334                   { RCODE_NAMEERROR, "Requested name does not exist"   },
335                   { RCODE_NOTIMPL,   "Request is not implemented"      },
336                   { RCODE_REFUSED,   "Request was refused"             },
337                   { RCODE_ACTIVE,    "Name is owned by another node"   },
338                   { RCODE_CONFLICT,  "Name is in conflict"             },
339                   { 0,               NULL                              }
340         };
341
342         strcpy(buf, val_to_str(flags & F_OPCODE, opcode_vals,
343                                 "Unknown operation"));
344         if (flags & F_RESPONSE && !is_wack) {
345                 strcat(buf, " response");
346                 strcat(buf, ", ");
347                 strcat(buf, val_to_str(flags & F_RCODE, rcode_vals,
348                     "Unknown error"));
349         }
350         tf = proto_tree_add_item(nbns_tree, offset, 2,
351                         "Flags: 0x%04x (%s)", flags, buf);
352         field_tree = proto_tree_new();
353         proto_item_add_subtree(tf, field_tree, ETT_NBNS_FLAGS);
354         proto_tree_add_item(field_tree, offset, 2, "%s",
355                         decode_boolean_bitfield(flags, F_RESPONSE,
356                                 2*8, "Response", "Query"));
357         proto_tree_add_item(field_tree, offset, 2, "%s",
358                         decode_enumerated_bitfield(flags, F_OPCODE,
359                                 2*8, opcode_vals, "%s"));
360         if (flags & F_RESPONSE) {
361                 proto_tree_add_item(field_tree, offset, 2,
362                         "%s",
363                         decode_boolean_bitfield(flags, F_AUTHORITATIVE,
364                                 2*8,
365                                 "Server is an authority for domain",
366                                 "Server isn't an authority for domain"));
367         }
368         proto_tree_add_item(field_tree, offset, 2, "%s",
369                         decode_boolean_bitfield(flags, F_TRUNCATED,
370                                 2*8,
371                                 "Message is truncated",
372                                 "Message is not truncated"));
373         proto_tree_add_item(field_tree, offset, 2, "%s",
374                         decode_boolean_bitfield(flags, F_RECDESIRED,
375                                 2*8,
376                                 "Do query recursively",
377                                 "Don't do query recursively"));
378         if (flags & F_RESPONSE) {
379                 proto_tree_add_item(field_tree, offset, 2,
380                         "%s",
381                         decode_boolean_bitfield(flags, F_RECAVAIL,
382                                 2*8,
383                                 "Server can do recursive queries",
384                                 "Server can't do recursive queries"));
385         }
386         proto_tree_add_item(field_tree, offset, 2, "%s",
387                         decode_boolean_bitfield(flags, F_BROADCAST,
388                                 2*8,
389                                 "Broadcast packet",
390                                 "Not a broadcast packet"));
391         if (flags & F_RESPONSE && !is_wack) {
392                 proto_tree_add_item(field_tree, offset, 2,
393                         "%s",
394                         decode_enumerated_bitfield(flags, F_RCODE,
395                                 2*8,
396                                 rcode_vals, "%s"));
397         }
398 }
399
400 static void
401 nbns_add_nb_flags(proto_tree *rr_tree, int offset, u_short flags)
402 {
403         char buf[128+1];
404         proto_tree *field_tree;
405         proto_item *tf;
406         static const value_string nb_flags_ont_vals[] = {
407                   { NB_FLAGS_ONT_B_NODE, "B-node" },
408                   { NB_FLAGS_ONT_P_NODE, "P-node" },
409                   { NB_FLAGS_ONT_M_NODE, "M-node" },
410                   { NB_FLAGS_ONT_H_NODE, "H-node" },
411                   { 0,                   NULL     }
412         };
413
414         strcpy(buf, val_to_str(flags & NB_FLAGS_ONT, nb_flags_ont_vals,
415             "Unknown"));
416         strcat(buf, ", ");
417         if (flags & NB_FLAGS_G)
418                 strcat(buf, "group");
419         else
420                 strcat(buf, "unique");
421         tf = proto_tree_add_item(rr_tree, offset, 2, "Flags: 0x%x (%s)", flags,
422                         buf);
423         field_tree = proto_tree_new();
424         proto_item_add_subtree(tf, field_tree, ETT_NBNS_NB_FLAGS);
425         proto_tree_add_item(field_tree, offset, 2, "%s",
426                         decode_boolean_bitfield(flags, NB_FLAGS_G,
427                                 2*8,
428                                 "Group name",
429                                 "Unique name"));
430         proto_tree_add_item(field_tree, offset, 2, "%s",
431                         decode_enumerated_bitfield(flags, NB_FLAGS_ONT,
432                                 2*8, nb_flags_ont_vals, "%s"));
433 }
434
435 static void
436 nbns_add_name_flags(proto_tree *rr_tree, int offset, u_short flags)
437 {
438         char buf[128+1];
439         proto_item *field_tree;
440         proto_item *tf;
441         static const value_string name_flags_ont_vals[] = {
442                   { NAME_FLAGS_ONT_B_NODE, "B-node" },
443                   { NAME_FLAGS_ONT_P_NODE, "P-node" },
444                   { NAME_FLAGS_ONT_M_NODE, "M-node" },
445                   { 0,                     NULL     }
446         };
447
448         strcpy(buf, val_to_str(flags & NAME_FLAGS_ONT, name_flags_ont_vals,
449             "Unknown"));
450         strcat(buf, ", ");
451         if (flags & NAME_FLAGS_G)
452                 strcat(buf, "group");
453         else
454                 strcat(buf, "unique");
455         if (flags & NAME_FLAGS_DRG)
456                 strcat(buf, ", being deregistered");
457         if (flags & NAME_FLAGS_CNF)
458                 strcat(buf, ", in conflict");
459         if (flags & NAME_FLAGS_ACT)
460                 strcat(buf, ", active");
461         if (flags & NAME_FLAGS_PRM)
462                 strcat(buf, ", permanent node name");
463         tf = proto_tree_add_item(rr_tree, offset, 2, "Name flags: 0x%x (%s)",
464                         flags, buf);
465         field_tree = proto_tree_new();
466         proto_item_add_subtree(tf, field_tree, ETT_NBNS_NAME_FLAGS);
467         proto_tree_add_item(field_tree, offset, 2, "%s",
468                         decode_boolean_bitfield(flags, NAME_FLAGS_G,
469                                 2*8,
470                                 "Group name",
471                                 "Unique name"));
472         proto_tree_add_item(field_tree, offset, 2, "%s",
473                         decode_enumerated_bitfield(flags, NAME_FLAGS_ONT,
474                                 2*8, name_flags_ont_vals, "%s"));
475         proto_tree_add_item(field_tree, offset, 2, "%s",
476                         decode_boolean_bitfield(flags, NAME_FLAGS_DRG,
477                                 2*8,
478                                 "Name is being deregistered",
479                                 "Name is not being deregistered"));
480         proto_tree_add_item(field_tree, offset, 2, "%s",
481                         decode_boolean_bitfield(flags, NAME_FLAGS_CNF,
482                                 2*8,
483                                 "Name is in conflict",
484                                 "Name is not in conflict"));
485         proto_tree_add_item(field_tree, offset, 2, "%s",
486                         decode_boolean_bitfield(flags, NAME_FLAGS_ACT,
487                                 2*8,
488                                 "Name is active",
489                                 "Name is not active"));
490         proto_tree_add_item(field_tree, offset, 2, "%s",
491                         decode_boolean_bitfield(flags, NAME_FLAGS_PRM,
492                                 2*8,
493                                 "Permanent node name",
494                                 "Not permanent node name"));
495 }
496
497 static int
498 dissect_nbns_answer(const u_char *nbns_data_ptr, const u_char *pd, int offset,
499     proto_tree *nbns_tree, int opcode)
500 {
501         int len;
502         char name[MAXDNAME];
503         int name_len;
504         int type;
505         int class;
506         char *class_name;
507         char *type_name;
508         const u_char *dptr;
509         const u_char *data_start;
510         u_int ttl;
511         u_short data_len;
512         u_short flags;
513         proto_tree *rr_tree;
514         proto_item *trr;
515
516         data_start = dptr = pd + offset;
517
518         len = get_nbns_name_type_class(nbns_data_ptr, pd, offset, name,
519             &name_len, &type, &class);
520         dptr += len;
521
522         type_name = nbns_type_name(type);
523         class_name = dns_class_name(class);
524
525         ttl = pntohl(dptr);
526         dptr += 4;
527
528         data_len = pntohs(dptr);
529         dptr += 2;
530
531         switch (type) {
532         case T_NB:              /* "NB" record */
533                 trr = proto_tree_add_item(nbns_tree, offset,
534                     (dptr - data_start) + data_len,
535                     "%s: type %s, class %s",
536                     name, type_name, class_name);
537                 rr_tree = add_rr_to_tree(trr, ETT_NBNS_RR, offset, name,
538                     name_len, type_name, class_name, ttl, data_len);
539                 offset += (dptr - data_start);
540                 while (data_len > 0) {
541                         if (opcode == OPCODE_WACK) {
542                                 /* WACK response.  This doesn't contain the
543                                  * same type of RR data as other T_NB
544                                  * responses.  */
545                                 if (data_len < 2) {
546                                         proto_tree_add_item(rr_tree, offset,
547                                             data_len, "(incomplete entry)");
548                                         break;
549                                 }
550                                 flags = pntohs(dptr);
551                                 dptr += 2;
552                                 nbns_add_nbns_flags(rr_tree, offset, flags, 1);
553                                 offset += 2;
554                                 data_len -= 2;
555                         } else {
556                                 if (data_len < 2) {
557                                         proto_tree_add_item(rr_tree, offset,
558                                             data_len, "(incomplete entry)");
559                                         break;
560                                 }
561                                 flags = pntohs(dptr);
562                                 dptr += 2;
563                                 nbns_add_nb_flags(rr_tree, offset, flags);
564                                 offset += 2;
565                                 data_len -= 2;
566
567                                 if (data_len < 4) {
568                                         proto_tree_add_item(rr_tree, offset,
569                                             data_len, "(incomplete entry)");
570                                         break;
571                                 }
572                                 proto_tree_add_item(rr_tree, offset, 4,
573                                     "Addr: %s",
574                                     ip_to_str((guint8 *)dptr));
575                                 dptr += 4;
576                                 offset += 4;
577                                 data_len -= 4;
578                         }
579                 }
580                 break;
581
582         case T_NBSTAT:  /* "NBSTAT" record */
583                 {
584                         u_int num_names;
585                         char nbname[16+4+1];    /* 4 for [<last char>] */
586                         u_short name_flags;
587                         
588                         trr = proto_tree_add_item(nbns_tree, offset,
589                             (dptr - data_start) + data_len,
590                             "%s: type %s, class %s",
591                             name, type_name, class_name);
592                         rr_tree = add_rr_to_tree(trr, ETT_NBNS_RR, offset, name,
593                             name_len, type_name, class_name, ttl, data_len);
594                         offset += (dptr - data_start);
595                         if (data_len < 1) {
596                                 proto_tree_add_item(rr_tree, offset,
597                                     data_len, "(incomplete entry)");
598                                 break;
599                         }
600                         num_names = *dptr;
601                         dptr += 1;
602                         proto_tree_add_item(rr_tree, offset, 2,
603                             "Number of names: %u", num_names);
604                         offset += 1;
605
606                         while (num_names != 0) {
607                                 if (data_len < 16) {
608                                         proto_tree_add_item(rr_tree, offset,
609                                             data_len, "(incomplete entry)");
610                                         goto out;
611                                 }
612                                 memcpy(nbname, dptr, 16);
613                                 dptr += 16;
614                                 canonicalize_netbios_name(nbname);
615                                 proto_tree_add_item(rr_tree, offset, 16,
616                                     "Name: %s", nbname);
617                                 offset += 16;
618                                 data_len -= 16;
619
620                                 if (data_len < 2) {
621                                         proto_tree_add_item(rr_tree, offset,
622                                             data_len, "(incomplete entry)");
623                                         goto out;
624                                 }
625                                 name_flags = pntohs(dptr);
626                                 dptr += 2;
627                                 nbns_add_name_flags(rr_tree, offset, name_flags);
628                                 offset += 2;
629                                 data_len -= 2;
630
631                                 num_names--;
632                         }
633
634                         if (data_len < 6) {
635                                 proto_tree_add_item(rr_tree, offset,
636                                     data_len, "(incomplete entry)");
637                                 break;
638                         }
639                         proto_tree_add_item(rr_tree, offset, 6,
640                             "Unit ID: %s",
641                             ether_to_str((guint8 *)dptr));
642                         dptr += 6;
643                         offset += 6;
644                         data_len -= 6;
645
646                         if (data_len < 1) {
647                                 proto_tree_add_item(rr_tree, offset,
648                                     data_len, "(incomplete entry)");
649                                 break;
650                         }
651                         proto_tree_add_item(rr_tree, offset, 1,
652                             "Jumpers: 0x%x", *dptr);
653                         dptr += 1;
654                         offset += 1;
655                         data_len -= 1;
656
657                         if (data_len < 1) {
658                                 proto_tree_add_item(rr_tree, offset,
659                                     data_len, "(incomplete entry)");
660                                 break;
661                         }
662                         proto_tree_add_item(rr_tree, offset, 1,
663                             "Test result: 0x%x", *dptr);
664                         dptr += 1;
665                         offset += 1;
666                         data_len -= 1;
667
668                         if (data_len < 2) {
669                                 proto_tree_add_item(rr_tree, offset,
670                                     data_len, "(incomplete entry)");
671                                 break;
672                         }
673                         proto_tree_add_item(rr_tree, offset, 2,
674                             "Version number: 0x%x", pntohs(dptr));
675                         dptr += 2;
676                         offset += 2;
677                         data_len -= 2;
678
679                         if (data_len < 2) {
680                                 proto_tree_add_item(rr_tree, offset,
681                                     data_len, "(incomplete entry)");
682                                 break;
683                         }
684                         proto_tree_add_item(rr_tree, offset, 2,
685                             "Period of statistics: 0x%x", pntohs(dptr));
686                         dptr += 2;
687                         offset += 2;
688                         data_len -= 2;
689
690                         if (data_len < 2) {
691                                 proto_tree_add_item(rr_tree, offset,
692                                     data_len, "(incomplete entry)");
693                                 break;
694                         }
695                         proto_tree_add_item(rr_tree, offset, 2,
696                             "Number of CRCs: %u", pntohs(dptr));
697                         dptr += 2;
698                         offset += 2;
699                         data_len -= 2;
700
701                         if (data_len < 2) {
702                                 proto_tree_add_item(rr_tree, offset,
703                                     data_len, "(incomplete entry)");
704                                 break;
705                         }
706                         proto_tree_add_item(rr_tree, offset, 2,
707                             "Number of alignment errors: %u", pntohs(dptr));
708                         dptr += 2;
709                         offset += 2;
710                         data_len -= 2;
711
712                         if (data_len < 2) {
713                                 proto_tree_add_item(rr_tree, offset,
714                                     data_len, "(incomplete entry)");
715                                 break;
716                         }
717                         proto_tree_add_item(rr_tree, offset, 2,
718                             "Number of collisions: %u", pntohs(dptr));
719                         dptr += 2;
720                         offset += 2;
721                         data_len -= 2;
722
723                         if (data_len < 2) {
724                                 proto_tree_add_item(rr_tree, offset,
725                                     data_len, "(incomplete entry)");
726                                 break;
727                         }
728                         proto_tree_add_item(rr_tree, offset, 2,
729                             "Number of send aborts: %u", pntohs(dptr));
730                         dptr += 2;
731                         offset += 2;
732                         data_len -= 2;
733
734                         if (data_len < 4) {
735                                 proto_tree_add_item(rr_tree, offset,
736                                     data_len, "(incomplete entry)");
737                                 break;
738                         }
739                         proto_tree_add_item(rr_tree, offset, 4,
740                             "Number of good sends: %u", pntohl(dptr));
741                         dptr += 4;
742                         offset += 4;
743                         data_len -= 4;
744
745                         if (data_len < 4) {
746                                 proto_tree_add_item(rr_tree, offset,
747                                     data_len, "(incomplete entry)");
748                                 break;
749                         }
750                         proto_tree_add_item(rr_tree, offset, 4,
751                             "Number of good receives: %u", pntohl(dptr));
752                         dptr += 4;
753                         offset += 4;
754                         data_len -= 4;
755
756                         if (data_len < 2) {
757                                 proto_tree_add_item(rr_tree, offset,
758                                     data_len, "(incomplete entry)");
759                                 break;
760                         }
761                         proto_tree_add_item(rr_tree, offset, 2,
762                             "Number of retransmits: %u", pntohs(dptr));
763                         dptr += 2;
764                         offset += 2;
765                         data_len -= 2;
766
767                         if (data_len < 2) {
768                                 proto_tree_add_item(rr_tree, offset,
769                                     data_len, "(incomplete entry)");
770                                 break;
771                         }
772                         proto_tree_add_item(rr_tree, offset, 2,
773                             "Number of no resource conditions: %u", pntohs(dptr));
774                         dptr += 2;
775                         offset += 2;
776                         data_len -= 2;
777
778                         if (data_len < 2) {
779                                 proto_tree_add_item(rr_tree, offset,
780                                     data_len, "(incomplete entry)");
781                                 break;
782                         }
783                         proto_tree_add_item(rr_tree, offset, 2,
784                             "Number of command blocks: %u", pntohs(dptr));
785                         dptr += 2;
786                         offset += 2;
787                         data_len -= 2;
788
789                         if (data_len < 2) {
790                                 proto_tree_add_item(rr_tree, offset,
791                                     data_len, "(incomplete entry)");
792                                 break;
793                         }
794                         proto_tree_add_item(rr_tree, offset, 2,
795                             "Number of pending sessions: %u", pntohs(dptr));
796                         dptr += 2;
797                         offset += 2;
798                         data_len -= 2;
799
800                         if (data_len < 2) {
801                                 proto_tree_add_item(rr_tree, offset,
802                                     data_len, "(incomplete entry)");
803                                 break;
804                         }
805                         proto_tree_add_item(rr_tree, offset, 2,
806                             "Max number of pending sessions: %u", pntohs(dptr));
807                         dptr += 2;
808                         offset += 2;
809
810                         proto_tree_add_item(rr_tree, offset, 2,
811                             "Max total sessions possible: %u", pntohs(dptr));
812                         dptr += 2;
813                         offset += 2;
814                         data_len -= 2;
815
816                         if (data_len < 2) {
817                                 proto_tree_add_item(rr_tree, offset,
818                                     data_len, "(incomplete entry)");
819                                 break;
820                         }
821                         proto_tree_add_item(rr_tree, offset, 2,
822                             "Session data packet size: %u", pntohs(dptr));
823                         dptr += 2;
824                         offset += 2;
825                         data_len -= 2;
826                 }
827         out:
828                 break;
829
830         default:
831                 trr = proto_tree_add_item(nbns_tree, offset,
832                     (dptr - data_start) + data_len,
833                     "%s: type %s, class %s",
834                     name, type_name, class_name);
835                 rr_tree = add_rr_to_tree(trr, ETT_NBNS_RR, offset, name,
836                     name_len, type_name, class_name, ttl, data_len);
837                 offset += (dptr - data_start);
838                 proto_tree_add_item(rr_tree, offset, data_len, "Data");
839                 break;
840         }
841         dptr += data_len;
842         
843         return dptr - data_start;
844 }
845
846 static int
847 dissect_query_records(const u_char *nbns_data_ptr, int count, const u_char *pd, 
848     int cur_off, proto_tree *nbns_tree)
849 {
850         int start_off;
851         proto_tree *qatree;
852         proto_item *ti;
853         
854         start_off = cur_off;
855         ti = proto_tree_add_item(nbns_tree, start_off, 0, "Queries");
856         qatree = proto_tree_new();
857         proto_item_add_subtree(ti, qatree, ETT_NBNS_QRY);
858         while (count-- > 0)
859                 cur_off += dissect_nbns_query(nbns_data_ptr, pd, cur_off, qatree);
860         proto_item_set_len(ti, cur_off - start_off);
861
862         return cur_off - start_off;
863 }
864
865
866
867 static int
868 dissect_answer_records(const u_char *nbns_data_ptr, int count,
869     const u_char *pd, int cur_off, proto_tree *nbns_tree, int opcode, char *name)
870 {
871         int start_off;
872         proto_tree *qatree;
873         proto_item *ti;
874         
875         start_off = cur_off;
876         ti = proto_tree_add_item(nbns_tree, start_off, 0, name);
877         qatree = proto_tree_new();
878         proto_item_add_subtree(ti, qatree, ETT_NBNS_ANS);
879         while (count-- > 0)
880                 cur_off += dissect_nbns_answer(nbns_data_ptr, pd, cur_off,
881                                         qatree, opcode);
882         proto_item_set_len(ti, cur_off - start_off);
883         return cur_off - start_off;
884 }
885
886 void
887 dissect_nbns(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
888 {
889         const u_char            *nbns_data_ptr;
890         proto_tree              *nbns_tree;
891         proto_item              *ti;
892         guint16                 id, flags, quest, ans, auth, add;
893         int                     cur_off;
894
895         nbns_data_ptr = &pd[offset];
896
897         /* To do: check for runts, errs, etc. */
898         id    = pntohs(&pd[offset + NBNS_ID]);
899         flags = pntohs(&pd[offset + NBNS_FLAGS]);
900         quest = pntohs(&pd[offset + NBNS_QUEST]);
901         ans   = pntohs(&pd[offset + NBNS_ANS]);
902         auth  = pntohs(&pd[offset + NBNS_AUTH]);
903         add   = pntohs(&pd[offset + NBNS_ADD]);
904
905         if (check_col(fd, COL_PROTOCOL))
906                 col_add_str(fd, COL_PROTOCOL, "NBNS (UDP)");
907         if (check_col(fd, COL_INFO)) {
908                 col_add_fstr(fd, COL_INFO, "%s%s",
909                     val_to_str(flags & F_OPCODE, opcode_vals,
910                       "Unknown operation (%x)"),
911                     (flags & F_RESPONSE) ? " response" : "");
912         }
913
914         if (tree) {
915                 ti = proto_tree_add_item(tree, offset, END_OF_FRAME,
916                                 "NetBIOS Name Service");
917                 nbns_tree = proto_tree_new();
918                 proto_item_add_subtree(ti, nbns_tree, ETT_NBNS);
919
920                 proto_tree_add_item(nbns_tree, offset + NBNS_ID, 2,
921                                 "Transaction ID: 0x%04X", id);
922
923                 nbns_add_nbns_flags(nbns_tree, offset + NBNS_FLAGS, flags, 0);
924                 proto_tree_add_item(nbns_tree, offset + NBNS_QUEST, 2,
925                                         "Questions: %d",
926                                         quest);
927                 proto_tree_add_item(nbns_tree, offset + NBNS_ANS, 2,
928                                         "Answer RRs: %d",
929                                         ans);
930                 proto_tree_add_item(nbns_tree, offset + NBNS_AUTH, 2,
931                                         "Authority RRs: %d",
932                                         auth);
933                 proto_tree_add_item(nbns_tree, offset + NBNS_ADD, 2,
934                                         "Additional RRs: %d",
935                                         add);
936
937                 cur_off = offset + NBNS_HDRLEN;
938     
939                 if (quest > 0)
940                         cur_off += dissect_query_records(nbns_data_ptr,
941                                         quest, pd, cur_off, nbns_tree);
942
943                 if (ans > 0)
944                         cur_off += dissect_answer_records(nbns_data_ptr,
945                                         ans, pd, cur_off, nbns_tree,
946                                         flags & F_OPCODE,
947                                         "Answers");
948
949                 if (auth > 0)
950                         cur_off += dissect_answer_records(nbns_data_ptr,
951                                         auth, pd, cur_off, nbns_tree, 
952                                         flags & F_OPCODE,
953                                         "Authoritative nameservers");
954
955                 if (add > 0)
956                         cur_off += dissect_answer_records(nbns_data_ptr,
957                                         add, pd, cur_off, nbns_tree, 
958                                         flags & F_OPCODE,
959                                         "Additional records");
960         }
961 }
962
963 /* NetBIOS datagram packet, from RFC 1002, page 32 */
964 struct nbdgm_header {
965         guint8          msg_type;
966         struct {
967                 guint8  more;
968                 guint8  first;
969                 guint8  node_type;
970         } flags;
971         guint16         dgm_id;
972         guint32         src_ip;
973         guint16         src_port;
974
975         /* For packets with data */
976         guint16         dgm_length;
977         guint16         pkt_offset;
978
979         /* For error packets */
980         guint8          error_code;
981 };
982
983 void
984 dissect_nbdgm(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
985     int max_data)
986 {
987         proto_tree              *nbdgm_tree = NULL;
988         proto_item              *ti;
989         struct nbdgm_header     header;
990         int                     flags;
991         int                     message_index;
992
993         char *message[] = {
994                 "Unknown",
995                 "Direct_unique datagram",
996                 "Direct_group datagram",
997                 "Broadcast datagram",
998                 "Datagram error",
999                 "Datagram query request",
1000                 "Datagram positive query response",
1001                 "Datagram negative query response"
1002         };
1003
1004         char *node[] = {
1005                 "B node",
1006                 "P node",
1007                 "M node",
1008                 "NBDD"
1009         };
1010
1011         static value_string error_codes[] = {
1012                 { 0x82, "Destination name not present" },
1013                 { 0x83, "Invalid source name format" },
1014                 { 0x84, "Invalid destination name format" },
1015                 { 0x00, NULL }
1016         };
1017
1018         char *yesno[] = { "No", "Yes" };
1019
1020         char name[MAXDNAME+4];
1021         int len;
1022
1023         header.msg_type = pd[offset];
1024         
1025         flags = pd[offset+1];
1026         header.flags.more = flags & 1;
1027         header.flags.first = (flags & 2) >> 1;
1028         header.flags.node_type = (flags & 12) >> 2;
1029
1030         header.dgm_id = pntohs(&pd[offset+2]);
1031         memcpy(&header.src_ip, &pd[offset+4], 4);
1032         header.src_port = pntohs(&pd[offset+8]);
1033
1034         if (header.msg_type == 0x10 ||
1035                         header.msg_type == 0x11 || header.msg_type == 0x12) {
1036                 header.dgm_length = pntohs(&pd[offset+10]);
1037                 header.pkt_offset = pntohs(&pd[offset+12]);
1038         }
1039         else if (header.msg_type == 0x13) {
1040                 header.error_code = pntohs(&pd[offset+10]);
1041         }
1042
1043         message_index = header.msg_type - 0x0f;
1044         if (message_index < 1 || message_index > 8) {
1045                 message_index = 0;
1046         }
1047
1048         if (check_col(fd, COL_PROTOCOL))
1049                 col_add_str(fd, COL_PROTOCOL, "NBDS (UDP)");
1050         if (check_col(fd, COL_INFO)) {
1051                 col_add_fstr(fd, COL_INFO, "%s", message[message_index]);
1052         }
1053
1054         if (tree) {
1055                 ti = proto_tree_add_item(tree, offset, header.dgm_length,
1056                                 "NetBIOS Datagram Service");
1057                 nbdgm_tree = proto_tree_new();
1058                 proto_item_add_subtree(ti, nbdgm_tree, ETT_NBDGM);
1059
1060                 proto_tree_add_item(nbdgm_tree, offset, 1, "Message Type: %s",
1061                                 message[message_index]);
1062                 proto_tree_add_item(nbdgm_tree, offset+1, 1, "More fragments follow: %s",
1063                                 yesno[header.flags.more]);
1064                 proto_tree_add_item(nbdgm_tree, offset+1, 1, "This is first fragment: %s",
1065                                 yesno[header.flags.first]);
1066                 proto_tree_add_item(nbdgm_tree, offset+1, 1, "Node Type: %s",
1067                                 node[header.flags.node_type]);
1068
1069                 proto_tree_add_item(nbdgm_tree, offset+2, 2, "Datagram ID: 0x%04X",
1070                                 header.dgm_id);
1071                 proto_tree_add_item(nbdgm_tree, offset+4, 4, "Source IP: %s",
1072                                 ip_to_str((guint8 *)&header.src_ip));
1073                 proto_tree_add_item(nbdgm_tree, offset+8, 2, "Source Port: %d",
1074                                 header.src_port);
1075         }
1076
1077         offset += 10;
1078         max_data -= 10;
1079
1080         if (header.msg_type == 0x10 ||
1081                         header.msg_type == 0x11 || header.msg_type == 0x12) {
1082
1083                 if (tree) {
1084                         proto_tree_add_item(nbdgm_tree, offset, 2,
1085                                         "Datagram length: %d bytes", header.dgm_length);
1086                         proto_tree_add_item(nbdgm_tree, offset+2, 2,
1087                                         "Packet offset: %d bytes", header.pkt_offset);
1088                 }
1089
1090                 offset += 4;
1091                 max_data -= 4;
1092
1093                 /* Source name */
1094                 len = get_nbns_name(&pd[offset], pd, offset, name);
1095
1096                 if (tree) {
1097                         proto_tree_add_item(nbdgm_tree, offset, len, "Source name: %s",
1098                                         name);
1099                 }
1100                 offset += len;
1101                 max_data -= len;
1102
1103                 /* Destination name */
1104                 len = get_nbns_name(&pd[offset], pd, offset, name);
1105
1106                 if (tree) {
1107                         proto_tree_add_item(nbdgm_tree, offset, len, "Destination name: %s",
1108                                         name);
1109                 }
1110                 offset += len;
1111                 max_data -= len;
1112
1113                 /* here we can pass the packet off to the next protocol */
1114                 dissect_smb(pd, offset, fd, tree, max_data);
1115         }
1116         else if (header.msg_type == 0x13) {
1117                 if (tree) {
1118                         proto_tree_add_item(nbdgm_tree, offset, 1, "Error code: %s",
1119                                 val_to_str(header.error_code, error_codes, "Unknown (0x%x)"));
1120                 }
1121         }
1122         else if (header.msg_type == 0x14 ||
1123                         header.msg_type == 0x15 || header.msg_type == 0x16) {
1124                 /* Destination name */
1125                 len = get_nbns_name(&pd[offset], pd, offset, name);
1126
1127                 if (tree) {
1128                         proto_tree_add_item(nbdgm_tree, offset, len, "Destination name: %s",
1129                                         name);
1130                 }
1131         }
1132 }
1133
1134 /*
1135  * NetBIOS Session Service message types.
1136  */
1137 #define SESSION_MESSAGE                 0x00
1138 #define SESSION_REQUEST                 0x81
1139 #define POSITIVE_SESSION_RESPONSE       0x82
1140 #define NEGATIVE_SESSION_RESPONSE       0x83
1141 #define RETARGET_SESSION_RESPONSE       0x84
1142 #define SESSION_KEEP_ALIVE              0x85
1143
1144 static const value_string message_types[] = {
1145         { SESSION_MESSAGE,           "Session message" },
1146         { SESSION_REQUEST,           "Session request" },
1147         { POSITIVE_SESSION_RESPONSE, "Positive session response" },
1148         { NEGATIVE_SESSION_RESPONSE, "Negative session response" },
1149         { RETARGET_SESSION_RESPONSE, "Retarget session response" },
1150         { SESSION_KEEP_ALIVE,        "Session keep-alive" },
1151         { 0x0,                       NULL }
1152 };
1153
1154 /*
1155  * NetBIOS Session Service flags.
1156  */
1157 #define NBSS_FLAGS_E                    0x1
1158
1159 static const value_string error_codes[] = {
1160         { 0x80, "Not listening on called name" },
1161         { 0x81, "Not listening for called name" },
1162         { 0x82, "Called name not present" },
1163         { 0x83, "Called name present, but insufficient resources" },
1164         { 0x8F, "Unspecified error" },
1165         { 0x0,  NULL }
1166 };
1167
1168 /*
1169  * Dissect a single NBSS packet (there may be more than one in a given TCP
1170  * segment). Hmmm, in my experience, I have never seen more than one NBSS
1171  * in a single segment, since they mostly contain SMBs which are essentially
1172  * a request response type protocol (RJS). Also, a single session message 
1173  * may be split over multiple segments.
1174  */
1175 static int
1176 dissect_nbss_packet(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int max_data)
1177 {
1178         proto_tree      *nbss_tree = NULL;
1179         proto_item      *ti;
1180         proto_tree      *field_tree;
1181         proto_item      *tf;
1182         guint8          msg_type;
1183         guint8          flags;
1184         guint16         length;
1185         int             len;
1186         char            name[MAXDNAME+4];
1187
1188         msg_type = pd[offset];
1189         flags = pd[offset + 1];
1190         length = pntohs(&pd[offset + 2]);
1191         if (flags & NBSS_FLAGS_E)
1192                 length += 65536;
1193
1194         if (tree) {
1195           ti = proto_tree_add_item(tree, offset, length + 4,
1196                                    "NetBIOS Session Service");
1197           nbss_tree = proto_tree_new();
1198           proto_item_add_subtree(ti, nbss_tree, ETT_NBSS);
1199           
1200           proto_tree_add_item(nbss_tree, offset, 1, "Message Type: %s",
1201                               val_to_str(msg_type, message_types, "Unknown (%x)"));
1202         }
1203
1204         offset += 1;
1205
1206         if (tree) {
1207           tf = proto_tree_add_item(nbss_tree, offset, 1, "Flags: 0x%04x", flags);
1208           field_tree = proto_tree_new();
1209           proto_item_add_subtree(tf, field_tree, ETT_NBSS_FLAGS);
1210           proto_tree_add_item(field_tree, offset, 1, "%s",
1211                               decode_boolean_bitfield(flags, NBSS_FLAGS_E,
1212                                                       8, "Add 65536 to length", "Add 0 to length"));
1213         }
1214
1215         offset += 1;
1216
1217         if (tree) {
1218           proto_tree_add_item(nbss_tree, offset, 2, "Length: %u", length);
1219         }
1220
1221         offset += 2;
1222
1223         switch (msg_type) {
1224
1225         case SESSION_REQUEST:
1226           len = get_nbns_name(&pd[offset], pd, offset, name);
1227           if (tree)
1228             proto_tree_add_item(nbss_tree, offset, len,
1229                                 "Called name: %s", name);
1230           offset += len;
1231
1232           len = get_nbns_name(&pd[offset], pd, offset, name);
1233           
1234           if (tree)
1235             proto_tree_add_item(nbss_tree, offset, len,
1236                                 "Calling name: %s", name);
1237
1238           break;
1239
1240         case NEGATIVE_SESSION_RESPONSE:
1241           if (tree) 
1242             proto_tree_add_item(nbss_tree, offset, 1,
1243                                 "Error code: %s",
1244                                 val_to_str(pd[offset], error_codes, "Unknown (%x)"));
1245           break;
1246
1247         case RETARGET_SESSION_RESPONSE:
1248           if (tree)
1249             proto_tree_add_item(nbss_tree, offset, 4,
1250                                 "Retarget IP address: %s",
1251                                 ip_to_str((guint8 *)&pd[offset]));
1252           
1253           offset += 4;
1254
1255           if (tree)
1256             proto_tree_add_item(nbss_tree, offset, 2,
1257                                 "Retarget port: %u", pntohs(&pd[offset]));
1258
1259           break;
1260
1261         case SESSION_MESSAGE:
1262           /*
1263            * Here we can pass the packet off to the next protocol.
1264            */
1265
1266           dissect_smb(pd, offset, fd, tree, max_data - 4);
1267
1268           break;
1269
1270         }
1271         return length + 4;
1272 }
1273
1274 void
1275 dissect_nbss(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int max_data)
1276 {
1277         guint8          msg_type;
1278         guint8          flags;
1279         guint16         length;
1280         int             len;
1281
1282         msg_type = pd[offset];
1283         flags = pd[offset + 1];
1284         length = pntohs(&pd[offset + 2]);
1285         if (flags & NBSS_FLAGS_E)
1286                 length += 65536;
1287
1288         if (check_col(fd, COL_PROTOCOL))
1289                 col_add_str(fd, COL_PROTOCOL, "NBSS (TCP)");
1290         if (check_col(fd, COL_INFO)) {
1291                 col_add_fstr(fd, COL_INFO,
1292                     val_to_str(msg_type, message_types, "Unknown (%x)"));
1293         }
1294
1295         while (max_data > 0) { 
1296           len = dissect_nbss_packet(pd, offset, fd, tree, max_data);
1297           offset += len;
1298           max_data -= len;
1299         }
1300
1301 }