Define some fcns & vars as static...
[metze/wireshark/wip.git] / epan / dissectors / packet-netbios.c
1 /* packet-netbios.c
2  * Routines for NetBIOS protocol packet disassembly
3  * Jeff Foster <jfoste@woodward.com>
4  * Copyright 1999 Jeffrey C. Foster
5  *
6  * derived from the packet-nbns.c
7  *
8  * $Id$
9  *
10  * Wireshark - Network traffic analyzer
11  * By Gerald Combs <gerald@wireshark.org>
12  * Copyright 1998 Gerald Combs
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 #include <string.h>
34 #include <glib.h>
35
36 #include <epan/packet.h>
37 #include <epan/llcsaps.h>
38 #include <epan/reassemble.h>
39 #include <epan/prefs.h>
40 #include "packet-netbios.h"
41
42 /* Netbios command numbers */
43 #define NB_ADD_GROUP            0x00
44 #define NB_ADD_NAME             0x01
45 #define NB_NAME_IN_CONFLICT     0x02
46 #define NB_STATUS_QUERY         0x03
47 #define NB_TERMINATE_TRACE_R    0x07
48 #define NB_DATAGRAM             0x08
49 #define NB_DATAGRAM_BCAST       0x09
50 #define NB_NAME_QUERY           0x0a
51 #define NB_ADD_NAME_RESP        0x0d
52 #define NB_NAME_RESP            0x0e
53 #define NB_STATUS_RESP          0x0f
54 #define NB_TERMINATE_TRACE_LR   0x13
55 #define NB_DATA_ACK             0x14
56 #define NB_DATA_FIRST_MIDDLE    0x15
57 #define NB_DATA_ONLY_LAST       0x16
58 #define NB_SESSION_CONFIRM      0x17
59 #define NB_SESSION_END          0x18
60 #define NB_SESSION_INIT         0x19
61 #define NB_NO_RECEIVE           0x1a
62 #define NB_RECEIVE_OUTSTANDING  0x1b
63 #define NB_RECEIVE_CONTINUE     0x1c
64 #define NB_KEEP_ALIVE           0x1f
65
66 /* Offsets of fields in the NetBIOS header. */
67 #define NB_LENGTH               0
68 #define NB_DELIMITER            2
69 #define NB_COMMAND              4
70 #define NB_FLAGS                5
71 #define NB_DATA1                5
72 #define NB_RESYNC               6
73 #define NB_DATA2                6
74 #define NB_CALL_NAME_TYPE       7
75 #define NB_XMIT_CORL            8
76 #define NB_RESP_CORL            10
77 #define NB_RMT_SES              12
78 #define NB_LOCAL_SES            13
79 #define NB_RECVER_NAME          12
80 #define NB_SENDER_NAME          28
81
82
83 static int proto_netbios = -1;
84 static int hf_netb_cmd = -1;
85 static int hf_netb_hdr_len = -1;
86 static int hf_netb_xmit_corrl = -1;
87 static int hf_netb_resp_corrl = -1;
88 static int hf_netb_call_name_type = -1;
89 static int hf_netb_ack = -1;
90 static int hf_netb_ack_with_data = -1;
91 static int hf_netb_ack_expected = -1;
92 static int hf_netb_recv_cont_req = -1;
93 static int hf_netb_send_no_ack = -1;
94 static int hf_netb_version = -1;
95 static int hf_netb_largest_frame = -1;
96 static int hf_netb_nb_name = -1;
97 static int hf_netb_nb_name_type = -1;
98 static int hf_netb_status_buffer_len = -1;
99 static int hf_netb_status = -1;
100 static int hf_netb_name_type = -1;
101 static int hf_netb_max_data_recv_size = -1;
102 static int hf_netb_termination_indicator = -1;
103 static int hf_netb_num_data_bytes_accepted = -1;
104 static int hf_netb_local_ses_no = -1;
105 static int hf_netb_remote_ses_no = -1;
106 static int hf_netb_data1 = -1;
107 static int hf_netb_data2 = -1;
108 static int hf_netb_fragments = -1;
109 static int hf_netb_fragment = -1;
110 static int hf_netb_fragment_overlap = -1;
111 static int hf_netb_fragment_overlap_conflict = -1;
112 static int hf_netb_fragment_multiple_tails = -1;
113 static int hf_netb_fragment_too_long_fragment = -1;
114 static int hf_netb_fragment_error = -1;
115 static int hf_netb_reassembled_length = -1;
116
117 static gint ett_netb = -1;
118 static gint ett_netb_name = -1;
119 static gint ett_netb_flags = -1;
120 static gint ett_netb_status = -1;
121 static gint ett_netb_fragments = -1;
122 static gint ett_netb_fragment = -1;
123
124 static const fragment_items netbios_frag_items = {
125         &ett_netb_fragment,
126         &ett_netb_fragments,
127         &hf_netb_fragments,
128         &hf_netb_fragment,
129         &hf_netb_fragment_overlap,
130         &hf_netb_fragment_overlap_conflict,
131         &hf_netb_fragment_multiple_tails,
132         &hf_netb_fragment_too_long_fragment,
133         &hf_netb_fragment_error,
134         NULL,
135         &hf_netb_reassembled_length,
136         "fragments"
137 };
138
139 static dissector_handle_t data_handle;
140
141 /* The strings for the station type, used by get_netbios_name function;
142    many of them came from the file "NetBIOS.txt" in the Zip archive at
143
144         http://www.net3group.com/ftp/browser.zip
145  */
146
147 static const value_string nb_name_type_vals[] = {
148         {0x00,  "Workstation/Redirector"},
149         {0x01,  "Browser"},
150         {0x02,  "Workstation/Redirector"},
151                 /* not sure what 0x02 is, I'm seeing alot of them however */
152                 /* i'm seeing them with workstation/redirection host
153                         announcements */
154         {0x03,  "Messenger service/Main name"},
155         {0x05,  "Forwarded name"},
156         {0x06,  "RAS Server service"},
157         {0x1b,  "Domain Master Browser"},
158         {0x1c,  "Domain Controllers"},
159         {0x1d,  "Local Master Browser"},
160         {0x1e,  "Browser Election Service"},
161         {0x1f,  "Net DDE Service"},
162         {0x20,  "Server service"},
163         {0x21,  "RAS client service"},
164         {0x22,  "Exchange Interchange (MSMail Connector)"},
165         {0x23,  "Exchange Store"},
166         {0x24,  "Exchange Directory"},
167         {0x2b,  "Lotus Notes Server service"},
168         {0x30,  "Modem sharing server service"},
169         {0x31,  "Modem sharing client service"},
170         {0x43,  "SMS Clients Remote Control"},
171         {0x44,  "SMS Administrators Remote Control Tool"},
172         {0x45,  "SMS Clients Remote Chat"},
173         {0x46,  "SMS Clients Remote Transfer"},
174         {0x4c,  "DEC Pathworks TCP/IP Service on Windows NT"},
175         {0x52,  "DEC Pathworks TCP/IP Service on Windows NT"},
176         {0x6a,  "Microsoft Exchange IMC"},
177         {0x87,  "Microsoft Exchange MTA"},
178         {0xbe,  "Network Monitor Agent"},
179         {0xbf,  "Network Monitor Analyzer"},
180         {0x00,  NULL}
181 };
182
183 /* Tables for reassembly of fragments. */
184 static GHashTable *netbios_fragment_table = NULL;
185 static GHashTable *netbios_reassembled_table = NULL;
186
187 /* defragmentation of NetBIOS Frame */
188 static gboolean netbios_defragment = TRUE;
189
190 /* See
191
192         http://www.s390.ibm.com/bookmgr-cgi/bookmgr.cmd/BOOKS/BK8P7001/CCONTENTS
193
194    and
195
196         http://ourworld.compuserve.com/homepages/TimothyDEvans/contents.htm
197
198    for information about the NetBIOS Frame Protocol (which is what this
199    module dissects). */
200
201 /* the strings for the command types  */
202
203 static const value_string cmd_vals[] = {
204         { NB_ADD_GROUP,                 "Add Group Name Query" },
205         { NB_ADD_NAME,                  "Add Name Query" },
206         { NB_NAME_IN_CONFLICT,          "Name In Conflict" },
207         { NB_STATUS_QUERY,              "Status Query" },
208         { NB_TERMINATE_TRACE_R,         "Terminate Trace" },
209         { NB_DATAGRAM,                  "Datagram" },
210         { NB_DATAGRAM_BCAST,            "Broadcast Datagram" },
211         { NB_NAME_QUERY,                "Name Query" },
212         { NB_ADD_NAME_RESP,             "Add Name Response" },
213         { NB_NAME_RESP,                 "Name Recognized" },
214         { NB_STATUS_RESP,               "Status Response" },
215         { NB_TERMINATE_TRACE_LR,        "Terminate Trace" },
216         { NB_DATA_ACK,                  "Data Ack" },
217         { NB_DATA_FIRST_MIDDLE,         "Data First Middle" },
218         { NB_DATA_ONLY_LAST,            "Data Only Last" },
219         { NB_SESSION_CONFIRM,           "Session Confirm" },
220         { NB_SESSION_END,               "Session End" },
221         { NB_SESSION_INIT,              "Session Initialize" },
222         { NB_NO_RECEIVE,                "No Receive" },
223         { NB_RECEIVE_OUTSTANDING,       "Receive Outstanding" },
224         { NB_RECEIVE_CONTINUE,          "Receive Continue" },
225         { NB_KEEP_ALIVE,                "Session Alive" },
226         { 0,                            NULL }
227 };
228
229 static const value_string name_types[] = {
230         { 0, "Unique name" },
231         { 1, "Group name" },
232         { 0, NULL }
233 };
234
235 static const true_false_string flags_allowed = {
236         "Allowed",
237         "Not allowed"
238 };
239
240 static const true_false_string netb_version_str = {
241         "2.00 or higher",
242         "1.xx"
243 };
244
245 static const value_string termination_indicator_vals[] = {
246         { 0x0000, "Normal session end" },
247         { 0x0001, "Abnormal session end" },
248         { 0,      NULL }
249 };
250
251 static const value_string status_vals[] = {
252         { 0, "Add name not in process" },
253         { 1, "Add name in process" },
254         { 0, NULL }
255 };
256
257 static const value_string max_frame_size_vals[] = {
258         { 0,    "516" },
259         { 1,    "1500" },
260         { 2,    "2052" },
261         { 3,    "4472" },
262         { 4,    "8144" },
263         { 5,    "11407" },
264         { 6,    "17800" },      /* 17800 in TR spec, 17749 in NBF spec */
265         { 7,    "65535" },
266         { 0,    NULL }
267 };
268
269
270 void capture_netbios(packet_counts *ld)
271 {
272         ld->netbios++;
273 }
274
275
276 int
277 process_netbios_name(const guchar *name_ptr, char *name_ret, int name_ret_len)
278 {
279         int i;
280         int name_type = *(name_ptr + NETBIOS_NAME_LEN - 1);
281         guchar name_char;
282         static const char hex_digits[16] = "0123456789abcdef";
283
284         for (i = 0; i < NETBIOS_NAME_LEN - 1; i++) {
285                 name_char = *name_ptr++;
286                 if (name_char >= ' ' && name_char <= '~') {
287                         if (--name_ret_len > 0)
288                                 *name_ret++ = name_char;
289                 } else {
290                         /* It's not printable; show it as <XX>, where
291                            XX is the value in hex. */
292                         if (--name_ret_len > 0)
293                                 *name_ret++ = '<';
294                         if (--name_ret_len > 0)
295                                 *name_ret++ = hex_digits[(name_char >> 4)];
296                         if (--name_ret_len > 0)
297                                 *name_ret++ = hex_digits[(name_char & 0x0F)];
298                         if (--name_ret_len > 0)
299                                 *name_ret++ = '>';
300                 }
301         }
302         *name_ret = '\0';
303
304         /* Remove trailing space characters from name. */
305
306         name_ret--;
307
308         for (i = 0; i < NETBIOS_NAME_LEN - 1; i++) {
309                 if (*name_ret != ' ') {
310                         *(name_ret + 1) = 0;
311                         break;
312                 }
313                 name_ret--;
314         }
315
316         return name_type;
317 }
318
319
320 int get_netbios_name( tvbuff_t *tvb, int offset, char *name_ret, int name_ret_len)
321
322 {/*  Extract the name string and name type.  Return the name string in  */
323  /* name_ret and return the name_type. */
324
325         return process_netbios_name( tvb_get_ptr( tvb, offset, NETBIOS_NAME_LEN ), name_ret, name_ret_len);
326 }
327
328
329 /*
330  * Get a string describing the type of a NetBIOS name.
331  */
332 const char *
333 netbios_name_type_descr(int name_type)
334 {
335         return val_to_str(name_type, nb_name_type_vals, "Unknown");
336 }
337
338 void netbios_add_name(const char* label, tvbuff_t *tvb, int offset,
339     proto_tree *tree)
340
341 {/* add a name field display tree. Display the name and station type in sub-tree */
342
343         proto_tree *field_tree;
344         proto_item *tf;
345         char  name_str[(NETBIOS_NAME_LEN - 1)*4 + 1];
346         int   name_type;
347         const char  *name_type_str;
348
349                                         /* decode the name field */
350         name_type = get_netbios_name( tvb, offset, name_str, (NETBIOS_NAME_LEN - 1)*4 + 1);
351         name_type_str = netbios_name_type_descr(name_type);
352         tf = proto_tree_add_text( tree, tvb, offset, NETBIOS_NAME_LEN,
353                 "%s: %s<%02x> (%s)", label, name_str, name_type, name_type_str);
354
355         field_tree = proto_item_add_subtree( tf, ett_netb_name);
356         proto_tree_add_string_format( field_tree, hf_netb_nb_name, tvb, offset,
357                 15, name_str, "%s", name_str);
358         proto_tree_add_uint_format( field_tree, hf_netb_nb_name_type, tvb, offset + 15, 1, name_type,
359             "0x%02x (%s)", name_type, name_type_str);
360 }
361
362
363 static void netbios_data_first_middle_flags( tvbuff_t *tvb, proto_tree *tree, int offset)
364
365 {
366         proto_tree *field_tree;
367         proto_item *tf;
368         guint flags = tvb_get_guint8( tvb, offset);
369
370                 /* decode the flag field for Data First Middle packet*/
371
372         tf = proto_tree_add_text(tree, tvb, offset, 1,
373                         "Flags: 0x%02x", flags);
374         field_tree = proto_item_add_subtree(tf, ett_netb_flags);
375
376         proto_tree_add_boolean( field_tree, hf_netb_ack, tvb, offset, 1, flags);
377
378         proto_tree_add_boolean( field_tree, hf_netb_ack_expected, tvb, offset, 1, flags);
379
380         proto_tree_add_boolean( field_tree, hf_netb_recv_cont_req, tvb, offset, 1, flags);
381 }
382
383 static void netbios_data_only_flags( tvbuff_t *tvb, proto_tree *tree,
384    int offset)
385 {
386         proto_tree *field_tree;
387         proto_item *tf;
388         guint flags = tvb_get_guint8( tvb, offset);
389
390                 /* decode the flag field for Data Only Last packet*/
391
392         tf = proto_tree_add_text(tree, tvb, offset, 1,
393                         "Flags: 0x%02x", flags);
394         field_tree = proto_item_add_subtree(tf, ett_netb_flags);
395
396         proto_tree_add_boolean( field_tree, hf_netb_ack, tvb, offset, 1, flags);
397
398         proto_tree_add_boolean( field_tree, hf_netb_ack_with_data, tvb, offset, 1, flags);
399
400         proto_tree_add_boolean( field_tree, hf_netb_ack_expected, tvb, offset, 1, flags);
401 }
402
403
404
405 static void netbios_add_ses_confirm_flags( tvbuff_t *tvb, proto_tree *tree,
406         int offset)
407 {
408         proto_tree *field_tree;
409         proto_item *tf;
410         guint flags = tvb_get_guint8( tvb, offset);
411
412                 /* decode the flag field for Session Confirm packet */
413         tf = proto_tree_add_text(tree, tvb, offset, 1,
414                         "Flags: 0x%02x", flags);
415         field_tree = proto_item_add_subtree( tf, ett_netb_flags);
416
417         proto_tree_add_boolean( field_tree, hf_netb_send_no_ack, tvb, offset, 1, flags);
418
419         proto_tree_add_boolean( field_tree, hf_netb_version, tvb, offset, 1, flags);
420 }
421
422
423 static void netbios_add_session_init_flags( tvbuff_t *tvb, proto_tree *tree,
424         int offset)
425 {
426         proto_tree *field_tree;
427         proto_item *tf;
428         guint flags = tvb_get_guint8( tvb, offset);
429                 /* decode the flag field for Session Init packet */
430
431         tf = proto_tree_add_text(tree, tvb, offset, 1,
432                         "Flags: 0x%02x", flags);
433         field_tree = proto_item_add_subtree(tf, ett_netb_flags);
434
435         proto_tree_add_boolean( field_tree, hf_netb_send_no_ack, tvb, offset, 1, flags);
436
437         proto_tree_add_uint( field_tree, hf_netb_largest_frame, tvb, offset, 1,
438                 flags);
439
440         proto_tree_add_boolean( field_tree, hf_netb_version, tvb, offset, 1, flags);
441 }
442
443
444 static void netbios_no_receive_flags( tvbuff_t *tvb, proto_tree *tree,
445     int offset)
446
447 {
448         proto_tree *field_tree;
449         proto_item *tf;
450         guint flags = tvb_get_guint8( tvb, offset);
451
452                 /* decode the flag field for No Receive packet*/
453
454         tf = proto_tree_add_text(tree, tvb, offset, 1,
455                         "Flags: 0x%02x", flags);
456
457         if (flags & 0x02) {
458                 field_tree = proto_item_add_subtree(tf, ett_netb_flags);
459                 proto_tree_add_text(field_tree, tvb, offset, 1, "%s",
460                     decode_boolean_bitfield(flags, 0x02, 8,
461                         "SEND.NO.ACK data not received", NULL));
462         }
463 }
464
465
466 /************************************************************************/
467 /*                                                                      */
468 /*  The routines to display the netbios field values in the tree        */
469 /*                                                                      */
470 /************************************************************************/
471
472
473 static void nb_xmit_corrl( tvbuff_t *tvb, int offset, proto_tree *tree)
474
475 {/* display the transmit correlator */
476
477         proto_tree_add_item( tree, hf_netb_xmit_corrl, tvb, offset + NB_XMIT_CORL,
478                 2, TRUE);
479 }
480
481
482 static void nb_resp_corrl( tvbuff_t *tvb, int offset, proto_tree *tree)
483
484 {/* display the response correlator */
485
486         proto_tree_add_item( tree, hf_netb_resp_corrl, tvb, offset + NB_RESP_CORL,
487                 2, TRUE);
488 }
489
490
491 static void nb_call_name_type( tvbuff_t *tvb, int offset, proto_tree *tree)
492
493 {/* display the call name type */
494
495         proto_tree_add_item( tree, hf_netb_call_name_type, tvb, offset + NB_CALL_NAME_TYPE,
496                 1, TRUE);
497
498 }
499
500
501 static guint8 nb_local_session( tvbuff_t *tvb, int offset, proto_tree *tree)
502
503 {/* add the local session to tree, and return its value */
504
505         guint8 local_session = tvb_get_guint8( tvb, offset + NB_LOCAL_SES);
506
507         proto_tree_add_uint( tree, hf_netb_local_ses_no, tvb, offset + NB_LOCAL_SES, 1,
508                 local_session);
509
510         return local_session;
511 }
512
513
514 static guint8 nb_remote_session( tvbuff_t *tvb, int offset, proto_tree *tree)
515
516 {/* add the remote session to tree, and return its value */
517
518         guint8 remote_session = tvb_get_guint8( tvb, offset + NB_RMT_SES);
519
520         proto_tree_add_uint( tree, hf_netb_remote_ses_no, tvb, offset + NB_RMT_SES, 1,
521                 remote_session);
522
523         return remote_session;
524 }
525
526
527 static void nb_data1(int hf, tvbuff_t *tvb, int offset, proto_tree *tree)
528
529 {/* add the DATA1 to tree with specified hf_ value */
530
531         proto_tree_add_item( tree, hf, tvb, offset + NB_DATA1, 1, TRUE);
532
533 }
534
535
536 static void nb_data2(int hf, tvbuff_t *tvb, int offset, proto_tree *tree)
537
538 {/* add the DATA2 to tree with specified hf_ value */
539
540         proto_tree_add_item( tree, hf, tvb, offset + NB_DATA2, 2, TRUE);
541
542 }
543
544
545 static void nb_resync_indicator( tvbuff_t *tvb, int offset, proto_tree *tree, const char *cmd_str)
546 {
547         guint16 resync_indicator = tvb_get_letohs( tvb, offset + NB_DATA2);
548
549
550         switch (resync_indicator) {
551
552         case 0x0000:
553                 proto_tree_add_text(tree, tvb, offset + NB_DATA2, 2,
554                     "Re-sync indicator: No re-sync");
555                 break;
556
557         case 0x0001:
558                 proto_tree_add_text(tree, tvb, offset + NB_DATA2, 2,
559                     "Re-sync indicator: First '%s' following 'Receive Outstanding'", cmd_str);
560                 break;
561
562         default:
563                 proto_tree_add_text(tree, tvb, offset + NB_DATA2, 2,
564                     "Re-sync indicator: 0x%04x", resync_indicator);
565                 break;
566         }
567 }
568
569 /************************************************************************/
570 /*                                                                      */
571 /*  The routines called by the top level to handle individual commands  */
572 /*                                                                      */
573 /************************************************************************/
574
575 static guint32
576 dissect_netb_unknown( tvbuff_t *tvb, int offset, proto_tree *tree)
577
578 {/* Handle any unknown commands, do nothing */
579
580         proto_tree_add_text(tree, tvb, offset + NB_COMMAND + 1, -1,
581             "Unknown NetBIOS command data");
582
583         return 0;
584 }
585
586
587 static guint32
588 dissect_netb_add_group_name( tvbuff_t *tvb, int offset, proto_tree *tree)
589
590 {/* Handle the ADD GROUP NAME QUERY command */
591
592         nb_resp_corrl( tvb, offset, tree);
593
594         netbios_add_name("Group name to add", tvb, offset + NB_SENDER_NAME,
595             tree);
596
597         return 0;
598 }
599
600
601 static guint32
602 dissect_netb_add_name( tvbuff_t *tvb, int offset, proto_tree *tree)
603
604 {/* Handle the ADD NAME QUERY command */
605
606         nb_resp_corrl( tvb, offset, tree);
607
608         netbios_add_name("Name to add", tvb, offset + NB_SENDER_NAME, tree);
609
610         return 0;
611 }
612
613
614 static guint32
615 dissect_netb_name_in_conflict( tvbuff_t *tvb, int offset, proto_tree *tree)
616
617 {/* Handle the NAME IN CONFLICT command */
618
619         netbios_add_name("Name In Conflict", tvb, offset + NB_RECVER_NAME,
620             tree);
621         netbios_add_name("Sender's Name", tvb, offset + NB_SENDER_NAME, tree);
622
623         return 0;
624 }
625
626
627 static guint32
628 dissect_netb_status_query( tvbuff_t *tvb, int offset, proto_tree *tree)
629
630 {/* Handle the STATUS QUERY command */
631
632         guint8 status_request = tvb_get_guint8( tvb, offset + NB_DATA1);
633
634         switch (status_request) {
635
636         case 0:
637                 proto_tree_add_text(tree, tvb, offset + NB_DATA1, 1,
638                     "Status request: NetBIOS 1.x or 2.0");
639                 break;
640
641         case 1:
642                 proto_tree_add_text(tree, tvb, offset + NB_DATA1, 1,
643                     "Status request: NetBIOS 2.1, initial status request");
644                 break;
645
646         default:
647                 proto_tree_add_text(tree, tvb, offset + NB_DATA1, 1,
648                     "Status request: NetBIOS 2.1, %u names received so far",
649                     status_request);
650                 break;
651         }
652         nb_data2( hf_netb_status_buffer_len, tvb, offset, tree);
653         nb_resp_corrl( tvb, offset, tree);
654         netbios_add_name("Receiver's Name", tvb, offset + NB_RECVER_NAME, tree);
655         netbios_add_name("Sender's Name", tvb, offset + NB_SENDER_NAME, tree);
656
657         return 0;
658 }
659
660
661 static guint32
662 dissect_netb_terminate_trace( tvbuff_t *tvb _U_, int offset _U_, proto_tree *tree _U_)
663
664 {/* Handle the TERMINATE TRACE command */
665
666         /*
667          * XXX - are any of the fields in this message significant?
668          * The IBM NetBIOS document shows them as "Reserved".
669          */
670
671         return 0;
672 }
673
674
675 static guchar zeroes[10];
676
677 static guint32
678 dissect_netb_datagram( tvbuff_t *tvb, int offset, proto_tree *tree)
679
680 {/* Handle the DATAGRAM command */
681
682         netbios_add_name("Receiver's Name", tvb, offset + NB_RECVER_NAME, tree);
683         /* Weird.  In some datagrams, this is 10 octets of 0, followed
684            by a MAC address.... */
685
686         if (memcmp( tvb_get_ptr( tvb,offset + NB_SENDER_NAME, 10), zeroes, 10) == 0) {
687                 proto_tree_add_text( tree, tvb, offset + NB_SENDER_NAME + 10, 6,
688                     "Sender's MAC Address: %s",
689                     ether_to_str( tvb_get_ptr( tvb,offset + NB_SENDER_NAME + 10, 6)));
690         } else {
691                 netbios_add_name("Sender's Name", tvb, offset + NB_SENDER_NAME,
692                     tree);
693         }
694
695         return 0;
696 }
697
698
699 static guint32
700 dissect_netb_datagram_bcast( tvbuff_t *tvb, int offset, proto_tree *tree)
701
702 {/* Handle the DATAGRAM BROADCAST command */
703
704         /* We assume the same weirdness can happen here.... */
705         if ( memcmp( tvb_get_ptr( tvb,offset + NB_SENDER_NAME + 10, 6), zeroes, 10) == 0) {
706                 proto_tree_add_text( tree, tvb, offset + NB_SENDER_NAME + 10, 6,
707                     "Sender's Node Address: %s",
708                     ether_to_str( tvb_get_ptr( tvb,offset + NB_SENDER_NAME + 10, 6)));
709         } else {
710                 netbios_add_name("Sender's Name", tvb, offset + NB_SENDER_NAME,
711                     tree);
712         }
713
714         return 0;
715 }
716
717
718 static guint32
719 dissect_netb_name_query( tvbuff_t *tvb, int offset, proto_tree *tree)
720
721 {/* Handle the NAME QUERY command */
722         guint8 local_session_number = tvb_get_guint8( tvb, offset + NB_DATA2);
723
724         if (local_session_number == 0) {
725                 proto_tree_add_text( tree, tvb, offset + NB_DATA2, 1,
726                     "Local Session No.: 0 (FIND.NAME request)");
727         } else {
728                 proto_tree_add_text( tree, tvb, offset + NB_DATA2, 1,
729                     "Local Session No.: 0x%02x", local_session_number);
730         }
731         nb_call_name_type( tvb, offset, tree);
732         nb_resp_corrl( tvb, offset, tree);
733         netbios_add_name("Query Name", tvb, offset + NB_RECVER_NAME, tree);
734         if (local_session_number != 0) {
735                 netbios_add_name("Sender's Name", tvb, offset + NB_SENDER_NAME,
736                     tree);
737         }
738
739         return 0;
740 }
741
742
743 static guint32
744 dissect_netb_add_name_resp( tvbuff_t *tvb, int offset, proto_tree *tree)
745
746 {/* Handle the ADD NAME RESPONSE command */
747
748         nb_data1( hf_netb_status, tvb, offset, tree);
749         nb_data2( hf_netb_name_type, tvb, offset, tree);
750         nb_xmit_corrl( tvb, offset, tree);
751         netbios_add_name("Name to be added", tvb, offset + NB_RECVER_NAME,
752             tree);
753         netbios_add_name("Name to be added", tvb, offset + NB_SENDER_NAME,
754             tree);
755
756         return 0;
757 }
758
759
760 static guint32
761 dissect_netb_name_resp( tvbuff_t *tvb, int offset, proto_tree *tree)
762
763 {/* Handle the NAME RECOGNIZED command */
764         guint8 local_session_number = tvb_get_guint8( tvb, offset + NB_DATA2);
765
766         switch (local_session_number) {
767
768         case 0x00:
769                 proto_tree_add_text( tree, tvb, offset + NB_DATA2, 1,
770                     "State of name: No LISTEN pending, or FIND.NAME response");
771                 break;
772
773         case 0xFF:
774                 proto_tree_add_text( tree, tvb, offset + NB_DATA2, 1,
775                     "State of name: LISTEN pending, but insufficient resources to establish session");
776                 break;
777
778         default:
779                 proto_tree_add_text( tree, tvb, offset + NB_DATA2, 1,
780                     "Local Session No.: 0x%02x", local_session_number);
781                 break;
782         }
783         nb_call_name_type( tvb, offset, tree);
784         nb_xmit_corrl( tvb, offset, tree);
785         if (local_session_number != 0x00 && local_session_number != 0xFF)
786                 nb_resp_corrl(tvb, offset, tree);
787         netbios_add_name("Receiver's Name", tvb, offset + NB_RECVER_NAME, tree);
788         if (local_session_number != 0x00 && local_session_number != 0xFF) {
789                 netbios_add_name("Sender's Name", tvb, offset + NB_SENDER_NAME,
790                     tree);
791         }
792
793         return 0;
794 }
795
796
797 static guint32
798 dissect_netb_status_resp( tvbuff_t *tvb, int offset, proto_tree *tree)
799
800 {/* Handle the STATUS RESPONSE command */
801         guint8 status_response = tvb_get_guint8( tvb, offset + NB_DATA1);
802         proto_item *td2;
803         proto_tree *data2_tree;
804         guint16 data2;
805
806         nb_call_name_type( tvb, offset, tree);
807         if (status_response == 0) {
808                 proto_tree_add_text(tree, tvb, offset + NB_DATA1, 1,
809                     "Status response: NetBIOS 1.x or 2.0");
810         } else {
811                 proto_tree_add_text(tree, tvb, offset + NB_DATA1, 1,
812                     "Status response: NetBIOS 2.1, %u names sent so far",
813                     status_response);
814         }
815         data2 = tvb_get_letohs( tvb, offset + NB_DATA2);
816
817         td2 = proto_tree_add_text(tree, tvb, offset + NB_DATA2, 2, "Status: 0x%04x",
818             data2);
819         data2_tree = proto_item_add_subtree(td2, ett_netb_status);
820         if (data2 & 0x8000) {
821                 proto_tree_add_text(data2_tree, tvb, offset, 2, "%s",
822                     decode_boolean_bitfield(data2, 0x8000, 8*2,
823                         "Data length exceeds maximum frame size", NULL));
824         }
825         if (data2 & 0x4000) {
826                 proto_tree_add_text(data2_tree, tvb, offset, 2, "%s",
827                     decode_boolean_bitfield(data2, 0x4000, 8*2,
828                         "Data length exceeds user's buffer", NULL));
829         }
830         proto_tree_add_text(data2_tree, tvb, offset, 2, "%s",
831             decode_numeric_bitfield(data2, 0x3FFF, 2*8,
832                         "Status data length = %u"));
833         nb_xmit_corrl( tvb, offset, tree);
834         netbios_add_name("Receiver's Name", tvb, offset + NB_RECVER_NAME, tree);
835         netbios_add_name("Sender's Name", tvb, offset + NB_SENDER_NAME,
836             tree);
837
838         return 0;
839 }
840
841
842 static guint32
843 dissect_netb_data_ack( tvbuff_t* tvb, int offset, proto_tree *tree)
844
845 {/* Handle the DATA ACK command */
846
847         nb_xmit_corrl( tvb, offset, tree);
848         nb_remote_session( tvb, offset, tree);
849         nb_local_session( tvb, offset, tree);
850
851         return 0;
852 }
853
854
855 static guint32
856 dissect_netb_data_first_middle( tvbuff_t *tvb, int offset, proto_tree *tree)
857
858 {/* Handle the DATA FIRST MIDDLE command */
859
860         guint8 remote_session, local_session;
861
862         /*
863          * This is the first frame, or the middle frame, of a fragmented
864          * packet.
865          *
866          * XXX - there are no sequence numbers, so we have to assume
867          * that fragments arrive in order with no duplicates.
868          * In fact, 802.2 LLC is supposed to handle that, so we
869          * might have to have the LLC dissector do so (but the TCP
870          * dissector doesn't currently handle out-of-order or duplicate
871          * data, either).
872          */
873
874         netbios_data_first_middle_flags( tvb, tree, offset + NB_FLAGS);
875
876         nb_resync_indicator( tvb, offset, tree, "DATA FIRST MIDDLE");
877         nb_xmit_corrl( tvb, offset, tree);
878         nb_resp_corrl( tvb, offset, tree);
879         remote_session = nb_remote_session( tvb, offset, tree);
880         local_session = nb_local_session( tvb, offset, tree);
881
882         /*
883          * Return a combination of the remote and local session numbers,
884          * for use when reassembling.
885          */
886         return (remote_session << 8) + local_session;
887 }
888
889
890 static guint32
891 dissect_netb_data_only_last( tvbuff_t *tvb, int offset, proto_tree *tree)
892
893 {/* Handle the DATA ONLY LAST command */
894
895         guint8 remote_session, local_session;
896
897         /*
898          * This is a complete packet, or the last frame of a fragmented
899          * packet.
900          */
901
902         netbios_data_only_flags( tvb, tree, offset + NB_FLAGS);
903
904         nb_resync_indicator( tvb, offset, tree, "DATA ONLY LAST");
905         nb_xmit_corrl( tvb, offset, tree);
906         nb_resp_corrl( tvb, offset, tree);
907         remote_session = nb_remote_session( tvb, offset, tree);
908         local_session = nb_local_session( tvb, offset, tree);
909
910         /*
911          * Return a combination of the remote and local session numbers,
912          * for use when reassembling.
913          */
914         return (remote_session << 8) + local_session;
915 }
916
917
918 static guint32
919 dissect_netb_session_confirm( tvbuff_t *tvb, int offset, proto_tree *tree)
920
921 {/* Handle the SESSION CONFIRM command */
922
923         netbios_add_ses_confirm_flags( tvb, tree, offset + NB_FLAGS);
924
925         nb_data2( hf_netb_max_data_recv_size, tvb, offset, tree);
926         nb_xmit_corrl( tvb, offset, tree);
927         nb_resp_corrl( tvb, offset, tree);
928         nb_remote_session( tvb, offset, tree);
929         nb_local_session( tvb, offset, tree);
930
931         return 0;
932 }
933
934
935 static guint32
936 dissect_netb_session_end( tvbuff_t *tvb, int offset, proto_tree *tree)
937
938 {/* Handle the SESSION END command */
939
940         nb_data2( hf_netb_termination_indicator, tvb, offset, tree);
941         nb_remote_session( tvb, offset, tree);
942         nb_local_session( tvb, offset, tree);
943
944         return 0;
945 }
946
947
948 static guint32
949 dissect_netb_session_init( tvbuff_t *tvb, int offset, proto_tree *tree)
950
951 {/* Handle the SESSION INITIALIZE command */
952
953         netbios_add_session_init_flags( tvb, tree, offset + NB_FLAGS);
954
955         nb_data2( hf_netb_max_data_recv_size, tvb, offset, tree);
956         nb_resp_corrl( tvb, offset, tree);
957         nb_xmit_corrl( tvb, offset, tree);
958         nb_remote_session( tvb, offset, tree);
959         nb_local_session( tvb, offset, tree);
960
961         return 0;
962 }
963
964 static guint32
965 dissect_netb_no_receive( tvbuff_t *tvb, int offset, proto_tree *tree)
966
967 {/* Handle the NO RECEIVE command */
968
969         netbios_no_receive_flags( tvb, tree, offset + NB_FLAGS);
970
971         nb_data2( hf_netb_num_data_bytes_accepted, tvb, offset, tree);
972         nb_remote_session( tvb, offset, tree);
973         nb_local_session( tvb, offset, tree);
974
975         return 0;
976 }
977
978
979 static guint32
980 dissect_netb_receive_outstanding( tvbuff_t *tvb, int offset, proto_tree *tree)
981
982 {/* Handle the RECEIVE OUTSTANDING command */
983
984         nb_data2( hf_netb_num_data_bytes_accepted, tvb, offset, tree);
985         nb_remote_session( tvb, offset, tree);
986         nb_local_session( tvb, offset, tree);
987
988         return 0;
989 }
990
991
992 static guint32
993 dissect_netb_receive_continue( tvbuff_t *tvb, int offset, proto_tree *tree)
994
995 {/* Handle the RECEIVE CONTINUE command */
996
997         nb_xmit_corrl( tvb, offset, tree);
998         nb_remote_session( tvb, offset, tree);
999         nb_local_session( tvb, offset, tree);
1000
1001         return 0;
1002 }
1003
1004
1005 static guint32
1006 dissect_netb_session_alive( tvbuff_t *tvb, int offset, proto_tree *tree)
1007
1008 {/* Handle the SESSION ALIVE command */
1009
1010         /*
1011          * XXX - all the fields are claimed to be "Reserved", but
1012          * the session numbers appear to be non-zero in at least
1013          * one capture, and they do appear to match session numbers
1014          * in other messages, and I'd expect that you had to identify
1015          * sessions in this message in any case.
1016          *
1017          * We show only those fields.
1018          */
1019         nb_remote_session( tvb, offset, tree);
1020         nb_local_session( tvb, offset, tree);
1021
1022         return 0;
1023 }
1024
1025
1026 /************************************************************************/
1027 /*                                                                      */
1028 /*  The table routines called by the top level to handle commands       */
1029 /*                                                                      */
1030 /************************************************************************/
1031
1032
1033 static guint32 (*dissect_netb[])(tvbuff_t *, int, proto_tree *) = {
1034
1035   dissect_netb_add_group_name,  /* Add Group Name       0x00 */
1036   dissect_netb_add_name,        /* Add Name             0x01 */
1037   dissect_netb_name_in_conflict,/* Name In Conflict     0x02 */
1038   dissect_netb_status_query,    /* Status Query         0x03 */
1039   dissect_netb_unknown,         /* unknown              0x04 */
1040   dissect_netb_unknown,         /* unknown              0x05 */
1041   dissect_netb_unknown,         /* unknown              0x06 */
1042   dissect_netb_terminate_trace, /* Terminate Trace      0x07 */
1043   dissect_netb_datagram,        /* Datagram             0x08 */
1044   dissect_netb_datagram_bcast,  /* Datagram Broadcast   0x09 */
1045   dissect_netb_name_query,      /* Name Query           0x0A */
1046   dissect_netb_unknown,         /* unknown              0x0B */
1047   dissect_netb_unknown,         /* unknown              0x0C */
1048   dissect_netb_add_name_resp,   /* Add Name Response    0x0D */
1049   dissect_netb_name_resp,       /* Name Recognized      0x0E */
1050   dissect_netb_status_resp,     /* Status Response      0x0F */
1051   dissect_netb_unknown,         /* unknown              0x10 */
1052   dissect_netb_unknown,         /* unknown              0x11 */
1053   dissect_netb_unknown,         /* unknown              0x12 */
1054   dissect_netb_terminate_trace, /* Terminate Trace      0x13 */
1055   dissect_netb_data_ack,        /* Data Ack             0x14 */
1056   dissect_netb_data_first_middle,/* Data First Middle   0x15 */
1057   dissect_netb_data_only_last,  /* Data Only Last       0x16 */
1058   dissect_netb_session_confirm, /* Session Confirm      0x17 */
1059   dissect_netb_session_end,     /* Session End          0x18 */
1060   dissect_netb_session_init,    /* Session Initialize   0x19 */
1061   dissect_netb_no_receive,      /* No Receive           0x1A */
1062   dissect_netb_receive_outstanding,/* Receive Outstanding 0x1B */
1063   dissect_netb_receive_continue,/* Receive Continue     0x1C */
1064   dissect_netb_unknown,         /* unknown              0x1D */
1065   dissect_netb_unknown,         /* unknown              0x1E */
1066   dissect_netb_session_alive,   /* Session Alive        0x1f */
1067   dissect_netb_unknown,
1068 };
1069
1070 static heur_dissector_list_t netbios_heur_subdissector_list;
1071
1072 void
1073 dissect_netbios_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1074 {
1075         /*
1076          * Try the heuristic dissectors for NetBIOS; if none of them
1077          * accept the packet, dissect it as data.
1078          */
1079         if (!dissector_try_heuristic(netbios_heur_subdissector_list,
1080                                     tvb, pinfo, tree))
1081                 call_dissector(data_handle,tvb, pinfo, tree);
1082 }
1083
1084 static void
1085 dissect_netbios(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1086
1087 {
1088         proto_tree              *netb_tree = NULL;
1089         proto_item              *ti;
1090         guint16                 hdr_len, command;
1091         const char              *command_name;
1092         char                    name[(NETBIOS_NAME_LEN - 1)*4 + 1];
1093         int                     name_type;
1094         guint16                 session_id;
1095         gboolean                save_fragmented;
1096         int                     len;
1097         fragment_data           *fd_head;
1098         tvbuff_t                *next_tvb;
1099
1100         int offset = 0;
1101
1102                                         /* load the display labels      */
1103         col_set_str(pinfo->cinfo, COL_PROTOCOL, "NetBIOS");
1104
1105
1106 /* Find NetBIOS marker EFFF, this is done because I have seen an extra LLC */
1107 /* byte on our network. This only checks for one extra LLC byte. */
1108
1109         if ( 0xefff != tvb_get_letohs(tvb, 2)){
1110                 ++offset;
1111                 if ( 0xefff != tvb_get_letohs(tvb, 3)){
1112
1113                         /* print bad packet */
1114                         col_set_str( pinfo->cinfo, COL_INFO, "Bad packet, no 0xEFFF marker");
1115
1116                         return;         /* this is an unknown packet, no marker */
1117                 }
1118         }
1119
1120
1121         hdr_len = tvb_get_letohs(tvb, offset + NB_LENGTH);
1122         command = tvb_get_guint8( tvb, offset + NB_COMMAND);
1123                                         /* limit command so no table overflows */
1124         command = MIN( command, sizeof( dissect_netb)/ sizeof(void *));
1125
1126         if (check_col( pinfo->cinfo, COL_INFO)) {              /* print command name */
1127                 command_name = val_to_str(command, cmd_vals, "Unknown (0x%02x)");
1128                 switch ( command ) {
1129                 case NB_NAME_QUERY:
1130                         name_type = get_netbios_name( tvb, offset + 12, name, (NETBIOS_NAME_LEN - 1)*4 + 1);
1131                         col_add_fstr( pinfo->cinfo, COL_INFO, "%s for %s<%02x>",
1132                             command_name, name, name_type);
1133                         break;
1134
1135                 case NB_NAME_RESP:
1136                 case NB_ADD_NAME:
1137                 case NB_ADD_GROUP:
1138                         name_type = get_netbios_name( tvb, offset + 28, name, (NETBIOS_NAME_LEN - 1)*4 + 1);
1139                         col_add_fstr( pinfo->cinfo, COL_INFO, "%s - %s<%02x>",
1140                             command_name, name, name_type);
1141                         break;
1142
1143                 default:
1144                         col_add_str( pinfo->cinfo, COL_INFO, 
1145                             command_name);
1146                         break;
1147                 }
1148         }
1149
1150         if ( tree) {
1151                 ti = proto_tree_add_item(tree, proto_netbios, tvb, 0, hdr_len, FALSE);
1152                 netb_tree = proto_item_add_subtree(ti, ett_netb);
1153
1154                 proto_tree_add_uint_format(netb_tree, hf_netb_hdr_len, tvb, offset, 2, hdr_len,
1155                         "Length: %d bytes", hdr_len);
1156
1157                 proto_tree_add_text(netb_tree, tvb, offset + 2, 2,
1158                         "Delimiter: EFFF (NetBIOS)");
1159
1160                 proto_tree_add_uint(netb_tree, hf_netb_cmd, tvb, offset + NB_COMMAND, 1, command);
1161         }
1162
1163                                         /* if command in table range */
1164         if ( command < sizeof( dissect_netb)/ sizeof(void *)) {
1165
1166                                         /* branch to handle commands */
1167                 session_id = (dissect_netb[ command])( tvb, offset, netb_tree);
1168
1169                 offset += hdr_len;                      /* move past header */
1170
1171                 save_fragmented = pinfo->fragmented;
1172
1173                 /*
1174                  * Process user data in frames that have it.
1175                  */
1176                 switch (command) {
1177
1178                 case NB_DATAGRAM:
1179                 case NB_DATAGRAM_BCAST:
1180                         /*
1181                          * No fragmentation here.
1182                          */
1183                         next_tvb = tvb_new_subset_remaining(tvb, offset);
1184                         dissect_netbios_payload(next_tvb, pinfo, tree);
1185                         break;
1186
1187                 case NB_DATA_FIRST_MIDDLE:
1188                 case NB_DATA_ONLY_LAST:
1189                         /*
1190                          * Possibly fragmented.
1191                          */
1192                         len = tvb_reported_length_remaining(tvb, offset);
1193                         if (netbios_defragment &&
1194                             tvb_bytes_exist(tvb, offset, len)) {
1195                                 fd_head = fragment_add_seq_next(tvb, offset,
1196                                     pinfo, session_id,
1197                                     netbios_fragment_table,
1198                                     netbios_reassembled_table,
1199                                     len, command == NB_DATA_FIRST_MIDDLE);
1200                                 if (fd_head != NULL) {
1201                                         if (fd_head->next != NULL) {
1202                                                 next_tvb = tvb_new_child_real_data(tvb, fd_head->data,
1203                                                     fd_head->len, fd_head->len);
1204                                                 add_new_data_source(pinfo,
1205                                                     next_tvb,
1206                                                     "Reassembled NetBIOS");
1207                                                 /* Show all fragments. */
1208                                                 if (tree) {
1209                                                         proto_item *frag_tree_item;
1210
1211                                                         show_fragment_seq_tree(fd_head,
1212                                                             &netbios_frag_items,
1213                                                             netb_tree, pinfo,
1214                                                             next_tvb, &frag_tree_item);
1215                                                 }
1216                                         } else {
1217                                                 next_tvb = tvb_new_subset_remaining(tvb,
1218                                                     offset);
1219                                         }
1220                                 } else {
1221                                         next_tvb = NULL;
1222                                 }
1223                         } else {
1224                                 /*
1225                                  * Dissect this, regardless of whether
1226                                  * it's NB_DATA_FIRST_MIDDLE or
1227                                  * NB_DATA_ONLY_LAST.
1228                                  *
1229                                  * XXX - it'd be nice to show
1230                                  * NB_DATA_FIRST_MIDDLE as a fragment
1231                                  * if it's not the first fragment (i.e.,
1232                                  * MIDDLE rather than FIRST), and show
1233                                  * NB_DATA_ONLY_LAST as a fragment if
1234                                  * it's part of a fragmented datagram
1235                                  * (i.e, LAST rather than ONLY), but
1236                                  * we'd have to do reassembly to
1237                                  * be able to determine that.
1238                                  */
1239                                 next_tvb = tvb_new_subset_remaining(tvb, offset);
1240                         }
1241                         if (next_tvb != NULL)
1242                                 dissect_netbios_payload(next_tvb, pinfo, tree);
1243                         else {
1244                                 next_tvb = tvb_new_subset_remaining (tvb, offset);
1245                                 call_dissector(data_handle, next_tvb, pinfo,
1246                                     tree);
1247                         }
1248                         break;
1249                 }
1250         }
1251 }
1252
1253 static void
1254 netbios_init(void)
1255 {
1256         /*
1257          * Initialize the fragment and reassembly tables.
1258          */
1259         fragment_table_init(&netbios_fragment_table);
1260         reassembled_table_init(&netbios_reassembled_table);
1261 }
1262
1263 void proto_register_netbios(void)
1264 {
1265         static gint *ett[] = {
1266                 &ett_netb,
1267                 &ett_netb_name,
1268                 &ett_netb_flags,
1269                 &ett_netb_status,
1270                 &ett_netb_fragments,
1271                 &ett_netb_fragment,
1272         };
1273
1274         static hf_register_info hf_netb[] = {
1275                 { &hf_netb_cmd,
1276                 { "Command", "netbios.command", FT_UINT8, BASE_HEX, VALS(cmd_vals), 0x0,
1277                         NULL, HFILL }},
1278
1279                 { &hf_netb_hdr_len,
1280                 { "Header Length", "netbios.hdr_len", FT_UINT16, BASE_DEC, NULL, 0x0,
1281                         NULL, HFILL }},
1282
1283                 { &hf_netb_xmit_corrl,
1284                 { "Transmit Correlator", "netbios.xmit_corrl", FT_UINT16, BASE_HEX, NULL, 0x0,
1285                         NULL, HFILL }},
1286
1287                 { &hf_netb_resp_corrl,
1288                 { "Response Correlator", "netbios.resp_corrl", FT_UINT16, BASE_HEX, NULL, 0x0,
1289                         NULL, HFILL }},
1290
1291                 { &hf_netb_call_name_type,
1292                 { "Caller's Name Type", "netbios.call_name_type", FT_UINT8, BASE_HEX, VALS(name_types), 0x0,
1293                         NULL, HFILL }},
1294
1295                 { &hf_netb_nb_name_type,
1296                 { "NetBIOS Name Type", "netbios.nb_name_type", FT_UINT8, BASE_HEX, VALS(nb_name_type_vals), 0x0,
1297                         NULL, HFILL }},
1298
1299                 { &hf_netb_nb_name,
1300                 { "NetBIOS Name", "netbios.nb_name", FT_STRING, BASE_NONE, NULL, 0x0,
1301                         NULL, HFILL }},
1302
1303                 { &hf_netb_ack,
1304                 { "Acknowledge", "netbios.ack", FT_BOOLEAN, 8, TFS( &tfs_set_notset), 0x08,
1305                         NULL, HFILL }},
1306
1307                 { &hf_netb_ack_with_data,
1308                 { "Acknowledge with data", "netbios.ack_with_data", FT_BOOLEAN, 8, TFS( &flags_allowed), 0x04,
1309                         NULL, HFILL }},
1310
1311                 { &hf_netb_ack_expected,
1312                 { "Acknowledge expected", "netbios.ack_expected", FT_BOOLEAN,  8,
1313                         TFS( &tfs_yes_no), 0x02, NULL, HFILL }},
1314
1315                 { &hf_netb_recv_cont_req,
1316                 { "RECEIVE_CONTINUE requested", "netbios.recv_cont_req", FT_BOOLEAN,  8,
1317                         TFS( &tfs_yes_no), 0x01, NULL, HFILL }},
1318
1319                 { &hf_netb_send_no_ack,
1320                 { "Handle SEND.NO.ACK", "netbios.send_no_ack", FT_BOOLEAN,  8,
1321                         TFS( &tfs_yes_no), 0x80, NULL, HFILL }},
1322
1323                 { &hf_netb_version,
1324                 { "NetBIOS Version", "netbios.version", FT_BOOLEAN,  8,
1325                         TFS( &netb_version_str), 0x01, NULL, HFILL }},
1326
1327                 { &hf_netb_largest_frame,
1328                 { "Largest Frame", "netbios.largest_frame", FT_UINT8, BASE_DEC, VALS(max_frame_size_vals), 0x0E,
1329                         NULL, HFILL }},
1330
1331                 { &hf_netb_status_buffer_len,
1332                 { "Length of status buffer", "netbios.status_buffer_len", FT_UINT16, BASE_DEC, NULL, 0x0,
1333                         NULL, HFILL }},
1334
1335                 { &hf_netb_status,
1336                 { "Status", "netbios.status", FT_UINT8, BASE_DEC, VALS(status_vals), 0x0,
1337                         NULL, HFILL }},
1338
1339                 { &hf_netb_name_type,
1340                 { "Name type", "netbios.name_type", FT_UINT16, BASE_DEC, VALS(name_types), 0x0,
1341                         NULL, HFILL }},
1342
1343                 { &hf_netb_max_data_recv_size,
1344                 { "Maximum data receive size", "netbios.max_data_recv_size", FT_UINT16, BASE_DEC, NULL, 0x0,
1345                         NULL, HFILL }},
1346
1347                 { &hf_netb_termination_indicator,
1348                 { "Termination indicator", "netbios.termination_indicator", FT_UINT16, BASE_HEX, VALS(termination_indicator_vals), 0x0,
1349                         NULL, HFILL }},
1350
1351                 { &hf_netb_num_data_bytes_accepted,
1352                 { "Number of data bytes accepted", "netbios.num_data_bytes_accepted", FT_UINT16, BASE_DEC, NULL, 0x0,
1353                         NULL, HFILL }},
1354
1355                 { &hf_netb_local_ses_no,
1356                 { "Local Session No.", "netbios.local_session", FT_UINT8, BASE_HEX, NULL, 0x0,
1357                         NULL, HFILL }},
1358
1359                 { &hf_netb_remote_ses_no,
1360                 { "Remote Session No.", "netbios.remote_session", FT_UINT8, BASE_HEX, NULL, 0x0,
1361                         NULL, HFILL }},
1362
1363                 { &hf_netb_data1,
1364                 { "DATA1 value", "netbios.data1", FT_UINT8, BASE_HEX, NULL, 0x0,
1365                         NULL, HFILL }},
1366
1367                 { &hf_netb_data2,
1368                 { "DATA2 value", "netbios.data2", FT_UINT16, BASE_HEX, NULL, 0x0,
1369                         NULL, HFILL }},
1370
1371                 { &hf_netb_fragment_overlap,
1372                 { "Fragment overlap",   "netbios.fragment.overlap", FT_BOOLEAN, BASE_NONE,
1373                         NULL, 0x0, "Fragment overlaps with other fragments", HFILL }},
1374
1375                 { &hf_netb_fragment_overlap_conflict,
1376                 { "Conflicting data in fragment overlap", "netbios.fragment.overlap.conflict",
1377                         FT_BOOLEAN, BASE_NONE,
1378                         NULL, 0x0, "Overlapping fragments contained conflicting data", HFILL }},
1379
1380                 { &hf_netb_fragment_multiple_tails,
1381                 { "Multiple tail fragments found", "netbios.fragment.multipletails",
1382                         FT_BOOLEAN, BASE_NONE,
1383                         NULL, 0x0, "Several tails were found when defragmenting the packet", HFILL }},
1384
1385                 { &hf_netb_fragment_too_long_fragment,
1386                 { "Fragment too long",  "netbios.fragment.toolongfragment", FT_BOOLEAN, BASE_NONE,
1387                         NULL, 0x0, "Fragment contained data past end of packet", HFILL }},
1388
1389                 { &hf_netb_fragment_error,
1390                 {"Defragmentation error",       "netbios.fragment.error", FT_FRAMENUM, BASE_NONE,
1391                         NULL, 0x0, "Defragmentation error due to illegal fragments", HFILL }},
1392
1393                 { &hf_netb_fragment,
1394                 { "NetBIOS Fragment",           "netbios.fragment", FT_FRAMENUM, BASE_NONE,
1395                         NULL, 0x0, NULL, HFILL }},
1396
1397                 { &hf_netb_fragments,
1398                 { "NetBIOS Fragments",  "netbios.fragments", FT_NONE, BASE_NONE,
1399                         NULL, 0x0, NULL, HFILL }},
1400
1401                 { &hf_netb_reassembled_length,
1402                 {"Reassembled NetBIOS length",  "netbios.reassembled.length", FT_UINT32, BASE_DEC,
1403                         NULL, 0x0, "The total length of the reassembled payload", HFILL }},
1404         };
1405         module_t *netbios_module;
1406
1407         proto_netbios = proto_register_protocol("NetBIOS", "NetBIOS", "netbios");
1408         proto_register_subtree_array(ett, array_length(ett));
1409         proto_register_field_array(proto_netbios, hf_netb, array_length(hf_netb));
1410
1411         register_heur_dissector_list("netbios", &netbios_heur_subdissector_list);
1412
1413         netbios_module = prefs_register_protocol(proto_netbios, NULL);
1414         prefs_register_bool_preference(netbios_module, "defragment",
1415             "Reassemble fragmented NetBIOS messages spanning multiple frames",
1416             "Whether the NetBIOS dissector should defragment messages spanning multiple frames",
1417             &netbios_defragment);
1418
1419         register_init_routine(netbios_init);
1420 }
1421
1422 void
1423 proto_reg_handoff_netbios(void)
1424 {
1425         dissector_handle_t netbios_handle;
1426
1427         netbios_handle = create_dissector_handle(dissect_netbios,
1428             proto_netbios);
1429         dissector_add("llc.dsap", SAP_NETBIOS, netbios_handle);
1430         data_handle = find_dissector("data");
1431 }