#include "idl_types.h"

/*
   IDL structures for WINS replication protocol (port 42)

   Note that WINS replication is not traditionally encoded using
   IDL/NDR

   Written by Andrew Tridgell <tridge@osdl.org>
*/

[
  uuid("0-1-2-3-4"),
  version(0.0),
  pointer_default(unique),
  pointer_default_top(unique)
]
interface wrepl
{
	const int WINS_REPLICATION_PORT = 42;

	typedef [flag(NDR_BIG_ENDIAN)] struct {
		ipv4address owner;
		ipv4address ip;
	} wrepl_ip;

	typedef [flag(NDR_LITTLE_ENDIAN)] struct {
		uint32      num_ips;
		wrepl_ip    ips[num_ips];
		ipv4address unknown;
	} wrepl_address_list;

	typedef [nodiscriminant] union {
		[case(0)] wrepl_ip           address;
		[case(2)] wrepl_address_list addresses;
	} wrepl_addresses;

	typedef struct {
		uint32    name_len;
		uint8     name[name_len];
		uint32    flags;
		[flag(NDR_LITTLE_ENDIAN)] uint32 group_flag;
		udlongr   id;
		[switch_is(flags & 2)] wrepl_addresses addresses;
	} wrepl_wins_name;

	typedef struct {
		uint32          num_names;
		wrepl_wins_name names[num_names];
	} wrepl_send_reply;

	typedef struct {
		ipv4address address;
		udlongr     max_version;
		udlongr     min_version;
		uint32      type;
	} wrepl_wins_owner;

	typedef struct {
		uint32           partner_count;
		wrepl_wins_owner partners[partner_count];
		ipv4address      initiator;
	} wrepl_table;

	typedef [v1_enum] enum {
		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
	} wrepl_replication_cmd;

	typedef [nodiscriminant] union {
		[case(WREPL_REPL_TABLE_QUERY)] ;
		[case(WREPL_REPL_TABLE_REPLY)]  wrepl_table      table;
		[case(WREPL_REPL_SEND_REQUEST)] wrepl_wins_owner owner;
		[case(WREPL_REPL_SEND_REPLY)]   wrepl_send_reply reply;
		[case(WREPL_REPL_UPDATE)] ;
		[case(WREPL_REPL_INFORM)]       wrepl_table      table;
	} wrepl_replication_info;

	typedef struct {
		wrepl_replication_cmd command;
		[switch_is(command)] wrepl_replication_info info;
	} wrepl_replication;

	typedef struct {
		uint32 assoc_ctx;
		uint16 minor_version;
		uint16 major_version;
	} wrepl_start;

	typedef struct {
		uint32 reason;
	} wrepl_stop;

	typedef [v1_enum] enum {
		WREPL_START_ASSOCIATION       = 0,
		WREPL_START_ASSOCIATION_REPLY = 1,
		WREPL_STOP_ASSOCIATION        = 2,
		WREPL_REPLICATION             = 3
	} wrepl_mess_type;

	typedef [nodiscriminant] union {
		[case(WREPL_START_ASSOCIATION)]       wrepl_start start;
		[case(WREPL_START_ASSOCIATION_REPLY)] wrepl_start start_reply;
		[case(WREPL_STOP_ASSOCIATION)]        wrepl_stop stop;
		[case(WREPL_REPLICATION)]             wrepl_replication replication;
	} wrepl_message;

	/*
	  the opcode appears to be a bitfield, but as far as I can tell
	  you must always set the following bits. Additional bits don't
	  seem to matter. Very strange.
	*/
	const int WREPL_OPCODE_BITS = 0x7800;


	typedef [gensize,flag(NDR_BIG_ENDIAN|NDR_PAHEX),public] struct {
		uint32                 opcode;
		uint32                 assoc_ctx;
		wrepl_mess_type        mess_type;
		[switch_is(mess_type)] wrepl_message message;
		[flag(NDR_REMAINING)] DATA_BLOB padding;
	} wrepl_packet;

	typedef [flag(NDR_BIG_ENDIAN|NDR_PAHEX),public] struct {
		[value(ndr_size_wrepl_packet(&packet, ndr->flags))] uint32 size;
		wrepl_packet    packet;
	} wrepl_wrap;

	void decode_winsrepl(
		[in] wrepl_wrap p
		);

}