Ethereal-dev: [Ethereal-dev] WINS Replication dissector

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Stefan Metzmacher <metze@xxxxxxxxx>
Date: Wed, 7 Sep 2005 13:30:26 +0200
Hi *,

can some apply this for me?

I have allready uploaded some stuff to the Wiki
http://wiki.ethereal.com/WINS-Replication

-- 
metze
--
Stefan (metze) Metzmcher <metze at samba dot org>
Index: epan/dissectors/packet-winsrepl.c
===================================================================
--- epan/dissectors/packet-winsrepl.c	(Revision 0)
+++ epan/dissectors/packet-winsrepl.c	(Revision 0)
@@ -0,0 +1,850 @@
+/*
+ * packet-winsrepl.c
+ * 
+ * Routines for WINS Replication packet dissection
+ *
+ * Copyright 2005 Stefan Metzmacher <metze@xxxxxxxxx>
+ *
+ * $Id$
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@xxxxxxxxxxxx>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+
+#include <time.h>
+#include <string.h>
+#include <glib.h>
+#include <ctype.h>
+#include <epan/packet.h>
+#include <epan/conversation.h>
+#include <epan/strutil.h>
+#include <epan/prefs.h>
+#include <epan/reassemble.h>
+#include <epan/tap.h>
+
+#include "packet-windows-common.h"
+#include "packet-netbios.h"
+
+#include "packet-winsrepl.h"
+
+static gboolean winsrepl_reassemble = TRUE;
+
+struct winsrepl_frame_data {
+	struct wrepl_wrap w;
+};
+
+static int proto_winsrepl = -1;
+
+static int hf_winsrepl_size = -1;
+static int hf_winsrepl_opcode = -1;
+static int hf_winsrepl_assoc_ctx = -1;
+static int hf_winsrepl_mess_type = -1;
+
+static int hf_winsrepl_start_minor_version = -1;
+static int hf_winsrepl_start_major_version = -1;
+
+static int hf_winsrepl_stop_reason = -1;
+
+static int hf_winsrepl_replication_command = -1;
+
+static int hf_winsrepl_owner_address = -1;
+static int hf_winsrepl_owner_max_version = -1;
+static int hf_winsrepl_owner_min_version = -1;
+static int hf_winsrepl_owner_type = -1;
+
+static int hf_winsrepl_table_partner_count = -1;
+static int hf_winsrepl_table_initiator = -1;
+
+static int hf_winsrepl_ip_owner = -1;
+static int hf_winsrepl_ip_ip = -1;
+static int hf_winsrepl_addr_list_num_ips = -1;
+
+static int hf_winsrepl_name_len = -1;
+static int hf_winsrepl_name_flags = -1;
+static int hf_winsrepl_name_group_flag = -1;
+static int hf_winsrepl_name_id = -1;
+static int hf_winsrepl_name_unknown = -1;
+
+static int hf_winsrepl_reply_num_names = -1;
+
+static gint ett_winsrepl = -1;
+
+static gint ett_winsrepl_start = -1;
+static gint ett_winsrepl_stop = -1;
+static gint ett_winsrepl_replication = -1;
+
+static gint ett_winsrepl_owner = -1;
+static gint ett_winsrepl_table_reply = -1;
+
+static gint ett_winsrepl_ip = -1;
+static gint ett_winsrepl_addr_list = -1;
+
+static gint ett_winsrepl_name = -1;
+static gint ett_winsrepl_send_reply = -1;
+
+dissector_handle_t winsrepl_handle;
+
+static unsigned int glb_winsrepl_tcp_port = WINS_REPLICATION_PORT;
+
+static const char *
+decode_winsrepl_replication_cmd(enum wrepl_replication_cmd cmd)
+{
+	switch (cmd) {
+	case WREPL_REPL_TABLE_QUERY:
+		return "WREPL_REPL_TABLE_QUERY";
+	case WREPL_REPL_TABLE_REPLY:
+		return "WREPL_REPL_TABLE_REPLY";
+	case WREPL_REPL_SEND_REQUEST:
+		return "WREPL_REPL_SEND_REQUEST";
+	case WREPL_REPL_SEND_REPLY:
+		return "WREPL_REPL_SEND_REPLY";
+	case WREPL_REPL_UPDATE:
+		return "WREPL_REPL_UPDATE";
+	case WREPL_REPL_INFORM:
+		return "WREPL_REPL_INFORM";
+	}
+	return "UNKNOWN";
+}
+
+static const char *
+decode_winsrepl_message_type(enum wrepl_mess_type type)
+{
+	switch (type) {
+	case WREPL_START_ASSOCIATION:
+		return "WREPL_START_ASSOCIATION";
+	case WREPL_START_ASSOCIATION_REPLY:
+		return "WREPL_START_ASSOCIATION_REPLY";
+	case WREPL_STOP_ASSOCIATION:
+		return "WREPL_STOP_ASSOCIATION";
+	case WREPL_REPLICATION:
+		return "WREPL_REPLICATION";
+	}
+	return "UNKNOWN";
+}
+
+static int
+dissect_winsrepl_start(tvbuff_t *winsrepl_tvb, _U_ packet_info *pinfo,
+		       int winsrepl_offset, proto_tree *winsrepl_tree,
+		       struct winsrepl_frame_data *winsrepl)
+{
+	struct wrepl_start *start = &winsrepl->w.packet.message.start;
+	proto_item *start_item = NULL;
+	proto_tree *start_tree = NULL;
+
+	if (winsrepl_tree) {
+		start_item = proto_tree_add_text(winsrepl_tree, winsrepl_tvb, winsrepl_offset, -1 , "WREPL_START_ASSOCIATION");
+		start_tree = proto_item_add_subtree(start_item, ett_winsrepl_start);
+	}
+
+	/* ASSOC_CTX */
+	start->assoc_ctx = tvb_get_ntohl(winsrepl_tvb, winsrepl_offset);
+	proto_tree_add_uint(start_tree, hf_winsrepl_assoc_ctx, winsrepl_tvb, winsrepl_offset, 4, start->assoc_ctx);
+	winsrepl_offset += 4;
+
+	/* MINOR VERSION */
+	start->minor_version = tvb_get_ntohs(winsrepl_tvb, winsrepl_offset);
+	proto_tree_add_uint(start_tree, hf_winsrepl_start_minor_version, winsrepl_tvb, winsrepl_offset, 2, start->minor_version);
+	winsrepl_offset += 2;
+
+	/* MAJOR VERSION */
+	start->major_version = tvb_get_ntohs(winsrepl_tvb, winsrepl_offset);
+	proto_tree_add_uint(start_tree, hf_winsrepl_start_major_version, winsrepl_tvb, winsrepl_offset, 2, start->major_version);
+	winsrepl_offset += 2;
+
+	return winsrepl_offset;
+}
+
+static int
+dissect_winsrepl_stop(tvbuff_t *winsrepl_tvb, _U_ packet_info *pinfo,
+		      int winsrepl_offset, proto_tree *winsrepl_tree,
+		      struct winsrepl_frame_data *winsrepl)
+{
+	struct wrepl_stop *stop = &winsrepl->w.packet.message.stop;
+	proto_item *stop_item = NULL;
+	proto_tree *stop_tree = NULL;
+
+	if (winsrepl_tree) {
+		stop_item = proto_tree_add_text(winsrepl_tree, winsrepl_tvb, winsrepl_offset, -1 , "WREPL_STOP_ASSOCIATION");
+		stop_tree = proto_item_add_subtree(stop_item, ett_winsrepl_stop);
+	}
+
+	/* REASON */
+	stop->reason = tvb_get_ntohl(winsrepl_tvb, winsrepl_offset);
+	proto_tree_add_uint(stop_tree, hf_winsrepl_stop_reason, winsrepl_tvb, winsrepl_offset, 4, stop->reason);
+	winsrepl_offset += 4;
+
+	return winsrepl_offset;
+}
+
+static int
+dissect_winsrepl_table_query(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
+			     int winsrepl_offset, proto_tree *winsrepl_tree,
+			     struct winsrepl_frame_data *winsrepl)
+{
+	/* Nothing to do here */
+	return winsrepl_offset;
+}
+
+static int
+dissect_winsrepl_wins_owner(tvbuff_t *winsrepl_tvb, _U_ packet_info *pinfo,
+			    int winsrepl_offset, proto_tree *winsrepl_tree,
+			    _U_ struct winsrepl_frame_data *winsrepl,
+			    struct wrepl_wins_owner *owner,
+			    proto_tree *sub_tree,
+			    guint32 index)
+{
+	proto_item *owner_item = NULL;
+	proto_tree *owner_tree = NULL;
+	const guint8 *addr_ptr;
+	guint32 addr;
+
+	if (sub_tree) {
+		owner_item = proto_tree_add_text(sub_tree, winsrepl_tvb, winsrepl_offset, 24 , "Wins Owner [%u]", index);
+		owner_tree = proto_item_add_subtree(owner_item, ett_winsrepl_owner);
+	} else if (winsrepl_tree) {
+		owner_item = proto_tree_add_text(winsrepl_tree, winsrepl_tvb, winsrepl_offset, 24 , "Wins Owner");
+		owner_tree = proto_item_add_subtree(owner_item, ett_winsrepl_owner);
+	}
+
+	/* ADDRESS */
+	addr_ptr = tvb_get_ptr(winsrepl_tvb, winsrepl_offset, 4);
+	addr = tvb_get_letohl(winsrepl_tvb, winsrepl_offset);
+	SET_ADDRESS(&owner->address, AT_IPv4, 4, addr_ptr);
+	proto_tree_add_ipv4(owner_tree, hf_winsrepl_owner_address, winsrepl_tvb, winsrepl_offset, 4, addr);
+	winsrepl_offset += 4;
+
+	/* MAX_VERSION */
+	owner->max_version = tvb_get_ntoh64(winsrepl_tvb, winsrepl_offset);
+	proto_tree_add_uint64(owner_tree, hf_winsrepl_owner_max_version, winsrepl_tvb, winsrepl_offset, 8, owner->max_version);
+	winsrepl_offset += 8;
+
+	/* MIN_VERSION */
+	owner->min_version = tvb_get_ntoh64(winsrepl_tvb, winsrepl_offset);
+	proto_tree_add_uint64(owner_tree, hf_winsrepl_owner_min_version, winsrepl_tvb, winsrepl_offset, 8, owner->min_version);
+	winsrepl_offset += 8;
+
+	/* TYPE */
+	owner->type = tvb_get_ntohl(winsrepl_tvb, winsrepl_offset);
+	proto_tree_add_uint(owner_tree, hf_winsrepl_owner_type, winsrepl_tvb, winsrepl_offset, 4, owner->type);
+	winsrepl_offset += 4;
+
+	return winsrepl_offset;
+}
+
+static int
+dissect_winsrepl_table_reply(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
+			     int winsrepl_offset, proto_tree *winsrepl_tree,
+			     struct winsrepl_frame_data *winsrepl)
+{
+	struct wrepl_table *table = &winsrepl->w.packet.message.replication.info.table;
+	struct wrepl_wins_owner owner;
+	proto_item *table_item = NULL;
+	proto_tree *table_tree = NULL;
+	const guint8 *initiator_ptr;
+	guint32 initiator;
+	guint32 i;
+
+	if (winsrepl_tree) {
+		table_item = proto_tree_add_text(winsrepl_tree, winsrepl_tvb, winsrepl_offset, -1 , "WREPL_REPL_TABLE_REPLY");
+		table_tree = proto_item_add_subtree(table_item, ett_winsrepl_table_reply);
+	}
+
+	/* PARTNER COUNT */
+	table->partner_count = tvb_get_ntohl(winsrepl_tvb, winsrepl_offset);
+	proto_tree_add_uint(table_tree, hf_winsrepl_table_partner_count, winsrepl_tvb, winsrepl_offset, 4, table->partner_count);
+	winsrepl_offset += 4;
+
+	for (i=0; i < table->partner_count; i++) {
+		winsrepl_offset = dissect_winsrepl_wins_owner(winsrepl_tvb, pinfo,
+							      winsrepl_offset, table_tree,
+							      winsrepl, &owner, table_tree, i);
+	}
+
+	/* INITIATOR */
+	initiator_ptr= tvb_get_ptr(winsrepl_tvb, winsrepl_offset, 4);
+	initiator = tvb_get_letohl(winsrepl_tvb, winsrepl_offset);
+	SET_ADDRESS(&table->initiator, AT_IPv4, 4, initiator_ptr);
+	proto_tree_add_ipv4(table_tree, hf_winsrepl_table_initiator, winsrepl_tvb, winsrepl_offset, 4, initiator);
+	winsrepl_offset += 4;
+
+	return winsrepl_offset;
+}
+
+static int
+dissect_winsrepl_send_request(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
+			     int winsrepl_offset, proto_tree *winsrepl_tree,
+			     struct winsrepl_frame_data *winsrepl)
+{
+	struct wrepl_wins_owner *owner = &winsrepl->w.packet.message.replication.info.owner;
+
+	winsrepl_offset = dissect_winsrepl_wins_owner(winsrepl_tvb, pinfo,
+						      winsrepl_offset, winsrepl_tree,
+						      winsrepl, owner, NULL, 0);
+
+	return winsrepl_offset;
+}
+
+static int
+dissect_winsrepl_wins_ip(tvbuff_t *winsrepl_tvb, _U_ packet_info *pinfo,
+			 int winsrepl_offset, proto_tree *winsrepl_tree,
+			 _U_ struct winsrepl_frame_data *winsrepl,
+			 struct wrepl_ip *ip,
+			 proto_tree *sub_tree,
+			 guint32 index)
+{
+	proto_item *ip_item = NULL;
+	proto_tree *ip_tree = NULL;
+	const guint8 *addr_ptr;
+	guint32 addr;
+
+	if (sub_tree) {
+		ip_item = proto_tree_add_text(sub_tree, winsrepl_tvb, winsrepl_offset, 8 , "Wins IP [%u]", index);
+		ip_tree = proto_item_add_subtree(ip_item, ett_winsrepl_ip);
+	} else if (winsrepl_tree) {
+		ip_item = proto_tree_add_text(winsrepl_tree, winsrepl_tvb, winsrepl_offset, 8 , "Wins IP");
+		ip_tree = proto_item_add_subtree(ip_item, ett_winsrepl_ip);
+	}
+
+	/* OWNER */
+	addr_ptr= tvb_get_ptr(winsrepl_tvb, winsrepl_offset, 4);
+	addr = tvb_get_letohl(winsrepl_tvb, winsrepl_offset);
+	SET_ADDRESS(&ip->owner, AT_IPv4, 4, addr_ptr);
+	proto_tree_add_ipv4(ip_tree, hf_winsrepl_ip_owner, winsrepl_tvb, winsrepl_offset, 4, addr);
+	winsrepl_offset += 4;
+
+	/* IP */
+	addr_ptr= tvb_get_ptr(winsrepl_tvb, winsrepl_offset, 4);
+	addr = tvb_get_letohl(winsrepl_tvb, winsrepl_offset);
+	SET_ADDRESS(&ip->ip, AT_IPv4, 4, addr_ptr);
+	proto_tree_add_ipv4(ip_tree, hf_winsrepl_ip_ip, winsrepl_tvb, winsrepl_offset, 4, addr);
+	proto_item_append_text(ip_item, ": %s", ip_to_str(ip->ip.data));
+	winsrepl_offset += 4;
+
+	return winsrepl_offset;
+}
+
+static int
+dissect_winsrepl_wins_address_list(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
+				   int winsrepl_offset, proto_tree *winsrepl_tree,
+				   struct winsrepl_frame_data *winsrepl,
+				   struct wrepl_address_list *addresses,
+				   proto_item *parent_item)
+{
+	proto_item *addr_list_item = NULL;
+	proto_tree *addr_list_tree = NULL;
+	int old_offset = winsrepl_offset;
+	struct wrepl_ip ip;
+	guint32 i;
+
+	if (winsrepl_tree) {
+		addr_list_item = proto_tree_add_text(winsrepl_tree, winsrepl_tvb, winsrepl_offset, -1 , "Wins Address LIst");
+		addr_list_tree = proto_item_add_subtree(addr_list_item, ett_winsrepl_addr_list);
+	}
+
+	/* NUM_IPS */
+	addresses->num_ips = tvb_get_letohl(winsrepl_tvb, winsrepl_offset);
+	proto_tree_add_uint(addr_list_tree, hf_winsrepl_addr_list_num_ips, winsrepl_tvb, winsrepl_offset, 4, addresses->num_ips);
+	winsrepl_offset += 4;
+
+	for (i=0; i < addresses->num_ips; i++) {
+		winsrepl_offset = dissect_winsrepl_wins_ip(winsrepl_tvb, pinfo,
+							   winsrepl_offset, addr_list_tree,
+							   winsrepl, &ip, addr_list_tree, i);
+		if (i == 0) {
+			proto_item_append_text(parent_item, ": %s", ip_to_str(ip.ip.data));
+			proto_item_append_text(addr_list_item, ": %s", ip_to_str(ip.ip.data));
+		} else {
+			proto_item_append_text(parent_item, ", %s", ip_to_str(ip.ip.data));
+			proto_item_append_text(addr_list_item, ", %s", ip_to_str(ip.ip.data));
+		}
+	}
+
+	proto_item_set_len(addr_list_item, winsrepl_offset - old_offset);
+
+	return winsrepl_offset;
+}
+
+static int
+dissect_winsrepl_wins_name(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
+			   int winsrepl_offset, proto_tree *winsrepl_tree,
+			   struct winsrepl_frame_data *winsrepl,
+			   struct wrepl_wins_name *name,
+			   proto_tree *sub_tree,
+			   guint32 index)
+{
+	proto_item *name_item = NULL;
+	proto_tree *name_tree = NULL;
+	int old_offset = winsrepl_offset;
+	tvbuff_t *name_tvb = NULL;
+	char  name_str[(NETBIOS_NAME_LEN - 1)*4 + 1];
+	int   name_type;
+	const guint8 *addr_ptr;
+	guint32 addr;
+
+	if (sub_tree) {
+		name_item = proto_tree_add_text(sub_tree, winsrepl_tvb, winsrepl_offset, -1 , "Wins Name [%u]", index);
+		name_tree = proto_item_add_subtree(name_item, ett_winsrepl_name);
+	} else if (winsrepl_tree) {
+		name_item = proto_tree_add_text(winsrepl_tree, winsrepl_tvb, winsrepl_offset, -1 , "Wins Name");
+		name_tree = proto_item_add_subtree(name_item, ett_winsrepl_name);
+	}
+
+	/* NAME_LEN */
+	name->name_len = tvb_get_ntohl(winsrepl_tvb, winsrepl_offset);
+	proto_tree_add_uint(name_tree, hf_winsrepl_name_len, winsrepl_tvb, winsrepl_offset, 4, name->name_len);
+	winsrepl_offset += 4;
+
+	/* NAME: TODO! */
+	name_tvb = tvb_new_subset(winsrepl_tvb, winsrepl_offset, name->name_len, name->name_len);
+	netbios_add_name("Name", name_tvb, 0, name_tree);
+	name_type = get_netbios_name(name_tvb, 0, name_str);
+	proto_item_append_text(name_item, ": %s<%02x>", name_str, name_type);
+	winsrepl_offset += name->name_len;
+
+	/* ALIGN to 4 Byte */
+	winsrepl_offset += ((winsrepl_offset & (4-1)) == 0 ? 0 : (4 - (winsrepl_offset & (4-1))));
+
+	/* FLAGS */
+	name->flags = tvb_get_ntohl(winsrepl_tvb, winsrepl_offset);
+	proto_tree_add_uint(name_tree, hf_winsrepl_name_flags, winsrepl_tvb, winsrepl_offset, 4, name->flags);
+	winsrepl_offset += 4;
+
+	/* GROUP_FLAG */
+	name->group_flag = tvb_get_letohl(winsrepl_tvb, winsrepl_offset);
+	proto_tree_add_uint(name_tree, hf_winsrepl_name_group_flag, winsrepl_tvb, winsrepl_offset, 4, name->group_flag);
+	winsrepl_offset += 4;
+
+	/* ID */
+	name->id = tvb_get_ntoh64(winsrepl_tvb, winsrepl_offset);
+	proto_tree_add_uint64(name_tree, hf_winsrepl_name_id, winsrepl_tvb, winsrepl_offset, 8, name->id);
+	winsrepl_offset += 8;
+
+	switch (name->flags & 2) {
+		case 0:
+			/* IP */
+			addr_ptr= tvb_get_ptr(winsrepl_tvb, winsrepl_offset, 4);
+			addr = tvb_get_letohl(winsrepl_tvb, winsrepl_offset);
+			SET_ADDRESS(&name->addresses.ip, AT_IPv4, 4, addr_ptr);
+			proto_tree_add_ipv4(name_tree, hf_winsrepl_ip_ip, winsrepl_tvb, winsrepl_offset, 4, addr);
+			proto_item_append_text(name_item, ": %s", ip_to_str(name->addresses.ip.data));
+			winsrepl_offset += 4;
+			break;
+		case 2:
+			winsrepl_offset = dissect_winsrepl_wins_address_list(winsrepl_tvb, pinfo,
+									     winsrepl_offset, name_tree,
+			 						     winsrepl, &name->addresses.addresses, name_item);
+			break;
+	}
+
+
+	/* UNKNOWN, little or big endian??? */
+	addr_ptr= tvb_get_ptr(winsrepl_tvb, winsrepl_offset, 4);
+	addr = tvb_get_letohl(winsrepl_tvb, winsrepl_offset);
+	SET_ADDRESS(&name->unknown, AT_IPv4, 4, addr_ptr);
+	proto_tree_add_ipv4(name_tree, hf_winsrepl_name_unknown, winsrepl_tvb, winsrepl_offset, 4, addr);
+	winsrepl_offset += 4;
+
+	proto_item_set_len(name_item, winsrepl_offset - old_offset);
+
+	return winsrepl_offset;
+}
+
+static int
+dissect_winsrepl_send_reply(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
+			    int winsrepl_offset, proto_tree *winsrepl_tree,
+			    struct winsrepl_frame_data *winsrepl)
+{
+	struct wrepl_send_reply *reply = &winsrepl->w.packet.message.replication.info.reply;
+	struct wrepl_wins_name name;
+	proto_item *rep_item = NULL;
+	proto_tree *rep_tree = NULL;
+	guint32 i;
+
+	if (winsrepl_tree) {
+		rep_item = proto_tree_add_text(winsrepl_tree, winsrepl_tvb, winsrepl_offset, -1 , "WREPL_REPL_SEND_REPLY");
+		rep_tree = proto_item_add_subtree(rep_item, ett_winsrepl_send_reply);
+	}
+
+	/* NUM NAMES */
+	reply->num_names = tvb_get_ntohl(winsrepl_tvb, winsrepl_offset);
+	proto_tree_add_uint(rep_tree, hf_winsrepl_reply_num_names, winsrepl_tvb, winsrepl_offset, 4, reply->num_names);
+	winsrepl_offset += 4;
+
+	for (i=0; i < reply->num_names; i++) {
+		winsrepl_offset = dissect_winsrepl_wins_name(winsrepl_tvb, pinfo,
+							     winsrepl_offset, rep_tree,
+							     winsrepl, &name, rep_tree, i);
+	}
+
+	return winsrepl_offset;
+}
+
+static int
+dissect_winsrepl_update(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
+			int winsrepl_offset, proto_tree *winsrepl_tree,
+			struct winsrepl_frame_data *winsrepl)
+{
+	return winsrepl_offset;
+}
+
+static int
+dissect_winsrepl_inform(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
+			int winsrepl_offset, proto_tree *winsrepl_tree,
+			struct winsrepl_frame_data *winsrepl)
+{
+	winsrepl_offset = dissect_winsrepl_table_reply(winsrepl_tvb, pinfo,
+						       winsrepl_offset, winsrepl_tree,
+						       winsrepl);
+	return winsrepl_offset;
+}
+
+static int
+dissect_winsrepl_replication(tvbuff_t *winsrepl_tvb, packet_info *pinfo,
+			     int winsrepl_offset, proto_tree *winsrepl_tree,
+			     struct winsrepl_frame_data *winsrepl)
+{
+	struct wrepl_replication *repl = &winsrepl->w.packet.message.replication;
+	proto_item *repl_item = NULL;
+	proto_tree *repl_tree = NULL;
+
+	if (winsrepl_tree) {
+		repl_item = proto_tree_add_text(winsrepl_tree, winsrepl_tvb, winsrepl_offset, -1 , "WREPL_REPLICATION");
+		repl_tree = proto_item_add_subtree(repl_item, ett_winsrepl_replication);
+	}
+	
+	/* REPLIICATION_CMD */
+	repl->command = tvb_get_ntohl(winsrepl_tvb, winsrepl_offset);
+	proto_tree_add_uint_format(repl_tree, hf_winsrepl_replication_command, winsrepl_tvb, winsrepl_offset, 4,
+				   repl->command, "Replication Cmd: %s (0x%08X)",
+				   decode_winsrepl_replication_cmd(repl->command), repl->command);
+	winsrepl_offset += 4;
+
+	switch (repl->command) {
+		case WREPL_REPL_TABLE_QUERY:
+			winsrepl_offset = dissect_winsrepl_table_query(winsrepl_tvb, pinfo,
+								       winsrepl_offset, repl_tree,
+								       winsrepl);
+			break;
+		case WREPL_REPL_TABLE_REPLY:
+			winsrepl_offset = dissect_winsrepl_table_reply(winsrepl_tvb, pinfo,
+								       winsrepl_offset, repl_tree,
+								       winsrepl);
+			break;
+		case WREPL_REPL_SEND_REQUEST:
+			winsrepl_offset = dissect_winsrepl_send_request(winsrepl_tvb, pinfo,
+									winsrepl_offset, repl_tree,
+									winsrepl);
+			break;
+		case WREPL_REPL_SEND_REPLY:
+			winsrepl_offset = dissect_winsrepl_send_reply(winsrepl_tvb, pinfo,
+								      winsrepl_offset, repl_tree,
+								      winsrepl);
+			break;
+		case WREPL_REPL_UPDATE:
+			winsrepl_offset = dissect_winsrepl_update(winsrepl_tvb, pinfo,
+								  winsrepl_offset, repl_tree,
+								  winsrepl);
+			break;
+		case WREPL_REPL_INFORM:
+			winsrepl_offset = dissect_winsrepl_inform(winsrepl_tvb, pinfo,
+								  winsrepl_offset, repl_tree,
+								  winsrepl);
+			break;
+	}
+
+	return winsrepl_offset;
+}
+
+static void
+dissect_winsrepl_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
+{
+	int winsrepl_offset = 0;
+	tvbuff_t *winsrepl_tvb = NULL;
+	proto_item *winsrepl_item = NULL;
+	proto_tree *winsrepl_tree = NULL;
+	struct winsrepl_frame_data _winsrepl_frame;
+	struct winsrepl_frame_data *winsrepl = &_winsrepl_frame;
+
+	if (check_col(pinfo->cinfo, COL_PROTOCOL)){
+		col_set_str(pinfo->cinfo, COL_PROTOCOL, "WINS-Replication");
+	}
+	if (check_col(pinfo->cinfo, COL_INFO)){
+		col_clear(pinfo->cinfo, COL_INFO);
+	}
+
+	winsrepl_tvb = tvb_new_subset(tvb, 0, -1, -1);
+
+	if (parent_tree) {
+		winsrepl_item = proto_tree_add_item(parent_tree, proto_winsrepl, winsrepl_tvb, winsrepl_offset, -1, FALSE);
+		winsrepl_tree = proto_item_add_subtree(winsrepl_item, ett_winsrepl);
+	}
+
+	/* SIZE */
+	winsrepl->w.size = tvb_get_ntohl(winsrepl_tvb, winsrepl_offset);
+	proto_tree_add_uint(winsrepl_tree, hf_winsrepl_size, winsrepl_tvb, winsrepl_offset, 4, winsrepl->w.size);
+	winsrepl_offset += 4;
+
+	proto_item_set_len(winsrepl_item, winsrepl->w.size + 4);
+
+	/* OPCODE */
+	winsrepl->w.packet.opcode = tvb_get_ntohl(winsrepl_tvb, winsrepl_offset);
+	proto_tree_add_uint(winsrepl_tree, hf_winsrepl_opcode, winsrepl_tvb, winsrepl_offset, 4, winsrepl->w.packet.opcode);
+	winsrepl_offset += 4;
+
+	/* ASSOC_CTX */
+	winsrepl->w.packet.assoc_ctx = tvb_get_ntohl(winsrepl_tvb, winsrepl_offset);
+	proto_tree_add_uint(winsrepl_tree, hf_winsrepl_assoc_ctx, winsrepl_tvb, winsrepl_offset, 4, winsrepl->w.packet.assoc_ctx);
+	winsrepl_offset += 4;
+
+	/* MESSAGE_TYPE */
+	winsrepl->w.packet.mess_type = tvb_get_ntohl(winsrepl_tvb, winsrepl_offset);
+	proto_tree_add_uint_format(winsrepl_tree, hf_winsrepl_mess_type, winsrepl_tvb, winsrepl_offset, 4,
+				   winsrepl->w.packet.mess_type, "Message Type: %s (0x%08X)",
+				   decode_winsrepl_message_type(winsrepl->w.packet.mess_type),
+				   winsrepl->w.packet.mess_type);
+	winsrepl_offset += 4;
+
+	switch (winsrepl->w.packet.mess_type) {
+		case WREPL_START_ASSOCIATION:
+			winsrepl_offset = dissect_winsrepl_start(winsrepl_tvb, pinfo,
+								 winsrepl_offset, winsrepl_tree,
+								 winsrepl);
+			break;
+		case WREPL_START_ASSOCIATION_REPLY:
+			winsrepl_offset = dissect_winsrepl_start(winsrepl_tvb, pinfo,
+								 winsrepl_offset, winsrepl_tree,
+								 winsrepl);
+			break;
+		case WREPL_STOP_ASSOCIATION:
+			winsrepl_offset = dissect_winsrepl_stop(winsrepl_tvb, pinfo,
+								winsrepl_offset, winsrepl_tree,
+								winsrepl);
+			break;
+		case WREPL_REPLICATION:
+			winsrepl_offset = dissect_winsrepl_replication(winsrepl_tvb, pinfo,
+								       winsrepl_offset, winsrepl_tree,
+								       winsrepl);
+			break;
+	}
+
+	return;
+}
+
+static void
+dissect_winsrepl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
+{
+	int offset = 0;
+
+	if (!winsrepl_reassemble || !pinfo->can_desegment) {
+		dissect_winsrepl_pdu(tvb, pinfo, parent_tree);
+		return;
+	}
+
+	while (tvb_reported_length_remaining(tvb, offset) > 0) {
+		guint length_remaining = 0;
+		tvbuff_t *pdu_tvb = NULL;
+		guint32 pdu_size = 0;
+
+		length_remaining = tvb_ensure_length_remaining(tvb, offset);
+		if (length_remaining < 4) {
+			pinfo->desegment_offset	= offset;
+			pinfo->desegment_len	= 4 - length_remaining;
+			return;
+		}
+
+		pdu_size = tvb_get_ntohl(tvb, offset);
+		pdu_size += 4;
+
+		if (length_remaining < pdu_size) {
+			pinfo->want_pdu_tracking	= 2;
+			pinfo->bytes_until_next_pdu	= pdu_size - length_remaining;
+			pinfo->desegment_offset	= offset;
+			pinfo->desegment_len	= pdu_size - length_remaining;
+			return;
+		}
+
+		pdu_tvb = tvb_new_subset(tvb, offset, pdu_size, pdu_size);
+
+		dissect_winsrepl_pdu(pdu_tvb, pinfo, parent_tree);
+
+		offset += pdu_size;
+	}
+
+	return;
+}
+
+void
+proto_register_winsrepl(void)
+{
+	static hf_register_info hf[] = {
+		{ &hf_winsrepl_size, {
+			"Packet Size", "winsrepl.size",
+			FT_UINT32, BASE_DEC, NULL, 0x0,
+			"WINS Replication Packet Size", HFILL }},
+
+		{ &hf_winsrepl_opcode, {
+			"Opcode", "winsrepl.opcode",
+			FT_UINT32, BASE_HEX, NULL, 0x0,
+			"WINS Replication Opcode", HFILL }},
+
+		{ &hf_winsrepl_assoc_ctx, {
+			"Assoc_Ctx", "winsrepl.assoc_ctx",
+			FT_UINT32, BASE_HEX, NULL, 0x0,
+			"WINS Replication Assoc_Ctx", HFILL }},
+
+		{ &hf_winsrepl_mess_type, {
+			"Assoc_Ctx", "winsrepl.message_type",
+			FT_UINT32, BASE_DEC, NULL, 0x0,
+			"WINS Replication Message_Type", HFILL }},
+
+		{ &hf_winsrepl_start_minor_version, {
+			"Minor Version", "winsrepl.minor_version",
+			FT_UINT16, BASE_DEC, NULL, 0x0,
+			"WINS Replication Minor Version", HFILL }},
+
+		{ &hf_winsrepl_start_major_version, {
+			"Major Version", "winsrepl.major_version",
+			FT_UINT16, BASE_DEC, NULL, 0x0,
+			"WINS Replication Major Version", HFILL }},
+
+		{ &hf_winsrepl_stop_reason, {
+			"Reason", "winsrepl.reason",
+			FT_UINT32, BASE_HEX, NULL, 0x0,
+			"WINS Replication Reason", HFILL }},
+
+		{ &hf_winsrepl_replication_command, {
+			"Replication Command", "winsrepl.repl_cmd",
+			FT_UINT32, BASE_HEX, NULL, 0x0,
+			"WINS Replication Command", HFILL }},
+
+		{ &hf_winsrepl_owner_address, {
+			"Owner Address", "winsrepl.owner_address",
+			FT_IPv4, BASE_NONE, NULL, 0x0,
+			"WINS Replication Owner Address", HFILL }},
+
+		{ &hf_winsrepl_owner_max_version, {
+			"Max Version", "winsrepl.max_version",
+			FT_UINT64, BASE_DEC, NULL, 0x0,
+			"WINS Replication Max Version", HFILL }},
+
+		{ &hf_winsrepl_owner_min_version, {
+			"Min Version", "winsrepl.min_version",
+			FT_UINT64, BASE_DEC, NULL, 0x0,
+			"WINS Replication Min Version", HFILL }},
+
+		{ &hf_winsrepl_owner_type, {
+			"Owner Type", "winsrepl.owner_type",
+			FT_UINT32, BASE_DEC, NULL, 0x0,
+			"WINS Replication Owner Type", HFILL }},
+
+		{ &hf_winsrepl_table_partner_count, {
+			"Partner Count", "winsrepl.partner_count",
+			FT_UINT32, BASE_DEC, NULL, 0x0,
+			"WINS Replication Partner Count", HFILL }},
+
+		{ &hf_winsrepl_table_initiator, {
+			"Initiator", "winsrepl.initiator",
+			FT_IPv4, BASE_NONE, NULL, 0x0,
+			"WINS Replication Initiator", HFILL }},
+
+		{ &hf_winsrepl_ip_owner, {
+			"IP Owner", "winsrepl.ip_owner",
+			FT_IPv4, BASE_NONE, NULL, 0x0,
+			"WINS Replication IP Owner", HFILL }},
+
+		{ &hf_winsrepl_ip_ip, {
+			"IP Address", "winsrepl.ip_address",
+			FT_IPv4, BASE_NONE, NULL, 0x0,
+			"WINS Replication IP Address", HFILL }},
+
+		{ &hf_winsrepl_addr_list_num_ips, {
+			"Num IPs", "winsrepl.num_ips",
+			FT_UINT32, BASE_DEC, NULL, 0x0,
+			"WINS Replication Num IPs", HFILL }},
+
+		{ &hf_winsrepl_name_len, {
+			"Name Len", "winsrepl.name_len",
+			FT_UINT32, BASE_DEC, NULL, 0x0,
+			"WINS Replication Name Len", HFILL }},
+
+		{ &hf_winsrepl_name_flags, {
+			"Name Flags", "winsrepl.name_flags",
+			FT_UINT32, BASE_HEX, NULL, 0x0,
+			"WINS Replication Name Flags", HFILL }},
+
+		{ &hf_winsrepl_name_group_flag, {
+			"Name Group Flag", "winsrepl.name_group_flag",
+			FT_UINT32, BASE_HEX, NULL, 0x0,
+			"WINS Replication Name Group Flag", HFILL }},
+
+		{ &hf_winsrepl_name_id, {
+			"Name Id", "winsrepl.name_id",
+			FT_UINT64, BASE_DEC, NULL, 0x0,
+			"WINS Replication Name Id", HFILL }},
+
+		{ &hf_winsrepl_name_unknown, {
+			"Unknown IP", "winsrepl.unknown",
+			FT_IPv4, BASE_NONE, NULL, 0x0,
+			"WINS Replication Unknown IP", HFILL }},
+
+		{ &hf_winsrepl_reply_num_names, {
+			"Num Names", "winsrepl.num_names",
+			FT_UINT32, BASE_DEC, NULL, 0x0,
+			"WINS Replication Num Names", HFILL }},
+	};
+
+	static gint *ett[] = {
+		&ett_winsrepl,
+		&ett_winsrepl_start,
+		&ett_winsrepl_stop,
+		&ett_winsrepl_replication,
+		&ett_winsrepl_owner,
+		&ett_winsrepl_table_reply,
+		&ett_winsrepl_ip,
+		&ett_winsrepl_addr_list,
+		&ett_winsrepl_name,
+		&ett_winsrepl_send_reply,
+	};
+
+	module_t *winsrepl_module;
+
+	proto_winsrepl = proto_register_protocol("WINS (Windows Internet Name Service) Replication",
+						 "WINS-Replication", "winsrepl");
+	proto_register_subtree_array(ett, array_length(ett));
+	proto_register_field_array(proto_winsrepl, hf, array_length(hf));
+
+	winsrepl_module = prefs_register_protocol(proto_winsrepl, NULL);
+	prefs_register_bool_preference(winsrepl_module, "reassemble",
+		"Reassemble WINS-Replication messages spanning multiple TCP segments",
+		"Whether the WINS-Replication dissector should reassemble messages spanning multiple TCP segments."
+		" To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
+		&winsrepl_reassemble);
+}
+
+void
+proto_reg_handoff_winsrepl(void)
+{
+	winsrepl_handle = create_dissector_handle(dissect_winsrepl, proto_winsrepl);
+	dissector_add("tcp.port", glb_winsrepl_tcp_port, winsrepl_handle);
+}
Index: epan/dissectors/packet-winsrepl.h
===================================================================
--- epan/dissectors/packet-winsrepl.h	(Revision 0)
+++ epan/dissectors/packet-winsrepl.h	(Revision 0)
@@ -0,0 +1,129 @@
+/* header auto-generated by pidl */
+
+/*
+ * winsrepl.h (generated from winsrepl.idl)
+ *
+ * Modified for ethereal:
+ *
+ * uint8_t			=> guint8
+ * uint16_t			=> guint16
+ * uint32_t			=> guint32
+ * uint64_t			=> guint64
+ * ipv4addres (const char *)	=> address
+ * DATA_BLOB			=> (skipped)
+ */
+
+#ifndef _HEADER_wrepl
+#define _HEADER_wrepl
+
+#define WINS_REPLICATION_PORT	( 42 )
+#define WREPL_OPCODE_BITS	( 0x7800 )
+struct wrepl_ip {
+	address owner;
+	address ip;
+}/* [flag(LIBNDR_FLAG_BIGENDIAN)] */;
+
+struct wrepl_address_list {
+	guint32 num_ips;
+	struct wrepl_ip *ips;
+}/* [flag(LIBNDR_FLAG_LITTLE_ENDIAN)] */;
+
+union wrepl_addresses {
+	address ip;/* [case(0)] */
+	struct wrepl_address_list addresses;/* [case(2)] */
+}/* [nodiscriminant] */;
+
+struct wrepl_wins_name {
+	guint32 name_len;
+	guint8 *name;
+	guint32 flags;
+	guint32 group_flag;/* [flag(LIBNDR_FLAG_LITTLE_ENDIAN)] */
+	guint64 id;
+	union wrepl_addresses addresses;/* [switch_is(flags&2)] */
+	address unknown;
+};
+
+struct wrepl_send_reply {
+	guint32 num_names;
+	struct wrepl_wins_name *names;
+};
+
+struct wrepl_wins_owner {
+	address address;
+	guint64 max_version;
+	guint64 min_version;
+	guint32 type;
+};
+
+struct wrepl_table {
+	guint32 partner_count;
+	struct wrepl_wins_owner *partners;
+	address initiator;
+};
+
+enum wrepl_replication_cmd {
+	WREPL_REPL_TABLE_QUERY=0,
+	WREPL_REPL_TABLE_REPLY=1,
+	WREPL_REPL_SEND_REQUEST=2,
+	WREPL_REPL_SEND_REPLY=3,
+	WREPL_REPL_UPDATE=4,
+	WREPL_REPL_INFORM=8
+};
+
+union wrepl_replication_info {
+	struct wrepl_table table;/* [case(WREPL_REPL_TABLE_REPLY)] */
+	struct wrepl_wins_owner owner;/* [case(WREPL_REPL_SEND_REQUEST)] */
+	struct wrepl_send_reply reply;/* [case(WREPL_REPL_SEND_REPLY)] */
+}/* [nodiscriminant] */;
+
+struct wrepl_replication {
+	enum wrepl_replication_cmd command;
+	union wrepl_replication_info info;/* [switch_is(command)] */
+};
+
+struct wrepl_start {
+	guint32 assoc_ctx;
+	guint16 minor_version;
+	guint16 major_version;
+};
+
+struct wrepl_stop {
+	guint32 reason;
+};
+
+enum wrepl_mess_type {
+	WREPL_START_ASSOCIATION=0,
+	WREPL_START_ASSOCIATION_REPLY=1,
+	WREPL_STOP_ASSOCIATION=2,
+	WREPL_REPLICATION=3
+};
+
+union wrepl_message {
+	struct wrepl_start start;/* [case(WREPL_START_ASSOCIATION)] */
+	struct wrepl_start start_reply;/* [case(WREPL_START_ASSOCIATION_REPLY)] */
+	struct wrepl_stop stop;/* [case(WREPL_STOP_ASSOCIATION)] */
+	struct wrepl_replication replication;/* [case(WREPL_REPLICATION)] */
+}/* [nodiscriminant] */;
+
+struct wrepl_packet {
+	guint32 opcode;
+	guint32 assoc_ctx;
+	enum wrepl_mess_type mess_type;
+	union wrepl_message message;/* [switch_is(mess_type)] */
+	/*DATA_BLOB padding;*//* [flag(LIBNDR_FLAG_REMAINING)] */
+}/* [gensize,public,flag(LIBNDR_FLAG_BIGENDIAN|LIBNDR_PRINT_ARRAY_HEX)] */;
+
+struct wrepl_wrap {
+	guint32 size;/* [value(ndr_size_wrepl_packet(&packet,ndr->flags))] */
+	struct wrepl_packet packet;
+}/* [public,flag(LIBNDR_FLAG_BIGENDIAN|LIBNDR_PRINT_ARRAY_HEX)] */;
+
+
+struct decode_winsrepl {
+	struct {
+		struct wrepl_wrap p;
+	} in;
+
+};
+
+#endif /* _HEADER_wrepl */
Index: epan/dissectors/Makefile.common
===================================================================
--- epan/dissectors/Makefile.common	(Revision 15680)
+++ epan/dissectors/Makefile.common	(Arbeitskopie)
@@ -596,6 +596,7 @@
 	packet-wfleet-hdlc.c	\
 	packet-who.c	\
 	packet-windows-common.c	\
+	packet-winsrepl.c	\
 	packet-wlancap.c	\
 	packet-wlancertextn.c	\
 	packet-wsp.c	\
@@ -848,6 +849,7 @@
 	packet-wap.h	\
 	packet-wccp.h	\
 	packet-windows-common.h	\
+	packet-winsrepl.h	\
 	packet-wlancap.h	\
 	packet-wlancertextn.h	\
 	packet-wsp.h	\

Attachment: pgpbls7xLIP6J.pgp
Description: PGP signature