epan/dissectors/pidl/samr/samr.cnf cnf_dissect_lsa_BinaryString => lsarpc_dissect_str...
[wireshark-sm.git] / epan / dissectors / packet-smb-browse.c
blob69537d9a5f904a56307c152532505fd38089ac59
1 /* packet-smb-browse.c
2 * Routines for SMB Browser packet dissection
3 * Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * Copied from packet-pop.c
11 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include "config.h"
17 #include <epan/packet.h>
18 #include <epan/to_str.h>
19 #include <epan/tfs.h>
20 #include <wsutil/array.h>
21 #include "packet-smb-browse.h"
22 #include "packet-dcerpc.h"
24 void proto_register_smb_browse(void);
26 static int proto_smb_browse;
27 static int hf_command;
28 static int hf_update_count;
29 static int hf_periodicity;
30 static int hf_server_name;
31 static int hf_mb_server_name;
32 static int hf_mb_reset_command;
33 static int hf_mb_reset_demote;
34 static int hf_mb_reset_flush;
35 static int hf_mb_reset_stop;
36 static int hf_os_major;
37 static int hf_os_minor;
38 static int hf_server_type;
39 static int hf_server_type_workstation;
40 static int hf_server_type_server;
41 static int hf_server_type_sql;
42 static int hf_server_type_domain;
43 static int hf_server_type_backup;
44 static int hf_server_type_time;
45 static int hf_server_type_apple;
46 static int hf_server_type_novell;
47 static int hf_server_type_member;
48 static int hf_server_type_print;
49 static int hf_server_type_dialin;
50 static int hf_server_type_xenix;
51 static int hf_server_type_ntw;
52 static int hf_server_type_wfw;
53 static int hf_server_type_nts;
54 static int hf_server_type_potentialb;
55 static int hf_server_type_backupb;
56 static int hf_server_type_masterb;
57 static int hf_server_type_domainmasterb;
58 static int hf_server_type_osf;
59 static int hf_server_type_vms;
60 static int hf_server_type_w95;
61 static int hf_server_type_dfs;
62 static int hf_server_type_local;
63 static int hf_server_type_domainenum;
64 static int hf_election_version;
65 static int hf_proto_major;
66 static int hf_proto_minor;
67 static int hf_sig_const;
68 static int hf_server_comment;
69 static int hf_unused_flags;
70 static int hf_response_computer_name;
71 static int hf_election_criteria;
72 static int hf_election_desire;
73 static int hf_election_desire_flags_backup;
74 static int hf_election_desire_flags_standby;
75 static int hf_election_desire_flags_master;
76 static int hf_election_desire_flags_domain_master;
77 static int hf_election_desire_flags_wins;
78 static int hf_election_desire_flags_nt;
79 /* static int hf_election_revision; */
80 static int hf_election_os;
81 static int hf_election_os_wfw;
82 static int hf_election_os_ntw;
83 static int hf_election_os_nts;
84 static int hf_server_uptime;
85 static int hf_backup_count;
86 static int hf_backup_token;
87 static int hf_backup_server;
88 static int hf_browser_to_promote;
89 static int hf_windows_version;
90 static int hf_mysterious_field;
92 static int ett_browse;
93 static int ett_browse_flags;
94 static int ett_browse_election_criteria;
95 static int ett_browse_election_os;
96 static int ett_browse_election_desire;
97 static int ett_browse_reset_cmd_flags;
99 #define SERVER_WORKSTATION 0
100 #define SERVER_SERVER 1
101 #define SERVER_SQL_SERVER 2
102 #define SERVER_DOMAIN_CONTROLLER 3
103 #define SERVER_BACKUP_CONTROLLER 4
104 #define SERVER_TIME_SOURCE 5
105 #define SERVER_APPLE_SERVER 6
106 #define SERVER_NOVELL_SERVER 7
107 #define SERVER_DOMAIN_MEMBER_SERVER 8
108 #define SERVER_PRINT_QUEUE_SERVER 9
109 #define SERVER_DIALIN_SERVER 10
110 #define SERVER_XENIX_SERVER 11
111 #define SERVER_NT_WORKSTATION 12
112 #define SERVER_WINDOWS_FOR_WORKGROUPS 13
113 #define SERVER_NT_SERVER 15
114 #define SERVER_POTENTIAL_BROWSER 16
115 #define SERVER_BACKUP_BROWSER 17
116 #define SERVER_MASTER_BROWSER 18
117 #define SERVER_DOMAIN_MASTER_BROWSER 19
118 #define SERVER_OSF 20
119 #define SERVER_VMS 21
120 #define SERVER_WINDOWS_95 22
121 #define SERVER_DFS_SERVER 23
122 #define SERVER_LOCAL_LIST_ONLY 30
123 #define SERVER_DOMAIN_ENUM 31
125 static const value_string server_types[] = {
126 {SERVER_WORKSTATION, "Workstation"},
127 {SERVER_SERVER, "Server"},
128 {SERVER_SQL_SERVER, "SQL Server"},
129 {SERVER_DOMAIN_CONTROLLER, "Domain Controller"},
130 {SERVER_BACKUP_CONTROLLER, "Backup Controller"},
131 {SERVER_TIME_SOURCE, "Time Source"},
132 {SERVER_APPLE_SERVER, "Apple Server"},
133 {SERVER_NOVELL_SERVER, "Novell Server"},
134 {SERVER_DOMAIN_MEMBER_SERVER, "Domain Member Server"},
135 {SERVER_PRINT_QUEUE_SERVER, "Print Queue Server"},
136 {SERVER_DIALIN_SERVER, "Dialin Server"},
137 {SERVER_XENIX_SERVER, "Xenix Server"},
138 {SERVER_NT_WORKSTATION, "NT Workstation"},
139 {SERVER_WINDOWS_FOR_WORKGROUPS, "Windows for Workgroups"},
140 {SERVER_NT_SERVER, "NT Server"},
141 {SERVER_POTENTIAL_BROWSER, "Potential Browser"},
142 {SERVER_BACKUP_BROWSER, "Backup Browser"},
143 {SERVER_MASTER_BROWSER, "Master Browser"},
144 {SERVER_DOMAIN_MASTER_BROWSER, "Domain Master Browser"},
145 {SERVER_OSF, "OSF"},
146 {SERVER_VMS, "VMS"},
147 {SERVER_WINDOWS_95, "Windows 95 or above"},
148 {SERVER_DFS_SERVER, "DFS server"},
149 {SERVER_LOCAL_LIST_ONLY, "Local List Only"},
150 {SERVER_DOMAIN_ENUM, "Domain Enum"},
151 {0, NULL}
154 #define SET_WINDOWS_VERSION_STRING(os_major_ver, os_minor_ver, windows_version) \
155 if(os_major_ver == 6 && os_minor_ver == 1) \
156 windows_version = "Windows 7 or Windows Server 2008 R2"; \
158 else if(os_major_ver == 6 && os_minor_ver == 0) \
159 windows_version = "Windows Vista or Windows Server 2008"; \
161 else if(os_major_ver == 5 && os_minor_ver == 2) \
162 windows_version = "Windows Server 2003 R2 or Windows Server 2003"; \
164 else if(os_major_ver == 5 && os_minor_ver == 1) \
165 windows_version = "Windows XP"; \
167 else if(os_major_ver == 5 && os_minor_ver == 0) \
168 windows_version = "Windows 2000"; \
170 else \
171 windows_version = "";
173 static const value_string resetbrowserstate_command_names[] = {
174 { 0x01, "Stop being a master browser and become a backup browser"},
175 { 0x02, "Discard browse lists, stop being a master browser, and try again"},
176 { 0x04, "Stop being a master browser for ever"},
177 { 0, NULL}
180 static true_false_string tfs_demote_to_backup = {
181 "Demote an LMB to a Backup Browser",
182 "Do not demote an LMB to a Backup Browser"
185 static true_false_string tfs_flush_browse_list = {
186 "Flush the Browse List",
187 "Do not Flush the Browse List"
190 static true_false_string tfs_stop_being_lmb = {
191 "Stop Being a Local Master Browser",
192 "Do not Stop Being a Local Master Browser"
195 static const true_false_string tfs_workstation = {
196 "This is a Workstation",
197 "This is NOT a Workstation"
199 static const true_false_string tfs_server = {
200 "This is a Server",
201 "This is NOT a Server"
203 static const true_false_string tfs_sql = {
204 "This is an SQL server",
205 "This is NOT an SQL server"
207 static const true_false_string tfs_domain = {
208 "This is a Domain Controller",
209 "This is NOT a Domain Controller"
211 static const true_false_string tfs_backup = {
212 "This is a Backup Controller",
213 "This is NOT a Backup Controller"
215 static const true_false_string tfs_time = {
216 "This is a Time Source",
217 "This is NOT a Time Source"
219 static const true_false_string tfs_apple = {
220 "This is an Apple host",
221 "This is NOT an Apple host"
223 static const true_false_string tfs_novell = {
224 "This is a Novell server",
225 "This is NOT a Novell server"
227 static const true_false_string tfs_member = {
228 "This is a Domain Member server",
229 "This is NOT a Domain Member server"
231 static const true_false_string tfs_print = {
232 "This is a Print Queue server",
233 "This is NOT a Print Queue server"
235 static const true_false_string tfs_dialin = {
236 "This is a Dialin server",
237 "This is NOT a Dialin server"
239 static const true_false_string tfs_xenix = {
240 "This is a Xenix server",
241 "This is NOT a Xenix server"
243 static const true_false_string tfs_ntw = {
244 "This is an NT Workstation",
245 "This is NOT an NT Workstation"
247 static const true_false_string tfs_wfw = {
248 "This is a WfW host",
249 "This is NOT a WfW host"
251 static const true_false_string tfs_nts = {
252 "This is an NT Server",
253 "This is NOT an NT Server"
255 static const true_false_string tfs_potentialb = {
256 "This is a Potential Browser",
257 "This is NOT a Potential Browser"
259 static const true_false_string tfs_backupb = {
260 "This is a Backup Browser",
261 "This is NOT a Backup Browser"
263 static const true_false_string tfs_masterb = {
264 "This is a Master Browser",
265 "This is NOT a Master Browser"
267 static const true_false_string tfs_domainmasterb = {
268 "This is a Domain Master Browser",
269 "This is NOT a Domain Master Browser"
271 static const true_false_string tfs_osf = {
272 "This is an OSF host",
273 "This is NOT an OSF host"
275 static const true_false_string tfs_vms = {
276 "This is a VMS host",
277 "This is NOT a VMS host"
279 static const true_false_string tfs_w95 = {
280 "This is a Windows 95 or above host",
281 "This is NOT a Windows 95 or above host"
283 static const true_false_string tfs_dfs = {
284 "This is a DFS server",
285 "THis is NOT a DFS server"
287 static const true_false_string tfs_local = {
288 "This is a local list only request",
289 "This is NOT a local list only request"
291 static const true_false_string tfs_domainenum = {
292 "This is a Domain Enum request",
293 "This is NOT a Domain Enum request"
296 #define DESIRE_BACKUP 0
297 #define DESIRE_STANDBY 1
298 #define DESIRE_MASTER 2
299 #define DESIRE_DOMAIN_MASTER 3
300 #define DESIRE_WINS 5
301 #define DESIRE_NT 7
303 static const true_false_string tfs_desire_backup = {
304 "Backup Browse Server",
305 "NOT Backup Browse Server"
307 static const true_false_string tfs_desire_standby = {
308 "Standby Browse Server",
309 "NOT Standby Browse Server"
311 static const true_false_string tfs_desire_master = {
312 "Master Browser",
313 "NOT Master Browser"
315 static const true_false_string tfs_desire_domain_master = {
316 "Domain Master Browse Server",
317 "NOT Domain Master Browse Server"
319 static const true_false_string tfs_desire_wins = {
320 "WINS Client",
321 "NOT WINS Client"
323 static const true_false_string tfs_desire_nt = {
324 "Windows NT Advanced Server",
325 "NOT Windows NT Advanced Server"
328 #define BROWSE_HOST_ANNOUNCE 1
329 #define BROWSE_REQUEST_ANNOUNCE 2
330 #define BROWSE_ELECTION_REQUEST 8
331 #define BROWSE_BACKUP_LIST_REQUEST 9
332 #define BROWSE_BACKUP_LIST_RESPONSE 10
333 #define BROWSE_BECOME_BACKUP 11
334 #define BROWSE_DOMAIN_ANNOUNCEMENT 12
335 #define BROWSE_MASTER_ANNOUNCEMENT 13
336 #define BROWSE_RESETBROWSERSTATE_ANNOUNCEMENT 14
337 #define BROWSE_LOCAL_MASTER_ANNOUNCEMENT 15
339 static const value_string commands[] = {
340 {BROWSE_HOST_ANNOUNCE, "Host Announcement"},
341 {BROWSE_REQUEST_ANNOUNCE, "Request Announcement"},
342 {BROWSE_ELECTION_REQUEST, "Browser Election Request"},
343 {BROWSE_BACKUP_LIST_REQUEST, "Get Backup List Request"},
344 {BROWSE_BACKUP_LIST_RESPONSE, "Get Backup List Response"},
345 {BROWSE_BECOME_BACKUP, "Become Backup Browser"},
346 {BROWSE_DOMAIN_ANNOUNCEMENT, "Domain/Workgroup Announcement"},
347 {BROWSE_MASTER_ANNOUNCEMENT, "Master Announcement"},
348 {BROWSE_RESETBROWSERSTATE_ANNOUNCEMENT, "Reset Browser State Announcement"},
349 {BROWSE_LOCAL_MASTER_ANNOUNCEMENT, "Local Master Announcement"},
350 {0, NULL}
353 #define OS_WFW 0
354 #define OS_NTW 4
355 #define OS_NTS 5
357 static const true_false_string tfs_os_wfw = {
358 "Windows for Workgroups",
359 "Not Windows for Workgroups"
361 static const true_false_string tfs_os_ntw = {
362 "Windows NT Workstation",
363 "Not Windows NT Workstation"
365 static const true_false_string tfs_os_nts = {
366 "Windows NT Server",
367 "Not Windows NT Server"
370 static void
371 dissect_election_criterion_os(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
373 static int * const flags[] = {
374 &hf_election_os_wfw,
375 &hf_election_os_ntw,
376 &hf_election_os_nts,
377 NULL
380 proto_tree_add_bitmask(parent_tree, tvb, offset, hf_election_os, ett_browse_election_os, flags, ENC_NA);
383 static void
384 dissect_election_criterion_desire(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
386 static int * const flags[] = {
387 &hf_election_desire_flags_backup,
388 &hf_election_desire_flags_standby,
389 &hf_election_desire_flags_master,
390 &hf_election_desire_flags_domain_master,
391 &hf_election_desire_flags_wins,
392 &hf_election_desire_flags_nt,
393 NULL
396 proto_tree_add_bitmask(parent_tree, tvb, offset, hf_election_desire, ett_browse_election_desire, flags, ENC_NA);
399 static void
400 dissect_election_criterion(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
402 proto_tree *tree = NULL;
403 proto_item *item = NULL;
404 uint32_t criterion;
406 criterion = tvb_get_letohl(tvb, offset);
408 if (parent_tree) {
409 item = proto_tree_add_uint(parent_tree, hf_election_criteria, tvb, offset, 4, criterion);
410 tree = proto_item_add_subtree(item, ett_browse_election_criteria);
413 /* election desire */
414 dissect_election_criterion_desire(tvb, tree, offset);
415 offset += 1;
417 /* browser protocol major version */
418 proto_tree_add_item(tree, hf_proto_major, tvb, offset, 1, ENC_LITTLE_ENDIAN);
419 offset += 1;
421 /* browser protocol minor version */
422 proto_tree_add_item(tree, hf_proto_minor, tvb, offset, 1, ENC_LITTLE_ENDIAN);
423 offset += 1;
425 /* election os */
426 dissect_election_criterion_os(tvb, tree, offset);
431 * XXX - this causes non-browser packets to have browser fields.
434 dissect_smb_server_type_flags(tvbuff_t *tvb, int offset, packet_info *pinfo,
435 proto_tree *parent_tree, uint8_t *drep,
436 bool infoflag)
438 uint32_t flags;
439 int i;
441 static int * const type_flags[] = {
442 &hf_server_type_workstation,
443 &hf_server_type_server,
444 &hf_server_type_sql,
445 &hf_server_type_domain,
446 &hf_server_type_backup,
447 &hf_server_type_time,
448 &hf_server_type_apple,
449 &hf_server_type_novell,
450 &hf_server_type_member,
451 &hf_server_type_print,
452 &hf_server_type_dialin,
453 &hf_server_type_xenix,
454 &hf_server_type_ntw,
455 &hf_server_type_wfw,
456 &hf_server_type_nts,
457 &hf_server_type_potentialb,
458 &hf_server_type_backupb,
459 &hf_server_type_masterb,
460 &hf_server_type_domainmasterb,
461 &hf_server_type_osf,
462 &hf_server_type_vms,
463 &hf_server_type_w95,
464 &hf_server_type_dfs,
465 &hf_server_type_local,
466 &hf_server_type_domainenum,
467 NULL
470 if (drep != NULL) {
472 * Called from a DCE RPC protocol dissector, for a
473 * protocol where a 32-bit NDR integer contains
474 * an server type mask; extract the server type mask
475 * with an NDR call (but don't put it into the
476 * protocol tree, as we can't get a pointer to the
477 * item it puts in, and thus can't put a tree below
478 * it with the values of the individual bits).
480 offset = dissect_ndr_uint32(
481 tvb, offset, pinfo, NULL, NULL, drep, hf_server_type, &flags);
482 } else {
484 * Called from SMB browser or RAP, where the server type
485 * mask is just a 4-byte little-endian quantity with no
486 * special NDR alignment requirement; extract it with
487 * "tvb_get_letohl()".
489 flags = tvb_get_letohl(tvb, offset);
490 offset += 4;
493 if (infoflag) {
494 /* Append the type(s) of the system to the COL_INFO line ... */
495 for (i = 0; i < 32; i++) {
496 if (flags & (1U<<i)) {
497 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
498 val_to_str(i, server_types,
499 "Unknown server type:%d"));
504 proto_tree_add_bitmask_value(parent_tree, tvb, offset-4,
505 hf_server_type, ett_browse_flags, type_flags, flags);
507 return offset;
510 #define HOST_NAME_LEN 16
512 static int
513 dissect_mailslot_browse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data _U_)
515 int offset = 0;
516 uint8_t cmd;
517 proto_tree *tree = NULL;
518 proto_item *item = NULL;
519 uint32_t periodicity;
520 uint8_t *host_name;
521 int namelen;
522 uint8_t server_count;
523 uint8_t os_major_ver, os_minor_ver;
524 const char *windows_version;
525 int i;
526 uint32_t uptime;
528 col_set_str(pinfo->cinfo, COL_PROTOCOL, "BROWSER");
529 col_clear(pinfo->cinfo, COL_INFO);
531 cmd = tvb_get_uint8(tvb, offset);
533 /* Put in something, and replace it later */
534 col_add_str(pinfo->cinfo, COL_INFO, val_to_str(cmd, commands, "Unknown command:0x%02x"));
537 item = proto_tree_add_item(parent_tree, proto_smb_browse, tvb, offset, -1, ENC_NA);
538 tree = proto_item_add_subtree(item, ett_browse);
540 /* command */
541 proto_tree_add_uint(tree, hf_command, tvb, offset, 1, cmd);
542 offset += 1;
544 switch (cmd) {
545 case BROWSE_DOMAIN_ANNOUNCEMENT:
546 case BROWSE_LOCAL_MASTER_ANNOUNCEMENT:
547 case BROWSE_HOST_ANNOUNCE: {
548 /* update count */
549 proto_tree_add_item(tree, hf_update_count, tvb, offset, 1, ENC_LITTLE_ENDIAN);
550 offset += 1;
552 /* periodicity (in milliseconds) */
553 periodicity = tvb_get_letohl(tvb, offset);
554 proto_tree_add_uint_format_value(tree, hf_periodicity, tvb, offset, 4,
555 periodicity,
556 "%s",
557 signed_time_msecs_to_str(pinfo->pool, periodicity));
558 offset += 4;
560 /* server name */
561 host_name = tvb_get_stringzpad(pinfo->pool, tvb, offset, HOST_NAME_LEN, ENC_CP437|ENC_NA);
562 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", host_name);
563 proto_tree_add_string_format(tree, hf_server_name,
564 tvb, offset, HOST_NAME_LEN,
565 host_name,
566 (cmd==BROWSE_DOMAIN_ANNOUNCEMENT)?
567 "Domain/Workgroup: %s":
568 "Host Name: %s",
569 host_name);
570 offset += HOST_NAME_LEN;
572 /* Windows version (See "OSVERSIONINFO Structure" on MSDN) */
573 os_major_ver = tvb_get_uint8(tvb, offset);
574 os_minor_ver = tvb_get_uint8(tvb, offset+1);
576 SET_WINDOWS_VERSION_STRING(os_major_ver, os_minor_ver, windows_version);
577 proto_tree_add_string(tree, hf_windows_version, tvb, offset, 2, windows_version);
579 /* OS major version */
580 proto_tree_add_item(tree, hf_os_major, tvb, offset, 1, ENC_LITTLE_ENDIAN);
581 offset += 1;
583 /* OS minor version */
584 proto_tree_add_item(tree, hf_os_minor, tvb, offset, 1, ENC_LITTLE_ENDIAN);
585 offset += 1;
587 /* server type flags */
588 offset = dissect_smb_server_type_flags(
589 tvb, offset, pinfo, tree, NULL, true);
591 if (cmd == BROWSE_DOMAIN_ANNOUNCEMENT && tvb_get_letohs (tvb, offset + 2) != 0xAA55) {
593 * Network Monitor claims this is a "Comment
594 * Pointer". I don't believe it.
596 * It's not a browser protocol major/minor
597 * version number, and signature constant,
598 * however.
600 proto_tree_add_item(tree, hf_mysterious_field, tvb, offset, 4, ENC_LITTLE_ENDIAN);
601 offset += 4;
602 } else {
603 /* browser protocol major version */
604 proto_tree_add_item(tree, hf_proto_major, tvb, offset, 1, ENC_LITTLE_ENDIAN);
605 offset += 1;
607 /* browser protocol minor version */
608 proto_tree_add_item(tree, hf_proto_minor, tvb, offset, 1, ENC_LITTLE_ENDIAN);
609 offset += 1;
611 /* signature constant */
612 proto_tree_add_item(tree, hf_sig_const, tvb, offset, 2, ENC_LITTLE_ENDIAN);
613 offset += 2;
616 /* master browser server name or server comment */
617 namelen = tvb_strsize(tvb, offset);
618 proto_tree_add_item(tree,
619 (cmd==BROWSE_DOMAIN_ANNOUNCEMENT)?
620 hf_mb_server_name : hf_server_comment,
621 tvb, offset, namelen, ENC_ASCII|ENC_NA);
622 break;
624 case BROWSE_REQUEST_ANNOUNCE: {
625 uint8_t *computer_name;
627 /* unused/unknown flags */
628 proto_tree_add_item(tree, hf_unused_flags,
629 tvb, offset, 1, ENC_LITTLE_ENDIAN);
630 offset += 1;
632 /* name of computer to which to send reply */
633 computer_name = tvb_get_stringz_enc(pinfo->pool, tvb, offset, &namelen, ENC_ASCII);
634 proto_tree_add_string(tree, hf_response_computer_name,
635 tvb, offset, namelen, computer_name);
636 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", computer_name);
637 break;
640 case BROWSE_ELECTION_REQUEST:
641 /* election version */
642 proto_tree_add_item(tree, hf_election_version, tvb, offset, 1, ENC_LITTLE_ENDIAN);
643 offset += 1;
645 /* criterion */
646 dissect_election_criterion(tvb, tree, offset);
647 offset += 4;
649 /* server uptime */
650 uptime = tvb_get_letohl(tvb, offset);
651 proto_tree_add_uint_format_value(tree, hf_server_uptime,
652 tvb, offset, 4, uptime,
653 "%s",
654 signed_time_msecs_to_str(pinfo->pool, uptime));
655 offset += 4;
657 /* next 4 bytes must be zero */
658 offset += 4;
660 /* server name */
661 namelen = tvb_strsize(tvb, offset);
662 proto_tree_add_item(tree, hf_server_name,
663 tvb, offset, namelen, ENC_ASCII);
664 break;
666 case BROWSE_BACKUP_LIST_REQUEST:
667 /* backup list requested count */
668 proto_tree_add_item(tree, hf_backup_count, tvb, offset, 1, ENC_LITTLE_ENDIAN);
669 offset += 1;
671 /* backup requested token */
672 proto_tree_add_item(tree, hf_backup_token, tvb, offset, 4, ENC_LITTLE_ENDIAN);
673 break;
675 case BROWSE_BACKUP_LIST_RESPONSE:
676 /* backup list requested count */
677 server_count = tvb_get_uint8(tvb, offset);
678 proto_tree_add_uint(tree, hf_backup_count, tvb, offset, 1,
679 server_count);
680 offset += 1;
682 /* backup requested token */
683 proto_tree_add_item(tree, hf_backup_token, tvb, offset, 4, ENC_LITTLE_ENDIAN);
684 offset += 4;
686 /* backup server names */
687 for (i = 0; i < server_count; i++) {
688 namelen = tvb_strsize(tvb, offset);
689 proto_tree_add_item(tree, hf_backup_server,
690 tvb, offset, namelen, ENC_ASCII);
691 offset += namelen;
693 break;
695 case BROWSE_MASTER_ANNOUNCEMENT:
696 /* master browser server name */
697 namelen = tvb_strsize(tvb, offset);
698 proto_tree_add_item(tree, hf_mb_server_name,
699 tvb, offset, namelen, ENC_ASCII);
700 break;
702 case BROWSE_RESETBROWSERSTATE_ANNOUNCEMENT: {
703 static int * const flags[] = {
704 &hf_mb_reset_demote,
705 &hf_mb_reset_flush,
706 &hf_mb_reset_stop,
707 NULL
710 proto_tree_add_bitmask(tree, tvb, offset, hf_mb_reset_command, ett_browse_reset_cmd_flags, flags, ENC_NA);
711 break;
714 case BROWSE_BECOME_BACKUP:
715 /* name of browser to promote */
716 namelen = tvb_strsize(tvb, offset);
717 proto_tree_add_item(tree, hf_browser_to_promote,
718 tvb, offset, namelen, ENC_ASCII);
719 break;
721 return tvb_captured_length(tvb);
725 * It appears that browser announcements sent to \MAILSLOT\LANMAN aren't
726 * the same as browser announcements sent to \MAILSLOT\BROWSE.
727 * Was that an older version of the protocol?
729 * The document at
731 * http://www.samba.org/samba/ftp/specs/brow_rev.txt
733 * gives both formats of host announcement packets, saying that
734 * "[The first] format seems wrong", that one being what appears to
735 * show up in \MAILSLOT\LANMAN packets, and that "[The second one]
736 * may be better", that one being what appears to show up in
737 * \MAILSLOT\BROWSE packets.
739 * XXX - what other browser packets go out to that mailslot?
741 static int
742 dissect_mailslot_lanman(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data _U_)
744 int offset = 0;
745 uint8_t cmd;
746 proto_tree *tree;
747 proto_item *item;
748 uint32_t periodicity;
749 const uint8_t *host_name;
750 uint8_t os_major_ver, os_minor_ver;
751 const char *windows_version;
752 unsigned namelen;
754 col_set_str(pinfo->cinfo, COL_PROTOCOL, "BROWSER");
755 col_clear(pinfo->cinfo, COL_INFO);
757 cmd = tvb_get_uint8(tvb, offset);
759 /* Put in something, and replace it later */
760 col_add_str(pinfo->cinfo, COL_INFO, val_to_str(cmd, commands, "Unknown command:0x%02x"));
762 item = proto_tree_add_item(parent_tree, proto_smb_browse, tvb, offset, -1, ENC_NA);
763 tree = proto_item_add_subtree(item, ett_browse);
765 /* command */
766 proto_tree_add_uint(tree, hf_command, tvb, offset, 1, cmd);
767 offset += 1;
769 switch (cmd) {
770 case BROWSE_DOMAIN_ANNOUNCEMENT:
771 case BROWSE_LOCAL_MASTER_ANNOUNCEMENT:
772 case BROWSE_HOST_ANNOUNCE:
773 /* update count */
774 proto_tree_add_item(tree, hf_update_count, tvb, offset, 1, ENC_LITTLE_ENDIAN);
775 offset += 1;
777 /* server type flags */
778 offset = dissect_smb_server_type_flags(
779 tvb, offset, pinfo, tree, NULL, true);
781 /* OS version string (See "OSVERSIONINFO Structure" on MSDN) */
782 os_major_ver = tvb_get_uint8(tvb, offset);
783 os_minor_ver = tvb_get_uint8(tvb, offset+1);
785 SET_WINDOWS_VERSION_STRING(os_major_ver, os_minor_ver, windows_version);
786 proto_tree_add_string(tree, hf_windows_version, tvb, offset, 2, windows_version);
788 /* OS major version */
789 proto_tree_add_item(tree, hf_os_major, tvb, offset, 1, ENC_LITTLE_ENDIAN);
790 offset += 1;
792 /* OS minor version */
793 proto_tree_add_item(tree, hf_os_minor, tvb, offset, 1, ENC_LITTLE_ENDIAN);
794 offset += 1;
796 /* periodicity (in seconds; convert to milliseconds) */
797 periodicity = tvb_get_letohs(tvb, offset)*1000;
798 proto_tree_add_uint_format_value(tree, hf_periodicity, tvb, offset, 2,
799 periodicity,
800 "%s",
801 signed_time_msecs_to_str(pinfo->pool, periodicity));
802 offset += 2;
804 /* server name */
805 host_name = tvb_get_stringz_enc(pinfo->pool, tvb, offset, &namelen, ENC_CP437|ENC_NA);
806 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", host_name);
808 proto_tree_add_item(tree, hf_server_name,
809 tvb, offset, namelen, ENC_ASCII);
810 offset += namelen;
812 /* master browser server name or server comment */
813 namelen = tvb_strsize(tvb, offset);
814 proto_tree_add_item(tree,
815 (cmd==BROWSE_DOMAIN_ANNOUNCEMENT)?
816 hf_mb_server_name : hf_server_comment,
817 tvb, offset, namelen, ENC_CP437|ENC_NA);
818 break;
820 return tvb_captured_length(tvb);
823 void
824 proto_register_smb_browse(void)
826 static hf_register_info hf[] = {
827 { &hf_command,
828 { "Command", "browser.command", FT_UINT8, BASE_HEX,
829 VALS(commands), 0, "Browse command opcode", HFILL }},
831 { &hf_update_count,
832 { "Update Count", "browser.update_count", FT_UINT8, BASE_DEC,
833 NULL, 0, "Browse Update Count", HFILL }},
835 { &hf_periodicity,
836 { "Update Periodicity", "browser.period", FT_UINT32, BASE_DEC,
837 NULL, 0, "Update Periodicity in ms", HFILL }},
839 { &hf_server_name,
840 { "Server Name", "browser.server", FT_STRING, BASE_NONE,
841 NULL, 0, "BROWSE Server Name", HFILL }},
843 { &hf_mb_server_name,
844 { "Master Browser Server Name", "browser.mb_server", FT_STRING, BASE_NONE,
845 NULL, 0, "BROWSE Master Browser Server Name", HFILL }},
847 { &hf_mb_reset_command,
848 { "ResetBrowserState Command", "browser.reset_cmd", FT_UINT8,
849 BASE_HEX, VALS(resetbrowserstate_command_names), 0,
850 NULL, HFILL }},
851 { &hf_mb_reset_demote,
852 { "Demote LMB", "browser.reset_cmd.demote", FT_BOOLEAN,
853 8, TFS(&tfs_demote_to_backup), 0x01, NULL, HFILL}},
854 { &hf_mb_reset_flush,
855 { "Flush Browse List", "browser.reset_cmd.flush", FT_BOOLEAN,
856 8, TFS(&tfs_flush_browse_list), 0x02, NULL, HFILL}},
857 { &hf_mb_reset_stop,
858 { "Stop Being LMB", "browser.reset_cmd.stop_lmb", FT_BOOLEAN,
859 8, TFS(&tfs_stop_being_lmb), 0x04, NULL, HFILL}},
860 { &hf_os_major,
861 { "OS Major Version", "browser.os_major", FT_UINT8, BASE_DEC,
862 NULL, 0, "Operating System Major Version", HFILL }},
864 { &hf_os_minor,
865 { "OS Minor Version", "browser.os_minor", FT_UINT8, BASE_DEC,
866 NULL, 0, "Operating System Minor Version", HFILL }},
868 { &hf_server_type,
869 { "Server Type", "browser.server_type", FT_UINT32, BASE_HEX,
870 NULL, 0, "Server Type Flags", HFILL }},
872 { &hf_server_type_workstation,
873 { "Workstation", "browser.server_type.workstation", FT_BOOLEAN, 32,
874 TFS(&tfs_workstation), 1U<<SERVER_WORKSTATION, "Is This A Workstation?", HFILL }},
876 { &hf_server_type_server,
877 { "Server", "browser.server_type.server", FT_BOOLEAN, 32,
878 TFS(&tfs_server), 1U<<SERVER_SERVER, "Is This A Server?", HFILL }},
880 { &hf_server_type_sql,
881 { "SQL", "browser.server_type.sql", FT_BOOLEAN, 32,
882 TFS(&tfs_sql), 1U<<SERVER_SQL_SERVER, "Is This A SQL Server?", HFILL }},
884 { &hf_server_type_domain,
885 { "Domain Controller", "browser.server_type.domain_controller", FT_BOOLEAN, 32,
886 TFS(&tfs_domain), 1U<<SERVER_DOMAIN_CONTROLLER, "Is This A Domain Controller?", HFILL }},
888 { &hf_server_type_backup,
889 { "Backup Controller", "browser.server_type.backup_controller", FT_BOOLEAN, 32,
890 TFS(&tfs_backup), 1U<<SERVER_BACKUP_CONTROLLER, "Is This A Backup Domain Controller?", HFILL }},
892 { &hf_server_type_time,
893 { "Time Source", "browser.server_type.time", FT_BOOLEAN, 32,
894 TFS(&tfs_time), 1U<<SERVER_TIME_SOURCE, "Is This A Time Source?", HFILL }},
896 { &hf_server_type_apple,
897 { "Apple", "browser.server_type.apple", FT_BOOLEAN, 32,
898 TFS(&tfs_apple), 1U<<SERVER_APPLE_SERVER, "Is This An Apple Server ?", HFILL }},
900 { &hf_server_type_novell,
901 { "Novell", "browser.server_type.novell", FT_BOOLEAN, 32,
902 TFS(&tfs_novell), 1U<<SERVER_NOVELL_SERVER, "Is This A Novell Server?", HFILL }},
904 { &hf_server_type_member,
905 { "Member", "browser.server_type.member", FT_BOOLEAN, 32,
906 TFS(&tfs_member), 1U<<SERVER_DOMAIN_MEMBER_SERVER, "Is This A Domain Member Server?", HFILL }},
908 { &hf_server_type_print,
909 { "Print", "browser.server_type.print", FT_BOOLEAN, 32,
910 TFS(&tfs_print), 1U<<SERVER_PRINT_QUEUE_SERVER, "Is This A Print Server?", HFILL }},
912 { &hf_server_type_dialin,
913 { "Dialin", "browser.server_type.dialin", FT_BOOLEAN, 32,
914 TFS(&tfs_dialin), 1U<<SERVER_DIALIN_SERVER, "Is This A Dialin Server?", HFILL }},
916 { &hf_server_type_xenix,
917 { "Xenix", "browser.server_type.xenix", FT_BOOLEAN, 32,
918 TFS(&tfs_xenix), 1U<<SERVER_XENIX_SERVER, "Is This A Xenix Server?", HFILL }},
920 { &hf_server_type_ntw,
921 { "NT Workstation", "browser.server_type.ntw", FT_BOOLEAN, 32,
922 TFS(&tfs_ntw), 1U<<SERVER_NT_WORKSTATION, "Is This A NT Workstation?", HFILL }},
924 { &hf_server_type_wfw,
925 { "WfW", "browser.server_type.wfw", FT_BOOLEAN, 32,
926 TFS(&tfs_wfw), 1U<<SERVER_WINDOWS_FOR_WORKGROUPS, "Is This A Windows For Workgroups Server?", HFILL }},
928 { &hf_server_type_nts,
929 { "NT Server", "browser.server_type.nts", FT_BOOLEAN, 32,
930 TFS(&tfs_nts), 1U<<SERVER_NT_SERVER, "Is This A NT Server?", HFILL }},
932 { &hf_server_type_potentialb,
933 { "Potential Browser", "browser.server_type.browser.potential", FT_BOOLEAN, 32,
934 TFS(&tfs_potentialb), 1U<<SERVER_POTENTIAL_BROWSER, "Is This A Potential Browser?", HFILL }},
936 { &hf_server_type_backupb,
937 { "Backup Browser", "browser.server_type.browser.backup", FT_BOOLEAN, 32,
938 TFS(&tfs_backupb), 1U<<SERVER_BACKUP_BROWSER, "Is This A Backup Browser?", HFILL }},
940 { &hf_server_type_masterb,
941 { "Master Browser", "browser.server_type.browser.master", FT_BOOLEAN, 32,
942 TFS(&tfs_masterb), 1U<<SERVER_MASTER_BROWSER, "Is This A Master Browser?", HFILL }},
944 { &hf_server_type_domainmasterb,
945 { "Domain Master Browser", "browser.server_type.browser.domain_master", FT_BOOLEAN, 32,
946 TFS(&tfs_domainmasterb), 1U<<SERVER_DOMAIN_MASTER_BROWSER, "Is This A Domain Master Browser?", HFILL }},
948 { &hf_server_type_osf,
949 { "OSF", "browser.server_type.osf", FT_BOOLEAN, 32,
950 TFS(&tfs_osf), 1U<<SERVER_OSF, "Is This An OSF server ?", HFILL }},
952 { &hf_server_type_vms,
953 { "VMS", "browser.server_type.vms", FT_BOOLEAN, 32,
954 TFS(&tfs_vms), 1U<<SERVER_VMS, "Is This A VMS Server?", HFILL }},
956 { &hf_server_type_w95,
957 { "Windows 95+", "browser.server_type.w95", FT_BOOLEAN, 32,
958 TFS(&tfs_w95), 1U<<SERVER_WINDOWS_95, "Is This A Windows 95 or above server?", HFILL }},
960 { &hf_server_type_dfs,
961 { "DFS", "browser.server_type.dfs", FT_BOOLEAN, 32,
962 TFS(&tfs_dfs), 1U<<SERVER_DFS_SERVER, "Is This A DFS server?", HFILL }},
964 { &hf_server_type_local,
965 { "Local", "browser.server_type.local", FT_BOOLEAN, 32,
966 TFS(&tfs_local), 1U<<SERVER_LOCAL_LIST_ONLY, "Is This A Local List Only request?", HFILL }},
968 { &hf_server_type_domainenum,
969 { "Domain Enum", "browser.server_type.domainenum", FT_BOOLEAN, 32,
970 TFS(&tfs_domainenum), 1U<<SERVER_DOMAIN_ENUM, "Is This A Domain Enum request?", HFILL }},
972 { &hf_election_version,
973 { "Election Version", "browser.election.version", FT_UINT8, BASE_DEC,
974 NULL, 0, NULL, HFILL }},
976 { &hf_proto_major,
977 { "Browser Protocol Major Version", "browser.proto_major", FT_UINT8, BASE_DEC,
978 NULL, 0, NULL, HFILL }},
980 { &hf_proto_minor,
981 { "Browser Protocol Minor Version", "browser.proto_minor", FT_UINT8, BASE_DEC,
982 NULL, 0, NULL, HFILL }},
984 { &hf_sig_const,
985 { "Signature", "browser.sig", FT_UINT16, BASE_HEX,
986 NULL, 0, "Signature Constant", HFILL }},
988 { &hf_server_comment,
989 { "Host Comment", "browser.comment", FT_STRINGZ, BASE_NONE,
990 NULL, 0, "Server Comment", HFILL }},
992 { &hf_unused_flags,
993 { "Unused flags", "browser.unused", FT_UINT8, BASE_HEX,
994 NULL, 0, "Unused/unknown flags", HFILL }},
996 { &hf_response_computer_name,
997 { "Response Computer Name", "browser.response_computer_name", FT_STRINGZ, BASE_NONE,
998 NULL, 0, NULL, HFILL }},
1000 { &hf_election_criteria,
1001 { "Election Criteria", "browser.election.criteria", FT_UINT32, BASE_HEX,
1002 NULL, 0, NULL, HFILL }},
1004 { &hf_election_desire,
1005 { "Election Desire", "browser.election.desire", FT_UINT8, BASE_HEX,
1006 NULL, 0, NULL, HFILL }},
1008 { &hf_election_desire_flags_backup,
1009 { "Backup", "browser.election.desire.backup", FT_BOOLEAN, 8,
1010 TFS(&tfs_desire_backup), 1U<<DESIRE_BACKUP, "Is this a backup server", HFILL }},
1012 { &hf_election_desire_flags_standby,
1013 { "Standby", "browser.election.desire.standby", FT_BOOLEAN, 8,
1014 TFS(&tfs_desire_standby), 1U<<DESIRE_STANDBY, "Is this a standby server?", HFILL }},
1016 { &hf_election_desire_flags_master,
1017 { "Master", "browser.election.desire.master", FT_BOOLEAN, 8,
1018 TFS(&tfs_desire_master), 1U<<DESIRE_MASTER, "Is this a master server", HFILL }},
1020 { &hf_election_desire_flags_domain_master,
1021 { "Domain Master", "browser.election.desire.domain_master", FT_BOOLEAN, 8,
1022 TFS(&tfs_desire_domain_master), 1U<<DESIRE_DOMAIN_MASTER, "Is this a domain master", HFILL }},
1024 { &hf_election_desire_flags_wins,
1025 { "WINS", "browser.election.desire.wins", FT_BOOLEAN, 8,
1026 TFS(&tfs_desire_wins), 1U<<DESIRE_WINS, "Is this a WINS server", HFILL }},
1028 { &hf_election_desire_flags_nt,
1029 { "NT", "browser.election.desire.nt", FT_BOOLEAN, 8,
1030 TFS(&tfs_desire_nt), 1U<<DESIRE_NT, "Is this a NT server", HFILL }},
1032 #if 0
1033 { &hf_election_revision,
1034 { "Election Revision", "browser.election.revision", FT_UINT16, BASE_DEC,
1035 NULL, 0, NULL, HFILL }},
1036 #endif
1038 { &hf_election_os,
1039 { "Election OS", "browser.election.os", FT_UINT8, BASE_HEX,
1040 NULL, 0, NULL, HFILL }},
1042 { &hf_election_os_wfw,
1043 { "WfW", "browser.election.os.wfw", FT_BOOLEAN, 8,
1044 TFS(&tfs_os_wfw), 1U<<OS_WFW, "Is this a WfW host?", HFILL }},
1046 { &hf_election_os_ntw,
1047 { "NT Workstation", "browser.election.os.ntw", FT_BOOLEAN, 8,
1048 TFS(&tfs_os_ntw), 1U<<OS_NTW, "Is this a NT Workstation?", HFILL }},
1050 { &hf_election_os_nts,
1051 { "NT Server", "browser.election.os.nts", FT_BOOLEAN, 8,
1052 TFS(&tfs_os_nts), 1U<<OS_NTS, "Is this a NT Server?", HFILL }},
1054 { &hf_server_uptime,
1055 { "Uptime", "browser.uptime", FT_UINT32, BASE_DEC,
1056 NULL, 0, "Server uptime in ms", HFILL }},
1058 { &hf_backup_count,
1059 { "Backup List Requested Count", "browser.backup.count", FT_UINT8, BASE_DEC,
1060 NULL, 0, NULL, HFILL }},
1062 { &hf_backup_token,
1063 { "Backup Request Token", "browser.backup.token", FT_UINT32, BASE_DEC,
1064 NULL, 0, "Backup requested/response token", HFILL }},
1066 { &hf_backup_server,
1067 { "Backup Server", "browser.backup.server", FT_STRING, BASE_NONE,
1068 NULL, 0, "Backup Server Name", HFILL }},
1070 { &hf_browser_to_promote,
1071 { "Browser to Promote", "browser.browser_to_promote", FT_STRINGZ, BASE_NONE,
1072 NULL, 0, NULL, HFILL }},
1074 { &hf_windows_version,
1075 { "Windows version", "browser.windows_version", FT_STRING, BASE_NONE,
1076 NULL, 0, NULL, HFILL }},
1078 { &hf_mysterious_field,
1079 { "Mysterious Field", "browser.mysterious_field", FT_UINT32, BASE_HEX,
1080 NULL, 0, NULL, HFILL }},
1083 static int *ett[] = {
1084 &ett_browse,
1085 &ett_browse_flags,
1086 &ett_browse_election_criteria,
1087 &ett_browse_election_os,
1088 &ett_browse_election_desire,
1089 &ett_browse_reset_cmd_flags,
1092 proto_smb_browse = proto_register_protocol("Microsoft Windows Browser Protocol",
1093 "BROWSER", "browser");
1095 proto_register_field_array(proto_smb_browse, hf, array_length(hf));
1096 proto_register_subtree_array(ett, array_length(ett));
1098 register_dissector("mailslot_browse", dissect_mailslot_browse,
1099 proto_smb_browse);
1100 register_dissector("mailslot_lanman", dissect_mailslot_lanman,
1101 proto_smb_browse);
1105 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1107 * Local variables:
1108 * c-basic-offset: 8
1109 * tab-width: 8
1110 * indent-tabs-mode: t
1111 * End:
1113 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1114 * :indentSize=8:tabSize=8:noTabs=false: