#include "idl_types.h"

/*
   IDL structures for DNSP structures

   See [MS-DNSP].pdf in MCPP for details
*/

import "misc.idl";

/*
  note that this is not a real RPC interface. We are just using PIDL
  to save us a lot of tedious hand parsing of the dnsRecord
  attribute. The uuid is randomly generated.
 */
[
  uuid("bdd66e9e-d45f-4202-85c0-6132edc4f30a"),
  version(0.0),
  pointer_default(unique),
  helper("../librpc/ndr/ndr_dnsp.h"),
  helpstring("DNSP interfaces")
]

interface dnsp
{
	typedef [enum16bit,public] enum {
		DNS_TYPE_TOMBSTONE  = 0x0,
		DNS_TYPE_A     = 0x1,
		DNS_TYPE_NS    = 0x2,
		DNS_TYPE_MD    = 0x3,
		DNS_TYPE_MF    = 0x4,
		DNS_TYPE_CNAME = 0x5,
		DNS_TYPE_SOA   = 0x6,
		DNS_TYPE_MB    = 0x7,
		DNS_TYPE_MG    = 0x8,
		DNS_TYPE_MR    = 0x9,
		DNS_TYPE_NULL  = 0xA,
		DNS_TYPE_WKS   = 0xB,
		DNS_TYPE_PTR   = 0xC,
		DNS_TYPE_HINFO = 0xD,
		DNS_TYPE_MINFO = 0xE,
		DNS_TYPE_MX    = 0xF,
		DNS_TYPE_TXT   = 0x10,
		DNS_TYPE_RP    = 0x11,
		DNS_TYPE_AFSDB = 0x12,
		DNS_TYPE_X25   = 0x13,
		DNS_TYPE_ISDN  = 0x14,
		DNS_TYPE_RT    = 0x15,
		DNS_TYPE_SIG   = 0x18,
		DNS_TYPE_KEY   = 0x19,
		DNS_TYPE_AAAA  = 0x1C,
		DNS_TYPE_LOC   = 0x1D,
		DNS_TYPE_NXT   = 0x1E,
		DNS_TYPE_SRV   = 0x21,
		DNS_TYPE_ATMA  = 0x22,
		DNS_TYPE_NAPTR = 0x23,
		DNS_TYPE_DNAME = 0x27,
		DNS_TYPE_DS    = 0x2B,
		DNS_TYPE_RRSIG = 0x2E,
		DNS_TYPE_NSEC  = 0x2F,
		DNS_TYPE_DNSKEY= 0x30,
		DNS_TYPE_DHCID = 0x31,
		DNS_TYPE_ALL   = 0xFF,
		DNS_TYPE_WINS  = 0xFF01,
		DNS_TYPE_WINSR = 0xFF02
	} dns_record_type;

	typedef [bitmap32bit] bitmap {
		DNS_RPC_FLAG_SUPPRESS_NOTIFY	= 0x00010000,
		DNS_RPC_FLAG_AGING_ON			= 0x00020000,
		DNS_RPC_FLAG_OPEN_ACL			= 0x00040000,
		DNS_RPC_FLAG_NODE_COMPLETE		= 0x00800000,
		DNS_RPC_FLAG_NODE_STICKY		= 0x01000000,
		DNS_RPC_FLAG_RECORD_CREATE_PTR	= 0x02000000,
		DNS_RPC_FLAG_RECORD_TTL_CHANGE	= 0x04000000,
		DNS_RPC_FLAG_RECORD_DEFAULT_TTL	= 0x08000000,
		DNS_RPC_FLAG_ZONE_DELEGATION	= 0x10000000,
		DNS_RPC_FLAG_AUTH_ZONE_ROOT		= 0x20000000,
		DNS_RPC_FLAG_ZONE_ROOT			= 0x40000000,
		DNS_RPC_FLAG_CACHE_DATA			= 0x80000000
	}
	dns_rpc_node_flags;


	typedef [enum8bit] enum {
		DNS_RANK_NONE		        = 0x00,
		DNS_RANK_CACHE_BIT              = 0x01,
		DNS_RANK_ROOT_HINT              = 0x08,
		DNS_RANK_OUTSIDE_GLUE           = 0x20,
		DNS_RANK_CACHE_NA_ADDITIONAL    = 0x31,
		DNS_RANK_CACHE_NA_AUTHORITY     = 0x41,
		DNS_RANK_CACHE_A_ADDITIONAL     = 0x51,
		DNS_RANK_CACHE_NA_ANSWER        = 0x61,
		DNS_RANK_CACHE_A_AUTHORITY      = 0x71,
		DNS_RANK_GLUE                   = 0x80,
		DNS_RANK_NS_GLUE                = 0x82,
		DNS_RANK_CACHE_A_ANSWER         = 0xc1,
		DNS_RANK_ZONE                   = 0xf0
	} dns_record_rank;

	typedef [v1_enum] enum {
		DNS_ZONE_TYPE_CACHE             = 0x00,
		DNS_ZONE_TYPE_PRIMARY           = 0x01,
		DNS_ZONE_TYPE_SECONDARY         = 0x02,
		DNS_ZONE_TYPE_STUB              = 0x03,
		DNS_ZONE_TYPE_FORWARDER         = 0x04,
		DNS_ZONE_TYPE_SECONDARY_CACHE   = 0x05
	} dns_zone_type;

	typedef [public,enum8bit] enum {
		DNS_ZONE_UPDATE_OFF         = 0x00,
		DNS_ZONE_UPDATE_UNSECURE    = 0x01,
		DNS_ZONE_UPDATE_SECURE      = 0x02
	} dns_zone_update;

	typedef [v1_enum] enum {
		DSPROPERTY_ZONE_EMPTY                   = 0x00,
		DSPROPERTY_ZONE_TYPE                    = 0x01,
		DSPROPERTY_ZONE_ALLOW_UPDATE            = 0x02,
		DSPROPERTY_ZONE_SECURE_TIME             = 0x08,
		DSPROPERTY_ZONE_NOREFRESH_INTERVAL      = 0x10,
		DSPROPERTY_ZONE_SCAVENGING_SERVERS      = 0x11,
		DSPROPERTY_ZONE_AGING_ENABLED_TIME      = 0x12,
		DSPROPERTY_ZONE_REFRESH_INTERVAL        = 0x20,
		DSPROPERTY_ZONE_AGING_STATE             = 0x40,
		DSPROPERTY_ZONE_DELETED_FROM_HOSTNAME   = 0x80,
		DSPROPERTY_ZONE_MASTER_SERVERS          = 0x81,
		DSPROPERTY_ZONE_AUTO_NS_SERVERS         = 0x82,
		DSPROPERTY_ZONE_DCPROMO_CONVERT         = 0x83,
		DSPROPERTY_ZONE_SCAVENGING_SERVERS_DA   = 0x90,
		DSPROPERTY_ZONE_MASTER_SERVERS_DA       = 0x91,
		DSPROPERTY_ZONE_NS_SERVERS_DA           = 0x92,
		DSPROPERTY_ZONE_NODE_DBFLAGS			= 0x100

	} dns_property_id;

	typedef [enum8bit] enum {
		DCPROMO_CONVERT_NONE    = 0x00,
		DCPROMO_CONVERT_DOMAIN  = 0x01,
		DCPROMO_CONVERT_FOREST  = 0x02
	} dns_dcpromo_flag;

	typedef [public] struct {
		uint32		serial;
		uint32		refresh;
		uint32		retry;
		uint32		expire;
		uint32		minimum;
		dnsp_name       mname;
		dnsp_name       rname;
	} dnsp_soa;

	typedef [public] struct {
		uint16	        wPriority;
		dnsp_name       nameTarget;
	} dnsp_mx;

	typedef [public] struct {
		dnsp_string     cpu;
		dnsp_string     os;
	} dnsp_hinfo;

	typedef [public] struct {
		uint16          wPriority;
		uint16          wWeight;
		uint16          wPort;
		dnsp_name       nameTarget;
	} dnsp_srv;

	typedef struct {
		uint32  addrCount;
		[size_is(addrCount)] uint32 *addr;
	} dnsp_ip4_array;

	typedef struct {
		uint16 	family;
		uint16	port;
		ipv4address ipv4;
		ipv6address ipv6;
		uint8	pad[8];
		uint32	unused[8];
	} dnsp_dns_addr;

	typedef [public] struct {
		uint32	MaxCount;
		uint32	AddrCount;
		uint32	Tag;
		uint16	Family;
		uint16	Reserved0;
		uint32	MatchFlag;
		uint32	Reserved1;
		uint32	Reserved2;
		dnsp_dns_addr AddrArray[AddrCount];
	} dnsp_dns_addr_array;

	typedef [public,nopull,nopush,noprint,gensize] struct {
		uint8		count;
		dnsp_string	str[count];
	} dnsp_string_list;

	typedef [nodiscriminant,gensize] union {
		[case(DNS_TYPE_TOMBSTONE)] 		    NTTIME timestamp;
		[case(DNS_TYPE_A)] [flag(NDR_BIG_ENDIAN)]   ipv4address ipv4;
		[case(DNS_TYPE_NS)]                         dnsp_name ns;
		[case(DNS_TYPE_CNAME)]                      dnsp_name cname;
		[case(DNS_TYPE_SOA)] [flag(NDR_BIG_ENDIAN)] dnsp_soa soa;
		[case(DNS_TYPE_MX)] [flag(NDR_BIG_ENDIAN)]  dnsp_mx mx;
		[case(DNS_TYPE_TXT)]                        dnsp_string_list txt;
		[case(DNS_TYPE_PTR)]                        dnsp_name ptr;
		[case(DNS_TYPE_HINFO)]                      dnsp_hinfo hinfo;
		[case(DNS_TYPE_AAAA)]                       ipv6address ipv6;
		[case(DNS_TYPE_SRV)] [flag(NDR_BIG_ENDIAN)] dnsp_srv srv;
		[default] [flag(NDR_REMAINING)] DATA_BLOB data;
	} dnsRecordData;

	/* this is the format for the dnsRecord attribute in the DNS
	   partitions in AD */
	typedef [public] struct {
		[value(ndr_size_dnsRecordData(&data,wType,ndr->flags))] uint16 wDataLength;
		dns_record_type 	wType;
		[value(5)] uint8	version;
		dns_record_rank 	rank;
		uint16			flags;
		uint32          	dwSerial;
		[flag(NDR_BIG_ENDIAN)]  uint32   dwTtlSeconds;
		uint32          	dwReserved;
		uint32			dwTimeStamp;
		[switch_is(wType)] dnsRecordData data;
	} dnsp_DnssrvRpcRecord;

	typedef [nodiscriminant,gensize] union {
		[case(DSPROPERTY_ZONE_EMPTY)]					;
		[case(DSPROPERTY_ZONE_TYPE)]                    dns_zone_type zone_type;
		[case(DSPROPERTY_ZONE_ALLOW_UPDATE)]            dns_zone_update allow_update_flag;
		[case(DSPROPERTY_ZONE_SECURE_TIME)]             NTTIME zone_secure_time;
		[case(DSPROPERTY_ZONE_NOREFRESH_INTERVAL)]      uint32 norefresh_hours;
		[case(DSPROPERTY_ZONE_REFRESH_INTERVAL)]        uint32 refresh_hours;
		[case(DSPROPERTY_ZONE_AGING_STATE)]             uint32 aging_enabled;
		[case(DSPROPERTY_ZONE_SCAVENGING_SERVERS)]      dnsp_ip4_array servers;
		[case(DSPROPERTY_ZONE_AGING_ENABLED_TIME)]      uint32 next_scavenging_cycle_hours;
		[case(DSPROPERTY_ZONE_DELETED_FROM_HOSTNAME)]   utf8string deleted_by_hostname;
		[case(DSPROPERTY_ZONE_MASTER_SERVERS)]          dnsp_ip4_array master_servers;
		[case(DSPROPERTY_ZONE_AUTO_NS_SERVERS)]         dnsp_ip4_array ns_servers;
		[case(DSPROPERTY_ZONE_DCPROMO_CONVERT)]         dns_dcpromo_flag dcpromo_flag;
		[case(DSPROPERTY_ZONE_SCAVENGING_SERVERS_DA)]	dnsp_dns_addr_array s_ns_servers;
		[case(DSPROPERTY_ZONE_MASTER_SERVERS_DA)]		dnsp_dns_addr_array z_master_servers;
		[case(DSPROPERTY_ZONE_NS_SERVERS_DA)]			dnsp_dns_addr_array d_ns_servers;
		[case(DSPROPERTY_ZONE_NODE_DBFLAGS)]			dns_rpc_node_flags flags;
	} dnsPropertyData;

	/* this is the format for the dnsProperty attribute in the DNS
	   partitions in AD */
	typedef [flag(NDR_NOALIGN),public] struct {
		[value(ndr_size_dnsPropertyData(&data,id,ndr->flags))] uint32 wDataLength;
		uint32   			namelength;
		[value(0)] uint32   flag;
		[value(1)] uint32   version;
		dns_property_id     id;
		[switch_is(wDataLength?id:DSPROPERTY_ZONE_EMPTY)]     dnsPropertyData data;
		uint32              name;
	} dnsp_DnsProperty;

	/*
	  these are convenience hooks for ndrdump
	 */
	void decode_DnssrvRpcRecord(
		[in] dnsp_DnssrvRpcRecord blob
		);

	void decode_DnsProperty(
		[in] dnsp_DnsProperty blob
		);
}