66841e5bfbf3bb582a3c07b86d85c6aebdc16ca3
[metze/wireshark/wip.git] / epan / dissectors / packet-smb-browse.c
1 /* packet-smb-browse.c
2  * Routines for SMB Browser packet dissection
3  * Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
4  *
5  * $Id$
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * Copied from packet-pop.c
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26  */
27
28 #include "config.h"
29
30 #include <string.h>
31
32 #include <glib.h>
33
34 #include <epan/packet.h>
35 #include <epan/to_str.h>
36 #include <epan/dissectors/packet-smb.h>
37
38 #include "packet-smb-browse.h"
39 #include "packet-dcerpc.h"
40
41 void proto_register_smb_browse(void);
42 void proto_reg_handoff_smb_browse(void);
43
44 static int proto_smb_browse = -1;
45 static int hf_command = -1;
46 static int hf_update_count = -1;
47 static int hf_periodicity = -1;
48 static int hf_server_name = -1;
49 static int hf_mb_server_name = -1;
50 static int hf_mb_reset_command = -1;
51 static int hf_mb_reset_demote = -1;
52 static int hf_mb_reset_flush = -1;
53 static int hf_mb_reset_stop = -1;
54 static int hf_os_major = -1;
55 static int hf_os_minor = -1;
56 static int hf_server_type = -1;
57 static int hf_server_type_workstation = -1;
58 static int hf_server_type_server = -1;
59 static int hf_server_type_sql = -1;
60 static int hf_server_type_domain = -1;
61 static int hf_server_type_backup = -1;
62 static int hf_server_type_time = -1;
63 static int hf_server_type_apple = -1;
64 static int hf_server_type_novell = -1;
65 static int hf_server_type_member = -1;
66 static int hf_server_type_print = -1;
67 static int hf_server_type_dialin = -1;
68 static int hf_server_type_xenix = -1;
69 static int hf_server_type_ntw = -1;
70 static int hf_server_type_wfw = -1;
71 static int hf_server_type_nts = -1;
72 static int hf_server_type_potentialb = -1;
73 static int hf_server_type_backupb = -1;
74 static int hf_server_type_masterb = -1;
75 static int hf_server_type_domainmasterb = -1;
76 static int hf_server_type_osf = -1;
77 static int hf_server_type_vms = -1;
78 static int hf_server_type_w95 = -1;
79 static int hf_server_type_dfs = -1;
80 static int hf_server_type_local = -1;
81 static int hf_server_type_domainenum = -1;
82 static int hf_election_version = -1;
83 static int hf_proto_major = -1;
84 static int hf_proto_minor = -1;
85 static int hf_sig_const = -1;
86 static int hf_server_comment = -1;
87 static int hf_unused_flags = -1;
88 static int hf_response_computer_name = -1;
89 static int hf_election_criteria = -1;
90 static int hf_election_desire = -1;
91 static int hf_election_desire_flags_backup = -1;
92 static int hf_election_desire_flags_standby = -1;
93 static int hf_election_desire_flags_master = -1;
94 static int hf_election_desire_flags_domain_master = -1;
95 static int hf_election_desire_flags_wins = -1;
96 static int hf_election_desire_flags_nt = -1;
97 /* static int hf_election_revision = -1; */
98 static int hf_election_os = -1;
99 static int hf_election_os_wfw = -1;
100 static int hf_election_os_ntw = -1;
101 static int hf_election_os_nts = -1;
102 static int hf_server_uptime = -1;
103 static int hf_backup_count = -1;
104 static int hf_backup_token = -1;
105 static int hf_backup_server = -1;
106 static int hf_browser_to_promote = -1;
107
108 static gint ett_browse = -1;
109 static gint ett_browse_flags = -1;
110 static gint ett_browse_election_criteria = -1;
111 static gint ett_browse_election_os = -1;
112 static gint ett_browse_election_desire = -1;
113 static gint ett_browse_reset_cmd_flags = -1;
114
115 #define SERVER_WORKSTATION              0
116 #define SERVER_SERVER                   1
117 #define SERVER_SQL_SERVER               2
118 #define SERVER_DOMAIN_CONTROLLER        3
119 #define SERVER_BACKUP_CONTROLLER        4
120 #define SERVER_TIME_SOURCE              5
121 #define SERVER_APPLE_SERVER             6
122 #define SERVER_NOVELL_SERVER            7
123 #define SERVER_DOMAIN_MEMBER_SERVER     8
124 #define SERVER_PRINT_QUEUE_SERVER       9
125 #define SERVER_DIALIN_SERVER            10
126 #define SERVER_XENIX_SERVER             11
127 #define SERVER_NT_WORKSTATION           12
128 #define SERVER_WINDOWS_FOR_WORKGROUPS   13
129 #define SERVER_NT_SERVER                15
130 #define SERVER_POTENTIAL_BROWSER        16
131 #define SERVER_BACKUP_BROWSER           17
132 #define SERVER_MASTER_BROWSER           18
133 #define SERVER_DOMAIN_MASTER_BROWSER    19
134 #define SERVER_OSF                      20
135 #define SERVER_VMS                      21
136 #define SERVER_WINDOWS_95               22
137 #define SERVER_DFS_SERVER               23
138 #define SERVER_LOCAL_LIST_ONLY          30
139 #define SERVER_DOMAIN_ENUM              31
140
141 static const value_string server_types[] = {
142         {SERVER_WORKSTATION,            "Workstation"},
143         {SERVER_SERVER,                 "Server"},
144         {SERVER_SQL_SERVER,             "SQL Server"},
145         {SERVER_DOMAIN_CONTROLLER,      "Domain Controller"},
146         {SERVER_BACKUP_CONTROLLER,      "Backup Controller"},
147         {SERVER_TIME_SOURCE,            "Time Source"},
148         {SERVER_APPLE_SERVER,           "Apple Server"},
149         {SERVER_NOVELL_SERVER,          "Novell Server"},
150         {SERVER_DOMAIN_MEMBER_SERVER,   "Domain Member Server"},
151         {SERVER_PRINT_QUEUE_SERVER,     "Print Queue Server"},
152         {SERVER_DIALIN_SERVER,          "Dialin Server"},
153         {SERVER_XENIX_SERVER,           "Xenix Server"},
154         {SERVER_NT_WORKSTATION,         "NT Workstation"},
155         {SERVER_WINDOWS_FOR_WORKGROUPS, "Windows for Workgroups"},
156         {SERVER_NT_SERVER,              "NT Server"},
157         {SERVER_POTENTIAL_BROWSER,      "Potential Browser"},
158         {SERVER_BACKUP_BROWSER,         "Backup Browser"},
159         {SERVER_MASTER_BROWSER,         "Master Browser"},
160         {SERVER_DOMAIN_MASTER_BROWSER,  "Domain Master Browser"},
161         {SERVER_OSF,                    "OSF"},
162         {SERVER_VMS,                    "VMS"},
163         {SERVER_WINDOWS_95,             "Windows 95 or above"},
164         {SERVER_DFS_SERVER,             "DFS server"},
165         {SERVER_LOCAL_LIST_ONLY,        "Local List Only"},
166         {SERVER_DOMAIN_ENUM,            "Domain Enum"},
167         {0,     NULL}
168 };
169
170 #define SET_WINDOWS_VERSION_STRING(os_major_ver, os_minor_ver, windows_version) \
171   if(os_major_ver == 6 && os_minor_ver == 1)                            \
172     windows_version = "Windows 7 or Windows Server 2008 R2";            \
173                                                                         \
174   else if(os_major_ver == 6 && os_minor_ver == 0)                       \
175     windows_version = "Windows Vista or Windows Server 2008";           \
176                                                                         \
177   else if(os_major_ver == 5 && os_minor_ver == 2)                       \
178     windows_version = "Windows Server 2003 R2 or Windows Server 2003";  \
179                                                                         \
180   else if(os_major_ver == 5 && os_minor_ver == 1)                       \
181     windows_version = "Windows XP";                                     \
182                                                                         \
183   else if(os_major_ver == 5 && os_minor_ver == 0)                       \
184     windows_version = "Windows 2000";                                   \
185                                                                         \
186   else                                                                  \
187     windows_version = NULL;
188
189 static const value_string resetbrowserstate_command_names[] = {
190   { 0x01, "Stop being a master browser and become a backup browser"},
191   { 0x02, "Discard browse lists, stop being a master browser, and try again"},
192   { 0x04, "Stop being a master browser for ever"},
193   { 0, NULL}
194 };
195
196 static true_false_string tfs_demote_to_backup = {
197         "Demote an LMB to a Backup Browser",
198         "Do not demote an LMB to a Backup Browser"
199 };
200
201 static true_false_string tfs_flush_browse_list = {
202         "Flush the Browse List",
203         "Do not Flush the Browse List"
204 };
205
206 static true_false_string tfs_stop_being_lmb = {
207         "Stop Being a Local Master Browser",
208         "Do not Stop Being a Local Master Browser"
209 };
210
211 static const true_false_string tfs_workstation = {
212         "This is a Workstation",
213         "This is NOT a Workstation"
214 };
215 static const true_false_string tfs_server = {
216         "This is a Server",
217         "This is NOT a Server"
218 };
219 static const true_false_string tfs_sql = {
220         "This is an SQL server",
221         "This is NOT an SQL server"
222 };
223 static const true_false_string tfs_domain = {
224         "This is a Domain Controller",
225         "This is NOT a Domain Controller"
226 };
227 static const true_false_string tfs_backup = {
228         "This is a Backup Controller",
229         "This is NOT a Backup Controller"
230 };
231 static const true_false_string tfs_time = {
232         "This is a Time Source",
233         "This is NOT a Time Source"
234 };
235 static const true_false_string tfs_apple = {
236         "This is an Apple host",
237         "This is NOT an Apple host"
238 };
239 static const true_false_string tfs_novell = {
240         "This is a Novell server",
241         "This is NOT a Novell server"
242 };
243 static const true_false_string tfs_member = {
244         "This is a Domain Member server",
245         "This is NOT a Domain Member server"
246 };
247 static const true_false_string tfs_print = {
248         "This is a Print Queue server",
249         "This is NOT a Print Queue server"
250 };
251 static const true_false_string tfs_dialin = {
252         "This is a Dialin server",
253         "This is NOT a Dialin server"
254 };
255 static const true_false_string tfs_xenix = {
256         "This is a Xenix server",
257         "This is NOT a Xenix server"
258 };
259 static const true_false_string tfs_ntw = {
260         "This is an NT Workstation",
261         "This is NOT an NT Workstation"
262 };
263 static const true_false_string tfs_wfw = {
264         "This is a WfW host",
265         "This is NOT a WfW host"
266 };
267 static const true_false_string tfs_nts = {
268         "This is an NT Server",
269         "This is NOT an NT Server"
270 };
271 static const true_false_string tfs_potentialb = {
272         "This is a Potential Browser",
273         "This is NOT a Potential Browser"
274 };
275 static const true_false_string tfs_backupb = {
276         "This is a Backup Browser",
277         "This is NOT a Backup Browser"
278 };
279 static const true_false_string tfs_masterb = {
280         "This is a Master Browser",
281         "This is NOT a Master Browser"
282 };
283 static const true_false_string tfs_domainmasterb = {
284         "This is a Domain Master Browser",
285         "This is NOT a Domain Master Browser"
286 };
287 static const true_false_string tfs_osf = {
288         "This is an OSF host",
289         "This is NOT an OSF host"
290 };
291 static const true_false_string tfs_vms = {
292         "This is a VMS host",
293         "This is NOT a VMS host"
294 };
295 static const true_false_string tfs_w95 = {
296         "This is a Windows 95 or above host",
297         "This is NOT a Windows 95 or above host"
298 };
299 static const true_false_string tfs_dfs = {
300         "This is a DFS server",
301         "THis is NOT a DFS server"
302 };
303 static const true_false_string tfs_local = {
304         "This is a local list only request",
305         "This is NOT a local list only request"
306 };
307 static const true_false_string tfs_domainenum = {
308         "This is a Domain Enum request",
309         "This is NOT a Domain Enum request"
310 };
311
312 #define DESIRE_BACKUP                   0
313 #define DESIRE_STANDBY                  1
314 #define DESIRE_MASTER                   2
315 #define DESIRE_DOMAIN_MASTER            3
316 #define DESIRE_WINS                     5
317 #define DESIRE_NT                       7
318
319 static const true_false_string tfs_desire_backup = {
320         "Backup Browse Server",
321         "NOT Backup Browse Server"
322 };
323 static const true_false_string tfs_desire_standby = {
324         "Standby Browse Server",
325         "NOT Standby Browse Server"
326 };
327 static const true_false_string tfs_desire_master = {
328         "Master Browser",
329         "NOT Master Browser"
330 };
331 static const true_false_string tfs_desire_domain_master = {
332         "Domain Master Browse Server",
333         "NOT Domain Master Browse Server"
334 };
335 static const true_false_string tfs_desire_wins = {
336         "WINS Client",
337         "NOT WINS Client"
338 };
339 static const true_false_string tfs_desire_nt = {
340         "Windows NT Advanced Server",
341         "NOT Windows NT Advanced Server"
342 };
343
344 #define BROWSE_HOST_ANNOUNCE                    1
345 #define BROWSE_REQUEST_ANNOUNCE                 2
346 #define BROWSE_ELECTION_REQUEST                 8
347 #define BROWSE_BACKUP_LIST_REQUEST              9
348 #define BROWSE_BACKUP_LIST_RESPONSE             10
349 #define BROWSE_BECOME_BACKUP                    11
350 #define BROWSE_DOMAIN_ANNOUNCEMENT              12
351 #define BROWSE_MASTER_ANNOUNCEMENT              13
352 #define BROWSE_RESETBROWSERSTATE_ANNOUNCEMENT   14
353 #define BROWSE_LOCAL_MASTER_ANNOUNCEMENT        15
354
355 static const value_string commands[] = {
356         {BROWSE_HOST_ANNOUNCE,          "Host Announcement"},
357         {BROWSE_REQUEST_ANNOUNCE,       "Request Announcement"},
358         {BROWSE_ELECTION_REQUEST,       "Browser Election Request"},
359         {BROWSE_BACKUP_LIST_REQUEST,    "Get Backup List Request"},
360         {BROWSE_BACKUP_LIST_RESPONSE,   "Get Backup List Response"},
361         {BROWSE_BECOME_BACKUP,          "Become Backup Browser"},
362         {BROWSE_DOMAIN_ANNOUNCEMENT,    "Domain/Workgroup Announcement"},
363         {BROWSE_MASTER_ANNOUNCEMENT,    "Master Announcement"},
364         {BROWSE_RESETBROWSERSTATE_ANNOUNCEMENT, "Reset Browser State Announcement"},
365         {BROWSE_LOCAL_MASTER_ANNOUNCEMENT,"Local Master Announcement"},
366         {0,                             NULL}
367 };
368
369 #define OS_WFW                          0
370 #define OS_NTW                          4
371 #define OS_NTS                          5
372
373 static const true_false_string tfs_os_wfw = {
374         "Windows for Workgroups",
375         "Not Windows for Workgroups"
376 };
377 static const true_false_string tfs_os_ntw = {
378         "Windows NT Workstation",
379         "Not Windows NT Workstation"
380 };
381 static const true_false_string tfs_os_nts = {
382         "Windows NT Server",
383         "Not Windows NT Server"
384 };
385
386 static void
387 dissect_election_criterion_os(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
388 {
389         proto_tree *tree = NULL;
390         proto_item *item = NULL;
391         guint8 os;
392
393         os = tvb_get_guint8(tvb, offset);
394
395         if (parent_tree) {
396                 item = proto_tree_add_uint(parent_tree, hf_election_os, tvb, offset, 1, os);
397                 tree = proto_item_add_subtree(item, ett_browse_election_os);
398         }
399
400         proto_tree_add_boolean(tree, hf_election_os_wfw,
401                 tvb, offset, 1, os);
402         proto_tree_add_boolean(tree, hf_election_os_ntw,
403                 tvb, offset, 1, os);
404         proto_tree_add_boolean(tree, hf_election_os_nts,
405                 tvb, offset, 1, os);
406
407 }
408
409 static void
410 dissect_election_criterion_desire(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
411 {
412         proto_tree *tree = NULL;
413         proto_item *item = NULL;
414         guint8 desire;
415
416         desire = tvb_get_guint8(tvb, offset);
417
418         if (parent_tree) {
419                 item = proto_tree_add_uint(parent_tree, hf_election_desire, tvb, offset, 1, desire);
420                 tree = proto_item_add_subtree(item, ett_browse_election_desire);
421         }
422
423         proto_tree_add_boolean(tree, hf_election_desire_flags_backup,
424                 tvb, offset, 1, desire);
425         proto_tree_add_boolean(tree, hf_election_desire_flags_standby,
426                 tvb, offset, 1, desire);
427         proto_tree_add_boolean(tree, hf_election_desire_flags_master,
428                 tvb, offset, 1, desire);
429         proto_tree_add_boolean(tree, hf_election_desire_flags_domain_master,
430                 tvb, offset, 1, desire);
431         proto_tree_add_boolean(tree, hf_election_desire_flags_wins,
432                 tvb, offset, 1, desire);
433         proto_tree_add_boolean(tree, hf_election_desire_flags_nt,
434                 tvb, offset, 1, desire);
435
436 }
437
438 static void
439 dissect_election_criterion(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
440 {
441         proto_tree *tree = NULL;
442         proto_item *item = NULL;
443         guint32 criterion;
444
445         criterion = tvb_get_letohl(tvb, offset);
446
447         if (parent_tree) {
448                 item = proto_tree_add_uint(parent_tree, hf_election_criteria, tvb, offset, 4, criterion);
449                 tree = proto_item_add_subtree(item, ett_browse_election_criteria);
450         }
451
452         /* election desire */
453         dissect_election_criterion_desire(tvb, tree, offset);
454         offset += 1;
455
456         /* browser protocol major version */
457         proto_tree_add_item(tree, hf_proto_major, tvb, offset, 1, ENC_LITTLE_ENDIAN);
458         offset += 1;
459
460         /* browser protocol minor version */
461         proto_tree_add_item(tree, hf_proto_minor, tvb, offset, 1, ENC_LITTLE_ENDIAN);
462         offset += 1;
463
464         /* election os */
465         dissect_election_criterion_os(tvb, tree, offset);
466
467 }
468
469 /*
470  * XXX - this causes non-browser packets to have browser fields.
471  */
472 int
473 dissect_smb_server_type_flags(tvbuff_t *tvb, int offset, packet_info *pinfo,
474                               proto_tree *parent_tree, guint8 *drep,
475                               gboolean infoflag)
476 {
477         proto_tree *tree = NULL;
478         proto_item *item = NULL;
479         guint32 flags;
480         int i;
481
482         if (drep != NULL) {
483                 /*
484                  * Called from a DCE RPC protocol dissector, for a
485                  * protocol where a 32-bit NDR integer contains
486                  * an server type mask; extract the server type mask
487                  * with an NDR call (but don't put it into the
488                  * protocol tree, as we can't get a pointer to the
489                  * item it puts in, and thus can't put a tree below
490                  * it with the values of the individual bits).
491                  */
492                 offset = dissect_ndr_uint32(
493                         tvb, offset, pinfo, NULL, NULL, drep, hf_server_type, &flags);
494         } else {
495                 /*
496                  * Called from SMB browser or RAP, where the server type
497                  * mask is just a 4-byte little-endian quantity with no
498                  * special NDR alignment requirement; extract it with
499                  * "tvb_get_letohl()".
500                  */
501                 flags = tvb_get_letohl(tvb, offset);
502                 offset += 4;
503         }
504
505         if (parent_tree) {
506                 item = proto_tree_add_uint(parent_tree, hf_server_type, tvb, offset-4, 4, flags);
507                 tree = proto_item_add_subtree(item, ett_browse_flags);
508         }
509
510         if (infoflag) {
511                 /* Append the type(s) of the system to the COL_INFO line ... */
512                 for (i = 0; i < 32; i++) {
513                         if (flags & (1<<i)) {
514                                 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
515                                         val_to_str(i, server_types,
516                                         "Unknown server type:%d"));
517                         }
518                 }
519         }
520
521         proto_tree_add_boolean(tree, hf_server_type_workstation,
522                 tvb, offset-4, 4, flags);
523         proto_tree_add_boolean(tree, hf_server_type_server,
524                 tvb, offset-4, 4, flags);
525         proto_tree_add_boolean(tree, hf_server_type_sql,
526                 tvb, offset-4, 4, flags);
527         proto_tree_add_boolean(tree, hf_server_type_domain,
528                 tvb, offset-4, 4, flags);
529         proto_tree_add_boolean(tree, hf_server_type_backup,
530                 tvb, offset-4, 4, flags);
531         proto_tree_add_boolean(tree, hf_server_type_time,
532                 tvb, offset-4, 4, flags);
533         proto_tree_add_boolean(tree, hf_server_type_apple,
534                 tvb, offset-4, 4, flags);
535         proto_tree_add_boolean(tree, hf_server_type_novell,
536                 tvb, offset-4, 4, flags);
537         proto_tree_add_boolean(tree, hf_server_type_member,
538                 tvb, offset-4, 4, flags);
539         proto_tree_add_boolean(tree, hf_server_type_print,
540                 tvb, offset-4, 4, flags);
541         proto_tree_add_boolean(tree, hf_server_type_dialin,
542                 tvb, offset-4, 4, flags);
543         proto_tree_add_boolean(tree, hf_server_type_xenix,
544                 tvb, offset-4, 4, flags);
545         proto_tree_add_boolean(tree, hf_server_type_ntw,
546                 tvb, offset-4, 4, flags);
547         proto_tree_add_boolean(tree, hf_server_type_wfw,
548                 tvb, offset-4, 4, flags);
549         proto_tree_add_boolean(tree, hf_server_type_nts,
550                 tvb, offset-4, 4, flags);
551         proto_tree_add_boolean(tree, hf_server_type_potentialb,
552                 tvb, offset-4, 4, flags);
553         proto_tree_add_boolean(tree, hf_server_type_backupb,
554                 tvb, offset-4, 4, flags);
555         proto_tree_add_boolean(tree, hf_server_type_masterb,
556                 tvb, offset-4, 4, flags);
557         proto_tree_add_boolean(tree, hf_server_type_domainmasterb,
558                 tvb, offset-4, 4, flags);
559         proto_tree_add_boolean(tree, hf_server_type_osf,
560                 tvb, offset-4, 4, flags);
561         proto_tree_add_boolean(tree, hf_server_type_vms,
562                 tvb, offset-4, 4, flags);
563         proto_tree_add_boolean(tree, hf_server_type_w95,
564                 tvb, offset-4, 4, flags);
565         proto_tree_add_boolean(tree, hf_server_type_dfs,
566                 tvb, offset-4, 4, flags);
567         proto_tree_add_boolean(tree, hf_server_type_local,
568                 tvb, offset-4, 4, flags);
569         proto_tree_add_boolean(tree, hf_server_type_domainenum,
570                 tvb, offset-4, 4, flags);
571
572         return offset;
573 }
574
575
576 static void
577 dissect_mailslot_browse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
578 {
579         int offset = 0;
580         guint8 cmd;
581         proto_tree *tree = NULL;
582         proto_item *item = NULL;
583         guint32 periodicity;
584         gchar host_name[17];
585         gchar *utf8_host_name;
586         gint namelen;
587         guint8 server_count, reset_cmd;
588         guint8 os_major_ver, os_minor_ver;
589         const gchar *windows_version = NULL;
590         int i;
591         guint32 uptime;
592
593         col_set_str(pinfo->cinfo, COL_PROTOCOL, "BROWSER");
594         col_clear(pinfo->cinfo, COL_INFO);
595
596         cmd = tvb_get_guint8(tvb, offset);
597
598         /* Put in something, and replace it later */
599         col_add_str(pinfo->cinfo, COL_INFO, val_to_str(cmd, commands, "Unknown command:0x%02x"));
600
601
602         item = proto_tree_add_item(parent_tree, proto_smb_browse, tvb, offset, -1, ENC_NA);
603         tree = proto_item_add_subtree(item, ett_browse);
604
605         /* command */
606         proto_tree_add_uint(tree, hf_command, tvb, offset, 1, cmd);
607         offset += 1;
608
609         switch (cmd) {
610         case BROWSE_DOMAIN_ANNOUNCEMENT:
611         case BROWSE_LOCAL_MASTER_ANNOUNCEMENT:
612         case BROWSE_HOST_ANNOUNCE: {
613                 /* update count */
614                 proto_tree_add_item(tree, hf_update_count, tvb, offset, 1, ENC_LITTLE_ENDIAN);
615                 offset += 1;
616
617                 /* periodicity (in milliseconds) */
618                 periodicity = tvb_get_letohl(tvb, offset);
619                 proto_tree_add_uint_format_value(tree, hf_periodicity, tvb, offset, 4,
620                     periodicity,
621                     "%s",
622                     time_msecs_to_str(periodicity));
623                 offset += 4;
624
625                 /* server name */
626                 tvb_get_nstringz0(tvb, offset, sizeof(host_name), host_name);
627                 utf8_host_name = g_convert(host_name, strlen(host_name),
628                         "UTF-8", "CP437", NULL, NULL, NULL);
629                 if (utf8_host_name == NULL)
630                         utf8_host_name = host_name;
631                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", utf8_host_name);
632                 proto_tree_add_string_format(tree, hf_server_name,
633                         tvb, offset, 16,
634                         utf8_host_name,
635                         (cmd==BROWSE_DOMAIN_ANNOUNCEMENT)?
636                                 "Domain/Workgroup: %s":
637                                 "Host Name: %s",
638                         utf8_host_name);
639                 if (utf8_host_name != host_name)
640                         g_free(utf8_host_name);
641                 offset += 16;
642
643                 /* Windows version (See "OSVERSIONINFO Structure" on MSDN) */
644                 os_major_ver = tvb_get_guint8(tvb, offset);
645                 os_minor_ver = tvb_get_guint8(tvb, offset+1);
646
647                 SET_WINDOWS_VERSION_STRING(os_major_ver, os_minor_ver, windows_version);
648
649                 if(windows_version)
650                   proto_tree_add_text(tree, tvb, offset, 2, "Windows version: %s", windows_version);
651
652                 /* OS major version */
653                 proto_tree_add_item(tree, hf_os_major, tvb, offset, 1, ENC_LITTLE_ENDIAN);
654                 offset += 1;
655
656                 /* OS minor version */
657                 proto_tree_add_item(tree, hf_os_minor, tvb, offset, 1, ENC_LITTLE_ENDIAN);
658                 offset += 1;
659
660                 /* server type flags */
661                 offset = dissect_smb_server_type_flags(
662                         tvb, offset, pinfo, tree, NULL, TRUE);
663
664                 if (cmd == BROWSE_DOMAIN_ANNOUNCEMENT && tvb_get_letohs (tvb, offset + 2) != 0xAA55) {
665                         /*
666                          * Network Monitor claims this is a "Comment
667                          * Pointer".  I don't believe it.
668                          *
669                          * It's not a browser protocol major/minor
670                          * version number, and signature constant,
671                          * however.
672                          */
673                         proto_tree_add_text(tree, tvb, offset, 4,
674                             "Mysterious Field: 0x%08x",
675                             tvb_get_letohl(tvb, offset));
676                         offset += 4;
677                 } else {
678                         /* browser protocol major version */
679                         proto_tree_add_item(tree, hf_proto_major, tvb, offset, 1, ENC_LITTLE_ENDIAN);
680                         offset += 1;
681
682                         /* browser protocol minor version */
683                         proto_tree_add_item(tree, hf_proto_minor, tvb, offset, 1, ENC_LITTLE_ENDIAN);
684                         offset += 1;
685
686                         /* signature constant */
687                         proto_tree_add_item(tree, hf_sig_const, tvb, offset, 2, ENC_LITTLE_ENDIAN);
688                         offset += 2;
689                 }
690
691                 /* master browser server name or server comment */
692                 namelen = tvb_strsize(tvb, offset);
693                 proto_tree_add_item(tree,
694                         (cmd==BROWSE_DOMAIN_ANNOUNCEMENT)?
695                             hf_mb_server_name : hf_server_comment,
696                         tvb, offset, namelen, ENC_ASCII|ENC_NA);
697                 break;
698         }
699         case BROWSE_REQUEST_ANNOUNCE: {
700                 guint8 *computer_name;
701
702                 /* unused/unknown flags */
703                 proto_tree_add_item(tree, hf_unused_flags,
704                         tvb, offset, 1, ENC_LITTLE_ENDIAN);
705                 offset += 1;
706
707                 /* name of computer to which to send reply */
708                 computer_name = tvb_get_stringz(wmem_packet_scope(), tvb, offset, &namelen);
709                 proto_tree_add_string(tree, hf_response_computer_name,
710                         tvb, offset, namelen, computer_name);
711                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", computer_name);
712                 break;
713         }
714
715         case BROWSE_ELECTION_REQUEST:
716                 /* election version */
717                 proto_tree_add_item(tree, hf_election_version, tvb, offset, 1, ENC_LITTLE_ENDIAN);
718                 offset += 1;
719
720                 /* criterion */
721                 dissect_election_criterion(tvb, tree, offset);
722                 offset += 4;
723
724                 /* server uptime */
725                 uptime = tvb_get_letohl(tvb, offset);
726                 proto_tree_add_uint_format_value(tree, hf_server_uptime,
727                     tvb, offset, 4, uptime,
728                     "%s",
729                     time_msecs_to_str(uptime));
730                 offset += 4;
731
732                 /* next 4 bytes must be zero */
733                 offset += 4;
734
735                 /* server name */
736                 namelen = tvb_strsize(tvb, offset);
737                 proto_tree_add_item(tree, hf_server_name,
738                         tvb, offset, namelen, ENC_ASCII|ENC_NA);
739                 break;
740
741         case BROWSE_BACKUP_LIST_REQUEST:
742                 /* backup list requested count */
743                 proto_tree_add_item(tree, hf_backup_count, tvb, offset, 1, ENC_LITTLE_ENDIAN);
744                 offset += 1;
745
746                 /* backup requested token */
747                 proto_tree_add_item(tree, hf_backup_token, tvb, offset, 4, ENC_LITTLE_ENDIAN);
748                 break;
749
750         case BROWSE_BACKUP_LIST_RESPONSE:
751                 /* backup list requested count */
752                 server_count = tvb_get_guint8(tvb, offset);
753                 proto_tree_add_uint(tree, hf_backup_count, tvb, offset, 1,
754                     server_count);
755                 offset += 1;
756
757                 /* backup requested token */
758                 proto_tree_add_item(tree, hf_backup_token, tvb, offset, 4, ENC_LITTLE_ENDIAN);
759                 offset += 4;
760
761                 /* backup server names */
762                 for (i = 0; i < server_count; i++) {
763                         namelen = tvb_strsize(tvb, offset);
764                         proto_tree_add_item(tree, hf_backup_server,
765                                 tvb, offset, namelen, ENC_ASCII|ENC_NA);
766                         offset += namelen;
767                 }
768                 break;
769
770         case BROWSE_MASTER_ANNOUNCEMENT:
771                 /* master browser server name */
772                 namelen = tvb_strsize(tvb, offset);
773                 proto_tree_add_item(tree, hf_mb_server_name,
774                         tvb, offset, namelen, ENC_ASCII|ENC_NA);
775                 break;
776
777         case BROWSE_RESETBROWSERSTATE_ANNOUNCEMENT: {
778                 proto_tree *sub_tree;
779                 proto_item *reset_item;
780
781                 /* the subcommand follows ... one of three values */
782
783                 reset_cmd = tvb_get_guint8(tvb, offset);
784                 reset_item = proto_tree_add_uint(tree, hf_mb_reset_command, tvb,
785                                                  offset, 1, reset_cmd);
786                 sub_tree = proto_item_add_subtree(reset_item, ett_browse_reset_cmd_flags);
787                 proto_tree_add_boolean(sub_tree, hf_mb_reset_demote, tvb,
788                                        offset, 1, reset_cmd);
789                 proto_tree_add_boolean(sub_tree, hf_mb_reset_flush, tvb,
790                                        offset, 1, reset_cmd);
791                 proto_tree_add_boolean(sub_tree, hf_mb_reset_stop, tvb,
792                                        offset, 1, reset_cmd);
793                 break;
794         }
795
796         case BROWSE_BECOME_BACKUP:
797                 /* name of browser to promote */
798                 namelen = tvb_strsize(tvb, offset);
799                 proto_tree_add_item(tree, hf_browser_to_promote,
800                         tvb, offset, namelen, ENC_ASCII|ENC_NA);
801                 break;
802         }
803 }
804
805 /*
806  * It appears that browser announcements sent to \MAILSLOT\LANMAN aren't
807  * the same as browser announcements sent to \MAILSLOT\BROWSE.
808  * Was that an older version of the protocol?
809  *
810  * The document at
811  *
812  *      http://www.samba.org/samba/ftp/specs/brow_rev.txt
813  *
814  * gives both formats of host announcement packets, saying that
815  * "[The first] format seems wrong", that one being what appears to
816  * show up in \MAILSLOT\LANMAN packets, and that "[The second one]
817  * may be better", that one being what appears to show up in
818  * \MAILSLOT\BROWSE packets.
819  *
820  * XXX - what other browser packets go out to that mailslot?
821  */
822 static void
823 dissect_mailslot_lanman(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
824 {
825         int offset = 0;
826         guint8 cmd;
827         proto_tree *tree = NULL;
828         proto_item *item = NULL;
829         guint32 periodicity;
830         const guint8 *host_name;
831         guint8 os_major_ver, os_minor_ver;
832         const gchar *windows_version = NULL;
833         guint namelen;
834
835         col_set_str(pinfo->cinfo, COL_PROTOCOL, "BROWSER");
836         col_clear(pinfo->cinfo, COL_INFO);
837
838         cmd = tvb_get_guint8(tvb, offset);
839
840         /* Put in something, and replace it later */
841         col_add_str(pinfo->cinfo, COL_INFO, val_to_str(cmd, commands, "Unknown command:0x%02x"));
842
843
844         if (parent_tree) {
845                 item = proto_tree_add_item(parent_tree, proto_smb_browse, tvb, offset, -1, ENC_NA);
846
847                 tree = proto_item_add_subtree(item, ett_browse);
848         }
849
850         /* command */
851         proto_tree_add_uint(tree, hf_command, tvb, offset, 1, cmd);
852         offset += 1;
853
854         switch (cmd) {
855         case BROWSE_DOMAIN_ANNOUNCEMENT:
856         case BROWSE_LOCAL_MASTER_ANNOUNCEMENT:
857         case BROWSE_HOST_ANNOUNCE:
858
859                 /* update count */
860                 proto_tree_add_item(tree, hf_update_count, tvb, offset, 1, ENC_LITTLE_ENDIAN);
861                 offset += 1;
862
863                 /* server type flags */
864                 offset = dissect_smb_server_type_flags(
865                         tvb, offset, pinfo, tree, NULL, TRUE);
866
867                 /* OS version string (See "OSVERSIONINFO Structure" on MSDN) */
868                 os_major_ver = tvb_get_guint8(tvb, offset);
869                 os_minor_ver = tvb_get_guint8(tvb, offset+1);
870
871                 SET_WINDOWS_VERSION_STRING(os_major_ver, os_minor_ver, windows_version);
872
873                 if(windows_version)
874                   proto_tree_add_text(tree, tvb, offset, 2, "Windows version: %s", windows_version);
875
876                 /* OS major version */
877                 proto_tree_add_item(tree, hf_os_major, tvb, offset, 1, ENC_LITTLE_ENDIAN);
878                 offset += 1;
879
880                 /* OS minor version */
881                 proto_tree_add_item(tree, hf_os_minor, tvb, offset, 1, ENC_LITTLE_ENDIAN);
882                 offset += 1;
883
884                 /* periodicity (in seconds; convert to milliseconds) */
885                 periodicity = tvb_get_letohs(tvb, offset)*1000;
886                 proto_tree_add_uint_format_value(tree, hf_periodicity, tvb, offset, 2,
887                     periodicity,
888                     "%s",
889                     time_msecs_to_str(periodicity));
890                 offset += 2;
891
892                 /* server name */
893                 host_name = tvb_get_const_stringz(tvb, offset, &namelen);
894                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", host_name);
895
896                 proto_tree_add_item(tree, hf_server_name,
897                         tvb, offset, namelen, ENC_ASCII|ENC_NA);
898                 offset += namelen;
899
900                 /* master browser server name or server comment */
901                 namelen = tvb_strsize(tvb, offset);
902                 proto_tree_add_item(tree,
903                         (cmd==BROWSE_DOMAIN_ANNOUNCEMENT)?
904                             hf_mb_server_name : hf_server_comment,
905                         tvb, offset, namelen, ENC_ASCII|ENC_NA);
906                 break;
907         }
908 }
909
910 void
911 proto_register_smb_browse(void)
912 {
913         static hf_register_info hf[] = {
914                 { &hf_command,
915                         { "Command", "browser.command", FT_UINT8, BASE_HEX,
916                         VALS(commands), 0, "Browse command opcode", HFILL }},
917
918                 { &hf_update_count,
919                         { "Update Count", "browser.update_count", FT_UINT8, BASE_DEC,
920                         NULL, 0, "Browse Update Count", HFILL }},
921
922                 { &hf_periodicity,
923                         { "Update Periodicity", "browser.period", FT_UINT32, BASE_DEC,
924                         NULL, 0, "Update Periodicity in ms", HFILL }},
925
926                 { &hf_server_name,
927                         { "Server Name", "browser.server", FT_STRING, BASE_NONE,
928                         NULL, 0, "BROWSE Server Name", HFILL }},
929
930                 { &hf_mb_server_name,
931                         { "Master Browser Server Name", "browser.mb_server", FT_STRING, BASE_NONE,
932                         NULL, 0, "BROWSE Master Browser Server Name", HFILL }},
933
934                 { &hf_mb_reset_command,
935                   { "ResetBrowserState Command", "browser.reset_cmd", FT_UINT8,
936                     BASE_HEX, VALS(resetbrowserstate_command_names), 0,
937                     NULL, HFILL }},
938                 { &hf_mb_reset_demote,
939                   { "Demote LMB", "browser.reset_cmd.demote", FT_BOOLEAN,
940                     8, TFS(&tfs_demote_to_backup), 0x01, NULL, HFILL}},
941                 { &hf_mb_reset_flush,
942                   { "Flush Browse List", "browser.reset_cmd.flush", FT_BOOLEAN,
943                     8, TFS(&tfs_flush_browse_list), 0x02, NULL, HFILL}},
944                 { &hf_mb_reset_stop,
945                   { "Stop Being LMB", "browser.reset_cmd.stop_lmb", FT_BOOLEAN,
946                     8, TFS(&tfs_stop_being_lmb), 0x04, NULL, HFILL}},
947                 { &hf_os_major,
948                         { "OS Major Version", "browser.os_major", FT_UINT8, BASE_DEC,
949                         NULL, 0, "Operating System Major Version", HFILL }},
950
951                 { &hf_os_minor,
952                         { "OS Minor Version", "browser.os_minor", FT_UINT8, BASE_DEC,
953                         NULL, 0, "Operating System Minor Version", HFILL }},
954
955                 { &hf_server_type,
956                         { "Server Type", "browser.server_type", FT_UINT32, BASE_HEX,
957                         NULL, 0, "Server Type Flags", HFILL }},
958
959                 { &hf_server_type_workstation,
960                         { "Workstation", "browser.server_type.workstation", FT_BOOLEAN, 32,
961                         TFS(&tfs_workstation), 1<<SERVER_WORKSTATION, "Is This A Workstation?", HFILL }},
962
963                 { &hf_server_type_server,
964                         { "Server", "browser.server_type.server", FT_BOOLEAN, 32,
965                         TFS(&tfs_server), 1<<SERVER_SERVER, "Is This A Server?", HFILL }},
966
967                 { &hf_server_type_sql,
968                         { "SQL", "browser.server_type.sql", FT_BOOLEAN, 32,
969                         TFS(&tfs_sql), 1<<SERVER_SQL_SERVER, "Is This A SQL Server?", HFILL }},
970
971                 { &hf_server_type_domain,
972                         { "Domain Controller", "browser.server_type.domain_controller", FT_BOOLEAN, 32,
973                         TFS(&tfs_domain), 1<<SERVER_DOMAIN_CONTROLLER, "Is This A Domain Controller?", HFILL }},
974
975                 { &hf_server_type_backup,
976                         { "Backup Controller", "browser.server_type.backup_controller", FT_BOOLEAN, 32,
977                         TFS(&tfs_backup), 1<<SERVER_BACKUP_CONTROLLER, "Is This A Backup Domain Controller?", HFILL }},
978
979                 { &hf_server_type_time,
980                         { "Time Source", "browser.server_type.time", FT_BOOLEAN, 32,
981                         TFS(&tfs_time), 1<<SERVER_TIME_SOURCE, "Is This A Time Source?", HFILL }},
982
983                 { &hf_server_type_apple,
984                         { "Apple", "browser.server_type.apple", FT_BOOLEAN, 32,
985                         TFS(&tfs_apple), 1<<SERVER_APPLE_SERVER, "Is This An Apple Server ?", HFILL }},
986
987                 { &hf_server_type_novell,
988                         { "Novell", "browser.server_type.novell", FT_BOOLEAN, 32,
989                         TFS(&tfs_novell), 1<<SERVER_NOVELL_SERVER, "Is This A Novell Server?", HFILL }},
990
991                 { &hf_server_type_member,
992                         { "Member", "browser.server_type.member", FT_BOOLEAN, 32,
993                         TFS(&tfs_member), 1<<SERVER_DOMAIN_MEMBER_SERVER, "Is This A Domain Member Server?", HFILL }},
994
995                 { &hf_server_type_print,
996                         { "Print", "browser.server_type.print", FT_BOOLEAN, 32,
997                         TFS(&tfs_print), 1<<SERVER_PRINT_QUEUE_SERVER, "Is This A Print Server?", HFILL }},
998
999                 { &hf_server_type_dialin,
1000                         { "Dialin", "browser.server_type.dialin", FT_BOOLEAN, 32,
1001                         TFS(&tfs_dialin), 1<<SERVER_DIALIN_SERVER, "Is This A Dialin Server?", HFILL }},
1002
1003                 { &hf_server_type_xenix,
1004                         { "Xenix", "browser.server_type.xenix", FT_BOOLEAN, 32,
1005                         TFS(&tfs_xenix), 1<<SERVER_XENIX_SERVER, "Is This A Xenix Server?", HFILL }},
1006
1007                 { &hf_server_type_ntw,
1008                         { "NT Workstation", "browser.server_type.ntw", FT_BOOLEAN, 32,
1009                         TFS(&tfs_ntw), 1<<SERVER_NT_WORKSTATION, "Is This A NT Workstation?", HFILL }},
1010
1011                 { &hf_server_type_wfw,
1012                         { "WfW", "browser.server_type.wfw", FT_BOOLEAN, 32,
1013                         TFS(&tfs_wfw), 1<<SERVER_WINDOWS_FOR_WORKGROUPS, "Is This A Windows For Workgroups Server?", HFILL }},
1014
1015                 { &hf_server_type_nts,
1016                         { "NT Server", "browser.server_type.nts", FT_BOOLEAN, 32,
1017                         TFS(&tfs_nts), 1<<SERVER_NT_SERVER, "Is This A NT Server?", HFILL }},
1018
1019                 { &hf_server_type_potentialb,
1020                         { "Potential Browser", "browser.server_type.browser.potential", FT_BOOLEAN, 32,
1021                         TFS(&tfs_potentialb), 1<<SERVER_POTENTIAL_BROWSER, "Is This A Potential Browser?", HFILL }},
1022
1023                 { &hf_server_type_backupb,
1024                         { "Backup Browser", "browser.server_type.browser.backup", FT_BOOLEAN, 32,
1025                         TFS(&tfs_backupb), 1<<SERVER_BACKUP_BROWSER, "Is This A Backup Browser?", HFILL }},
1026
1027                 { &hf_server_type_masterb,
1028                         { "Master Browser", "browser.server_type.browser.master", FT_BOOLEAN, 32,
1029                         TFS(&tfs_masterb), 1<<SERVER_MASTER_BROWSER, "Is This A Master Browser?", HFILL }},
1030
1031                 { &hf_server_type_domainmasterb,
1032                         { "Domain Master Browser", "browser.server_type.browser.domain_master", FT_BOOLEAN, 32,
1033                         TFS(&tfs_domainmasterb), 1<<SERVER_DOMAIN_MASTER_BROWSER, "Is This A Domain Master Browser?", HFILL }},
1034
1035                 { &hf_server_type_osf,
1036                         { "OSF", "browser.server_type.osf", FT_BOOLEAN, 32,
1037                         TFS(&tfs_osf), 1<<SERVER_OSF, "Is This An OSF server ?", HFILL }},
1038
1039                 { &hf_server_type_vms,
1040                         { "VMS", "browser.server_type.vms", FT_BOOLEAN, 32,
1041                         TFS(&tfs_vms), 1<<SERVER_VMS, "Is This A VMS Server?", HFILL }},
1042
1043                 { &hf_server_type_w95,
1044                         { "Windows 95+", "browser.server_type.w95", FT_BOOLEAN, 32,
1045                         TFS(&tfs_w95), 1<<SERVER_WINDOWS_95, "Is This A Windows 95 or above server?", HFILL }},
1046
1047                 { &hf_server_type_dfs,
1048                         { "DFS", "browser.server_type.dfs", FT_BOOLEAN, 32,
1049                         TFS(&tfs_dfs), 1<<SERVER_DFS_SERVER, "Is This A DFS server?", HFILL }},
1050
1051                 { &hf_server_type_local,
1052                         { "Local", "browser.server_type.local", FT_BOOLEAN, 32,
1053                         TFS(&tfs_local), 1<<SERVER_LOCAL_LIST_ONLY, "Is This A Local List Only request?", HFILL }},
1054
1055                 { &hf_server_type_domainenum,
1056                         { "Domain Enum", "browser.server_type.domainenum", FT_BOOLEAN, 32,
1057                         TFS(&tfs_domainenum), 1<<SERVER_DOMAIN_ENUM, "Is This A Domain Enum request?", HFILL }},
1058
1059                 { &hf_election_version,
1060                         { "Election Version", "browser.election.version", FT_UINT8, BASE_DEC,
1061                         NULL, 0, NULL, HFILL }},
1062
1063                 { &hf_proto_major,
1064                         { "Browser Protocol Major Version", "browser.proto_major", FT_UINT8, BASE_DEC,
1065                         NULL, 0, NULL, HFILL }},
1066
1067                 { &hf_proto_minor,
1068                         { "Browser Protocol Minor Version", "browser.proto_minor", FT_UINT8, BASE_DEC,
1069                         NULL, 0, NULL, HFILL }},
1070
1071                 { &hf_sig_const,
1072                         { "Signature", "browser.sig", FT_UINT16, BASE_HEX,
1073                         NULL, 0, "Signature Constant", HFILL }},
1074
1075                 { &hf_server_comment,
1076                         { "Host Comment", "browser.comment", FT_STRINGZ, BASE_NONE,
1077                         NULL, 0, "Server Comment", HFILL }},
1078
1079                 { &hf_unused_flags,
1080                         { "Unused flags", "browser.unused", FT_UINT8, BASE_HEX,
1081                         NULL, 0, "Unused/unknown flags", HFILL }},
1082
1083                 { &hf_response_computer_name,
1084                         { "Response Computer Name", "browser.response_computer_name", FT_STRINGZ, BASE_NONE,
1085                         NULL, 0, NULL, HFILL }},
1086
1087                 { &hf_election_criteria,
1088                         { "Election Criteria", "browser.election.criteria", FT_UINT32, BASE_HEX,
1089                         NULL, 0, NULL, HFILL }},
1090
1091                 { &hf_election_desire,
1092                         { "Election Desire", "browser.election.desire", FT_UINT8, BASE_HEX,
1093                         NULL, 0, NULL, HFILL }},
1094
1095                 { &hf_election_desire_flags_backup,
1096                         { "Backup", "browser.election.desire.backup", FT_BOOLEAN, 8,
1097                         TFS(&tfs_desire_backup), 1<<DESIRE_BACKUP, "Is this a backup server", HFILL }},
1098
1099                 { &hf_election_desire_flags_standby,
1100                         { "Standby", "browser.election.desire.standby", FT_BOOLEAN, 8,
1101                         TFS(&tfs_desire_standby), 1<<DESIRE_STANDBY, "Is this a standby server?", HFILL }},
1102
1103                 { &hf_election_desire_flags_master,
1104                         { "Master", "browser.election.desire.master", FT_BOOLEAN, 8,
1105                         TFS(&tfs_desire_master), 1<<DESIRE_MASTER, "Is this a master server", HFILL }},
1106
1107                 { &hf_election_desire_flags_domain_master,
1108                         { "Domain Master", "browser.election.desire.domain_master", FT_BOOLEAN, 8,
1109                         TFS(&tfs_desire_domain_master), 1<<DESIRE_DOMAIN_MASTER, "Is this a domain master", HFILL }},
1110
1111                 { &hf_election_desire_flags_wins,
1112                         { "WINS", "browser.election.desire.wins", FT_BOOLEAN, 8,
1113                         TFS(&tfs_desire_wins), 1<<DESIRE_WINS, "Is this a WINS server", HFILL }},
1114
1115                 { &hf_election_desire_flags_nt,
1116                         { "NT", "browser.election.desire.nt", FT_BOOLEAN, 8,
1117                         TFS(&tfs_desire_nt), 1<<DESIRE_NT, "Is this a NT server", HFILL }},
1118
1119 #if 0
1120                 { &hf_election_revision,
1121                         { "Election Revision", "browser.election.revision", FT_UINT16, BASE_DEC,
1122                         NULL, 0, NULL, HFILL }},
1123 #endif
1124
1125                 { &hf_election_os,
1126                         { "Election OS", "browser.election.os", FT_UINT8, BASE_HEX,
1127                         NULL, 0, NULL, HFILL }},
1128
1129                 { &hf_election_os_wfw,
1130                         { "WfW", "browser.election.os.wfw", FT_BOOLEAN, 8,
1131                         TFS(&tfs_os_wfw), 1<<OS_WFW, "Is this a WfW host?", HFILL }},
1132
1133                 { &hf_election_os_ntw,
1134                         { "NT Workstation", "browser.election.os.ntw", FT_BOOLEAN, 8,
1135                         TFS(&tfs_os_ntw), 1<<OS_NTW, "Is this a NT Workstation?", HFILL }},
1136
1137                 { &hf_election_os_nts,
1138                         { "NT Server", "browser.election.os.nts", FT_BOOLEAN, 8,
1139                         TFS(&tfs_os_nts), 1<<OS_NTS, "Is this a NT Server?", HFILL }},
1140
1141                 { &hf_server_uptime,
1142                         { "Uptime", "browser.uptime", FT_UINT32, BASE_DEC,
1143                         NULL, 0, "Server uptime in ms", HFILL }},
1144
1145                 { &hf_backup_count,
1146                         { "Backup List Requested Count", "browser.backup.count", FT_UINT8, BASE_DEC,
1147                         NULL, 0, NULL, HFILL }},
1148
1149                 { &hf_backup_token,
1150                         { "Backup Request Token", "browser.backup.token", FT_UINT32, BASE_DEC,
1151                         NULL, 0, "Backup requested/response token", HFILL }},
1152
1153                 { &hf_backup_server,
1154                         { "Backup Server", "browser.backup.server", FT_STRING, BASE_NONE,
1155                         NULL, 0, "Backup Server Name", HFILL }},
1156
1157                 { &hf_browser_to_promote,
1158                         { "Browser to Promote", "browser.browser_to_promote", FT_STRINGZ, BASE_NONE,
1159                         NULL, 0, NULL, HFILL }},
1160
1161         };
1162
1163         static gint *ett[] = {
1164                 &ett_browse,
1165                 &ett_browse_flags,
1166                 &ett_browse_election_criteria,
1167                 &ett_browse_election_os,
1168                 &ett_browse_election_desire,
1169                 &ett_browse_reset_cmd_flags,
1170         };
1171
1172         proto_smb_browse = proto_register_protocol("Microsoft Windows Browser Protocol",
1173             "BROWSER", "browser");
1174
1175         proto_register_field_array(proto_smb_browse, hf, array_length(hf));
1176         proto_register_subtree_array(ett, array_length(ett));
1177
1178         register_dissector("mailslot_browse", dissect_mailslot_browse,
1179             proto_smb_browse);
1180         register_dissector("mailslot_lanman", dissect_mailslot_lanman,
1181             proto_smb_browse);
1182 }