4 * Routines for WINS Replication packet dissection
6 * Copyright 2005 Stefan Metzmacher <metze@samba.org>
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1998 Gerald Combs
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
36 #include <epan/packet.h>
37 #include <epan/strutil.h>
38 #include <epan/prefs.h>
41 #include "packet-windows-common.h"
42 #include "packet-netbios.h"
44 #include "packet-tcp.h"
46 static gboolean winsrepl_reassemble = TRUE;
48 static int proto_winsrepl = -1;
50 static int hf_winsrepl_size = -1;
51 static int hf_winsrepl_opcode = -1;
52 static int hf_winsrepl_assoc_ctx = -1;
53 static int hf_winsrepl_mess_type = -1;
55 static int hf_winsrepl_start_minor_version = -1;
56 static int hf_winsrepl_start_major_version = -1;
58 static int hf_winsrepl_stop_reason = -1;
60 static int hf_winsrepl_replication_command = -1;
62 static int hf_winsrepl_owner_address = -1;
63 static int hf_winsrepl_owner_max_version = -1;
64 static int hf_winsrepl_owner_min_version = -1;
65 static int hf_winsrepl_owner_type = -1;
67 static int hf_winsrepl_table_partner_count = -1;
68 static int hf_winsrepl_table_initiator = -1;
70 static int hf_winsrepl_ip_owner = -1;
71 static int hf_winsrepl_ip_ip = -1;
72 static int hf_winsrepl_addr_list_num_ips = -1;
74 static int hf_winsrepl_name_len = -1;
75 static int hf_winsrepl_name_flags = -1;
76 static int hf_winsrepl_name_flags_rectype = -1;
77 static int hf_winsrepl_name_flags_recstate = -1;
78 static int hf_winsrepl_name_flags_local = -1;
79 static int hf_winsrepl_name_flags_hosttype = -1;
80 static int hf_winsrepl_name_flags_static = -1;
81 static int hf_winsrepl_name_group_flag = -1;
82 static int hf_winsrepl_name_version_id = -1;
83 static int hf_winsrepl_name_unknown = -1;
85 static int hf_winsrepl_reply_num_names = -1;
87 static gint ett_winsrepl = -1;
89 static gint ett_winsrepl_start = -1;
90 static gint ett_winsrepl_stop = -1;
91 static gint ett_winsrepl_replication = -1;
93 static gint ett_winsrepl_owner = -1;
94 static gint ett_winsrepl_table_reply = -1;
96 static gint ett_winsrepl_ip = -1;
97 static gint ett_winsrepl_addr_list = -1;
99 static gint ett_winsrepl_name = -1;
100 static gint ett_winsrepl_send_reply = -1;
102 static gint ett_winsrepl_flags = -1;
104 #define WINS_REPLICATION_PORT ( 42 )
105 #define WREPL_OPCODE_BITS ( 0x7800 )
107 enum wrepl_replication_cmd {
108 WREPL_REPL_TABLE_QUERY=0,
109 WREPL_REPL_TABLE_REPLY=1,
110 WREPL_REPL_SEND_REQUEST=2,
111 WREPL_REPL_SEND_REPLY=3,
113 WREPL_REPL_UPDATE2=5,
118 enum wrepl_mess_type {
119 WREPL_START_ASSOCIATION=0,
120 WREPL_START_ASSOCIATION_REPLY=1,
121 WREPL_STOP_ASSOCIATION=2,
125 static unsigned int glb_winsrepl_tcp_port = WINS_REPLICATION_PORT;
127 static const value_string replication_cmd_vals[] = {
128 {WREPL_REPL_TABLE_QUERY, "WREPL_REPL_TABLE_QUERY"},
129 {WREPL_REPL_TABLE_REPLY, "WREPL_REPL_TABLE_REPLY"},
130 {WREPL_REPL_SEND_REQUEST, "WREPL_REPL_SEND_REQUEST"},
131 {WREPL_REPL_SEND_REPLY, "WREPL_REPL_SEND_REPLY"},
132 {WREPL_REPL_UPDATE, "WREPL_REPL_UPDATE"},
133 {WREPL_REPL_UPDATE2, "WREPL_REPL_UPDATE2"},
134 {WREPL_REPL_INFORM, "WREPL_REPL_INFORM"},
135 {WREPL_REPL_INFORM2, "WREPL_REPL_INFORM2"},
139 static const value_string message_type_vals[] = {
140 {WREPL_START_ASSOCIATION, "WREPL_START_ASSOCIATION"},
141 {WREPL_START_ASSOCIATION_REPLY, "WREPL_START_ASSOCIATION_REPLY"},
142 {WREPL_STOP_ASSOCIATION, "WREPL_STOP_ASSOCIATION"},
143 {WREPL_REPLICATION, "WREPL_REPLICATION"},
147 #define WREPL_NAME_TYPE_MASK 0x03
149 #define WREPL_NAME_TYPE_UNIQUE 0x00
150 #define WREPL_NAME_TYPE_NORMAL_GROUP 0x01
151 #define WREPL_NAME_TYPE_SPECIAL_GROUP 0x02
152 #define WREPL_NAME_TYPE_MULTIHOMED 0x03
154 static const value_string rectype_vals[] = {
155 {WREPL_NAME_TYPE_UNIQUE, "Unique"},
156 {WREPL_NAME_TYPE_NORMAL_GROUP, "Normal group"},
157 {WREPL_NAME_TYPE_SPECIAL_GROUP, "Special group"},
158 {WREPL_NAME_TYPE_MULTIHOMED, "Multihomed"},
162 static const value_string recstate_vals[] = {
165 {0x02, "Tombstoned"},
170 static const value_string hosttype_vals[] = {
179 dissect_winsrepl_start(tvbuff_t *winsrepl_tvb, _U_ packet_info *pinfo,
180 int winsrepl_offset, proto_tree *winsrepl_tree)
182 proto_item *start_item = NULL;
183 proto_tree *start_tree = NULL;
186 start_item = proto_tree_add_text(winsrepl_tree, winsrepl_tvb, winsrepl_offset, -1 , "WREPL_START_ASSOCIATION");
187 start_tree = proto_item_add_subtree(start_item, ett_winsrepl_start);
191 proto_tree_add_item(start_tree, hf_winsrepl_assoc_ctx, winsrepl_tvb, winsrepl_offset, 4, ENC_BIG_ENDIAN);
192 winsrepl_offset += 4;
195 proto_tree_add_item(start_tree, hf_winsrepl_start_minor_version, winsrepl_tvb, winsrepl_offset, 2, ENC_BIG_ENDIAN);
196 winsrepl_offset += 2;
199 proto_tree_add_item(start_tree, hf_winsrepl_start_major_version, winsrepl_tvb, winsrepl_offset, 2, ENC_BIG_ENDIAN);
200 winsrepl_offset += 2;
202 return winsrepl_offset;
206 dissect_winsrepl_stop(tvbuff_t *winsrepl_tvb, _U_ packet_info *pinfo,
207 int winsrepl_offset, proto_tree *winsrepl_tree)
210 proto_item *stop_item = NULL;
211 proto_tree *stop_tree = NULL;
214 stop_item = proto_tree_add_text(winsrepl_tree, winsrepl_tvb, winsrepl_offset, -1 , "WREPL_STOP_ASSOCIATION");
215 stop_tree = proto_item_add_subtree(stop_item, ett_winsrepl_stop);
219 reason = tvb_get_ntohl(winsrepl_tvb, winsrepl_offset);
220 proto_tree_add_uint(stop_tree, hf_winsrepl_stop_reason, winsrepl_tvb, winsrepl_offset, 4, reason);
221 winsrepl_offset += 4;
223 proto_item_append_text(stop_item, ", Reason: 0x%08X", reason);
225 return winsrepl_offset;
229 dissect_winsrepl_table_query(tvbuff_t *winsrepl_tvb _U_, packet_info *pinfo _U_,
230 int winsrepl_offset, proto_tree *winsrepl_tree _U_)
232 /* Nothing to do here */
233 return winsrepl_offset;
237 dissect_winsrepl_wins_owner(tvbuff_t *winsrepl_tvb, _U_ packet_info *pinfo,
238 int winsrepl_offset, proto_tree *winsrepl_tree,
239 proto_tree *sub_tree, guint32 idx)
241 proto_item *owner_item = NULL;
242 proto_tree *owner_tree = NULL;
245 owner_item = proto_tree_add_text(sub_tree, winsrepl_tvb, winsrepl_offset, 24 , "WINS Owner [%u]", idx);
246 owner_tree = proto_item_add_subtree(owner_item, ett_winsrepl_owner);
247 } else if (winsrepl_tree) {
248 owner_item = proto_tree_add_text(winsrepl_tree, winsrepl_tvb, winsrepl_offset, 24 , "WINS Owner");
249 owner_tree = proto_item_add_subtree(owner_item, ett_winsrepl_owner);
253 proto_tree_add_item(owner_tree, hf_winsrepl_owner_address, winsrepl_tvb, winsrepl_offset, 4, ENC_BIG_ENDIAN);
254 winsrepl_offset += 4;
257 proto_tree_add_item(owner_tree, hf_winsrepl_owner_max_version, winsrepl_tvb, winsrepl_offset, 8, ENC_BIG_ENDIAN);
258 winsrepl_offset += 8;
261 proto_tree_add_item(owner_tree, hf_winsrepl_owner_min_version, winsrepl_tvb, winsrepl_offset, 8, ENC_BIG_ENDIAN);
262 winsrepl_offset += 8;
265 proto_tree_add_item(owner_tree, hf_winsrepl_owner_type, winsrepl_tvb, winsrepl_offset, 4, ENC_BIG_ENDIAN);
266 winsrepl_offset += 4;
268 return winsrepl_offset;
272 dissect_winsrepl_table_reply(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
273 int winsrepl_offset, proto_tree *winsrepl_tree)
275 proto_item *table_item = NULL;
276 proto_tree *table_tree = NULL;
277 guint32 partner_count;
281 table_item = proto_tree_add_text(winsrepl_tree, winsrepl_tvb, winsrepl_offset, -1 , "WREPL_REPL_TABLE_REPLY");
282 table_tree = proto_item_add_subtree(table_item, ett_winsrepl_table_reply);
286 partner_count = tvb_get_ntohl(winsrepl_tvb, winsrepl_offset);
287 proto_tree_add_uint(table_tree, hf_winsrepl_table_partner_count, winsrepl_tvb, winsrepl_offset, 4, partner_count);
288 winsrepl_offset += 4;
290 for (i=0; i < partner_count; i++) {
291 winsrepl_offset = dissect_winsrepl_wins_owner(winsrepl_tvb, pinfo,
292 winsrepl_offset, table_tree,
297 proto_tree_add_item(table_tree, hf_winsrepl_table_initiator, winsrepl_tvb, winsrepl_offset, 4, ENC_BIG_ENDIAN);
298 winsrepl_offset += 4;
300 return winsrepl_offset;
304 dissect_winsrepl_send_request(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
305 int winsrepl_offset, proto_tree *winsrepl_tree)
307 winsrepl_offset = dissect_winsrepl_wins_owner(winsrepl_tvb, pinfo,
308 winsrepl_offset, winsrepl_tree,
311 return winsrepl_offset;
315 dissect_winsrepl_wins_ip(tvbuff_t *winsrepl_tvb, _U_ packet_info *pinfo,
316 int winsrepl_offset, proto_tree *winsrepl_tree,
317 guint32 *addr, proto_tree *sub_tree, guint32 idx)
319 proto_item *ip_item = NULL;
320 proto_tree *ip_tree = NULL;
323 ip_item = proto_tree_add_text(sub_tree, winsrepl_tvb, winsrepl_offset, 8 , "WINS IP [%u]", idx);
324 ip_tree = proto_item_add_subtree(ip_item, ett_winsrepl_ip);
325 } else if (winsrepl_tree) {
326 ip_item = proto_tree_add_text(winsrepl_tree, winsrepl_tvb, winsrepl_offset, 8 , "WINS IP");
327 ip_tree = proto_item_add_subtree(ip_item, ett_winsrepl_ip);
331 proto_tree_add_item(ip_tree, hf_winsrepl_ip_owner, winsrepl_tvb, winsrepl_offset, 4, ENC_BIG_ENDIAN);
332 winsrepl_offset += 4;
335 *addr = tvb_get_ipv4(winsrepl_tvb, winsrepl_offset);
336 proto_tree_add_ipv4(ip_tree, hf_winsrepl_ip_ip, winsrepl_tvb, winsrepl_offset, 4, *addr);
337 proto_item_append_text(ip_item, ": %s", ip_to_str((guint8 *)addr));
338 winsrepl_offset += 4;
340 return winsrepl_offset;
344 dissect_winsrepl_wins_address_list(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
345 int winsrepl_offset, proto_tree *winsrepl_tree,
346 proto_item *parent_item)
348 proto_item *addr_list_item = NULL;
349 proto_tree *addr_list_tree = NULL;
350 int old_offset = winsrepl_offset;
356 addr_list_item = proto_tree_add_text(winsrepl_tree, winsrepl_tvb, winsrepl_offset, -1 , "WINS Address List");
357 addr_list_tree = proto_item_add_subtree(addr_list_item, ett_winsrepl_addr_list);
361 num_ips = tvb_get_letohl(winsrepl_tvb, winsrepl_offset);
362 proto_tree_add_uint(addr_list_tree, hf_winsrepl_addr_list_num_ips, winsrepl_tvb, winsrepl_offset, 4, num_ips);
363 winsrepl_offset += 4;
365 for (i=0; i < num_ips; i++) {
366 winsrepl_offset = dissect_winsrepl_wins_ip(winsrepl_tvb, pinfo,
367 winsrepl_offset, addr_list_tree,
368 &ip, addr_list_tree, i);
370 proto_item_append_text(parent_item, ": %s", ip_to_str((guint8 *)&ip));
371 proto_item_append_text(addr_list_item, ": %s", ip_to_str((guint8 *)&ip));
373 proto_item_append_text(parent_item, ", %s", ip_to_str((guint8 *)&ip));
374 proto_item_append_text(addr_list_item, ", %s", ip_to_str((guint8 *)&ip));
378 proto_item_set_len(addr_list_item, winsrepl_offset - old_offset);
380 return winsrepl_offset;
384 dissect_winsrepl_wins_name(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
385 int winsrepl_offset, proto_tree *winsrepl_tree,
386 proto_tree *sub_tree, guint32 idx)
388 proto_item *name_item = NULL;
389 proto_tree *name_tree = NULL;
390 proto_item *flags_item;
391 proto_tree *flags_tree;
392 int old_offset = winsrepl_offset;
393 tvbuff_t *name_tvb = NULL;
395 char name_str[(NETBIOS_NAME_LEN - 1)*4 + 1];
401 name_item = proto_tree_add_text(sub_tree, winsrepl_tvb, winsrepl_offset, -1 , "WINS Name [%u]", idx);
402 name_tree = proto_item_add_subtree(name_item, ett_winsrepl_name);
403 } else if (winsrepl_tree) {
404 name_item = proto_tree_add_text(winsrepl_tree, winsrepl_tvb, winsrepl_offset, -1 , "WINS Name");
405 name_tree = proto_item_add_subtree(name_item, ett_winsrepl_name);
409 name_len = tvb_get_ntohl(winsrepl_tvb, winsrepl_offset);
410 if ((gint) name_len < 1) {
411 proto_tree_add_text(name_tree, winsrepl_tvb, winsrepl_offset,
412 4, "Bad name length: %u", name_len);
413 THROW(ReportedBoundsError);
415 proto_tree_add_uint(name_tree, hf_winsrepl_name_len, winsrepl_tvb, winsrepl_offset, 4, name_len);
416 winsrepl_offset += 4;
420 * XXX - apparently, according to the Samba code for handling
421 * WINS replication, there's a bug in a lot of versions of Windows,
422 * including W2K SP2, wherein the first and last bytes of the
423 * name (the last byte being the name type) are swapped if
424 * the type is 0x1b. I think I've seen this in at least
427 name_tvb = tvb_new_subset(winsrepl_tvb, winsrepl_offset, name_len, name_len);
428 netbios_add_name("Name", name_tvb, 0, name_tree);
429 name_type = get_netbios_name(name_tvb, 0, name_str, (NETBIOS_NAME_LEN - 1)*4 + 1);
430 proto_item_append_text(name_item, ": %s<%02x>", name_str, name_type);
431 winsrepl_offset += name_len;
433 /* ALIGN to 4 Byte */
434 /* winsrepl_offset += ((winsrepl_offset & (4-1)) == 0 ? 0 : (4 - (winsrepl_offset & (4-1)))); */
435 /* Windows including w2k8 add 4 padding bytes, when it's already 4 byte
436 * alligned... This happens when the name has a "scope" part
438 winsrepl_offset += 4 - (winsrepl_offset & (4-1));
442 * XXX - there appear to be more flag bits, but I didn't see
443 * anything in the Samba code about them.
445 flags = tvb_get_ntohl(winsrepl_tvb, winsrepl_offset);
446 flags_item = proto_tree_add_uint(name_tree, hf_winsrepl_name_flags, winsrepl_tvb, winsrepl_offset, 4, flags);
447 flags_tree = proto_item_add_subtree(flags_item, ett_winsrepl_flags);
448 proto_tree_add_uint(flags_tree, hf_winsrepl_name_flags_rectype, winsrepl_tvb, winsrepl_offset, 4, flags);
449 proto_tree_add_uint(flags_tree, hf_winsrepl_name_flags_recstate, winsrepl_tvb, winsrepl_offset, 4, flags);
450 proto_tree_add_boolean(flags_tree, hf_winsrepl_name_flags_local, winsrepl_tvb, winsrepl_offset, 4, flags);
451 proto_tree_add_uint(flags_tree, hf_winsrepl_name_flags_hosttype, winsrepl_tvb, winsrepl_offset, 4, flags);
452 proto_tree_add_boolean(flags_tree, hf_winsrepl_name_flags_static, winsrepl_tvb, winsrepl_offset, 4, flags);
453 winsrepl_offset += 4;
456 /* XXX - is this just a Boolean? */
457 proto_tree_add_item(name_tree, hf_winsrepl_name_group_flag, winsrepl_tvb, winsrepl_offset, 4, ENC_LITTLE_ENDIAN);
458 winsrepl_offset += 4;
461 proto_tree_add_item(name_tree, hf_winsrepl_name_version_id, winsrepl_tvb, winsrepl_offset, 8, ENC_BIG_ENDIAN);
462 winsrepl_offset += 8;
464 switch (flags & WREPL_NAME_TYPE_MASK) {
466 case WREPL_NAME_TYPE_UNIQUE:
467 case WREPL_NAME_TYPE_NORMAL_GROUP:
469 addr = tvb_get_ipv4(winsrepl_tvb, winsrepl_offset);
470 proto_tree_add_ipv4(name_tree, hf_winsrepl_ip_ip, winsrepl_tvb, winsrepl_offset, 4, addr);
471 proto_item_append_text(name_item, ": %s", ip_to_str((guint8 *)&addr));
472 winsrepl_offset += 4;
475 case WREPL_NAME_TYPE_SPECIAL_GROUP:
476 case WREPL_NAME_TYPE_MULTIHOMED:
478 winsrepl_offset = dissect_winsrepl_wins_address_list(winsrepl_tvb, pinfo,
479 winsrepl_offset, name_tree,
484 /* UNKNOWN, little or big endian??? */
485 proto_tree_add_item(name_tree, hf_winsrepl_name_unknown, winsrepl_tvb, winsrepl_offset, 4, ENC_BIG_ENDIAN);
486 winsrepl_offset += 4;
488 proto_item_set_len(name_item, winsrepl_offset - old_offset);
490 return winsrepl_offset;
494 dissect_winsrepl_send_reply(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
495 int winsrepl_offset, proto_tree *winsrepl_tree)
497 proto_item *rep_item = NULL;
498 proto_tree *rep_tree = NULL;
503 rep_item = proto_tree_add_text(winsrepl_tree, winsrepl_tvb, winsrepl_offset, -1 , "WREPL_REPL_SEND_REPLY");
504 rep_tree = proto_item_add_subtree(rep_item, ett_winsrepl_send_reply);
508 num_names = tvb_get_ntohl(winsrepl_tvb, winsrepl_offset);
509 proto_tree_add_uint(rep_tree, hf_winsrepl_reply_num_names, winsrepl_tvb, winsrepl_offset, 4, num_names);
510 winsrepl_offset += 4;
512 for (i=0; i < num_names; i++) {
513 winsrepl_offset = dissect_winsrepl_wins_name(winsrepl_tvb, pinfo,
514 winsrepl_offset, rep_tree,
518 return winsrepl_offset;
522 dissect_winsrepl_update(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
523 int winsrepl_offset, proto_tree *winsrepl_tree)
525 winsrepl_offset = dissect_winsrepl_table_reply(winsrepl_tvb, pinfo,
526 winsrepl_offset, winsrepl_tree);
527 return winsrepl_offset;
531 dissect_winsrepl_update2(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
532 int winsrepl_offset, proto_tree *winsrepl_tree)
534 winsrepl_offset = dissect_winsrepl_table_reply(winsrepl_tvb, pinfo,
535 winsrepl_offset, winsrepl_tree);
536 return winsrepl_offset;
540 dissect_winsrepl_inform(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
541 int winsrepl_offset, proto_tree *winsrepl_tree)
543 winsrepl_offset = dissect_winsrepl_table_reply(winsrepl_tvb, pinfo,
544 winsrepl_offset, winsrepl_tree);
545 return winsrepl_offset;
549 dissect_winsrepl_inform2(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
550 int winsrepl_offset, proto_tree *winsrepl_tree)
552 winsrepl_offset = dissect_winsrepl_table_reply(winsrepl_tvb, pinfo,
553 winsrepl_offset, winsrepl_tree);
554 return winsrepl_offset;
558 dissect_winsrepl_replication(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
559 int winsrepl_offset, proto_item *winsrepl_item, proto_tree *winsrepl_tree)
561 proto_item *repl_item = NULL;
562 proto_tree *repl_tree = NULL;
563 enum wrepl_replication_cmd command;
566 repl_item = proto_tree_add_text(winsrepl_tree, winsrepl_tvb, winsrepl_offset, -1 , "WREPL_REPLICATION");
567 repl_tree = proto_item_add_subtree(repl_item, ett_winsrepl_replication);
570 /* REPLIICATION_CMD */
571 command = tvb_get_ntohl(winsrepl_tvb, winsrepl_offset);
572 proto_tree_add_uint(repl_tree, hf_winsrepl_replication_command, winsrepl_tvb, winsrepl_offset, 4, command);
573 winsrepl_offset += 4;
576 case WREPL_REPL_TABLE_QUERY:
577 col_set_str(pinfo->cinfo, COL_INFO, "WREPL_REPL_TABLE_QUERY");
578 proto_item_append_text(winsrepl_item, ", WREPL_REPL_TABLE_QUERY");
579 proto_item_append_text(repl_item, ", WREPL_REPL_TABLE_QUERY");
580 winsrepl_offset = dissect_winsrepl_table_query(winsrepl_tvb, pinfo,
581 winsrepl_offset, repl_tree);
583 case WREPL_REPL_TABLE_REPLY:
584 col_set_str(pinfo->cinfo, COL_INFO, "WREPL_REPL_TABLE_REPLY");
585 proto_item_append_text(winsrepl_item, ", WREPL_REPL_TABLE_REPLY");
586 proto_item_append_text(repl_item, ", WREPL_REPL_TABLE_REPLY");
587 winsrepl_offset = dissect_winsrepl_table_reply(winsrepl_tvb, pinfo,
588 winsrepl_offset, repl_tree);
590 case WREPL_REPL_SEND_REQUEST:
591 col_set_str(pinfo->cinfo, COL_INFO, "WREPL_REPL_SEND_REQUEST");
592 proto_item_append_text(winsrepl_item, ", WREPL_REPL_SEND_REQUEST");
593 proto_item_append_text(repl_item, ", WREPL_REPL_SEND_REQUEST");
594 winsrepl_offset = dissect_winsrepl_send_request(winsrepl_tvb, pinfo,
595 winsrepl_offset, repl_tree);
597 case WREPL_REPL_SEND_REPLY:
598 col_set_str(pinfo->cinfo, COL_INFO, "WREPL_REPL_SEND_REPLY");
599 proto_item_append_text(winsrepl_item, ", WREPL_REPL_SEND_REPLY");
600 proto_item_append_text(repl_item, ", WREPL_REPL_SEND_REPLY");
601 winsrepl_offset = dissect_winsrepl_send_reply(winsrepl_tvb, pinfo,
602 winsrepl_offset, repl_tree);
604 case WREPL_REPL_UPDATE:
605 col_set_str(pinfo->cinfo, COL_INFO, "WREPL_REPL_UPDATE");
606 proto_item_append_text(winsrepl_item, ", WREPL_REPL_UPDATE");
607 proto_item_append_text(repl_item, ", WREPL_REPL_UPDATE");
608 winsrepl_offset = dissect_winsrepl_update(winsrepl_tvb, pinfo,
609 winsrepl_offset, repl_tree);
611 case WREPL_REPL_UPDATE2:
612 col_set_str(pinfo->cinfo, COL_INFO, "WREPL_REPL_UPDATE2");
613 proto_item_append_text(winsrepl_item, ",WREPL_REPL_UPDATE2");
614 proto_item_append_text(repl_item, ",WREPL_REPL_UPDATE2");
615 winsrepl_offset = dissect_winsrepl_update2(winsrepl_tvb, pinfo,
616 winsrepl_offset, repl_tree);
618 case WREPL_REPL_INFORM:
619 col_set_str(pinfo->cinfo, COL_INFO, "WREPL_REPL_INFORM");
620 proto_item_append_text(winsrepl_item, ", WREPL_REPL_INFORM");
621 proto_item_append_text(repl_item, ", WREPL_REPL_INFORM");
622 winsrepl_offset = dissect_winsrepl_inform(winsrepl_tvb, pinfo,
623 winsrepl_offset, repl_tree);
625 case WREPL_REPL_INFORM2:
626 col_set_str(pinfo->cinfo, COL_INFO, "WREPL_REPL_INFORM2");
627 proto_item_append_text(winsrepl_item, ", WREPL_REPL_INFORM2");
628 proto_item_append_text(repl_item, ", WREPL_REPL_INFORM2");
629 winsrepl_offset = dissect_winsrepl_inform2(winsrepl_tvb, pinfo,
630 winsrepl_offset, repl_tree);
634 return winsrepl_offset;
638 dissect_winsrepl_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
641 proto_item *winsrepl_item = NULL;
642 proto_tree *winsrepl_tree = NULL;
643 enum wrepl_mess_type mess_type;
645 col_set_str(pinfo->cinfo, COL_PROTOCOL, "WINS-Replication");
646 col_clear(pinfo->cinfo, COL_INFO);
649 winsrepl_item = proto_tree_add_item(parent_tree, proto_winsrepl, tvb, offset, -1, ENC_NA);
650 winsrepl_tree = proto_item_add_subtree(winsrepl_item, ett_winsrepl);
654 proto_tree_add_item(winsrepl_tree, hf_winsrepl_size, tvb, offset, 4, ENC_BIG_ENDIAN);
658 proto_tree_add_item(winsrepl_tree, hf_winsrepl_opcode, tvb, offset, 4, ENC_BIG_ENDIAN);
662 proto_tree_add_item(winsrepl_tree, hf_winsrepl_assoc_ctx, tvb, offset, 4, ENC_BIG_ENDIAN);
666 mess_type = tvb_get_ntohl(tvb, offset);
667 proto_tree_add_uint(winsrepl_tree, hf_winsrepl_mess_type, tvb, offset, 4, mess_type);
671 case WREPL_START_ASSOCIATION:
672 col_set_str(pinfo->cinfo, COL_INFO, "WREPL_START_ASSOCIATION");
673 proto_item_append_text(winsrepl_item, ", WREPL_START_ASSOCIATION");
674 dissect_winsrepl_start(tvb, pinfo,
675 offset, winsrepl_tree);
677 case WREPL_START_ASSOCIATION_REPLY:
678 col_set_str(pinfo->cinfo, COL_INFO, "WREPL_START_ASSOCIATION_REPLY");
679 proto_item_append_text(winsrepl_item, ", WREPL_START_ASSOCIATION_REPLY");
680 dissect_winsrepl_start(tvb, pinfo,
681 offset, winsrepl_tree);
683 case WREPL_STOP_ASSOCIATION:
684 col_set_str(pinfo->cinfo, COL_INFO, "WREPL_STOP_ASSOCIATION");
685 proto_item_append_text(winsrepl_item, ", WREPL_STOP_ASSOCIATION");
686 dissect_winsrepl_stop(tvb, pinfo,
687 offset, winsrepl_tree);
689 case WREPL_REPLICATION:
690 dissect_winsrepl_replication(tvb, pinfo,
691 offset, winsrepl_item, winsrepl_tree);
699 get_winsrepl_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
703 pdu_len=tvb_get_ntohl(tvb, offset);
708 dissect_winsrepl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
710 tcp_dissect_pdus(tvb, pinfo, parent_tree, winsrepl_reassemble, 4, get_winsrepl_pdu_len, dissect_winsrepl_pdu);
714 proto_register_winsrepl(void)
716 static hf_register_info hf[] = {
717 { &hf_winsrepl_size, {
718 "Packet Size", "winsrepl.size",
719 FT_UINT32, BASE_DEC, NULL, 0x0,
720 "WINS Replication Packet Size", HFILL }},
722 { &hf_winsrepl_opcode, {
723 "Opcode", "winsrepl.opcode",
724 FT_UINT32, BASE_HEX, NULL, 0x0,
725 "WINS Replication Opcode", HFILL }},
727 { &hf_winsrepl_assoc_ctx, {
728 "Assoc_Ctx", "winsrepl.assoc_ctx",
729 FT_UINT32, BASE_HEX, NULL, 0x0,
730 "WINS Replication Assoc_Ctx", HFILL }},
732 { &hf_winsrepl_mess_type, {
733 "Message_Type", "winsrepl.message_type",
734 FT_UINT32, BASE_DEC, VALS(message_type_vals), 0x0,
735 "WINS Replication Message_Type", HFILL }},
737 { &hf_winsrepl_start_minor_version, {
738 "Minor Version", "winsrepl.minor_version",
739 FT_UINT16, BASE_DEC, NULL, 0x0,
740 "WINS Replication Minor Version", HFILL }},
742 { &hf_winsrepl_start_major_version, {
743 "Major Version", "winsrepl.major_version",
744 FT_UINT16, BASE_DEC, NULL, 0x0,
745 "WINS Replication Major Version", HFILL }},
747 { &hf_winsrepl_stop_reason, {
748 "Reason", "winsrepl.reason",
749 FT_UINT32, BASE_HEX, NULL, 0x0,
750 "WINS Replication Reason", HFILL }},
752 { &hf_winsrepl_replication_command, {
753 "Replication Command", "winsrepl.repl_cmd",
754 FT_UINT32, BASE_HEX, VALS(replication_cmd_vals), 0x0,
755 "WINS Replication Command", HFILL }},
757 { &hf_winsrepl_owner_address, {
758 "Owner Address", "winsrepl.owner_address",
759 FT_IPv4, BASE_NONE, NULL, 0x0,
760 "WINS Replication Owner Address", HFILL }},
762 { &hf_winsrepl_owner_max_version, {
763 "Max Version", "winsrepl.max_version",
764 FT_UINT64, BASE_DEC, NULL, 0x0,
765 "WINS Replication Max Version", HFILL }},
767 { &hf_winsrepl_owner_min_version, {
768 "Min Version", "winsrepl.min_version",
769 FT_UINT64, BASE_DEC, NULL, 0x0,
770 "WINS Replication Min Version", HFILL }},
772 { &hf_winsrepl_owner_type, {
773 "Owner Type", "winsrepl.owner_type",
774 FT_UINT32, BASE_DEC, NULL, 0x0,
775 "WINS Replication Owner Type", HFILL }},
777 { &hf_winsrepl_table_partner_count, {
778 "Partner Count", "winsrepl.partner_count",
779 FT_UINT32, BASE_DEC, NULL, 0x0,
780 "WINS Replication Partner Count", HFILL }},
782 { &hf_winsrepl_table_initiator, {
783 "Initiator", "winsrepl.initiator",
784 FT_IPv4, BASE_NONE, NULL, 0x0,
785 "WINS Replication Initiator", HFILL }},
787 { &hf_winsrepl_ip_owner, {
788 "IP Owner", "winsrepl.ip_owner",
789 FT_IPv4, BASE_NONE, NULL, 0x0,
790 "WINS Replication IP Owner", HFILL }},
792 { &hf_winsrepl_ip_ip, {
793 "IP Address", "winsrepl.ip_address",
794 FT_IPv4, BASE_NONE, NULL, 0x0,
795 "WINS Replication IP Address", HFILL }},
797 { &hf_winsrepl_addr_list_num_ips, {
798 "Num IPs", "winsrepl.num_ips",
799 FT_UINT32, BASE_DEC, NULL, 0x0,
800 "WINS Replication Num IPs", HFILL }},
802 { &hf_winsrepl_name_len, {
803 "Name Len", "winsrepl.name_len",
804 FT_UINT32, BASE_DEC, NULL, 0x0,
805 "WINS Replication Name Len", HFILL }},
807 { &hf_winsrepl_name_flags, {
808 "Name Flags", "winsrepl.name_flags",
809 FT_UINT32, BASE_HEX, NULL, 0x0,
810 "WINS Replication Name Flags", HFILL }},
812 { &hf_winsrepl_name_flags_rectype, {
813 "Record Type", "winsrepl.name_flags.rectype",
814 FT_UINT32, BASE_HEX, VALS(rectype_vals), 0x00000003,
815 "WINS Replication Name Flags Record Type", HFILL }},
817 { &hf_winsrepl_name_flags_recstate, {
818 "Record State", "winsrepl.name_flags.recstate",
819 FT_UINT32, BASE_HEX, VALS(recstate_vals), 0x0000000C,
820 "WINS Replication Name Flags Record State", HFILL }},
822 { &hf_winsrepl_name_flags_local, {
823 "Local", "winsrepl.name_flags.local",
824 FT_BOOLEAN, 32, NULL, 0x00000010,
825 "WINS Replication Name Flags Local Flag", HFILL }},
827 { &hf_winsrepl_name_flags_hosttype, {
828 "Host Type", "winsrepl.name_flags.hosttype",
829 FT_UINT32, BASE_HEX, VALS(hosttype_vals), 0x00000060,
830 "WINS Replication Name Flags Host Type", HFILL }},
832 { &hf_winsrepl_name_flags_static, {
833 "Static", "winsrepl.name_flags.static",
834 FT_BOOLEAN, 32, NULL, 0x00000080,
835 "WINS Replication Name Flags Static Flag", HFILL }},
837 { &hf_winsrepl_name_group_flag, {
838 "Name Group Flag", "winsrepl.name_group_flag",
839 FT_UINT32, BASE_HEX, NULL, 0x0,
840 "WINS Replication Name Group Flag", HFILL }},
842 { &hf_winsrepl_name_version_id, {
843 "Name Version Id", "winsrepl.name_version_id",
844 FT_UINT64, BASE_DEC, NULL, 0x0,
845 "WINS Replication Name Version Id", HFILL }},
847 { &hf_winsrepl_name_unknown, {
848 "Unknown IP", "winsrepl.unknown",
849 FT_IPv4, BASE_NONE, NULL, 0x0,
850 "WINS Replication Unknown IP", HFILL }},
852 { &hf_winsrepl_reply_num_names, {
853 "Num Names", "winsrepl.num_names",
854 FT_UINT32, BASE_DEC, NULL, 0x0,
855 "WINS Replication Num Names", HFILL }},
858 static gint *ett[] = {
862 &ett_winsrepl_replication,
864 &ett_winsrepl_table_reply,
866 &ett_winsrepl_addr_list,
868 &ett_winsrepl_send_reply,
872 module_t *winsrepl_module;
874 proto_winsrepl = proto_register_protocol("WINS (Windows Internet Name Service) Replication",
875 "WINS-Replication", "winsrepl");
876 proto_register_subtree_array(ett, array_length(ett));
877 proto_register_field_array(proto_winsrepl, hf, array_length(hf));
879 winsrepl_module = prefs_register_protocol(proto_winsrepl, NULL);
880 prefs_register_bool_preference(winsrepl_module, "reassemble",
881 "Reassemble WINS-Replication messages spanning multiple TCP segments",
882 "Whether the WINS-Replication dissector should reassemble messages spanning multiple TCP segments."
883 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
884 &winsrepl_reassemble);
888 proto_reg_handoff_winsrepl(void)
890 dissector_handle_t winsrepl_handle;
892 winsrepl_handle = create_dissector_handle(dissect_winsrepl, proto_winsrepl);
893 dissector_add_uint("tcp.port", glb_winsrepl_tcp_port, winsrepl_handle);