4 * Routines for WINS Replication packet dissection
6 * Copyright 2005 Stefan Metzmacher <metze@samba.org>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * SPDX-License-Identifier: GPL-2.0-or-later
17 #include <epan/packet.h>
18 #include <epan/expert.h>
19 #include <epan/exceptions.h>
20 #include <epan/prefs.h>
21 #include <epan/to_str.h>
23 #include "packet-netbios.h"
25 #include "packet-tcp.h"
27 void proto_register_winsrepl(void);
28 void proto_reg_handoff_winsrepl(void);
29 static dissector_handle_t winsrepl_handle
;
31 static bool winsrepl_reassemble
= true;
33 static int proto_winsrepl
;
35 static int hf_winsrepl_size
;
36 static int hf_winsrepl_opcode
;
37 static int hf_winsrepl_assoc_ctx
;
38 static int hf_winsrepl_mess_type
;
40 static int hf_winsrepl_start_minor_version
;
41 static int hf_winsrepl_start_major_version
;
43 static int hf_winsrepl_stop_reason
;
45 static int hf_winsrepl_replication_command
;
47 static int hf_winsrepl_owner_address
;
48 static int hf_winsrepl_owner_max_version
;
49 static int hf_winsrepl_owner_min_version
;
50 static int hf_winsrepl_owner_type
;
52 static int hf_winsrepl_table_partner_count
;
53 static int hf_winsrepl_table_initiator
;
55 static int hf_winsrepl_ip_owner
;
56 static int hf_winsrepl_ip_ip
;
57 static int hf_winsrepl_addr_list_num_ips
;
59 static int hf_winsrepl_name_len
;
60 static int hf_winsrepl_name_flags
;
61 static int hf_winsrepl_name_flags_rectype
;
62 static int hf_winsrepl_name_flags_recstate
;
63 static int hf_winsrepl_name_flags_local
;
64 static int hf_winsrepl_name_flags_hosttype
;
65 static int hf_winsrepl_name_flags_static
;
66 static int hf_winsrepl_name_group_flag
;
67 static int hf_winsrepl_name_version_id
;
68 static int hf_winsrepl_name_unknown
;
70 static int hf_winsrepl_reply_num_names
;
72 static int ett_winsrepl
;
74 static int ett_winsrepl_start
;
75 static int ett_winsrepl_stop
;
76 static int ett_winsrepl_replication
;
78 static int ett_winsrepl_owner
;
79 static int ett_winsrepl_table_reply
;
81 static int ett_winsrepl_ip
;
82 static int ett_winsrepl_addr_list
;
84 static int ett_winsrepl_name
;
85 static int ett_winsrepl_send_reply
;
87 static int ett_winsrepl_flags
;
89 static expert_field ei_winsrepl_name_len
;
91 #define WINS_REPLICATION_PORT ( 42 )
92 #define WREPL_OPCODE_BITS ( 0x7800 )
94 enum wrepl_replication_cmd
{
95 WREPL_REPL_TABLE_QUERY
=0,
96 WREPL_REPL_TABLE_REPLY
=1,
97 WREPL_REPL_SEND_REQUEST
=2,
98 WREPL_REPL_SEND_REPLY
=3,
100 WREPL_REPL_UPDATE2
=5,
105 enum wrepl_mess_type
{
106 WREPL_START_ASSOCIATION
=0,
107 WREPL_START_ASSOCIATION_REPLY
=1,
108 WREPL_STOP_ASSOCIATION
=2,
112 static const value_string replication_cmd_vals
[] = {
113 {WREPL_REPL_TABLE_QUERY
, "WREPL_REPL_TABLE_QUERY"},
114 {WREPL_REPL_TABLE_REPLY
, "WREPL_REPL_TABLE_REPLY"},
115 {WREPL_REPL_SEND_REQUEST
, "WREPL_REPL_SEND_REQUEST"},
116 {WREPL_REPL_SEND_REPLY
, "WREPL_REPL_SEND_REPLY"},
117 {WREPL_REPL_UPDATE
, "WREPL_REPL_UPDATE"},
118 {WREPL_REPL_UPDATE2
, "WREPL_REPL_UPDATE2"},
119 {WREPL_REPL_INFORM
, "WREPL_REPL_INFORM"},
120 {WREPL_REPL_INFORM2
, "WREPL_REPL_INFORM2"},
124 static const value_string message_type_vals
[] = {
125 {WREPL_START_ASSOCIATION
, "WREPL_START_ASSOCIATION"},
126 {WREPL_START_ASSOCIATION_REPLY
, "WREPL_START_ASSOCIATION_REPLY"},
127 {WREPL_STOP_ASSOCIATION
, "WREPL_STOP_ASSOCIATION"},
128 {WREPL_REPLICATION
, "WREPL_REPLICATION"},
132 #define WREPL_NAME_TYPE_MASK 0x03
134 #define WREPL_NAME_TYPE_UNIQUE 0x00
135 #define WREPL_NAME_TYPE_NORMAL_GROUP 0x01
136 #define WREPL_NAME_TYPE_SPECIAL_GROUP 0x02
137 #define WREPL_NAME_TYPE_MULTIHOMED 0x03
139 static const value_string rectype_vals
[] = {
140 {WREPL_NAME_TYPE_UNIQUE
, "Unique"},
141 {WREPL_NAME_TYPE_NORMAL_GROUP
, "Normal group"},
142 {WREPL_NAME_TYPE_SPECIAL_GROUP
, "Special group"},
143 {WREPL_NAME_TYPE_MULTIHOMED
, "Multihomed"},
147 static const value_string recstate_vals
[] = {
150 {0x02, "Tombstoned"},
155 static const value_string hosttype_vals
[] = {
164 dissect_winsrepl_start(tvbuff_t
*winsrepl_tvb
, _U_ packet_info
*pinfo
,
165 int winsrepl_offset
, proto_tree
*winsrepl_tree
)
167 proto_tree
*start_tree
;
169 start_tree
= proto_tree_add_subtree(winsrepl_tree
, winsrepl_tvb
, winsrepl_offset
, -1,
170 ett_winsrepl_start
, NULL
, "WREPL_START_ASSOCIATION");
173 proto_tree_add_item(start_tree
, hf_winsrepl_assoc_ctx
, winsrepl_tvb
, winsrepl_offset
, 4, ENC_BIG_ENDIAN
);
174 winsrepl_offset
+= 4;
177 proto_tree_add_item(start_tree
, hf_winsrepl_start_minor_version
, winsrepl_tvb
, winsrepl_offset
, 2, ENC_BIG_ENDIAN
);
178 winsrepl_offset
+= 2;
181 proto_tree_add_item(start_tree
, hf_winsrepl_start_major_version
, winsrepl_tvb
, winsrepl_offset
, 2, ENC_BIG_ENDIAN
);
182 winsrepl_offset
+= 2;
184 return winsrepl_offset
;
188 dissect_winsrepl_stop(tvbuff_t
*winsrepl_tvb
, _U_ packet_info
*pinfo
,
189 int winsrepl_offset
, proto_tree
*winsrepl_tree
)
192 proto_item
*stop_item
;
193 proto_tree
*stop_tree
;
195 stop_tree
= proto_tree_add_subtree(winsrepl_tree
, winsrepl_tvb
, winsrepl_offset
, -1,
196 ett_winsrepl_stop
, &stop_item
, "WREPL_STOP_ASSOCIATION");
199 reason
= tvb_get_ntohl(winsrepl_tvb
, winsrepl_offset
);
200 proto_tree_add_uint(stop_tree
, hf_winsrepl_stop_reason
, winsrepl_tvb
, winsrepl_offset
, 4, reason
);
201 winsrepl_offset
+= 4;
203 proto_item_append_text(stop_item
, ", Reason: 0x%08X", reason
);
205 return winsrepl_offset
;
209 dissect_winsrepl_table_query(tvbuff_t
*winsrepl_tvb _U_
, packet_info
*pinfo _U_
,
210 int winsrepl_offset
, proto_tree
*winsrepl_tree _U_
)
212 /* Nothing to do here */
213 return winsrepl_offset
;
217 dissect_winsrepl_wins_owner(tvbuff_t
*winsrepl_tvb
, _U_ packet_info
*pinfo
,
218 int winsrepl_offset
, proto_tree
*winsrepl_tree
,
219 proto_tree
*sub_tree
, uint32_t idx
)
221 proto_tree
*owner_tree
= NULL
;
224 owner_tree
= proto_tree_add_subtree_format(sub_tree
, winsrepl_tvb
, winsrepl_offset
, 24,
225 ett_winsrepl_owner
, NULL
, "WINS Owner [%u]", idx
);
226 } else if (winsrepl_tree
) {
227 owner_tree
= proto_tree_add_subtree(winsrepl_tree
, winsrepl_tvb
, winsrepl_offset
, 24,
228 ett_winsrepl_owner
, NULL
, "WINS Owner");
232 proto_tree_add_item(owner_tree
, hf_winsrepl_owner_address
, winsrepl_tvb
, winsrepl_offset
, 4, ENC_BIG_ENDIAN
);
233 winsrepl_offset
+= 4;
236 proto_tree_add_item(owner_tree
, hf_winsrepl_owner_max_version
, winsrepl_tvb
, winsrepl_offset
, 8, ENC_BIG_ENDIAN
);
237 winsrepl_offset
+= 8;
240 proto_tree_add_item(owner_tree
, hf_winsrepl_owner_min_version
, winsrepl_tvb
, winsrepl_offset
, 8, ENC_BIG_ENDIAN
);
241 winsrepl_offset
+= 8;
244 proto_tree_add_item(owner_tree
, hf_winsrepl_owner_type
, winsrepl_tvb
, winsrepl_offset
, 4, ENC_BIG_ENDIAN
);
245 winsrepl_offset
+= 4;
247 return winsrepl_offset
;
251 dissect_winsrepl_table_reply(tvbuff_t
*winsrepl_tvb
, packet_info
*pinfo
,
252 int winsrepl_offset
, proto_tree
*winsrepl_tree
)
254 proto_tree
*table_tree
;
255 uint32_t partner_count
;
258 table_tree
= proto_tree_add_subtree(winsrepl_tree
, winsrepl_tvb
, winsrepl_offset
, -1,
259 ett_winsrepl_table_reply
, NULL
, "WREPL_REPL_TABLE_REPLY");
262 partner_count
= tvb_get_ntohl(winsrepl_tvb
, winsrepl_offset
);
263 proto_tree_add_uint(table_tree
, hf_winsrepl_table_partner_count
, winsrepl_tvb
, winsrepl_offset
, 4, partner_count
);
264 winsrepl_offset
+= 4;
266 for (i
=0; i
< partner_count
; i
++) {
267 winsrepl_offset
= dissect_winsrepl_wins_owner(winsrepl_tvb
, pinfo
,
268 winsrepl_offset
, table_tree
,
273 proto_tree_add_item(table_tree
, hf_winsrepl_table_initiator
, winsrepl_tvb
, winsrepl_offset
, 4, ENC_BIG_ENDIAN
);
274 winsrepl_offset
+= 4;
276 return winsrepl_offset
;
280 dissect_winsrepl_send_request(tvbuff_t
*winsrepl_tvb
, packet_info
*pinfo
,
281 int winsrepl_offset
, proto_tree
*winsrepl_tree
)
283 winsrepl_offset
= dissect_winsrepl_wins_owner(winsrepl_tvb
, pinfo
,
284 winsrepl_offset
, winsrepl_tree
,
287 return winsrepl_offset
;
291 dissect_winsrepl_wins_ip(tvbuff_t
*winsrepl_tvb
, _U_ packet_info
*pinfo
,
292 int winsrepl_offset
, proto_tree
*winsrepl_tree
,
293 uint32_t *addr
, proto_tree
*sub_tree
, uint32_t idx
)
295 proto_item
*ip_item
= NULL
;
296 proto_tree
*ip_tree
= NULL
;
299 ip_tree
= proto_tree_add_subtree_format(sub_tree
, winsrepl_tvb
, winsrepl_offset
, 8,
300 ett_winsrepl_ip
, &ip_item
, "WINS IP [%u]", idx
);
301 } else if (winsrepl_tree
) {
302 ip_tree
= proto_tree_add_subtree(winsrepl_tree
, winsrepl_tvb
, winsrepl_offset
, 8,
303 ett_winsrepl_ip
, &ip_item
, "WINS IP");
307 proto_tree_add_item(ip_tree
, hf_winsrepl_ip_owner
, winsrepl_tvb
, winsrepl_offset
, 4, ENC_BIG_ENDIAN
);
308 winsrepl_offset
+= 4;
311 *addr
= tvb_get_ipv4(winsrepl_tvb
, winsrepl_offset
);
312 proto_tree_add_ipv4(ip_tree
, hf_winsrepl_ip_ip
, winsrepl_tvb
, winsrepl_offset
, 4, *addr
);
313 proto_item_append_text(ip_item
, ": %s", tvb_ip_to_str(pinfo
->pool
, winsrepl_tvb
, winsrepl_offset
));
314 winsrepl_offset
+= 4;
316 return winsrepl_offset
;
320 dissect_winsrepl_wins_address_list(tvbuff_t
*winsrepl_tvb
, packet_info
*pinfo
,
321 int winsrepl_offset
, proto_tree
*winsrepl_tree
,
322 proto_item
*parent_item
)
324 proto_item
*addr_list_item
;
325 proto_tree
*addr_list_tree
;
326 int old_offset
= winsrepl_offset
;
333 addr_list_tree
= proto_tree_add_subtree(winsrepl_tree
, winsrepl_tvb
, winsrepl_offset
, -1,
334 ett_winsrepl_addr_list
, &addr_list_item
, "WINS Address List");
337 num_ips
= tvb_get_letohl(winsrepl_tvb
, winsrepl_offset
);
338 proto_tree_add_uint(addr_list_tree
, hf_winsrepl_addr_list_num_ips
, winsrepl_tvb
, winsrepl_offset
, 4, num_ips
);
339 winsrepl_offset
+= 4;
341 for (i
=0; i
< num_ips
; i
++) {
342 winsrepl_offset
= dissect_winsrepl_wins_ip(winsrepl_tvb
, pinfo
,
343 winsrepl_offset
, addr_list_tree
,
344 &ip
, addr_list_tree
, i
);
345 set_address(&addr
, AT_IPv4
, 4, &ip
);
346 addr_str
= address_to_str(pinfo
->pool
, &addr
);
348 proto_item_append_text(parent_item
, ": %s", addr_str
);
349 proto_item_append_text(addr_list_item
, ": %s", addr_str
);
351 proto_item_append_text(parent_item
, ", %s", addr_str
);
352 proto_item_append_text(addr_list_item
, ", %s", addr_str
);
356 proto_item_set_len(addr_list_item
, winsrepl_offset
- old_offset
);
358 return winsrepl_offset
;
362 dissect_winsrepl_wins_name(tvbuff_t
*winsrepl_tvb
, packet_info
*pinfo
,
363 int winsrepl_offset
, proto_tree
*winsrepl_tree
,
364 proto_tree
*sub_tree
, uint32_t idx
)
366 proto_item
*name_item
= NULL
, *ti
;
367 proto_tree
*name_tree
= NULL
;
368 int old_offset
= winsrepl_offset
;
369 tvbuff_t
*name_tvb
= NULL
;
371 char name_str
[(NETBIOS_NAME_LEN
- 1)*4 + 1];
374 static int * const name_flags
[] = {
375 &hf_winsrepl_name_flags_rectype
,
376 &hf_winsrepl_name_flags_recstate
,
377 &hf_winsrepl_name_flags_local
,
378 &hf_winsrepl_name_flags_hosttype
,
379 &hf_winsrepl_name_flags_static
,
384 name_tree
= proto_tree_add_subtree_format(sub_tree
, winsrepl_tvb
, winsrepl_offset
, -1,
385 ett_winsrepl_name
, &name_item
, "WINS Name [%u]", idx
);
386 } else if (winsrepl_tree
) {
387 name_tree
= proto_tree_add_subtree(winsrepl_tree
, winsrepl_tvb
, winsrepl_offset
, -1,
388 ett_winsrepl_name
, &name_item
, "WINS Name");
392 name_len
= tvb_get_ntohl(winsrepl_tvb
, winsrepl_offset
);
393 ti
= proto_tree_add_uint(name_tree
, hf_winsrepl_name_len
, winsrepl_tvb
, winsrepl_offset
, 4, name_len
);
394 winsrepl_offset
+= 4;
396 expert_add_info(pinfo
, ti
, &ei_winsrepl_name_len
);
397 return winsrepl_offset
;
402 * XXX - apparently, according to the Samba code for handling
403 * WINS replication, there's a bug in a lot of versions of Windows,
404 * including W2K SP2, wherein the first and last bytes of the
405 * name (the last byte being the name type) are swapped if
406 * the type is 0x1b. I think I've seen this in at least
409 name_tvb
= tvb_new_subset_length(winsrepl_tvb
, winsrepl_offset
, name_len
);
410 netbios_add_name("Name", name_tvb
, 0, name_tree
);
411 name_type
= get_netbios_name(name_tvb
, 0, name_str
, (NETBIOS_NAME_LEN
- 1)*4 + 1);
412 proto_item_append_text(name_item
, ": %s<%02x>", name_str
, name_type
);
413 winsrepl_offset
+= name_len
;
415 /* ALIGN to 4 Byte */
416 /* winsrepl_offset += ((winsrepl_offset & (4-1)) == 0 ? 0 : (4 - (winsrepl_offset & (4-1)))); */
417 /* Windows including w2k8 add 4 padding bytes, when it's already 4 byte
418 * aligned... This happens when the name has a "scope" part
420 winsrepl_offset
+= 4 - (winsrepl_offset
& (4-1));
424 * XXX - there appear to be more flag bits, but I didn't see
425 * anything in the Samba code about them.
427 flags
= tvb_get_ntohl(winsrepl_tvb
, winsrepl_offset
);
428 proto_tree_add_bitmask(name_tree
, winsrepl_tvb
, winsrepl_offset
, hf_winsrepl_name_flags
, ett_winsrepl_flags
, name_flags
, ENC_BIG_ENDIAN
);
429 winsrepl_offset
+= 4;
432 /* XXX - is this just a Boolean? */
433 proto_tree_add_item(name_tree
, hf_winsrepl_name_group_flag
, winsrepl_tvb
, winsrepl_offset
, 4, ENC_LITTLE_ENDIAN
);
434 winsrepl_offset
+= 4;
437 proto_tree_add_item(name_tree
, hf_winsrepl_name_version_id
, winsrepl_tvb
, winsrepl_offset
, 8, ENC_BIG_ENDIAN
);
438 winsrepl_offset
+= 8;
440 switch (flags
& WREPL_NAME_TYPE_MASK
) {
442 case WREPL_NAME_TYPE_UNIQUE
:
443 case WREPL_NAME_TYPE_NORMAL_GROUP
:
445 proto_tree_add_item(name_tree
, hf_winsrepl_ip_ip
, winsrepl_tvb
, winsrepl_offset
, 4, ENC_BIG_ENDIAN
);
446 proto_item_append_text(name_item
, ": %s", tvb_ip_to_str(pinfo
->pool
, winsrepl_tvb
, winsrepl_offset
));
447 winsrepl_offset
+= 4;
450 case WREPL_NAME_TYPE_SPECIAL_GROUP
:
451 case WREPL_NAME_TYPE_MULTIHOMED
:
453 winsrepl_offset
= dissect_winsrepl_wins_address_list(winsrepl_tvb
, pinfo
,
454 winsrepl_offset
, name_tree
,
459 /* UNKNOWN, little or big endian??? */
460 proto_tree_add_item(name_tree
, hf_winsrepl_name_unknown
, winsrepl_tvb
, winsrepl_offset
, 4, ENC_BIG_ENDIAN
);
461 winsrepl_offset
+= 4;
463 proto_item_set_len(name_item
, winsrepl_offset
- old_offset
);
465 return winsrepl_offset
;
469 dissect_winsrepl_send_reply(tvbuff_t
*winsrepl_tvb
, packet_info
*pinfo
,
470 int winsrepl_offset
, proto_tree
*winsrepl_tree
)
472 proto_tree
*rep_tree
;
476 rep_tree
= proto_tree_add_subtree(winsrepl_tree
, winsrepl_tvb
, winsrepl_offset
, -1,
477 ett_winsrepl_send_reply
, NULL
, "WREPL_REPL_SEND_REPLY");
480 num_names
= tvb_get_ntohl(winsrepl_tvb
, winsrepl_offset
);
481 proto_tree_add_uint(rep_tree
, hf_winsrepl_reply_num_names
, winsrepl_tvb
, winsrepl_offset
, 4, num_names
);
482 winsrepl_offset
+= 4;
484 for (i
=0; i
< num_names
; i
++) {
485 winsrepl_offset
= dissect_winsrepl_wins_name(winsrepl_tvb
, pinfo
,
486 winsrepl_offset
, rep_tree
,
490 return winsrepl_offset
;
494 dissect_winsrepl_update(tvbuff_t
*winsrepl_tvb
, packet_info
*pinfo
,
495 int winsrepl_offset
, proto_tree
*winsrepl_tree
)
497 winsrepl_offset
= dissect_winsrepl_table_reply(winsrepl_tvb
, pinfo
,
498 winsrepl_offset
, winsrepl_tree
);
499 return winsrepl_offset
;
503 dissect_winsrepl_update2(tvbuff_t
*winsrepl_tvb
, packet_info
*pinfo
,
504 int winsrepl_offset
, proto_tree
*winsrepl_tree
)
506 winsrepl_offset
= dissect_winsrepl_table_reply(winsrepl_tvb
, pinfo
,
507 winsrepl_offset
, winsrepl_tree
);
508 return winsrepl_offset
;
512 dissect_winsrepl_inform(tvbuff_t
*winsrepl_tvb
, packet_info
*pinfo
,
513 int winsrepl_offset
, proto_tree
*winsrepl_tree
)
515 winsrepl_offset
= dissect_winsrepl_table_reply(winsrepl_tvb
, pinfo
,
516 winsrepl_offset
, winsrepl_tree
);
517 return winsrepl_offset
;
521 dissect_winsrepl_inform2(tvbuff_t
*winsrepl_tvb
, packet_info
*pinfo
,
522 int winsrepl_offset
, proto_tree
*winsrepl_tree
)
524 winsrepl_offset
= dissect_winsrepl_table_reply(winsrepl_tvb
, pinfo
,
525 winsrepl_offset
, winsrepl_tree
);
526 return winsrepl_offset
;
530 dissect_winsrepl_replication(tvbuff_t
*winsrepl_tvb
, packet_info
*pinfo
,
531 int winsrepl_offset
, proto_item
*winsrepl_item
, proto_tree
*winsrepl_tree
)
533 proto_item
*repl_item
;
534 proto_tree
*repl_tree
;
535 enum wrepl_replication_cmd command
;
537 repl_tree
= proto_tree_add_subtree(winsrepl_tree
, winsrepl_tvb
, winsrepl_offset
, -1,
538 ett_winsrepl_replication
, &repl_item
, "WREPL_REPLICATION");
540 /* REPLICATION_CMD */
541 command
= (enum wrepl_replication_cmd
)tvb_get_ntohl(winsrepl_tvb
, winsrepl_offset
);
542 proto_tree_add_uint(repl_tree
, hf_winsrepl_replication_command
, winsrepl_tvb
, winsrepl_offset
, 4, command
);
543 winsrepl_offset
+= 4;
546 case WREPL_REPL_TABLE_QUERY
:
547 col_set_str(pinfo
->cinfo
, COL_INFO
, "WREPL_REPL_TABLE_QUERY");
548 proto_item_append_text(winsrepl_item
, ", WREPL_REPL_TABLE_QUERY");
549 proto_item_append_text(repl_item
, ", WREPL_REPL_TABLE_QUERY");
550 winsrepl_offset
= dissect_winsrepl_table_query(winsrepl_tvb
, pinfo
,
551 winsrepl_offset
, repl_tree
);
553 case WREPL_REPL_TABLE_REPLY
:
554 col_set_str(pinfo
->cinfo
, COL_INFO
, "WREPL_REPL_TABLE_REPLY");
555 proto_item_append_text(winsrepl_item
, ", WREPL_REPL_TABLE_REPLY");
556 proto_item_append_text(repl_item
, ", WREPL_REPL_TABLE_REPLY");
557 winsrepl_offset
= dissect_winsrepl_table_reply(winsrepl_tvb
, pinfo
,
558 winsrepl_offset
, repl_tree
);
560 case WREPL_REPL_SEND_REQUEST
:
561 col_set_str(pinfo
->cinfo
, COL_INFO
, "WREPL_REPL_SEND_REQUEST");
562 proto_item_append_text(winsrepl_item
, ", WREPL_REPL_SEND_REQUEST");
563 proto_item_append_text(repl_item
, ", WREPL_REPL_SEND_REQUEST");
564 winsrepl_offset
= dissect_winsrepl_send_request(winsrepl_tvb
, pinfo
,
565 winsrepl_offset
, repl_tree
);
567 case WREPL_REPL_SEND_REPLY
:
568 col_set_str(pinfo
->cinfo
, COL_INFO
, "WREPL_REPL_SEND_REPLY");
569 proto_item_append_text(winsrepl_item
, ", WREPL_REPL_SEND_REPLY");
570 proto_item_append_text(repl_item
, ", WREPL_REPL_SEND_REPLY");
571 winsrepl_offset
= dissect_winsrepl_send_reply(winsrepl_tvb
, pinfo
,
572 winsrepl_offset
, repl_tree
);
574 case WREPL_REPL_UPDATE
:
575 col_set_str(pinfo
->cinfo
, COL_INFO
, "WREPL_REPL_UPDATE");
576 proto_item_append_text(winsrepl_item
, ", WREPL_REPL_UPDATE");
577 proto_item_append_text(repl_item
, ", WREPL_REPL_UPDATE");
578 winsrepl_offset
= dissect_winsrepl_update(winsrepl_tvb
, pinfo
,
579 winsrepl_offset
, repl_tree
);
581 case WREPL_REPL_UPDATE2
:
582 col_set_str(pinfo
->cinfo
, COL_INFO
, "WREPL_REPL_UPDATE2");
583 proto_item_append_text(winsrepl_item
, ",WREPL_REPL_UPDATE2");
584 proto_item_append_text(repl_item
, ",WREPL_REPL_UPDATE2");
585 winsrepl_offset
= dissect_winsrepl_update2(winsrepl_tvb
, pinfo
,
586 winsrepl_offset
, repl_tree
);
588 case WREPL_REPL_INFORM
:
589 col_set_str(pinfo
->cinfo
, COL_INFO
, "WREPL_REPL_INFORM");
590 proto_item_append_text(winsrepl_item
, ", WREPL_REPL_INFORM");
591 proto_item_append_text(repl_item
, ", WREPL_REPL_INFORM");
592 winsrepl_offset
= dissect_winsrepl_inform(winsrepl_tvb
, pinfo
,
593 winsrepl_offset
, repl_tree
);
595 case WREPL_REPL_INFORM2
:
596 col_set_str(pinfo
->cinfo
, COL_INFO
, "WREPL_REPL_INFORM2");
597 proto_item_append_text(winsrepl_item
, ", WREPL_REPL_INFORM2");
598 proto_item_append_text(repl_item
, ", WREPL_REPL_INFORM2");
599 winsrepl_offset
= dissect_winsrepl_inform2(winsrepl_tvb
, pinfo
,
600 winsrepl_offset
, repl_tree
);
604 return winsrepl_offset
;
608 dissect_winsrepl_pdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, void* data _U_
)
611 proto_item
*winsrepl_item
;
612 proto_tree
*winsrepl_tree
;
613 enum wrepl_mess_type mess_type
;
615 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "WINS-Replication");
616 col_clear(pinfo
->cinfo
, COL_INFO
);
618 winsrepl_item
= proto_tree_add_item(parent_tree
, proto_winsrepl
, tvb
, offset
, -1, ENC_NA
);
619 winsrepl_tree
= proto_item_add_subtree(winsrepl_item
, ett_winsrepl
);
622 proto_tree_add_item(winsrepl_tree
, hf_winsrepl_size
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
626 proto_tree_add_item(winsrepl_tree
, hf_winsrepl_opcode
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
630 proto_tree_add_item(winsrepl_tree
, hf_winsrepl_assoc_ctx
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
634 mess_type
= (enum wrepl_mess_type
)tvb_get_ntohl(tvb
, offset
);
635 proto_tree_add_uint(winsrepl_tree
, hf_winsrepl_mess_type
, tvb
, offset
, 4, mess_type
);
639 case WREPL_START_ASSOCIATION
:
640 col_set_str(pinfo
->cinfo
, COL_INFO
, "WREPL_START_ASSOCIATION");
641 proto_item_append_text(winsrepl_item
, ", WREPL_START_ASSOCIATION");
642 dissect_winsrepl_start(tvb
, pinfo
,
643 offset
, winsrepl_tree
);
645 case WREPL_START_ASSOCIATION_REPLY
:
646 col_set_str(pinfo
->cinfo
, COL_INFO
, "WREPL_START_ASSOCIATION_REPLY");
647 proto_item_append_text(winsrepl_item
, ", WREPL_START_ASSOCIATION_REPLY");
648 dissect_winsrepl_start(tvb
, pinfo
,
649 offset
, winsrepl_tree
);
651 case WREPL_STOP_ASSOCIATION
:
652 col_set_str(pinfo
->cinfo
, COL_INFO
, "WREPL_STOP_ASSOCIATION");
653 proto_item_append_text(winsrepl_item
, ", WREPL_STOP_ASSOCIATION");
654 dissect_winsrepl_stop(tvb
, pinfo
,
655 offset
, winsrepl_tree
);
657 case WREPL_REPLICATION
:
658 dissect_winsrepl_replication(tvb
, pinfo
,
659 offset
, winsrepl_item
, winsrepl_tree
);
663 return tvb_captured_length(tvb
);
667 get_winsrepl_pdu_len(packet_info
*pinfo _U_
, tvbuff_t
*tvb
,
668 int offset
, void *data _U_
)
672 pdu_len
=tvb_get_ntohl(tvb
, offset
);
677 dissect_winsrepl(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, void* data
)
679 tcp_dissect_pdus(tvb
, pinfo
, parent_tree
, winsrepl_reassemble
, 4, get_winsrepl_pdu_len
, dissect_winsrepl_pdu
, data
);
680 return tvb_captured_length(tvb
);
684 proto_register_winsrepl(void)
686 static hf_register_info hf
[] = {
687 { &hf_winsrepl_size
, {
688 "Packet Size", "winsrepl.size",
689 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
690 "WINS Replication Packet Size", HFILL
}},
692 { &hf_winsrepl_opcode
, {
693 "Opcode", "winsrepl.opcode",
694 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
695 "WINS Replication Opcode", HFILL
}},
697 { &hf_winsrepl_assoc_ctx
, {
698 "Assoc_Ctx", "winsrepl.assoc_ctx",
699 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
700 "WINS Replication Assoc_Ctx", HFILL
}},
702 { &hf_winsrepl_mess_type
, {
703 "Message_Type", "winsrepl.message_type",
704 FT_UINT32
, BASE_DEC
, VALS(message_type_vals
), 0x0,
705 "WINS Replication Message_Type", HFILL
}},
707 { &hf_winsrepl_start_minor_version
, {
708 "Minor Version", "winsrepl.minor_version",
709 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
710 "WINS Replication Minor Version", HFILL
}},
712 { &hf_winsrepl_start_major_version
, {
713 "Major Version", "winsrepl.major_version",
714 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
715 "WINS Replication Major Version", HFILL
}},
717 { &hf_winsrepl_stop_reason
, {
718 "Reason", "winsrepl.reason",
719 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
720 "WINS Replication Reason", HFILL
}},
722 { &hf_winsrepl_replication_command
, {
723 "Replication Command", "winsrepl.repl_cmd",
724 FT_UINT32
, BASE_HEX
, VALS(replication_cmd_vals
), 0x0,
725 "WINS Replication Command", HFILL
}},
727 { &hf_winsrepl_owner_address
, {
728 "Owner Address", "winsrepl.owner_address",
729 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
730 "WINS Replication Owner Address", HFILL
}},
732 { &hf_winsrepl_owner_max_version
, {
733 "Max Version", "winsrepl.max_version",
734 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
735 "WINS Replication Max Version", HFILL
}},
737 { &hf_winsrepl_owner_min_version
, {
738 "Min Version", "winsrepl.min_version",
739 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
740 "WINS Replication Min Version", HFILL
}},
742 { &hf_winsrepl_owner_type
, {
743 "Owner Type", "winsrepl.owner_type",
744 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
745 "WINS Replication Owner Type", HFILL
}},
747 { &hf_winsrepl_table_partner_count
, {
748 "Partner Count", "winsrepl.partner_count",
749 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
750 "WINS Replication Partner Count", HFILL
}},
752 { &hf_winsrepl_table_initiator
, {
753 "Initiator", "winsrepl.initiator",
754 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
755 "WINS Replication Initiator", HFILL
}},
757 { &hf_winsrepl_ip_owner
, {
758 "IP Owner", "winsrepl.ip_owner",
759 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
760 "WINS Replication IP Owner", HFILL
}},
762 { &hf_winsrepl_ip_ip
, {
763 "IP Address", "winsrepl.ip_address",
764 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
765 "WINS Replication IP Address", HFILL
}},
767 { &hf_winsrepl_addr_list_num_ips
, {
768 "Num IPs", "winsrepl.num_ips",
769 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
770 "WINS Replication Num IPs", HFILL
}},
772 { &hf_winsrepl_name_len
, {
773 "Name Len", "winsrepl.name_len",
774 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
775 "WINS Replication Name Len", HFILL
}},
777 { &hf_winsrepl_name_flags
, {
778 "Name Flags", "winsrepl.name_flags",
779 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
780 "WINS Replication Name Flags", HFILL
}},
782 { &hf_winsrepl_name_flags_rectype
, {
783 "Record Type", "winsrepl.name_flags.rectype",
784 FT_UINT32
, BASE_HEX
, VALS(rectype_vals
), 0x00000003,
785 "WINS Replication Name Flags Record Type", HFILL
}},
787 { &hf_winsrepl_name_flags_recstate
, {
788 "Record State", "winsrepl.name_flags.recstate",
789 FT_UINT32
, BASE_HEX
, VALS(recstate_vals
), 0x0000000C,
790 "WINS Replication Name Flags Record State", HFILL
}},
792 { &hf_winsrepl_name_flags_local
, {
793 "Local", "winsrepl.name_flags.local",
794 FT_BOOLEAN
, 32, NULL
, 0x00000010,
795 "WINS Replication Name Flags Local Flag", HFILL
}},
797 { &hf_winsrepl_name_flags_hosttype
, {
798 "Host Type", "winsrepl.name_flags.hosttype",
799 FT_UINT32
, BASE_HEX
, VALS(hosttype_vals
), 0x00000060,
800 "WINS Replication Name Flags Host Type", HFILL
}},
802 { &hf_winsrepl_name_flags_static
, {
803 "Static", "winsrepl.name_flags.static",
804 FT_BOOLEAN
, 32, NULL
, 0x00000080,
805 "WINS Replication Name Flags Static Flag", HFILL
}},
807 { &hf_winsrepl_name_group_flag
, {
808 "Name Group Flag", "winsrepl.name_group_flag",
809 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
810 "WINS Replication Name Group Flag", HFILL
}},
812 { &hf_winsrepl_name_version_id
, {
813 "Name Version Id", "winsrepl.name_version_id",
814 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
815 "WINS Replication Name Version Id", HFILL
}},
817 { &hf_winsrepl_name_unknown
, {
818 "Unknown IP", "winsrepl.unknown",
819 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
820 "WINS Replication Unknown IP", HFILL
}},
822 { &hf_winsrepl_reply_num_names
, {
823 "Num Names", "winsrepl.num_names",
824 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
825 "WINS Replication Num Names", HFILL
}},
828 static int *ett
[] = {
832 &ett_winsrepl_replication
,
834 &ett_winsrepl_table_reply
,
836 &ett_winsrepl_addr_list
,
838 &ett_winsrepl_send_reply
,
842 static ei_register_info ei
[] = {
843 { &ei_winsrepl_name_len
, { "winsrepl.name_len.invalid", PI_MALFORMED
, PI_ERROR
, "Bad name length", EXPFILL
}},
846 module_t
*winsrepl_module
;
847 expert_module_t
* expert_winsrepl
;
849 proto_winsrepl
= proto_register_protocol("WINS (Windows Internet Name Service) Replication",
850 "WINS-Replication", "winsrepl");
851 proto_register_subtree_array(ett
, array_length(ett
));
852 proto_register_field_array(proto_winsrepl
, hf
, array_length(hf
));
853 expert_winsrepl
= expert_register_protocol(proto_winsrepl
);
854 expert_register_field_array(expert_winsrepl
, ei
, array_length(ei
));
855 winsrepl_handle
= register_dissector("winsrepl", dissect_winsrepl
, proto_winsrepl
);
857 winsrepl_module
= prefs_register_protocol(proto_winsrepl
, NULL
);
858 prefs_register_bool_preference(winsrepl_module
, "reassemble",
859 "Reassemble WINS-Replication messages spanning multiple TCP segments",
860 "Whether the WINS-Replication dissector should reassemble messages spanning multiple TCP segments."
861 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
862 &winsrepl_reassemble
);
866 proto_reg_handoff_winsrepl(void)
868 dissector_add_uint_with_preference("tcp.port", WINS_REPLICATION_PORT
, winsrepl_handle
);
872 * Editor modelines - https://www.wireshark.org/tools/modelines.html
877 * indent-tabs-mode: t
880 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
881 * :indentSize=8:tabSize=8:noTabs=false: