4 * Routines for WINS Replication packet dissection
6 * Copyright 2005 Stefan Metzmacher <metze@samba.org>
10 * Ethereal - Network traffic analyzer
11 * By Gerald Combs <gerald@ethereal.com>
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.
39 #include <epan/packet.h>
40 #include <epan/conversation.h>
41 #include <epan/strutil.h>
42 #include <epan/prefs.h>
43 #include <epan/reassemble.h>
45 #include <epan/emem.h>
47 #include "packet-windows-common.h"
48 #include "packet-netbios.h"
50 #include "packet-winsrepl.h"
51 #include "packet-tcp.h"
53 static gboolean winsrepl_reassemble = TRUE;
55 struct winsrepl_frame_data {
59 static int proto_winsrepl = -1;
61 static int hf_winsrepl_size = -1;
62 static int hf_winsrepl_opcode = -1;
63 static int hf_winsrepl_assoc_ctx = -1;
64 static int hf_winsrepl_mess_type = -1;
66 static int hf_winsrepl_start_minor_version = -1;
67 static int hf_winsrepl_start_major_version = -1;
69 static int hf_winsrepl_stop_reason = -1;
71 static int hf_winsrepl_replication_command = -1;
73 static int hf_winsrepl_owner_address = -1;
74 static int hf_winsrepl_owner_max_version = -1;
75 static int hf_winsrepl_owner_min_version = -1;
76 static int hf_winsrepl_owner_type = -1;
78 static int hf_winsrepl_table_partner_count = -1;
79 static int hf_winsrepl_table_initiator = -1;
81 static int hf_winsrepl_ip_owner = -1;
82 static int hf_winsrepl_ip_ip = -1;
83 static int hf_winsrepl_addr_list_num_ips = -1;
85 static int hf_winsrepl_name_len = -1;
86 static int hf_winsrepl_name_flags = -1;
87 static int hf_winsrepl_name_group_flag = -1;
88 static int hf_winsrepl_name_id = -1;
89 static int hf_winsrepl_name_unknown = -1;
91 static int hf_winsrepl_reply_num_names = -1;
93 static gint ett_winsrepl = -1;
95 static gint ett_winsrepl_start = -1;
96 static gint ett_winsrepl_stop = -1;
97 static gint ett_winsrepl_replication = -1;
99 static gint ett_winsrepl_owner = -1;
100 static gint ett_winsrepl_table_reply = -1;
102 static gint ett_winsrepl_ip = -1;
103 static gint ett_winsrepl_addr_list = -1;
105 static gint ett_winsrepl_name = -1;
106 static gint ett_winsrepl_send_reply = -1;
108 dissector_handle_t winsrepl_handle;
110 static unsigned int glb_winsrepl_tcp_port = WINS_REPLICATION_PORT;
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_INFORM, "WREPL_REPL_INFORM"},
122 static const value_string message_type_vals[] = {
123 {WREPL_START_ASSOCIATION, "WREPL_START_ASSOCIATION"},
124 {WREPL_START_ASSOCIATION_REPLY, "WREPL_START_ASSOCIATION_REPLY"},
125 {WREPL_STOP_ASSOCIATION, "WREPL_STOP_ASSOCIATION"},
126 {WREPL_REPLICATION, "WREPL_REPLICATION"},
131 dissect_winsrepl_start(tvbuff_t *winsrepl_tvb, _U_ packet_info *pinfo,
132 int winsrepl_offset, proto_tree *winsrepl_tree,
133 struct winsrepl_frame_data *winsrepl)
135 struct wrepl_start *start = &winsrepl->w.packet.message.start;
136 proto_item *start_item = NULL;
137 proto_tree *start_tree = NULL;
140 start_item = proto_tree_add_text(winsrepl_tree, winsrepl_tvb, winsrepl_offset, -1 , "WREPL_START_ASSOCIATION");
141 start_tree = proto_item_add_subtree(start_item, ett_winsrepl_start);
145 start->assoc_ctx = tvb_get_ntohl(winsrepl_tvb, winsrepl_offset);
146 proto_tree_add_uint(start_tree, hf_winsrepl_assoc_ctx, winsrepl_tvb, winsrepl_offset, 4, start->assoc_ctx);
147 winsrepl_offset += 4;
150 start->minor_version = tvb_get_ntohs(winsrepl_tvb, winsrepl_offset);
151 proto_tree_add_uint(start_tree, hf_winsrepl_start_minor_version, winsrepl_tvb, winsrepl_offset, 2, start->minor_version);
152 winsrepl_offset += 2;
155 start->major_version = tvb_get_ntohs(winsrepl_tvb, winsrepl_offset);
156 proto_tree_add_uint(start_tree, hf_winsrepl_start_major_version, winsrepl_tvb, winsrepl_offset, 2, start->major_version);
157 winsrepl_offset += 2;
159 return winsrepl_offset;
163 dissect_winsrepl_stop(tvbuff_t *winsrepl_tvb, _U_ packet_info *pinfo,
164 int winsrepl_offset, proto_tree *winsrepl_tree,
165 struct winsrepl_frame_data *winsrepl)
167 struct wrepl_stop *stop = &winsrepl->w.packet.message.stop;
168 proto_item *stop_item = NULL;
169 proto_tree *stop_tree = NULL;
172 stop_item = proto_tree_add_text(winsrepl_tree, winsrepl_tvb, winsrepl_offset, -1 , "WREPL_STOP_ASSOCIATION");
173 stop_tree = proto_item_add_subtree(stop_item, ett_winsrepl_stop);
177 stop->reason = tvb_get_ntohl(winsrepl_tvb, winsrepl_offset);
178 proto_tree_add_uint(stop_tree, hf_winsrepl_stop_reason, winsrepl_tvb, winsrepl_offset, 4, stop->reason);
179 winsrepl_offset += 4;
181 proto_item_append_text(stop_item, ", Reason: 0x%08X", stop->reason);
183 return winsrepl_offset;
187 dissect_winsrepl_table_query(tvbuff_t *winsrepl_tvb _U_, packet_info *pinfo _U_,
188 int winsrepl_offset, proto_tree *winsrepl_tree _U_,
189 struct winsrepl_frame_data *winsrepl _U_)
191 /* Nothing to do here */
192 return winsrepl_offset;
196 dissect_winsrepl_wins_owner(tvbuff_t *winsrepl_tvb, _U_ packet_info *pinfo,
197 int winsrepl_offset, proto_tree *winsrepl_tree,
198 _U_ struct winsrepl_frame_data *winsrepl,
199 struct wrepl_wins_owner *owner,
200 proto_tree *sub_tree,
203 proto_item *owner_item = NULL;
204 proto_tree *owner_tree = NULL;
205 const guint8 *addr_ptr;
209 owner_item = proto_tree_add_text(sub_tree, winsrepl_tvb, winsrepl_offset, 24 , "WINS Owner [%u]", index);
210 owner_tree = proto_item_add_subtree(owner_item, ett_winsrepl_owner);
211 } else if (winsrepl_tree) {
212 owner_item = proto_tree_add_text(winsrepl_tree, winsrepl_tvb, winsrepl_offset, 24 , "WINS Owner");
213 owner_tree = proto_item_add_subtree(owner_item, ett_winsrepl_owner);
217 addr_ptr = tvb_get_ptr(winsrepl_tvb, winsrepl_offset, 4);
218 addr = tvb_get_ipv4(winsrepl_tvb, winsrepl_offset);
219 SET_ADDRESS(&owner->address, AT_IPv4, 4, addr_ptr);
220 proto_tree_add_ipv4(owner_tree, hf_winsrepl_owner_address, winsrepl_tvb, winsrepl_offset, 4, addr);
221 winsrepl_offset += 4;
224 owner->max_version = tvb_get_ntoh64(winsrepl_tvb, winsrepl_offset);
225 proto_tree_add_uint64(owner_tree, hf_winsrepl_owner_max_version, winsrepl_tvb, winsrepl_offset, 8, owner->max_version);
226 winsrepl_offset += 8;
229 owner->min_version = tvb_get_ntoh64(winsrepl_tvb, winsrepl_offset);
230 proto_tree_add_uint64(owner_tree, hf_winsrepl_owner_min_version, winsrepl_tvb, winsrepl_offset, 8, owner->min_version);
231 winsrepl_offset += 8;
234 owner->type = tvb_get_ntohl(winsrepl_tvb, winsrepl_offset);
235 proto_tree_add_uint(owner_tree, hf_winsrepl_owner_type, winsrepl_tvb, winsrepl_offset, 4, owner->type);
236 winsrepl_offset += 4;
238 return winsrepl_offset;
242 dissect_winsrepl_table_reply(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
243 int winsrepl_offset, proto_tree *winsrepl_tree,
244 struct winsrepl_frame_data *winsrepl)
246 struct wrepl_table *table = &winsrepl->w.packet.message.replication.info.table;
247 struct wrepl_wins_owner owner;
248 proto_item *table_item = NULL;
249 proto_tree *table_tree = NULL;
250 const guint8 *initiator_ptr;
255 table_item = proto_tree_add_text(winsrepl_tree, winsrepl_tvb, winsrepl_offset, -1 , "WREPL_REPL_TABLE_REPLY");
256 table_tree = proto_item_add_subtree(table_item, ett_winsrepl_table_reply);
260 table->partner_count = tvb_get_ntohl(winsrepl_tvb, winsrepl_offset);
261 proto_tree_add_uint(table_tree, hf_winsrepl_table_partner_count, winsrepl_tvb, winsrepl_offset, 4, table->partner_count);
262 winsrepl_offset += 4;
264 for (i=0; i < table->partner_count; i++) {
265 winsrepl_offset = dissect_winsrepl_wins_owner(winsrepl_tvb, pinfo,
266 winsrepl_offset, table_tree,
267 winsrepl, &owner, table_tree, i);
271 initiator_ptr= tvb_get_ptr(winsrepl_tvb, winsrepl_offset, 4);
272 initiator = tvb_get_ipv4(winsrepl_tvb, winsrepl_offset);
273 SET_ADDRESS(&table->initiator, AT_IPv4, 4, initiator_ptr);
274 proto_tree_add_ipv4(table_tree, hf_winsrepl_table_initiator, winsrepl_tvb, winsrepl_offset, 4, initiator);
275 winsrepl_offset += 4;
277 return winsrepl_offset;
281 dissect_winsrepl_send_request(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
282 int winsrepl_offset, proto_tree *winsrepl_tree,
283 struct winsrepl_frame_data *winsrepl)
285 struct wrepl_wins_owner *owner = &winsrepl->w.packet.message.replication.info.owner;
287 winsrepl_offset = dissect_winsrepl_wins_owner(winsrepl_tvb, pinfo,
288 winsrepl_offset, winsrepl_tree,
289 winsrepl, owner, NULL, 0);
291 return winsrepl_offset;
295 dissect_winsrepl_wins_ip(tvbuff_t *winsrepl_tvb, _U_ packet_info *pinfo,
296 int winsrepl_offset, proto_tree *winsrepl_tree,
297 _U_ struct winsrepl_frame_data *winsrepl,
299 proto_tree *sub_tree,
302 proto_item *ip_item = NULL;
303 proto_tree *ip_tree = NULL;
304 const guint8 *addr_ptr;
308 ip_item = proto_tree_add_text(sub_tree, winsrepl_tvb, winsrepl_offset, 8 , "WINS IP [%u]", index);
309 ip_tree = proto_item_add_subtree(ip_item, ett_winsrepl_ip);
310 } else if (winsrepl_tree) {
311 ip_item = proto_tree_add_text(winsrepl_tree, winsrepl_tvb, winsrepl_offset, 8 , "WINS IP");
312 ip_tree = proto_item_add_subtree(ip_item, ett_winsrepl_ip);
316 addr_ptr= tvb_get_ptr(winsrepl_tvb, winsrepl_offset, 4);
317 addr = tvb_get_ipv4(winsrepl_tvb, winsrepl_offset);
318 SET_ADDRESS(&ip->owner, AT_IPv4, 4, addr_ptr);
319 proto_tree_add_ipv4(ip_tree, hf_winsrepl_ip_owner, winsrepl_tvb, winsrepl_offset, 4, addr);
320 winsrepl_offset += 4;
323 addr_ptr= tvb_get_ptr(winsrepl_tvb, winsrepl_offset, 4);
324 addr = tvb_get_ipv4(winsrepl_tvb, winsrepl_offset);
325 SET_ADDRESS(&ip->ip, AT_IPv4, 4, addr_ptr);
326 proto_tree_add_ipv4(ip_tree, hf_winsrepl_ip_ip, winsrepl_tvb, winsrepl_offset, 4, addr);
327 proto_item_append_text(ip_item, ": %s", ip_to_str(ip->ip.data));
328 winsrepl_offset += 4;
330 return winsrepl_offset;
334 dissect_winsrepl_wins_address_list(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
335 int winsrepl_offset, proto_tree *winsrepl_tree,
336 struct winsrepl_frame_data *winsrepl,
337 struct wrepl_address_list *addresses,
338 proto_item *parent_item)
340 proto_item *addr_list_item = NULL;
341 proto_tree *addr_list_tree = NULL;
342 int old_offset = winsrepl_offset;
347 addr_list_item = proto_tree_add_text(winsrepl_tree, winsrepl_tvb, winsrepl_offset, -1 , "WINS Address LIst");
348 addr_list_tree = proto_item_add_subtree(addr_list_item, ett_winsrepl_addr_list);
352 addresses->num_ips = tvb_get_letohl(winsrepl_tvb, winsrepl_offset);
353 proto_tree_add_uint(addr_list_tree, hf_winsrepl_addr_list_num_ips, winsrepl_tvb, winsrepl_offset, 4, addresses->num_ips);
354 winsrepl_offset += 4;
356 for (i=0; i < addresses->num_ips; i++) {
357 winsrepl_offset = dissect_winsrepl_wins_ip(winsrepl_tvb, pinfo,
358 winsrepl_offset, addr_list_tree,
359 winsrepl, &ip, addr_list_tree, i);
361 proto_item_append_text(parent_item, ": %s", ip_to_str(ip.ip.data));
362 proto_item_append_text(addr_list_item, ": %s", ip_to_str(ip.ip.data));
364 proto_item_append_text(parent_item, ", %s", ip_to_str(ip.ip.data));
365 proto_item_append_text(addr_list_item, ", %s", ip_to_str(ip.ip.data));
369 proto_item_set_len(addr_list_item, winsrepl_offset - old_offset);
371 return winsrepl_offset;
375 dissect_winsrepl_wins_name(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
376 int winsrepl_offset, proto_tree *winsrepl_tree,
377 struct winsrepl_frame_data *winsrepl,
378 struct wrepl_wins_name *name,
379 proto_tree *sub_tree,
382 proto_item *name_item = NULL;
383 proto_tree *name_tree = NULL;
384 int old_offset = winsrepl_offset;
385 tvbuff_t *name_tvb = NULL;
386 char name_str[(NETBIOS_NAME_LEN - 1)*4 + 1];
388 const guint8 *addr_ptr;
392 name_item = proto_tree_add_text(sub_tree, winsrepl_tvb, winsrepl_offset, -1 , "WINS Name [%u]", index);
393 name_tree = proto_item_add_subtree(name_item, ett_winsrepl_name);
394 } else if (winsrepl_tree) {
395 name_item = proto_tree_add_text(winsrepl_tree, winsrepl_tvb, winsrepl_offset, -1 , "WINS Name");
396 name_tree = proto_item_add_subtree(name_item, ett_winsrepl_name);
400 name->name_len = tvb_get_ntohl(winsrepl_tvb, winsrepl_offset);
401 proto_tree_add_uint(name_tree, hf_winsrepl_name_len, winsrepl_tvb, winsrepl_offset, 4, name->name_len);
402 winsrepl_offset += 4;
405 name_tvb = tvb_new_subset(winsrepl_tvb, winsrepl_offset, name->name_len, name->name_len);
406 netbios_add_name("Name", name_tvb, 0, name_tree);
407 name_type = get_netbios_name(name_tvb, 0, name_str);
408 proto_item_append_text(name_item, ": %s<%02x>", name_str, name_type);
409 winsrepl_offset += name->name_len;
411 /* ALIGN to 4 Byte */
412 winsrepl_offset += ((winsrepl_offset & (4-1)) == 0 ? 0 : (4 - (winsrepl_offset & (4-1))));
415 name->flags = tvb_get_ntohl(winsrepl_tvb, winsrepl_offset);
416 proto_tree_add_uint(name_tree, hf_winsrepl_name_flags, winsrepl_tvb, winsrepl_offset, 4, name->flags);
417 winsrepl_offset += 4;
420 name->group_flag = tvb_get_letohl(winsrepl_tvb, winsrepl_offset);
421 proto_tree_add_uint(name_tree, hf_winsrepl_name_group_flag, winsrepl_tvb, winsrepl_offset, 4, name->group_flag);
422 winsrepl_offset += 4;
425 name->id = tvb_get_ntoh64(winsrepl_tvb, winsrepl_offset);
426 proto_tree_add_uint64(name_tree, hf_winsrepl_name_id, winsrepl_tvb, winsrepl_offset, 8, name->id);
427 winsrepl_offset += 8;
429 switch (name->flags & 2) {
432 addr_ptr= tvb_get_ptr(winsrepl_tvb, winsrepl_offset, 4);
433 addr = tvb_get_ipv4(winsrepl_tvb, winsrepl_offset);
434 SET_ADDRESS(&name->addresses.ip, AT_IPv4, 4, addr_ptr);
435 proto_tree_add_ipv4(name_tree, hf_winsrepl_ip_ip, winsrepl_tvb, winsrepl_offset, 4, addr);
436 proto_item_append_text(name_item, ": %s", ip_to_str(name->addresses.ip.data));
437 winsrepl_offset += 4;
440 winsrepl_offset = dissect_winsrepl_wins_address_list(winsrepl_tvb, pinfo,
441 winsrepl_offset, name_tree,
442 winsrepl, &name->addresses.addresses, name_item);
447 /* UNKNOWN, little or big endian??? */
448 addr_ptr= tvb_get_ptr(winsrepl_tvb, winsrepl_offset, 4);
449 addr = tvb_get_ipv4(winsrepl_tvb, winsrepl_offset);
450 SET_ADDRESS(&name->unknown, AT_IPv4, 4, addr_ptr);
451 proto_tree_add_ipv4(name_tree, hf_winsrepl_name_unknown, winsrepl_tvb, winsrepl_offset, 4, addr);
452 winsrepl_offset += 4;
454 proto_item_set_len(name_item, winsrepl_offset - old_offset);
456 return winsrepl_offset;
460 dissect_winsrepl_send_reply(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
461 int winsrepl_offset, proto_tree *winsrepl_tree,
462 struct winsrepl_frame_data *winsrepl)
464 struct wrepl_send_reply *reply = &winsrepl->w.packet.message.replication.info.reply;
465 struct wrepl_wins_name name;
466 proto_item *rep_item = NULL;
467 proto_tree *rep_tree = NULL;
471 rep_item = proto_tree_add_text(winsrepl_tree, winsrepl_tvb, winsrepl_offset, -1 , "WREPL_REPL_SEND_REPLY");
472 rep_tree = proto_item_add_subtree(rep_item, ett_winsrepl_send_reply);
476 reply->num_names = tvb_get_ntohl(winsrepl_tvb, winsrepl_offset);
477 proto_tree_add_uint(rep_tree, hf_winsrepl_reply_num_names, winsrepl_tvb, winsrepl_offset, 4, reply->num_names);
478 winsrepl_offset += 4;
480 for (i=0; i < reply->num_names; i++) {
481 winsrepl_offset = dissect_winsrepl_wins_name(winsrepl_tvb, pinfo,
482 winsrepl_offset, rep_tree,
483 winsrepl, &name, rep_tree, i);
486 return winsrepl_offset;
490 dissect_winsrepl_update(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
491 int winsrepl_offset, proto_tree *winsrepl_tree,
492 struct winsrepl_frame_data *winsrepl)
494 winsrepl_offset = dissect_winsrepl_table_reply(winsrepl_tvb, pinfo,
495 winsrepl_offset, winsrepl_tree,
497 return winsrepl_offset;
501 dissect_winsrepl_inform(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
502 int winsrepl_offset, proto_tree *winsrepl_tree,
503 struct winsrepl_frame_data *winsrepl)
505 winsrepl_offset = dissect_winsrepl_table_reply(winsrepl_tvb, pinfo,
506 winsrepl_offset, winsrepl_tree,
508 return winsrepl_offset;
512 dissect_winsrepl_5_or_9(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
513 int winsrepl_offset, proto_tree *winsrepl_tree,
514 struct winsrepl_frame_data *winsrepl)
516 winsrepl_offset = dissect_winsrepl_table_reply(winsrepl_tvb, pinfo,
517 winsrepl_offset, winsrepl_tree,
519 return winsrepl_offset;
523 dissect_winsrepl_replication(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
524 int winsrepl_offset, proto_item *winsrepl_item, proto_tree *winsrepl_tree,
525 struct winsrepl_frame_data *winsrepl)
527 struct wrepl_replication *repl = &winsrepl->w.packet.message.replication;
528 proto_item *repl_item = NULL;
529 proto_tree *repl_tree = NULL;
532 repl_item = proto_tree_add_text(winsrepl_tree, winsrepl_tvb, winsrepl_offset, -1 , "WREPL_REPLICATION");
533 repl_tree = proto_item_add_subtree(repl_item, ett_winsrepl_replication);
536 /* REPLIICATION_CMD */
537 repl->command = tvb_get_ntohl(winsrepl_tvb, winsrepl_offset);
538 proto_tree_add_uint(repl_tree, hf_winsrepl_replication_command, winsrepl_tvb, winsrepl_offset, 4, repl->command);
539 winsrepl_offset += 4;
541 switch (repl->command) {
542 case WREPL_REPL_TABLE_QUERY:
543 if (check_col(pinfo->cinfo, COL_INFO)) {
544 col_add_fstr(pinfo->cinfo, COL_INFO, "WREPL_REPL_TABLE_QUERY");
546 proto_item_append_text(winsrepl_item, ", WREPL_REPL_TABLE_QUERY");
547 proto_item_append_text(repl_item, ", WREPL_REPL_TABLE_QUERY");
548 winsrepl_offset = dissect_winsrepl_table_query(winsrepl_tvb, pinfo,
549 winsrepl_offset, repl_tree,
552 case WREPL_REPL_TABLE_REPLY:
553 if (check_col(pinfo->cinfo, COL_INFO)) {
554 col_add_fstr(pinfo->cinfo, COL_INFO, "WREPL_REPL_TABLE_REPLY");
556 proto_item_append_text(winsrepl_item, ", WREPL_REPL_TABLE_REPLY");
557 proto_item_append_text(repl_item, ", WREPL_REPL_TABLE_REPLY");
558 winsrepl_offset = dissect_winsrepl_table_reply(winsrepl_tvb, pinfo,
559 winsrepl_offset, repl_tree,
562 case WREPL_REPL_SEND_REQUEST:
563 if (check_col(pinfo->cinfo, COL_INFO)) {
564 col_add_fstr(pinfo->cinfo, COL_INFO, "WREPL_REPL_SEND_REQUEST");
566 proto_item_append_text(winsrepl_item, ", WREPL_REPL_SEND_REQUEST");
567 proto_item_append_text(repl_item, ", WREPL_REPL_SEND_REQUEST");
568 winsrepl_offset = dissect_winsrepl_send_request(winsrepl_tvb, pinfo,
569 winsrepl_offset, repl_tree,
572 case WREPL_REPL_SEND_REPLY:
573 if (check_col(pinfo->cinfo, COL_INFO)) {
574 col_add_fstr(pinfo->cinfo, COL_INFO, "WREPL_REPL_SEND_REPLY");
576 proto_item_append_text(winsrepl_item, ", WREPL_REPL_SEND_REPLY");
577 proto_item_append_text(repl_item, ", WREPL_REPL_SEND_REPLY");
578 winsrepl_offset = dissect_winsrepl_send_reply(winsrepl_tvb, pinfo,
579 winsrepl_offset, repl_tree,
582 case WREPL_REPL_UPDATE:
583 if (check_col(pinfo->cinfo, COL_INFO)) {
584 col_add_fstr(pinfo->cinfo, COL_INFO, "WREPL_REPL_UPDATE");
586 proto_item_append_text(winsrepl_item, ", WREPL_REPL_UPDATE");
587 proto_item_append_text(repl_item, ", WREPL_REPL_UPDATE");
588 winsrepl_offset = dissect_winsrepl_update(winsrepl_tvb, pinfo,
589 winsrepl_offset, repl_tree,
593 if (check_col(pinfo->cinfo, COL_INFO)) {
594 col_add_fstr(pinfo->cinfo, COL_INFO, "WREPL_REPL_5");
596 proto_item_append_text(winsrepl_item, ",WREPL_REPL_5");
597 proto_item_append_text(repl_item, ",WREPL_REPL_5");
598 winsrepl_offset = dissect_winsrepl_5_or_9(winsrepl_tvb, pinfo,
599 winsrepl_offset, repl_tree,
602 case WREPL_REPL_INFORM:
603 if (check_col(pinfo->cinfo, COL_INFO)) {
604 col_add_fstr(pinfo->cinfo, COL_INFO, "WREPL_REPL_INFORM");
606 proto_item_append_text(winsrepl_item, ", WREPL_REPL_INFORM");
607 proto_item_append_text(repl_item, ", WREPL_REPL_INFORM");
608 winsrepl_offset = dissect_winsrepl_inform(winsrepl_tvb, pinfo,
609 winsrepl_offset, repl_tree,
613 if (check_col(pinfo->cinfo, COL_INFO)) {
614 col_add_fstr(pinfo->cinfo, COL_INFO, "WREPL_REPL_9");
616 proto_item_append_text(winsrepl_item, ", WREPL_REPL_9");
617 proto_item_append_text(repl_item, ", WREPL_REPL_9");
618 winsrepl_offset = dissect_winsrepl_5_or_9(winsrepl_tvb, pinfo,
619 winsrepl_offset, repl_tree,
624 return winsrepl_offset;
628 dissect_winsrepl_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
631 proto_item *winsrepl_item = NULL;
632 proto_tree *winsrepl_tree = NULL;
633 struct winsrepl_frame_data *winsrepl;
636 winsrepl = ep_alloc(sizeof(struct winsrepl_frame_data));
638 winsrepl->w.size = tvb_get_ntohl(tvb, offset);
641 if (check_col(pinfo->cinfo, COL_PROTOCOL)){
642 col_set_str(pinfo->cinfo, COL_PROTOCOL, "WINS-Replication");
644 if (check_col(pinfo->cinfo, COL_INFO)){
645 col_clear(pinfo->cinfo, COL_INFO);
649 winsrepl_item = proto_tree_add_item(parent_tree, proto_winsrepl, tvb, offset, winsrepl->w.size+4, FALSE);
650 winsrepl_tree = proto_item_add_subtree(winsrepl_item, ett_winsrepl);
654 proto_tree_add_uint(winsrepl_tree, hf_winsrepl_size, tvb, offset, 4, winsrepl->w.size);
658 winsrepl->w.packet.opcode = tvb_get_ntohl(tvb, offset);
659 proto_tree_add_uint(winsrepl_tree, hf_winsrepl_opcode, tvb, offset, 4, winsrepl->w.packet.opcode);
663 winsrepl->w.packet.assoc_ctx = tvb_get_ntohl(tvb, offset);
664 proto_tree_add_uint(winsrepl_tree, hf_winsrepl_assoc_ctx, tvb, offset, 4, winsrepl->w.packet.assoc_ctx);
668 winsrepl->w.packet.mess_type = tvb_get_ntohl(tvb, offset);
669 proto_tree_add_uint(winsrepl_tree, hf_winsrepl_mess_type, tvb, offset, 4, winsrepl->w.packet.mess_type);
672 switch (winsrepl->w.packet.mess_type) {
673 case WREPL_START_ASSOCIATION:
674 if (check_col(pinfo->cinfo, COL_INFO)) {
675 col_add_fstr(pinfo->cinfo, COL_INFO, "WREPL_START_ASSOCIATION");
677 proto_item_append_text(winsrepl_item, ", WREPL_START_ASSOCIATION");
678 offset = dissect_winsrepl_start(tvb, pinfo,
679 offset, winsrepl_tree,
682 case WREPL_START_ASSOCIATION_REPLY:
683 if (check_col(pinfo->cinfo, COL_INFO)) {
684 col_add_fstr(pinfo->cinfo, COL_INFO, "WREPL_START_ASSOCIATION_REPLY");
686 proto_item_append_text(winsrepl_item, ", WREPL_START_ASSOCIATION_REPLY");
687 offset = dissect_winsrepl_start(tvb, pinfo,
688 offset, winsrepl_tree,
691 case WREPL_STOP_ASSOCIATION:
692 if (check_col(pinfo->cinfo, COL_INFO)) {
693 col_add_fstr(pinfo->cinfo, COL_INFO, "WREPL_STOP_ASSOCIATION");
695 proto_item_append_text(winsrepl_item, ", WREPL_STOP_ASSOCIATION");
696 offset = dissect_winsrepl_stop(tvb, pinfo,
697 offset, winsrepl_tree,
700 case WREPL_REPLICATION:
701 offset = dissect_winsrepl_replication(tvb, pinfo,
702 offset, winsrepl_item, winsrepl_tree,
711 get_winsrepl_pdu_len(tvbuff_t *tvb, int offset)
715 pdu_len=tvb_get_ntohl(tvb, offset);
720 dissect_winsrepl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
722 tcp_dissect_pdus(tvb, pinfo, parent_tree, winsrepl_reassemble, 4, get_winsrepl_pdu_len, dissect_winsrepl_pdu);
724 return tvb_length(tvb);
728 proto_register_winsrepl(void)
730 static hf_register_info hf[] = {
731 { &hf_winsrepl_size, {
732 "Packet Size", "winsrepl.size",
733 FT_UINT32, BASE_DEC, NULL, 0x0,
734 "WINS Replication Packet Size", HFILL }},
736 { &hf_winsrepl_opcode, {
737 "Opcode", "winsrepl.opcode",
738 FT_UINT32, BASE_HEX, NULL, 0x0,
739 "WINS Replication Opcode", HFILL }},
741 { &hf_winsrepl_assoc_ctx, {
742 "Assoc_Ctx", "winsrepl.assoc_ctx",
743 FT_UINT32, BASE_HEX, NULL, 0x0,
744 "WINS Replication Assoc_Ctx", HFILL }},
746 { &hf_winsrepl_mess_type, {
747 "Message_Type", "winsrepl.message_type",
748 FT_UINT32, BASE_DEC, VALS(message_type_vals), 0x0,
749 "WINS Replication Message_Type", HFILL }},
751 { &hf_winsrepl_start_minor_version, {
752 "Minor Version", "winsrepl.minor_version",
753 FT_UINT16, BASE_DEC, NULL, 0x0,
754 "WINS Replication Minor Version", HFILL }},
756 { &hf_winsrepl_start_major_version, {
757 "Major Version", "winsrepl.major_version",
758 FT_UINT16, BASE_DEC, NULL, 0x0,
759 "WINS Replication Major Version", HFILL }},
761 { &hf_winsrepl_stop_reason, {
762 "Reason", "winsrepl.reason",
763 FT_UINT32, BASE_HEX, NULL, 0x0,
764 "WINS Replication Reason", HFILL }},
766 { &hf_winsrepl_replication_command, {
767 "Replication Command", "winsrepl.repl_cmd",
768 FT_UINT32, BASE_HEX, VALS(replication_cmd_vals), 0x0,
769 "WINS Replication Command", HFILL }},
771 { &hf_winsrepl_owner_address, {
772 "Owner Address", "winsrepl.owner_address",
773 FT_IPv4, BASE_NONE, NULL, 0x0,
774 "WINS Replication Owner Address", HFILL }},
776 { &hf_winsrepl_owner_max_version, {
777 "Max Version", "winsrepl.max_version",
778 FT_UINT64, BASE_DEC, NULL, 0x0,
779 "WINS Replication Max Version", HFILL }},
781 { &hf_winsrepl_owner_min_version, {
782 "Min Version", "winsrepl.min_version",
783 FT_UINT64, BASE_DEC, NULL, 0x0,
784 "WINS Replication Min Version", HFILL }},
786 { &hf_winsrepl_owner_type, {
787 "Owner Type", "winsrepl.owner_type",
788 FT_UINT32, BASE_DEC, NULL, 0x0,
789 "WINS Replication Owner Type", HFILL }},
791 { &hf_winsrepl_table_partner_count, {
792 "Partner Count", "winsrepl.partner_count",
793 FT_UINT32, BASE_DEC, NULL, 0x0,
794 "WINS Replication Partner Count", HFILL }},
796 { &hf_winsrepl_table_initiator, {
797 "Initiator", "winsrepl.initiator",
798 FT_IPv4, BASE_NONE, NULL, 0x0,
799 "WINS Replication Initiator", HFILL }},
801 { &hf_winsrepl_ip_owner, {
802 "IP Owner", "winsrepl.ip_owner",
803 FT_IPv4, BASE_NONE, NULL, 0x0,
804 "WINS Replication IP Owner", HFILL }},
806 { &hf_winsrepl_ip_ip, {
807 "IP Address", "winsrepl.ip_address",
808 FT_IPv4, BASE_NONE, NULL, 0x0,
809 "WINS Replication IP Address", HFILL }},
811 { &hf_winsrepl_addr_list_num_ips, {
812 "Num IPs", "winsrepl.num_ips",
813 FT_UINT32, BASE_DEC, NULL, 0x0,
814 "WINS Replication Num IPs", HFILL }},
816 { &hf_winsrepl_name_len, {
817 "Name Len", "winsrepl.name_len",
818 FT_UINT32, BASE_DEC, NULL, 0x0,
819 "WINS Replication Name Len", HFILL }},
821 { &hf_winsrepl_name_flags, {
822 "Name Flags", "winsrepl.name_flags",
823 FT_UINT32, BASE_HEX, NULL, 0x0,
824 "WINS Replication Name Flags", HFILL }},
826 { &hf_winsrepl_name_group_flag, {
827 "Name Group Flag", "winsrepl.name_group_flag",
828 FT_UINT32, BASE_HEX, NULL, 0x0,
829 "WINS Replication Name Group Flag", HFILL }},
831 { &hf_winsrepl_name_id, {
832 "Name Id", "winsrepl.name_id",
833 FT_UINT64, BASE_DEC, NULL, 0x0,
834 "WINS Replication Name Id", HFILL }},
836 { &hf_winsrepl_name_unknown, {
837 "Unknown IP", "winsrepl.unknown",
838 FT_IPv4, BASE_NONE, NULL, 0x0,
839 "WINS Replication Unknown IP", HFILL }},
841 { &hf_winsrepl_reply_num_names, {
842 "Num Names", "winsrepl.num_names",
843 FT_UINT32, BASE_DEC, NULL, 0x0,
844 "WINS Replication Num Names", HFILL }},
847 static gint *ett[] = {
851 &ett_winsrepl_replication,
853 &ett_winsrepl_table_reply,
855 &ett_winsrepl_addr_list,
857 &ett_winsrepl_send_reply,
860 module_t *winsrepl_module;
862 proto_winsrepl = proto_register_protocol("WINS (Windows Internet Name Service) Replication",
863 "WINS-Replication", "winsrepl");
864 proto_register_subtree_array(ett, array_length(ett));
865 proto_register_field_array(proto_winsrepl, hf, array_length(hf));
867 winsrepl_module = prefs_register_protocol(proto_winsrepl, NULL);
868 prefs_register_bool_preference(winsrepl_module, "reassemble",
869 "Reassemble WINS-Replication messages spanning multiple TCP segments",
870 "Whether the WINS-Replication dissector should reassemble messages spanning multiple TCP segments."
871 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
872 &winsrepl_reassemble);
876 proto_reg_handoff_winsrepl(void)
878 winsrepl_handle = new_create_dissector_handle(dissect_winsrepl, proto_winsrepl);
879 dissector_add("tcp.port", glb_winsrepl_tcp_port, winsrepl_handle);