|
|
/*++
Copyright (c) 1996-2001 Microsoft Corporation
Module Name:
dnslib.h
Abstract:
Domain Name System (DNS) Library
DNS Library Routines -- Main Header File
Author:
Jim Gilroy (jamesg) December 7, 1996
Revision History:
--*/
#ifndef _DNSLIB_INCLUDED_ #define _DNSLIB_INCLUDED_
#include <windns.h> #include <dnsapi.h> #include <rpc.h>
#define BACKCOMPAT 1
#ifdef __cplusplus extern "C" { #endif // __cplusplus
// // Alignment and rounding macros //
#define WORD_ALIGN(ptr) ((PVOID) ((UINT_PTR)((PBYTE)ptr + 1) & ~(UINT_PTR)1))
#define DWORD_ALIGN(ptr) ((PVOID) ((UINT_PTR)((PBYTE)ptr + 3) & ~(UINT_PTR)3))
#define QWORD_ALIGN(ptr) ((PVOID) ((UINT_PTR)((PBYTE)ptr + 7) & ~(UINT_PTR)7))
#ifdef WIN64 #define POINTER_ALIGN(ptr) QWORD_ALIGN(ptr) #else #define POINTER_ALIGN(ptr) DWORD_ALIGN(ptr) #endif
#define WORD_ALIGN_DWORD(dw) (((WORD)dw + 1) & ~(DWORD)1) #define DWORD_ALIGN_DWORD(dw) (((DWORD)dw + 3) & ~(DWORD)3) #define QWORD_ALIGN_DWORD(dw) (((QWORD)dw + 7) & ~(DWORD)7)
#ifdef WIN64 #define POINTER_ALIGN_DWORD(dw) QWORD_ALIGN_DWORD(dw) #else #define POINTER_ALIGN_DWORD(dw) DWORD_ALIGN_DWORD(dw) #endif
// // Inline byte flipping //
__inline WORD inline_word_flip( IN WORD Word ) { return ( (Word << 8) | (Word >> 8) ); }
#define inline_htons(w) inline_word_flip(w) #define inline_ntohs(w) inline_word_flip(w)
__inline DWORD inline_dword_flip( IN DWORD Dword ) { return ( ((Dword << 8) & 0x00ff0000) | (Dword << 24) | ((Dword >> 8) & 0x0000ff00) | (Dword >> 24) ); }
#define inline_htonl(d) inline_dword_flip(d) #define inline_ntohl(d) inline_dword_flip(d)
// // Useful type defs //
#define PGUID LPGUID #define PADDRINFO LPADDRINFO
// // QWORD //
#ifndef QWORD typedef DWORD64 QWORD, *PQWORD; #endif
// // Until converted must define PDNS_NAME // // Note: PDNS_NAME is NOT really a LPTSTR. // Rather it's the definition of a field that can be // either an PWSTR or PSTR depending on some other field. //
#ifdef UNICODE typedef PWSTR PDNS_NAME; #else typedef PSTR PDNS_NAME; #endif
// // Flat buffer definition // // Note: using INT for sizes so that we can push BytesLeft negative // and use routines to determine REQUIRED space, even when no // buffer or buf too small. //
typedef struct _FLATBUF { PBYTE pBuffer; PBYTE pEnd; PBYTE pCurrent; INT Size; INT BytesLeft; } FLATBUF, *PFLATBUF;
// // Flat buffer routines -- argument versions // // These versions have the actual code so that we can // easily use this stuff with existing code that has // independent pCurrent and BytesLeft variables. // // FLATBUF structure versions just call these inline. //
PBYTE FlatBuf_Arg_Reserve( IN OUT PBYTE * ppCurrent, IN OUT PINT pBytesLeft, IN DWORD Size, IN DWORD Alignment );
PBYTE FlatBuf_Arg_WriteString( IN OUT PBYTE * ppCurrent, IN OUT PINT pBytesLeft, IN PSTR pString, IN BOOL fUnicode );
PBYTE FlatBuf_Arg_CopyMemory( IN OUT PBYTE * ppCurrent, IN OUT PINT pBytesLeft, IN PVOID pMemory, IN DWORD Length, IN DWORD Alignment );
__inline PBYTE FlatBuf_Arg_ReserveAlignPointer( IN OUT PBYTE * ppCurrent, IN OUT PINT pBytesLeft, IN DWORD Size ) { return FlatBuf_Arg_Reserve( ppCurrent, pBytesLeft, Size, sizeof(PVOID) ); }
__inline PBYTE FlatBuf_Arg_ReserveAlignQword( IN OUT PBYTE * ppCurrent, IN OUT PINT pBytesLeft, IN DWORD Size ) { return FlatBuf_Arg_Reserve( ppCurrent, pBytesLeft, Size, sizeof(QWORD) ); }
__inline PBYTE FlatBuf_Arg_ReserveAlignDword( IN OUT PBYTE * ppCurrent, IN OUT PINT pBytesLeft, IN DWORD Size ) { return FlatBuf_Arg_Reserve( ppCurrent, pBytesLeft, Size, sizeof(DWORD) ); }
__inline PBYTE FlatBuf_Arg_ReserveAlignWord( IN OUT PBYTE * ppCurrent, IN OUT PINT pBytesLeft, IN DWORD Size ) { return FlatBuf_Arg_Reserve( ppCurrent, pBytesLeft, Size, sizeof(WORD) ); }
__inline PBYTE FlatBuf_Arg_ReserveAlignByte( IN OUT PBYTE * ppCurrent, IN OUT PINT pBytesLeft, IN DWORD Size ) { return FlatBuf_Arg_Reserve( ppCurrent, pBytesLeft, Size, 0 ); }
PBYTE __inline FlatBuf_Arg_WriteString_A( IN OUT PBYTE * ppCurrent, IN OUT PINT pBytesLeft, IN PSTR pString ) { return FlatBuf_Arg_WriteString( ppCurrent, pBytesLeft, pString, FALSE // not unicode ); }
PBYTE __inline FlatBuf_Arg_WriteString_W( IN OUT PBYTE * ppCurrent, IN OUT PINT pBytesLeft, IN PWSTR pString ) { return FlatBuf_Arg_WriteString( ppCurrent, pBytesLeft, (PSTR) pString, TRUE // unicode ); }
// // Flat buffer routines -- structure versions //
VOID FlatBuf_Init( IN OUT PFLATBUF pFlatBuf, IN PBYTE pBuffer, IN INT Size );
__inline PBYTE FlatBuf_Reserve( IN OUT PFLATBUF pBuf, IN DWORD Size, IN DWORD Alignment ) { return FlatBuf_Arg_Reserve( & pBuf->pCurrent, & pBuf->BytesLeft, Size, Alignment ); }
__inline PBYTE FlatBuf_ReserveAlignPointer( IN OUT PFLATBUF pBuf, IN DWORD Size ) { return FlatBuf_Arg_Reserve( & pBuf->pCurrent, & pBuf->BytesLeft, Size, sizeof(PVOID) ); }
__inline PBYTE FlatBuf_ReserveAlignQword( IN OUT PFLATBUF pBuf, IN DWORD Size ) { return FlatBuf_Arg_Reserve( & pBuf->pCurrent, & pBuf->BytesLeft, Size, sizeof(QWORD) ); }
__inline PBYTE FlatBuf_ReserveAlignDword( IN OUT PFLATBUF pBuf, IN DWORD Size ) { return FlatBuf_Arg_Reserve( & pBuf->pCurrent, & pBuf->BytesLeft, Size, sizeof(DWORD) ); }
__inline PBYTE FlatBuf_ReserveAlignWord( IN OUT PFLATBUF pBuf, IN DWORD Size ) { return FlatBuf_Arg_Reserve( & pBuf->pCurrent, & pBuf->BytesLeft, Size, sizeof(WORD) ); }
__inline PBYTE FlatBuf_ReserveAlignByte( IN OUT PFLATBUF pBuf, IN DWORD Size ) { return FlatBuf_Arg_Reserve( & pBuf->pCurrent, & pBuf->BytesLeft, Size, 0 ); }
PBYTE __inline FlatBuf_WriteString( IN OUT PFLATBUF pBuf, IN PSTR pString, IN BOOL fUnicode ) { return FlatBuf_Arg_WriteString( & pBuf->pCurrent, & pBuf->BytesLeft, pString, fUnicode ); }
PBYTE __inline FlatBuf_WriteString_A( IN OUT PFLATBUF pBuf, IN PSTR pString ) { return FlatBuf_Arg_WriteString( & pBuf->pCurrent, & pBuf->BytesLeft, pString, FALSE // not unicode ); }
PBYTE __inline FlatBuf_WriteString_W( IN OUT PFLATBUF pBuf, IN PWSTR pString ) { return FlatBuf_Arg_WriteString( & pBuf->pCurrent, & pBuf->BytesLeft, (PSTR) pString, TRUE // unicode ); }
PBYTE __inline FlatBuf_CopyMemory( IN OUT PFLATBUF pBuf, IN PVOID pMemory, IN DWORD Length, IN DWORD Alignment ) { return FlatBuf_Arg_CopyMemory( & pBuf->pCurrent, & pBuf->BytesLeft, pMemory, Length, Alignment ); }
// // Multicast off until new features ready //
#define MULTICAST_ENABLED 0
// // Multicast DNS definitions //
#define MULTICAST_DNS_ADDR 0xEFFFFFFD // 239.255.255.253 #define MULTICAST_DNS_RADDR 0xFDFFFFEF // Same as above, in host ordering
#define MULTICAST_DNS_LOCAL_DOMAIN ("local.") #define MULTICAST_DNS_LOCAL_DOMAIN_W (L"local.") #define MULTICAST_DNS_SRV_RECORD_NAME ("_dns._udp.local.") #define MULTICAST_DNS_SRV_RECORD_NAME_W (L"_dns._udp.local.") #define MULTICAST_DNS_A_RECORD_NAME ("_dns.local.") #define MULTICAST_DNS_A_RECORD_NAME_W (L"_dns.local.")
// // Read unaligned value from given position in packet //
#define READ_PACKET_HOST_DWORD(pch) \ FlipUnalignedDword( pch )
#define READ_PACKET_NET_DWORD(pch) \ ( *(UNALIGNED DWORD *)(pch) )
#define READ_PACKET_HOST_WORD(pch) \ FlipUnalignedWord( pch )
#define READ_PACKET_NET_WORD(pch) \ ( *(UNALIGNED WORD *)(pch) )
// // Private DNS_RECORD Flag field structure definition and macros // // Note: don't add to this list -- private stuff in dnslibp.h //
typedef struct _DnsRecordLibFlags { DWORD Section : 2; DWORD Delete : 1; DWORD CharSet : 2;
DWORD Unused : 6; DWORD Matched : 1; DWORD FreeData : 1; DWORD FreeOwner : 1;
DWORD Reserved : 18; } DNSRECLIB_FLAGS, *PDNSRECLIB_FLAGS;
#define PFLAGS( pRecord ) ((PDNSRECLIB_FLAGS)&pRecord->Flags.DW) #define FLAG_Section( pRecord ) (PFLAGS( pRecord )->Section) #define FLAG_Delete( pRecord ) (PFLAGS( pRecord )->Delete) #define FLAG_CharSet( pRecord ) (PFLAGS( pRecord )->CharSet) #define FLAG_FreeData( pRecord ) (PFLAGS( pRecord )->FreeData) #define FLAG_FreeOwner( pRecord ) (PFLAGS( pRecord )->FreeOwner) #define FLAG_Matched( pRecord ) (PFLAGS( pRecord )->Matched)
#define SET_FREE_OWNER(pRR) (FLAG_FreeOwner(pRR) = TRUE) #define SET_FREE_DATA(pRR) (FLAG_FreeData(pRR) = TRUE) #define SET_RR_MATCHED(pRR) (FLAG_Matched(pRR) = TRUE)
#define CLEAR_FREE_OWNER(pRR) (FLAG_FreeOwner(pRR) = FALSE) #define CLEAR_FREE_DATA(pRR) (FLAG_FreeData(pRR) = FALSE) #define CLEAR_RR_MATCHED(pRR) (FLAG_Matched(pRR) = FALSE)
#define IS_FREE_OWNER(pRR) (FLAG_FreeOwner(pRR)) #define IS_FREE_DATA(pRR) (FLAG_FreeData(pRR)) #define IS_RR_MATCHED(pRR) (FLAG_Matched(pRR))
#define IS_ANSWER_RR(pRR) (FLAG_Section(pRR) == DNSREC_ANSWER) #define IS_AUTHORITY_RR(pRR) (FLAG_Section(pRR) == DNSREC_AUTHORITY) #define IS_ADDITIONAL_RR(pRR) (FLAG_Section(pRR) == DNSREC_ADDITIONAL)
// // Converting RCODEs to\from DNS errors. //
#define DNS_ERROR_FROM_RCODE(rcode) ((rcode)+DNS_ERROR_RESPONSE_CODES_BASE)
#define DNS_RCODE_FROM_ERROR(err) ((err)-DNS_ERROR_RESPONSE_CODES_BASE)
// // Record character sets // // Currently supports records in three character sets // - unicode // - ANSI // - UTF8 // // Unicode and ANSI are supported through external DNSAPI interfaces. // UTF8 is not (at least offcially). // // However, internally unicode and UTF8 are used for caching, reading // to and writing from packet. // // All DNS_RECORD structs created by our code, are tagged with a // character set type in the flags CharSet field. //
// // A couple of handy macros: //
#define RECORD_CHARSET(pRR) \ ( (DNS_CHARSET) (pRR)->Flags.S.CharSet )
#define IS_UNICODE_RECORD(pRR) \ ( (DNS_CHARSET) (pRR)->Flags.S.CharSet == DnsCharSetUnicode )
// // Quick buffer size determination // // Strings are read from the wire into dotted UTF8 format. // Strings are in UTF8 in RPC buffers. // // Goal here is to quickly determine adequate buffer size, // slight overallocation is not critical. // // Currently supporting only UTF8 or Unicode, however, if later // support direct ANSI conversion that's ok too, as ANSI will // no (to my knowledge) use more space than UTF8. //
#define STR_BUF_SIZE_GIVEN_UTF8_LEN( Utf8Length, CharSet ) \ ( ((CharSet)==DnsCharSetUnicode) ? ((Utf8Length)+1)*2 : (Utf8Length)+1 )
// // Default locale for string comparison and case mappings // // Sublang: US English (0x04) Lang: English (0x09) //
#define DNS_DEFAULT_LOCALE (0x0409)
// // IP Array utilities (iparray.c) // // Note some of these require memory allocation, see note // on memory allocation below. //
#define DNS_NET_ORDER_LOOPBACK (0x0100007f)
// NT5-autonet is 169.254.x.y
#define AUTONET_MASK (0x0000ffff) #define AUTONET_NET (0x0000fea9)
#define DNS_IS_AUTONET_IP(ip) ( ((ip) & AUTONET_MASK) == AUTONET_NET )
#define DNS_IPARRAY_CLEAN_ZERO (0x00000001) #define DNS_IPARRAY_CLEAN_LOOPBACK (0x00000002) #define DNS_IPARRAY_CLEAN_AUTONET (0x00000010)
// // Simple IP address array routines //
PIP_ADDRESS Dns_CreateIpAddressArrayCopy( IN PIP_ADDRESS aipAddress, IN DWORD cipAddress );
BOOL Dns_ValidateIpAddressArray( IN PIP_ADDRESS aipAddress, IN DWORD cipAddress, IN DWORD dwFlag );
// // IP_ARRAY datatype routines //
PIP_ARRAY Dns_CreateIpArray( IN DWORD cAddrCount );
DWORD Dns_SizeofIpArray( IN PIP_ARRAY pIpArray );
PIP_ARRAY Dns_BuildIpArray( IN DWORD cAddrCount, IN PIP_ADDRESS pipAddrs );
PIP_ARRAY Dns_CopyAndExpandIpArray( IN PIP_ARRAY pIpArray, IN DWORD ExpandCount, IN BOOL fDeleteExisting );
PIP_ARRAY Dns_CreateIpArrayCopy( IN PIP_ARRAY pIpArray );
BOOL Dns_IsAddressInIpArray( IN PIP_ARRAY pIpArray, IN IP_ADDRESS ipAddress );
BOOL Dns_AddIpToIpArray( IN OUT PIP_ARRAY pIpArray, IN IP_ADDRESS ipNew );
VOID Dns_ClearIpArray( IN OUT PIP_ARRAY pIpArray );
VOID Dns_ReverseOrderOfIpArray( IN OUT PIP_ARRAY pIpArray );
BOOL Dns_CheckAndMakeIpArraySubset( IN OUT PIP_ARRAY pIpArraySub, IN PIP_ARRAY pIpArraySuper );
INT WINAPI Dns_ClearIpFromIpArray( IN OUT PIP_ARRAY pIpArray, IN IP_ADDRESS IpDelete );
INT WINAPI Dns_DeleteIpFromIpArray( IN OUT PIP_ARRAY pIpArray, IN IP_ADDRESS IpDelete );
#define Dns_RemoveZerosFromIpArray(pArray) \ Dns_DeleteIpFromIpArray( (pArray), 0 )
INT WINAPI Dns_CleanIpArray( IN OUT PIP_ARRAY pIpArray, IN DWORD Flag );
BOOL Dns_AreIpArraysEqual( IN PIP_ARRAY pIpArray1, IN PIP_ARRAY pIpArray2 );
BOOL Dns_AreIpArraysSimilar( IN PIP_ARRAY pIpArray1, IN PIP_ARRAY pIpArray2 );
DNS_STATUS WINAPI Dns_DiffOfIpArrays( IN PIP_ARRAY pIpArray1, IN PIP_ARRAY pIpArray2, OUT PIP_ARRAY * ppOnlyIn1, OUT PIP_ARRAY * ppOnlyIn2, OUT PIP_ARRAY * ppIntersect );
BOOL WINAPI Dns_IsIntersectionOfIpArrays( IN PIP_ARRAY pIpArray1, IN PIP_ARRAY pIpArray2 );
DNS_STATUS WINAPI Dns_UnionOfIpArrays( IN PIP_ARRAY pIpArray1, IN PIP_ARRAY pIpArray2, OUT PIP_ARRAY * ppUnion );
#define Dns_IntersectionOfIpArrays(p1, p2, ppInt) \ Dns_DiffOfIpArrays( (p1), (p2), NULL, NULL, (ppInt) )
DNS_STATUS Dns_CreateIpArrayFromMultiIpString( IN PSTR pchMultiIpString, OUT PIP_ARRAY * ppIpArray );
PSTR Dns_CreateMultiIpStringFromIpArray( IN PIP_ARRAY pIpArray, IN CHAR chSeparator OPTIONAL );
// // Type list array routines //
DNS_STATUS Dns_CreateTypeArrayFromMultiTypeString( IN PSTR pchMultiTypeString, OUT INT * piTypeCount, OUT PWORD * ppwTypeArray );
PSTR Dns_CreateMultiTypeStringFromTypeArray( IN INT iTypeCount, IN PWORD ppwTypeArray, IN CHAR chSeparator OPTIONAL );
// // General utilities //
// // Wrap free, multi-thread safe seconds timer (timer.c) //
VOID Dns_InitializeSecondsTimer( VOID );
DWORD Dns_GetCurrentTimeInSeconds( VOID );
// // Tokenizer //
DWORD Dns_TokenizeString( IN OUT PSTR pBuffer, OUT PCHAR * Argv, IN DWORD MaxArgs );
// // IP interfaces on local machine (iplist.c) //
#define DNS_MAX_NAME_SERVERS (50) #define DNS_MAX_IP_INTERFACE_COUNT (10000)
DWORD Dns_GetIpAddresses( IN OUT PDNS_ADDRESS_INFO IpAddressInfoList, IN DWORD ListCount );
PIP_ARRAY Dns_GetLocalIpAddressArray( VOID );
// // IP interfaces on local machine (iplist4.c) //
DWORD Dns_GetIpAddressesNT4( IN OUT PDNS_ADDRESS_INFO IpAddressInfoList, IN DWORD ListCount );
// // IP interfaces on local machine (iplist9x.c) //
DWORD Dns_GetIpAddressesWin9X( IN OUT PDNS_ADDRESS_INFO IpAddressInfoList, IN DWORD ListCount );
// // DNS server list routines (servlist.c) // // Also includes default domain and search list information. //
#define DNS_FLAG_IGNORE_ADAPTER (0x00000001) #define DNS_FLAG_IS_WAN_ADAPTER (0x00000002) #define DNS_FLAG_IS_AUTONET_ADAPTER (0x00000004) #define DNS_FLAG_IS_DHCP_CFG_ADAPTER (0x00000008)
#define DNS_FLAG_REGISTER_DOMAIN_NAME (0x00000010) #define DNS_FLAG_REGISTER_IP_ADDRESSES (0x00000020)
#define DNS_FLAG_ALLOW_MULTICAST (0x00000100) #define DNS_FLAG_MULTICAST_ON_NAME_ERROR (0x00000200)
#define DNS_FLAG_AUTO_SERVER_DETECTED (0x00000400) #define DNS_FLAG_DUMMY_SEARCH_LIST (0x00000800)
#define DNS_FLAG_SERVERS_UNREACHABLE (0x00010000)
// // NetInfo structures // // WARNING: Do NOT use these! // // These are internal dnsapi.dll structures. They are only // included here for backward compatibility with previous // code (netdiag) which incorrectly used these. // // If you code with them you will inevitably wake up broken // down the road. //
//#ifdef _DNSLIB_NETINFO_
typedef struct { DNS_STATUS Status; DWORD Priority; IP_ADDRESS IpAddress; DWORD Reserved[3]; } DNSLIB_SERVER_INFO, *PDNSLIB_SERVER_INFO;
typedef struct { PSTR pszAdapterGuidName; PSTR pszAdapterDomain; PIP_ARRAY pAdapterIPAddresses; PIP_ARRAY pAdapterIPSubnetMasks; DWORD InterfaceIndex; DWORD InfoFlags; DWORD Reserved; DWORD Status; DWORD ReturnFlags; DWORD IpLastSend; DWORD cServerCount; DWORD cTotalListSize; DNSLIB_SERVER_INFO ServerArray[1]; } DNSLIB_ADAPTER, *PDNSLIB_ADAPTER;
#define DNS_MAX_SEARCH_LIST_ENTRIES (50)
typedef struct { PSTR pszName; DWORD Flags; } DNSLIB_SEARCH_NAME, *PDNSLIB_SEARCH_NAME;
typedef struct { PSTR pszDomainOrZoneName; DWORD cNameCount; // Zero for FindAuthoritativeZone DWORD cTotalListSize; // Zero for FindAuthoritativeZone DWORD CurrentName; // 0 for pszDomainOrZoneName // 1 for first name in array below // 2 for second name in array below // ... DNSLIB_SEARCH_NAME SearchNameArray[1]; } DNSLIB_SEARCH_LIST, *PDNSLIB_SEARCH_LIST;
typedef struct { PSTR pszDomainName; PSTR pszHostName; PDNSLIB_SEARCH_LIST pSearchList; DWORD TimeStamp; DWORD InfoFlags; DWORD Tag; DWORD ReturnFlags; DWORD cAdapterCount; DWORD cTotalListSize; PDNSLIB_ADAPTER AdapterArray[1]; } DNSLIB_NETINFO, *PDNSLIB_NETINFO;
// // Create correct internal\external definitions //
#ifdef DNSAPI_INTERNAL
typedef RPC_DNS_SERVER_INFO DNS_SERVER_INFO, *PDNS_SERVER_INFO; typedef RPC_DNS_ADAPTER DNS_ADAPTER, *PDNS_ADAPTER; typedef RPC_SEARCH_NAME SEARCH_NAME, *PSEARCH_NAME; typedef RPC_SEARCH_LIST SEARCH_LIST, *PSEARCH_LIST; typedef RPC_DNS_NETINFO DNS_NETINFO, *PDNS_NETINFO;
#else // external
typedef DNSLIB_SERVER_INFO DNS_SERVER_INFO, *PDNS_SERVER_INFO; typedef DNSLIB_ADAPTER DNS_ADAPTER, *PDNS_ADAPTER; typedef DNSLIB_SEARCH_NAME SEARCH_NAME, *PSEARCH_NAME; typedef DNSLIB_SEARCH_LIST SEARCH_LIST, *PSEARCH_LIST; typedef DNSLIB_NETINFO DNS_NETINFO, *PDNS_NETINFO;
#endif
// // NetInfo routines (should be private) // // But currently used in netdiag and nslookup // (nslookup problem is simply getting isolation // in header file) //
BOOL Dns_IsUpdateNetworkInfo( IN PDNS_NETINFO pNetInfo );
// // General DNS utilities (dnsutil.c) //
IP_ADDRESS Dns_GetNetworkMask( IN IP_ADDRESS ipAddress );
PSTR _fastcall Dns_StatusString( IN DNS_STATUS Status );
#define Dns_StatusToErrorString_A(status) Dns_StatusString(status)
DNS_STATUS _fastcall Dns_MapRcodeToStatus( IN BYTE ResponseCode );
BYTE _fastcall Dns_IsStatusRcode( IN DNS_STATUS Status );
// // Name utilities (name.c) //
PSTR _fastcall Dns_GetDomainName( IN PCSTR pszName );
PWSTR _fastcall Dns_GetDomainName_W( IN PCWSTR pwsName );
PCHAR _fastcall Dns_GetTldForName( IN PCSTR pszName );
BOOL _fastcall Dns_IsNameShort( IN PCSTR pszName );
BOOL _fastcall Dns_IsNameFQDN( IN PCSTR pszName );
DNS_STATUS Dns_ValidateAndCategorizeDnsNameEx( IN PCHAR pchName, IN DWORD cchNameLength, OUT PDWORD pLabelCount );
#define Dns_ValidateAndCategorizeDnsName(p,c) \ Dns_ValidateAndCategorizeDnsNameEx((p),(c),NULL)
DWORD Dns_NameLabelCount( IN PCSTR pszName );
#define DNS_NAME_UNKNOWN 0x00000000 #define DNS_NAME_IS_FQDN 0x00000001 #define DNS_NAME_SINGLE_LABEL 0x00000010 #define DNS_NAME_MULTI_LABEL 0x00000100
DWORD _fastcall Dns_GetNameAttributes( IN PCSTR pszName );
// // Packet create\read\write (packet.c) //
// // UDP packet buffer // // 1472 is the maximum ethernet IP\UDP payload size // without causing fragmentation, use as default buffer //
#define DNS_MAX_UDP_PACKET_BUFFER_LENGTH (1472)
// parsing RR // convenient to get WIRE records into aligned\host order format
typedef struct _DNS_PARSED_RR { PCHAR pchName; PCHAR pchRR; PCHAR pchData; PCHAR pchNextRR;
// note from here on down mimics wire record
WORD Type; WORD Class; DWORD Ttl; WORD DataLength; } DNS_PARSED_RR, *PDNS_PARSED_RR;
// // DNS Server Message Info structure // // This is structure in which requests are held while being // processed by the DNS server. //
// // Sockaddr big enough for either IP4 or IP6 // // DCR: make length field part of our sockaddr? //
#define SIZE_IP6_SOCKADDR_DNS_PRIVATE (28)
typedef union _DnsSockaddr { SOCKADDR_IN In4; #ifdef _WS2TCPIP_H_ SOCKADDR_IN6 In6; #else BYTE In6[28]; #endif } SOCKADDR_DNS, *PSOCKADDR_DNS;
typedef struct _DnsMessageBuf { LIST_ENTRY ListEntry; // for queuing
// // Addressing //
SOCKET Socket; INT RemoteAddressLength; //16 //SOCKADDR_IN RemoteAddress;
SOCKADDR_DNS RemoteAddress;
// // Basic packet info //
//32 DWORD BufferLength; // total length of buffer PCHAR pBufferEnd; // ptr to byte after buffer
PBYTE pCurrent; // current location in buffer PWORD pCurrentCountField; // current count field being written
// // Current lookup info //
// 48 DWORD Timeout; // recv timeout DWORD QueryTime; // time of original query WORD wTypeCurrent; // type of query being done WORD wOffsetCurrent;
// // Queuing //
WORD wQueuingXid; // match XID to response //64 DWORD QueuingTime; // time queued DWORD ExpireTime; // queue timeout
// // Basic packet flags //
BOOLEAN fTcp; BOOLEAN fSwapped; // header in net order BOOLEAN fMessageComplete; // complete message received BOOLEAN fConvertUnicode; // convert to unicode BOOLEAN fSocketKeepalive; // keep socket alive BOOLEAN fLastSendOpt; // last send contained OPT
// // TCP message reception //
//80 PCHAR pchRecv; // ptr to next pos in message
// // End of message before OPT addition //
PCHAR pPreOptEnd;
// // WARNING ! // // Message length MUST // - be a WORD type // - immediately preceed message itself // for proper send/recv of TCP messages. // // Use pointers above to DWORD (or QWORD) align, then recv bytes to push // message length against MessageHead. Note, that DNS_HEADER contains // only WORDs as it's largest element and so should chummy up even on // WORD boundary. DWORD boundary should be very safe. // //96 WORD BytesToReceive; WORD MessageLength;
// // DNS Message itself //
DNS_HEADER MessageHead;
// // Question and RR section // // This simply provides some coding simplicity in accessing // this section given MESSAGE_INFO structure. //
CHAR MessageBody[1];
} DNS_MSG_BUF, *PDNS_MSG_BUF;
#define SIZEOF_MSG_BUF_OVERHEAD (sizeof(DNS_MSG_BUF) - sizeof(DNS_HEADER) - 1)
#define DNS_MESSAGE_END(pMsg) \ ((PCHAR)&(pMsg)->MessageHead + (pMsg)->MessageLength)
#define DNS_MESSAGE_OFFSET( pMsg, p ) \ ((PCHAR)(p) - (PCHAR)(&(pMsg)->MessageHead))
#define DNS_MESSAGE_CURRENT_OFFSET( pMsg ) \ DNS_MESSAGE_OFFSET( (pMsg), (pMsg)->pCurrent )
// // Handy for packet setup //
#define CLEAR_DNS_HEADER_FLAGS_AND_XID( pHead ) ( *(PDWORD)(pHead) = 0 )
PDNS_MSG_BUF Dns_AllocateMsgBuf( IN WORD wBufferLength OPTIONAL );
VOID Dns_InitializeMsgBuf( IN OUT PDNS_MSG_BUF pMsg );
PDNS_MSG_BUF Dns_BuildPacket( IN PDNS_HEADER pHeader, IN BOOL fNoHeaderCounts, IN PDNS_NAME pszQuestionName, IN WORD wQuestionType, IN PDNS_RECORD pRecord, IN DWORD dwFlags, IN BOOL fUpdatePacket );
PCHAR _fastcall Dns_WriteDottedNameToPacket( IN OUT PCHAR pch, IN PCHAR pchStop, IN PSTR pszName, IN PSTR pszDomain, OPTIONAL IN WORD wDomainOffset, OPTIONAL IN BOOL fUnicodeName );
PCHAR _fastcall Dns_WriteStringToPacket( IN OUT PCHAR pch, IN PCHAR pchStop, IN PSTR pszString, IN BOOL fUnicodeString );
PCHAR Dns_WriteQuestionToMessage( IN OUT PDNS_MSG_BUF pMsg, IN PDNS_NAME pszName, IN WORD wType, IN BOOL fUnicodeName );
DNS_STATUS Dns_WriteRecordStructureToMessage( IN OUT PDNS_MSG_BUF pMsg, IN WORD wType, IN WORD wClass, IN DWORD dwTtl, IN WORD wDataLength );
PCHAR Dns_WriteRecordStructureToPacketEx( IN OUT PCHAR pchBuf, IN WORD wType, IN WORD wClass, IN DWORD dwTtl, IN WORD wDataLength );
DNS_STATUS Dns_WriteRecordStructureToPacket( IN OUT PCHAR pchBuf, IN PDNS_RECORD pRecord, IN BOOL fUpdatePacket );
VOID Dns_SetRecordDatalength( IN OUT PDNS_WIRE_RECORD pRecord, IN WORD wDataLength );
DNS_STATUS Dns_AddRecordsToMessage( IN OUT PDNS_MSG_BUF pMsg, IN PDNS_RECORD pRecord, IN BOOL fUpdateMessage );
PCHAR _fastcall Dns_SkipPacketName( IN PCHAR pch, IN PCHAR pchEnd );
BOOL Dns_IsSamePacketQuestion( IN PDNS_MSG_BUF pMsg1, IN PDNS_MSG_BUF pMsg2 );
PCHAR _fastcall Dns_SkipPacketRecord( IN PCHAR pchRecord, IN PCHAR pchMsgEnd );
PCHAR Dns_SkipToRecord( IN PDNS_HEADER pMsgHead, IN PCHAR pMsgEnd, IN INT iCount );
PCHAR Dns_ReadRecordStructureFromPacket( IN PCHAR pchPacket, IN PCHAR pchMsgEnd, IN OUT PDNS_PARSED_RR pParsedRR );
DNS_STATUS Dns_ExtractRecordsFromMessage( IN PDNS_MSG_BUF pMsg, IN BOOL fUnicode, OUT PDNS_RECORD * ppRecord );
DNS_STATUS Dns_ExtractRecordsFromBuffer( IN PDNS_MESSAGE_BUFFER pDnsBuffer, IN WORD wMessageLength, IN BOOL fUnicode, OUT PDNS_RECORD * ppRecord );
void Dns_NormalizeAllRecordTtls( IN PDNS_RECORD pRecord );
PCHAR _fastcall Dns_ReadPacketName( IN OUT PCHAR pchNameBuffer, OUT PWORD pwNameLength, IN OUT PWORD pwNameOffset, OPTIONAL OUT PBOOL pfNameSameAsPrevious, OPTIONAL IN PCHAR pchName, IN PCHAR pchStart, IN PCHAR pchEnd );
PCHAR _fastcall Dns_ReadPacketNameAllocate( IN OUT PCHAR * ppchName, OUT PWORD pwNameLength, IN OUT PWORD pwPrevNameOffset, OPTIONAL OUT PBOOL pfNameSameAsPrevious, OPTIONAL IN PCHAR pchPacketName, IN PCHAR pchStart, IN PCHAR pchEnd );
WORD Dns_GetRandomXid( IN PVOID pSeed );
// // Socket setup (socket.c) //
// // these two routines really don't belong here -- system stuff should be elsewhere //
DNS_STATUS Dns_InitializeWinsock( VOID ); VOID Dns_CleanupWinsock( VOID );
SOCKET Dns_CreateSocket( IN INT SockType, IN IP_ADDRESS ipAddress, IN USHORT Port );
SOCKET Dns_CreateMulticastSocket( IN INT SockType, IN IP_ADDRESS ipAddress, IN USHORT Port, IN BOOL fSend, IN BOOL fReceive );
VOID Dns_CloseSocket( IN SOCKET Socket );
VOID Dns_CloseConnection( IN SOCKET Socket );
DNS_STATUS Dns_SetupGlobalAsyncSocket( VOID );
// // Raw packet send and recv (send.c) //
DNS_STATUS Dns_SendEx( IN OUT PDNS_MSG_BUF pMsg, IN IP4_ADDRESS SendIp, OPTIONAL IN BOOL fNoOpt );
#define Dns_Send( pMsg ) Dns_SendEx( (pMsg), 0, 0 )
DNS_STATUS Dns_Recv( IN OUT PDNS_MSG_BUF pMsg );
DNS_STATUS Dns_RecvUdp( IN OUT PDNS_MSG_BUF pMsg );
VOID Dns_SendMultipleUdp( IN OUT PDNS_MSG_BUF pMsg, IN PIP_ARRAY aipSendAddrs );
DNS_STATUS Dns_SendAndRecvUdp( IN OUT PDNS_MSG_BUF pMsgSend, OUT PDNS_MSG_BUF pMsgRecv, IN DWORD dwFlags, IN PIP_ARRAY aipServers, IN OUT PDNS_NETINFO pAdapterInfo );
DNS_STATUS Dns_SendAndRecvMulticast( IN OUT PDNS_MSG_BUF pMsgSend, OUT PDNS_MSG_BUF pMsgRecv, IN OUT PDNS_NETINFO pAdapterInfo OPTIONAL );
DNS_STATUS Dns_OpenTcpConnectionAndSend( IN OUT PDNS_MSG_BUF pMsg, IN IP_ADDRESS ipServer, IN BOOL fBlocking );
DNS_STATUS Dns_RecvTcp( IN OUT PDNS_MSG_BUF pMsg );
DNS_STATUS Dns_SendAndRecvTcp( IN OUT PDNS_MSG_BUF pMsgSend, OUT PDNS_MSG_BUF pMsgRecv, IN PIP_ARRAY aipServers, IN OUT PDNS_NETINFO pAdapterInfo );
VOID Dns_InitializeMsgRemoteSockaddr( IN OUT PDNS_MSG_BUF pMsg, IN IP_ADDRESS IpAddress );
DNS_STATUS Dns_SendAndRecv( IN OUT PDNS_MSG_BUF pMsgSend, OUT PDNS_MSG_BUF * ppMsgRecv, OUT PDNS_RECORD * ppResponseRecords, IN DWORD dwFlags, IN PIP_ARRAY aipServers, IN OUT PDNS_NETINFO pAdapterInfo );
VOID Dns_InitQueryTimeouts( VOID );
// // Query (query.c) //
// // Flags to DnsQuery // // These are in addition to public flags in dnsapi.h // They must all be in the reserved section defined by // DNS_QUERY_RESERVED //
// Unicode i\o
#define DNSQUERY_UNICODE_NAME (0x01000000) #define DNSQUERY_UNICODE_OUT (0x02000000)
// DNS server query
#define DNS_SERVER_QUERY_NAME (L"..DnsServers")
DNS_STATUS Dns_QueryLib( IN OUT PDNS_MSG_BUF * ppMsgResponse, OUT PDNS_RECORD * ppRecord, IN PDNS_NAME pszName, IN WORD wType, IN DWORD dwFlags, IN PIP_ARRAY aipDnsServers, IN PDNS_NETINFO pNetworkInfo, IN SOCKET Socket OPTIONAL );
DNS_STATUS Dns_QueryLibEx( IN OUT PDNS_MSG_BUF * ppMsgResponse, OUT PDNS_RECORD * ppResponseRecord, IN PDNS_HEADER pHeader, IN BOOL fNoHeaderCounts, IN PDNS_NAME pszName, IN WORD wType, IN PDNS_RECORD pRecord, IN DWORD dwFlags, IN PIP_ARRAY aipDnsServers, IN PDNS_NETINFO pNetworkInfo );
DNS_STATUS Dns_FindAuthoritativeZoneLib( IN PDNS_NAME pszName, IN DWORD dwFlags, IN PIP_ARRAY aipQueryServers, OUT PDNS_NETINFO * ppNetworkInfo );
PDNS_NETINFO Dns_BuildUpdateNetworkInfoFromFAZ( IN PSTR pszZone, IN PSTR pszPrimaryDns, IN PDNS_RECORD pRecord );
// // Dynamic update (update.c) //
PCHAR Dns_WriteNoDataUpdateRecordToMessage( IN PCHAR pch, IN PCHAR pchStop, IN WORD wClass, IN WORD wType );
PCHAR Dns_WriteDataUpdateRecordToMessage( IN PCHAR pch, IN PCHAR pchStop, IN WORD wClass, IN WORD wType, IN DWORD dwTtl, IN WORD wDataLength );
PDNS_MSG_BUF Dns_BuildHostUpdateMessage( IN OUT PDNS_MSG_BUF pMsg, IN PSTR pszZone, IN PSTR pszName, IN PIP_ARRAY aipAddresses, IN DWORD dwTtl );
PDNS_RECORD Dns_HostUpdateRRSet( IN PSTR pszHostName, IN PIP_ARRAY aipAddrs, IN DWORD dwTtl );
DNS_STATUS Dns_UpdateHostAddrs( IN PSTR pszName, IN PIP_ARRAY aipAddresses, IN PIP_ARRAY aipServers, IN DWORD dwTtl );
DNS_STATUS Dns_UpdateHostAddrsOld( IN PSTR pszName, IN PIP_ARRAY aipAddresses, IN PIP_ARRAY aipServers, IN DWORD dwTtl );
DNS_STATUS Dns_UpdateLib( IN PDNS_RECORD pRecord, IN DWORD dwFlags, IN PDNS_NETINFO pNetworkInfo, IN HANDLE hCreds, OPTIONAL OUT PDNS_MSG_BUF * ppMsgRecv OPTIONAL );
DNS_STATUS Dns_UpdateLibEx( IN PDNS_RECORD pRecord, IN DWORD dwFlags, IN PDNS_NAME pszZone, IN PDNS_NAME pszServerName, IN PIP_ARRAY aipServers, IN HANDLE hCreds, OPTIONAL OUT PDNS_MSG_BUF * ppMsgRecv OPTIONAL );
// // List build // // pFirst points to first element in list. // pLast points to last element in list. // // This builds a list for element types which have a pNext field // as their first structure member. //
typedef struct _Dns_List { PVOID pFirst; PVOID pLast; } DNS_LIST, *PDNS_LIST;
// // To init pFirst is NULL. // But pLast points at the location of the pFirst pointer -- essentially // treating the DNS_LIST as an element and pFirst as its next ptr. // // During an add, the address given in pLast, is set with the new element, // equivalent to setting pLast's pNext field. Then pLast is reset to point // at a new element. // // When the first element is added to the list, pLast is pointing at the // DNS_LIST structure itself, so pFirst (as a dummy pNext) is set with // the ptr to the first element. // // This works ONLY for elements which have a pNext field as the first // structure member. //
#define DNS_LIST_INIT( pList ) \ { \ PDNS_LIST _plist = (pList); \ _plist->pFirst = NULL; \ _plist->pLast = (_plist); \ }
#define DNS_LIST_ADD( pList, pnew ) \ { \ PDNS_LIST _plist = (pList); \ PVOID _pnew = (pnew); \ *(PVOID*)(_plist->pLast) = _pnew; \ _plist->pLast = _pnew; \ }
#define IS_DNS_LIST_EMPTY( pList ) \ ( (pList)->pFirst == NULL )
// // DNS_LIST as structure macros // // Faster when function contains DNS_LIST structure itself and // NO SIDE EFFECTS will be present in call. //
#define DNS_LIST_STRUCT_INIT( List ) \ { \ List.pFirst = NULL; \ List.pLast = &List; \ }
#define DNS_LIST_STRUCT_ADD( List, pnew ) \ { \ *(PVOID*)(List.pLast) = (PVOID)pnew; \ List.pLast = (PVOID)pnew; \ }
#define IS_DNS_LIST_STRUCT_EMPTY( List ) \ ( List.pFirst == NULL )
// // Record building (rralloc.c) //
PDNS_RECORD WINAPI Dns_AllocateRecord( IN WORD wBufferLength );
VOID WINAPI Dns_RecordFree( IN OUT PDNS_RECORD pRecord );
#if 1 // Old BS with flag -- kill when all fixed up
VOID WINAPI Dns_RecordListFreeEx( IN OUT PDNS_RECORD pRRList, IN BOOL fFreeOwner );
#define Dns_RecordListFree(p, f) Dns_RecordListFreeEx(p, f)
#else // new version VOID WINAPI Dns_RecordListFree( IN OUT PDNS_RECORD pRRList );
#endif
PDNS_RECORD Dns_RecordSetDetach( IN OUT PDNS_RECORD pRRList );
PDNS_RECORD WINAPI Dns_RecordListAppend( IN OUT PDNS_RECORD pHeadList, IN PDNS_RECORD pTailList );
DWORD Dns_RecordListCount( IN PDNS_RECORD pRRList, IN WORD wType );
// // Record build from data strings (rrbuild.c) //
PDNS_RECORD Dns_RecordBuild_A( IN OUT PDNS_RRSET pRRSet, IN PSTR pszOwner, IN WORD wType, IN BOOL fAdd, IN UCHAR Section, IN INT Argc, IN PCHAR * Argv );
PDNS_RECORD Dns_RecordBuild_W( IN OUT PDNS_RRSET pRRSet, IN PWSTR pszOwner, IN WORD wType, IN BOOL fAdd, IN UCHAR Section, IN INT Argc, IN PWCHAR * Argv );
// // Record set manipulation //
// // Record Compare // // Note: these routines will NOT do proper unicode compare, unless // records have the fUnicode flag set. //
BOOL WINAPI Dns_RecordCompare( IN PDNS_RECORD pRecord1, IN PDNS_RECORD pRecord2 );
BOOL WINAPI Dns_RecordSetCompare( IN OUT PDNS_RECORD pRR1, IN OUT PDNS_RECORD pRR2, OUT PDNS_RECORD * ppDiff1, OPTIONAL OUT PDNS_RECORD * ppDiff2 OPTIONAL );
typedef enum _DnsSetCompareResult { DnsSetCompareError = (-1), DnsSetCompareIdentical, DnsSetCompareNoOverlap, DnsSetCompareOneSubsetOfTwo, DnsSetCompareTwoSubsetOfOne, DnsSetCompareIntersection } DNS_SET_COMPARE_RESULT;
DNS_SET_COMPARE_RESULT WINAPI Dns_RecordSetCompareEx( IN OUT PDNS_RECORD pRR1, IN OUT PDNS_RECORD pRR2, OUT PDNS_RECORD * ppDiff1, OPTIONAL OUT PDNS_RECORD * ppDiff2 OPTIONAL );
BOOL WINAPI Dns_RecordSetCompareForIntersection( IN OUT PDNS_RECORD pRR1, IN OUT PDNS_RECORD pRR2 );
// // Record set prioritization (rrsort.c) //
BOOL Dns_CompareIpAddresses( IN IP_ADDRESS addr1, IN IP_ADDRESS addr2, IN IP_ADDRESS subnetMask );
// // DNS Name compare //
BOOL Dns_NameCompare_A( IN PCSTR pName1, IN PCSTR pName2 );
BOOL Dns_NameCompare_W( IN PCWSTR pName1, IN PCWSTR pName2 );
BOOL Dns_NameCompare_UTF8( IN PCSTR pName1, IN PCSTR pName2 );
//#define Dns_NameCompare(pName1, pName2) Dns_NameCompare_UTF8((pName1),(pName2)) //#define Dns_NameCompare_U(pName1, pName2) Dns_NameCompare_UTF8((pName1),(pName2))
BOOL Dns_NameComparePrivate( IN PCSTR pName1, IN PCSTR pName2, IN DNS_CHARSET CharSet );
// // Advanced name comparison // Includes hierarchial name relationship. //
DNS_NAME_COMPARE_STATUS Dns_NameCompareEx( IN LPCSTR pszNameLeft, IN LPCSTR pszNameRight, IN DWORD dwReserved, IN DNS_CHARSET CharSet );
// // Record Copy //
PDNS_RECORD WINAPI Dns_RecordCopyEx( IN PDNS_RECORD pRecord, IN DNS_CHARSET CharSetIn, IN DNS_CHARSET CharSetOut );
// // RR Set copy //
PDNS_RECORD WINAPI Dns_RecordSetCopyEx( IN PDNS_RECORD pRR, IN DNS_CHARSET CharSetIn, IN DNS_CHARSET CharSetOut );
// // Record \ type routines // // // Resource record type\name mapping table //
typedef struct { PCHAR pszTypeName; // type string (used in database files) WORD wType; // type in host byte order } TYPE_NAME_TABLE;
extern TYPE_NAME_TABLE TypeTable[];
// // Max record name length, allows upcasing of incoming labels // to optimize comparisons //
#define MAX_RECORD_NAME_LENGTH (8)
// // Record type specific sizes //
#define WKS_MAX_PORT (1024) // max well known service port #define WKS_MAX_BITMASK_LENGTH (128) // 1024bits / 8bits/byte
#define SIZEOF_A6_ADDRESS_SUFFIX_LENGTH 16
#define SIZEOF_SOA_FIXED_DATA (5 * sizeof(DWORD)) #define SIZEOF_MX_FIXED_DATA (sizeof(WORD)) #define SIZEOF_WKS_FIXED_DATA (SIZEOF_IP_ADDRESS + sizeof(BYTE)) #define SIZEOF_KEY_FIXED_DATA (sizeof(DWORD)) #define SIZEOF_SIG_FIXED_DATA (4 * sizeof(DWORD) + sizeof(WORD)) #define SIZEOF_NXT_FIXED_DATA (0) #define SIZEOF_LOC_FIXED_DATA (4 * sizeof(DWORD)) #define SIZEOF_SRV_FIXED_DATA (3 * sizeof(WORD)) #define SIZEOF_A6_FIXED_DATA (1 + SIZEOF_A6_ADDRESS_SUFFIX_LENGTH)
#define SIZEOF_TKEY_FIXED_DATA (2 * sizeof(DWORD) + 4 * sizeof(WORD))
#define SIZEOF_TSIG_PRE_SIG_FIXED_DATA (2 * sizeof(DWORD) + sizeof(WORD)) #define SIZEOF_TSIG_POST_SIG_FIXED_DATA (3 * sizeof(WORD)) #define SIZEOF_TSIG_FIXED_DATA (2 * sizeof(DWORD) + 4 * sizeof(WORD))
#define SIZEOF_WINS_FIXED_DATA (4 * sizeof(DWORD)) #define SIZEOF_NBSTAT_FIXED_DATA (3 * sizeof(DWORD))
// // Record type routines // These ones are of possible public interest and exposed in dnsapi.dll //
BOOL _fastcall Dns_IsAMailboxType( IN WORD wType );
WORD Dns_RecordTypeForName( IN PCHAR pszName, IN INT cchNameLength );
BOOL Dns_WriteStringForType_A( OUT PCHAR pBuffer, IN WORD wType );
BOOL Dns_WriteStringForType_W( OUT PWCHAR pBuffer, IN WORD wType );
PCHAR Dns_RecordStringForType( IN WORD wType );
PCHAR Dns_RecordStringForWritableType( IN WORD wType );
// // Record type specific stuff //
BOOL Dns_IsStringCountValidForTextType( IN WORD wType, IN WORD StringCount );
// // ATMA conversions //
DWORD Dns_AtmaAddressLengthForAddressString( IN PCHAR pchString, IN DWORD dwStringLength );
DNS_STATUS Dns_AtmaStringToAddress( OUT PBYTE pAddress, IN OUT PDWORD pdwAddrLength, IN PCHAR pchString, IN DWORD dwStringLength );
PCHAR Dns_AtmaAddressToString( OUT PCHAR pchString, IN UCHAR AddrType, IN PBYTE pAddress, IN DWORD dwAddrLength );
// // DNSSEC SIG and KEY routines //
// Max key is 4096 bit giving 512 byte length. // // Max string representation is actually 33% larger as each three byte (24bit) // block contains four base64 characters.
#define DNS_MAX_KEY_LENGTH (512)
#define DNS_MAX_KEY_STRING_LENGTH (685)
WORD Dns_KeyRecordFlagForString( IN PCHAR pchName, IN INT cchNameLength );
PCHAR Dns_KeyRecordFlagString( IN DWORD dwFlag, IN OUT PCHAR pchFlag );
UCHAR Dns_KeyRecordProtocolForString( IN PCHAR pchName, IN INT cchNameLength );
PCHAR Dns_GetKeyProtocolString( IN UCHAR uchProtocol );
UCHAR Dns_SecurityAlgorithmForString( IN PCHAR pchName, IN INT cchNameLength );
PCHAR Dns_GetDnssecAlgorithmString( IN UCHAR uchAlgorithm );
UCHAR Dns_SecurityBase64CharToBits( IN CHAR ch64 );
DNS_STATUS Dns_SecurityBase64StringToKey( OUT PBYTE pKey, OUT PDWORD pKeyLength, IN PCHAR pchString, IN DWORD cchLength );
PCHAR Dns_SecurityKeyToBase64String( IN PBYTE pKey, IN DWORD KeyLength, OUT PCHAR pchBuffer );
LONG Dns_ParseSigTime( IN PCHAR pchString, IN INT cchLength );
PCHAR Dns_SigTimeString( IN LONG SigTime, OUT PCHAR pchBuffer );
// // WINS \ WINS-R types detection //
#define IS_WINS_TYPE(type) (((type) & 0xfffc) == 0xff00)
// // MS WINS mapping flags //
// return on invalid WINS flag
#define DNS_WINS_FLAG_ERROR (-1)
// max length of WINS flags // pass buffer at least this big
#define WINS_FLAG_MAX_LENGTH (80)
DWORD Dns_WinsRecordFlagForString( IN PCHAR pchName, IN INT cchNameLength );
PCHAR Dns_WinsRecordFlagString( IN DWORD dwFlag, IN OUT PCHAR pchFlag );
// // must sit here until PDNS_RECORD defined in public dns.h header //
DNS_STATUS Dns_RecordWriteFileString( IN PDNS_RECORD pRecord, IN PSTR pszZoneName, IN DWORD dwDefaultTtl OPTIONAL );
// // IP Address to\from string utilities (straddr.c) //
// // String to Address //
BOOL Dns_Ip4StringToAddress_W( OUT PIP4_ADDRESS pIp4Addr, IN PCWSTR pwString );
BOOL Dns_Ip4StringToAddress_A( OUT PIP4_ADDRESS pIp4Addr, IN PCSTR pString );
BOOL Dns_Ip6StringToAddress_A( OUT PIP6_ADDRESS pIp6Addr, IN PCSTR pString );
BOOL Dns_Ip6StringToAddress_W( OUT PIP6_ADDRESS pIp6Addr, IN PCWSTR pwString );
// // Combined IP4\IP6 string to address //
BOOL Dns_StringToAddress_W( OUT PCHAR pAddrBuf, IN OUT PDWORD pBufLength, IN PCWSTR pString, IN OUT PDWORD pAddrFamily );
BOOL Dns_StringToAddress_A( OUT PCHAR pAddrBuf, IN OUT PDWORD pBufLength, IN PCSTR pString, IN OUT PDWORD pAddrFamily );
// // Address to string //
PWCHAR Dns_Ip6AddressToString_W( OUT PWCHAR pwString, IN PIP6_ADDRESS pIp6Addr );
PCHAR Dns_Ip6AddressToString_A( OUT PCHAR pchString, IN PIP6_ADDRESS pIp6Addr );
PWCHAR Dns_Ip4AddressToString_W( OUT PWCHAR pwString, IN PIP4_ADDRESS pIp4Addr );
PCHAR Dns_Ip4AddressToString_A( OUT PCHAR pString, IN PIP4_ADDRESS pIp4Addr );
// // Address to string -- combined //
PCHAR Dns_AddressToString_A( OUT PCHAR pchString, IN OUT PDWORD pStringLength, IN PBYTE pAddr, IN DWORD AddrLength, IN DWORD AddrFamily );
// // Reverse lookup address-to-name IP4 //
PCHAR Dns_Ip4AddressToReverseName_A( OUT PCHAR pBuffer, IN IP4_ADDRESS IpAddr );
PWCHAR Dns_Ip4AddressToReverseName_W( OUT PWCHAR pBuffer, IN IP4_ADDRESS IpAddr );
PCHAR Dns_Ip4AddressToReverseNameAlloc_A( IN IP4_ADDRESS IpAddr );
PWCHAR Dns_Ip4AddressToReverseNameAlloc_W( IN IP4_ADDRESS IpAddr );
// // Reverse lookup address-to-name IP6 //
PCHAR Dns_Ip6AddressToReverseName_A( OUT PCHAR pBuffer, IN IP6_ADDRESS Ip6Addr );
PWCHAR Dns_Ip6AddressToReverseName_W( OUT PWCHAR pBuffer, IN IP6_ADDRESS Ip6Addr );
PCHAR Dns_Ip6AddressToReverseNameAlloc_A( IN IP6_ADDRESS Ip6Addr );
PWCHAR Dns_Ip6AddressToReverseNameAlloc_W( IN IP6_ADDRESS Ip6Addr );
// // Reverse lookup name-to-address //
BOOL Dns_Ip4ReverseNameToAddress_A( OUT PIP4_ADDRESS pIp4Addr, IN PCSTR pszName );
BOOL Dns_Ip4ReverseNameToAddress_W( OUT PIP4_ADDRESS pIp4Addr, IN PCWSTR pwsName );
BOOL Dns_Ip6ReverseNameToAddress_A( OUT PIP6_ADDRESS pIp6Addr, IN PCSTR pszName );
BOOL Dns_Ip6ReverseNameToAddress_W( OUT PIP6_ADDRESS pIp6Addr, IN PCWSTR pwsName );
// // Combined IP4\IP6 reverse lookup name-to-address //
BOOL Dns_ReverseNameToAddress_W( OUT PCHAR pAddrBuf, IN OUT PDWORD pBufLength, IN PCWSTR pString, IN OUT PDWORD pAddrFamily );
BOOL Dns_ReverseNameToAddress_A( OUT PCHAR pAddrBuf, IN OUT PDWORD pBufLength, IN PCSTR pString, IN OUT PDWORD pAddrFamily );
// // String utilities (string.c) // // Note some of these require memory allocation, see note // on memory allocation below. // // Flags are defined in dnsapi.h //
//#define DNS_ALLOW_RFC_NAMES_ONLY (0) //#define DNS_ALLOW_NONRFC_NAMES (0x00000001) //#define DNS_ALLOW_MULTIBYTE_NAMES (0x00000002) //#define DNS_ALLOW_ALL_NAMES (0x00000003)
// // Unicode name buffer length. // Non-type specific routines below take buffer counts in bytes. // Unicode buffers of max name length have twice the bytes. //
#define DNS_MAX_NAME_BUFFER_LENGTH_UNICODE (2 * DNS_MAX_NAME_BUFFER_LENGTH)
// // Macros to simplify UTF8 conversions // // UTF8 is simply a representation of unicode that maps one-to-one // for the ASCII space. // Unicode UTF8 // ------- ---- // < 0x80 (128) -> use low byte (one-to-one mapping) // < 0x07ff -> two chars // > 0x07ff -> three chars //
#define UTF8_1ST_OF_2 0xc0 // 110x xxxx #define UTF8_1ST_OF_3 0xe0 // 1110 xxxx #define UTF8_TRAIL 0x80 // 10xx xxxx
#define UTF8_2_MAX 0x07ff // max unicode character representable in // in two byte UTF8
// // Explicitly UTF8 string //
typedef PSTR PU8STR;
PSTR Dns_CreateStringCopy( IN PCHAR pchString, IN DWORD cchString );
DWORD Dns_GetBufferLengthForStringCopy( IN PCHAR pchString, IN DWORD cchString, IN DNS_CHARSET CharSetIn, IN DNS_CHARSET CharSetOut );
DWORD Dns_StringCopy( OUT PBYTE pBuffer, IN OUT PDWORD pdwBufLength, IN PCHAR pchString, IN DWORD cchString, IN DNS_CHARSET CharSetIn, IN DNS_CHARSET CharSetOut );
PVOID Dns_StringCopyAllocate( IN PCHAR pchString, IN DWORD cchString, IN DNS_CHARSET CharSetIn, IN DNS_CHARSET CharSetOut );
#define Dns_StringCopyAllocate_W( p, c ) \ ( (PWCHAR) Dns_StringCopyAllocate( \ (PCHAR) (p), \ (c), \ DnsCharSetUnicode, \ DnsCharSetUnicode ) )
#define Dns_StringCopyAllocate_A( p, c ) \ ( (PCHAR) Dns_StringCopyAllocate( \ (p), \ (c), \ DnsCharSetUtf8, \ DnsCharSetUtf8 ) )
PSTR Dns_CreateStringCopy_A( IN PCSTR pwsString );
PWSTR Dns_CreateStringCopy_W( IN PCWSTR pwsString );
PWSTR Dns_CreateConcatenatedString_W( IN PCWSTR * pStringArray );
PWSTR Dns_GetResourceString( IN DWORD dwStringId, IN PWSTR pwszBuffer, IN DWORD cbBuffer );
INT wcsicmp_ThatWorks( IN PWSTR pString1, IN PWSTR pString2 );
// // Special DNS name string functions //
#define Dns_GetBufferLengthForNameCopy(a,b,c,d)\ Dns_GetBufferLengthForStringCopy((a),(b),(c),(d))
#define Dns_NameCopy(a,b,c,d,e,f) \ Dns_StringCopy(a,b,c,d,e,f)
#define Dns_NameCopyAllocate(a,b,c,d) \ Dns_StringCopyAllocate(a,b,c,d)
// // Name validation (string.c) //
DNS_STATUS Dns_ValidateName_UTF8( IN LPCSTR pszName, IN DNS_NAME_FORMAT Format );
DNS_STATUS Dns_ValidateName_W( IN LPCWSTR pwszName, IN DNS_NAME_FORMAT Format );
DNS_STATUS Dns_ValidateName_A( IN LPCSTR pszName, IN DNS_NAME_FORMAT Format );
DNS_STATUS Dns_ValidateDnsString_UTF8( IN LPCSTR pszName );
DNS_STATUS Dns_ValidateDnsString_W( IN LPCWSTR pszName );
PSTR Dns_CreateStandardDnsNameCopy( IN PCHAR pchName, IN DWORD cchName, IN DWORD dwFlag );
// // UTF8 conversions (utf8.c) //
DNS_STATUS _fastcall Dns_ValidateUtf8Byte( IN BYTE chUtf8, IN OUT PDWORD pdwTrailCount );
DWORD _fastcall Dns_UnicodeToUtf8( IN PWCHAR pwUnicode, IN DWORD cchUnicode, OUT PCHAR pchResult, IN DWORD cchResult );
DWORD _fastcall Dns_Utf8ToUnicode( IN PCHAR pchUtf8, IN DWORD cchUtf8, OUT PWCHAR pwResult, IN DWORD cwResult );
DWORD Dns_Utf8ToOrFromAnsi( OUT PCHAR pchResult, IN DWORD cchResult, IN PCHAR pchIn, IN DWORD cchIn, IN DNS_CHARSET InCharSet, IN DNS_CHARSET OutCharSet );
DWORD Dns_AnsiToUtf8( IN PCHAR pchAnsi, IN DWORD cchAnsi, OUT PCHAR pchResult, IN DWORD cchResult );
DWORD Dns_Utf8ToAnsi( IN PCHAR pchUtf8, IN DWORD cchUtf8, OUT PCHAR pchResult, IN DWORD cchResult );
BOOL _fastcall Dns_IsStringAscii( IN PSTR pszString );
BOOL _fastcall Dns_IsStringAsciiEx( IN PCHAR pchString, IN DWORD cchString );
BOOL _fastcall Dns_IsWideStringAscii( IN PWSTR pwsString );
// // Resource record dispatch tables // // Resource record tables are indexed by type for standard types // These define limits on tables. // // Currently indexing out to RR 40, so that we'll handle any new RR types // out this far without interfering with WINS stuff. //
#define MAX_SELF_INDEXED_TYPE (48)
// // Mappings for non-self indexed types // // Note: these are presented here for information purposes only! // // Always call Dns_RecordTableIndexForType(wType) to get correct index. //
#define TKEY_TYPE_INDEX (MAX_SELF_INDEXED_TYPE + 1) #define TSIG_TYPE_INDEX (MAX_SELF_INDEXED_TYPE + 2)
#define WINS_TYPE_INDEX (MAX_SELF_INDEXED_TYPE + 3) #define WINSR_TYPE_INDEX (MAX_SELF_INDEXED_TYPE + 4)
// End of actual record types. // Query type indexes may extend beyond this index.
#define MAX_RECORD_TYPE_INDEX (MAX_SELF_INDEXED_TYPE + 4)
// // Generic indexer for both regular and extended (non-self-indexing) types //
#define INDEX_FOR_TYPE(type) Dns_RecordTableIndexForType(type)
// // Type to index mapping //
WORD Dns_RecordTableIndexForType( IN WORD wType );
// // Write record data to wire //
typedef PCHAR (* RR_WRITE_FUNCTION)( PDNS_RECORD, PCHAR, PCHAR );
extern RR_WRITE_FUNCTION RRWriteTable[];
// // Read record data from wire //
typedef PDNS_RECORD (* RR_READ_FUNCTION)( PDNS_RECORD, DNS_CHARSET, PCHAR, PCHAR, PCHAR );
extern RR_READ_FUNCTION RRReadTable[];
// // Proto type TSIG read from wire function //
PDNS_RECORD TsigRecordRead( IN OUT PDNS_RECORD pRR, IN DNS_CHARSET OutCharSet, IN OUT PCHAR pchStart, IN PCHAR pchData, IN PCHAR pchEnd );
PDNS_RECORD TkeyRecordRead( IN OUT PDNS_RECORD pRR, IN DNS_CHARSET OutCharSet, IN OUT PCHAR pchStart, IN PCHAR pchData, IN PCHAR pchEnd );
// // Copy record //
typedef PDNS_RECORD (* RR_COPY_FUNCTION)( PDNS_RECORD, DNS_CHARSET, DNS_CHARSET );
extern RR_COPY_FUNCTION RRCopyTable[];
// // Compare record data //
typedef BOOL (* RR_COMPARE_FUNCTION)( PDNS_RECORD, PDNS_RECORD );
extern RR_COMPARE_FUNCTION RRCompareTable[];
// // Generic print routine // // All our print routines will take the real print routine // as a parameter. This routine must have "sprintf-like" // or "fprintf-like" semantics. In other words a context, // format and variable number of arguments. // // Note the context argument is effectively a PVOID -- // different routines will have different contexts. The // explicit definition is to enforce strong type checking // so a call without a context is caught on compile. //
typedef struct _DnsPrintContext { PVOID pvDummy; DWORD Dummy; } PRINT_CONTEXT, *PPRINT_CONTEXT;
typedef VOID (* PRINT_ROUTINE)( PPRINT_CONTEXT, CHAR*, ... );
// // Print record //
typedef VOID (* RR_PRINT_FUNCTION)( PRINT_ROUTINE, PPRINT_CONTEXT, PDNS_RECORD );
extern RR_PRINT_FUNCTION RRPrintTable[];
// // Build from argc\argv data strings //
typedef PDNS_RECORD (* RR_BUILD_FUNCTION)( DWORD, PCHAR * );
extern RR_BUILD_FUNCTION RRBuildTable[];
typedef PDNS_RECORD (* RR_BUILD_FUNCTION_W)( DWORD, PWCHAR * );
extern RR_BUILD_FUNCTION_W RRBuildTableW[];
// // RnR utilities //
DWORD Dns_RnrLupFlagForString( IN PCHAR pchName, IN INT cchNameLength );
PCHAR Dns_GetRnrLupFlagString( IN DWORD dwFlag );
DWORD Dns_RnrNameSpaceIdForString( IN PCHAR pchName, IN INT cchNameLength );
PCHAR Dns_GetRnrNameSpaceIdString( IN DWORD dwFlag );
// // Hostent utilities //
BOOL Hostent_IsSupportedAddrType( IN WORD wType );
DWORD Hostent_Size( IN PHOSTENT pHostent, IN DNS_CHARSET CharSetExisting, IN DNS_CHARSET CharSetTarget, IN PDWORD pAliasCount, IN PDWORD pAddrCount );
PHOSTENT Hostent_Copy( IN OUT PBYTE * ppBuffer, IN OUT PINT pBufferSize, OUT PINT pHostentSize, IN PHOSTENT pHostent, IN DNS_CHARSET CharSetIn, IN DNS_CHARSET CharSetTarget, IN BOOL fOffsets, IN BOOL fAlloc );
DWORD Hostent_WriteIp4Addrs( IN OUT PHOSTENT pHostent, OUT PCHAR pAddrBuf, IN DWORD MaxBufCount, IN PIP4_ADDRESS Ip4Array, IN DWORD ArrayCount, IN BOOL fScreenZero );
DWORD Hostent_WriteLocalIp4Array( IN OUT PHOSTENT pHostent, OUT PCHAR pAddrBuf, IN DWORD MaxBufCount, IN PIP_ARRAY pIpArray );
BOOL Hostent_IsAddressInHostent( IN OUT PHOSTENT pHostent, IN PCHAR pAddr, IN DWORD AddrLength, IN INT Family OPTIONAL );
BOOL Hostent_IsIp4AddressInHostent( IN OUT PHOSTENT pHostent, IN IP4_ADDRESS Ip4Addr );
// // Hostent Object //
typedef struct _HostentBlob { PHOSTENT pHostent;
// flags BOOL fAllocatedBlob; BOOL fAllocatedBuf;
// buffer allocated PCHAR pBuffer; DWORD BufferLength;
DWORD AvailLength; PCHAR pAvailBuffer;
// buffer in build PCHAR pCurrent; DWORD BytesLeft;
// sizing info DWORD MaxAliasCount; DWORD MaxAddrCount;
// hostent building DWORD AliasCount; DWORD AddrCount; BOOL fWroteName; DNS_CHARSET CharSet; BOOL fUnicode; } HOSTENT_BLOB, *PHOSTENT_BLOB;
typedef struct _HostentInitRequest { INT AddrFamily; WORD wType; DWORD AddrCount; BOOL fUnicode; DNS_CHARSET CharSet; DWORD NameLength; PBYTE pName; DWORD AliasCount; DWORD AliasNameLength; } HOSTENT_INIT, *PHOSTENT_INIT;
DNS_STATUS HostentBlob_Create( IN OUT PHOSTENT_BLOB * ppBlob, IN PHOSTENT_INIT pReq );
PHOSTENT_BLOB HostentBlob_CreateAttachExisting( IN PHOSTENT pHostent, IN BOOL fUnicode );
VOID HostentBlob_Free( IN OUT PHOSTENT_BLOB pBlob );
DNS_STATUS HostentBlob_WriteAddress( IN OUT PHOSTENT_BLOB pBlob, IN PVOID pAddress, IN DWORD AddrSize, IN DWORD AddrType );
DNS_STATUS HostentBlob_WriteAddressArray( IN OUT PHOSTENT_BLOB pBlob, IN PVOID pAddrArray, IN DWORD AddrCount, IN DWORD AddrSize, IN DWORD AddrType );
DNS_STATUS HostentBlob_WriteNameOrAlias( IN OUT PHOSTENT_BLOB pBlob, IN PSTR pszName, IN BOOL fAlias, IN BOOL fUnicode );
DNS_STATUS HostentBlob_WriteRecords( IN OUT PHOSTENT_BLOB pBlob, IN PDNS_RECORD pRecords, IN BOOL fWriteName );
// Special hostents
PHOSTENT_BLOB Hostent_Localhost( IN INT AddrFamily );
DNS_STATUS HostentBlob_CreateFromIpArray( IN OUT PHOSTENT_BLOB * ppBlob, IN INT AddrFamily, IN INT AddrSize, IN INT AddrCount, IN PCHAR pArray, IN PSTR pName, IN BOOL fUnicode );
DNS_STATUS HostentBlob_CreateLocal( IN OUT PHOSTENT_BLOB * ppBlob, IN INT AddrFamily, IN BOOL fLoopback, IN BOOL fZero, IN BOOL fHostnameOnly );
// Query for hostent
PHOSTENT_BLOB HostentBlob_Query( IN PWSTR pwsName, IN WORD wType, IN DWORD Flags, IN OUT PVOID * ppMsg, OPTIONAL IN INT AddrFamily OPTIONAL );
// // Memory allocation // // Some DNS library functions -- including the IP array and string utils // -- allocate memory. This memory allocation defaults to routines that // use LocalAlloc, LocalReAlloc, LocalFree. If you desire alternative // memory allocation mechanisms, use this function to override the DNS // library defaults. All memory allocated by the DNS library, should // then be freed by the corresponding function. //
typedef PVOID (* DNSLIB_ALLOC_FUNCTION)(); typedef PVOID (* DNSLIB_REALLOC_FUNCTION)(); typedef VOID (* DNSLIB_FREE_FUNCTION)();
VOID Dns_LibHeapReset( IN DNSLIB_ALLOC_FUNCTION pAlloc, IN DNSLIB_REALLOC_FUNCTION pRealloc, IN DNSLIB_FREE_FUNCTION pFree );
// // These routines call the currently registered allocation functions // whether default or reset through Dns_ApiHeapReset() //
PVOID Dns_Alloc( IN INT iSize );
PVOID Dns_AllocZero( IN INT iSize );
PVOID Dns_Realloc( IN OUT PVOID pMem, IN INT iSize );
VOID Dns_Free( IN OUT PVOID pMem );
PVOID Dns_AllocMemCopy( IN PVOID pMem, IN INT iSize );
// // Print routines (print.c) // // Print routines below use any printf() like function to print. // this is typedef that function must match. //
// // Print Locking //
VOID DnsPrint_InitLocking( IN PCRITICAL_SECTION pLock );
VOID DnsPrint_Lock( VOID );
VOID DnsPrint_Unlock( VOID );
#define Dns_PrintInitLocking(a) DnsPrint_InitLocking(a) #define Dns_PrintLock() DnsPrint_Lock() #define Dns_PrintUnlock() DnsPrint_Unlock()
// // Print routines for general types and structures //
VOID DnsPrint_String( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, OPTIONAL IN PSTR pszString, IN BOOL fUnicode, IN PSTR pszTrailer OPTIONAL );
VOID DnsPrint_StringCharSet( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, OPTIONAL IN PSTR pszString, IN DNS_CHARSET CharSet, IN PSTR pszTrailer OPTIONAL );
VOID DnsPrint_Utf8StringBytes( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN PCHAR pUtf8, IN DWORD Length );
VOID DnsPrint_UnicodeStringBytes( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN PWCHAR pUnicode, IN DWORD Length );
VOID DnsPrint_StringArray( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN PSTR * StringArray, IN DWORD Count, OPTIONAL IN BOOL fUnicode );
VOID DnsPrint_Argv( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN CHAR ** Argv, IN DWORD Argc, OPTIONAL IN BOOL fUnicode );
VOID DnsPrint_DwordArray( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN PSTR pszName, IN DWORD dwCount, IN PDWORD adwArray );
VOID DnsPrint_IpAddressArray( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN PSTR pszName, IN DWORD dwIpAddrCount, IN PIP_ADDRESS pIpAddrs );
VOID DnsPrint_IpArray( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN PSTR pszName, IN PIP_ARRAY pIpArray );
VOID DnsPrint_Ip6Address( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN PIP6_ADDRESS pIp6Address, IN PSTR pszTrailer );
VOID DnsPrint_Guid( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN PGUID pGuid );
// // Winsock \ RnR types and structures //
VOID DnsPrint_FdSet( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN struct fd_set * pFdSet );
VOID DnsPrint_Sockaddr( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN DWORD Indent, IN PSOCKADDR pSockaddr, IN INT iSockaddrLength );
#ifdef _WS2TCPIP_H_ VOID DnsPrint_AddrInfo( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN DWORD Indent, IN PADDRINFO pAddrInfo );
VOID DnsPrint_AddrInfoList( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN DWORD Indent, IN PADDRINFO pAddrInfo ); #endif
#ifdef _WINSOCK2API_ VOID DnsPrint_SocketAddress( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN DWORD Indent, IN PSOCKET_ADDRESS pSocketAddress );
VOID DnsPrint_CsAddr( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN DWORD Indent, IN PCSADDR_INFO pCsAddrInfo );
VOID DnsPrint_AfProtocolsArray( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN PAFPROTOCOLS pProtocolArray, IN DWORD ProtocolCount );
VOID DnsPrint_WsaQuerySet( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN LPWSAQUERYSET pQuerySet, IN BOOL fUnicode );
VOID DnsPrint_WsaNsClassInfo( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN PWSANSCLASSINFO pInfo, IN BOOL fUnicode );
VOID DnsPrint_WsaServiceClassInfo( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN LPWSASERVICECLASSINFO pInfo, IN BOOL fUnicode ); #endif
VOID DnsPrint_Hostent( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN PHOSTENT pHostent, IN BOOL fUnicode );
// // Print routines for DNS types and structures //
VOID DnsPrint_Message( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN PDNS_MSG_BUF pMsg );
VOID DnsPrint_MessageNoContext( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN PDNS_HEADER pMsgHead, IN WORD wLength );
INT DnsPrint_PacketName( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, OPTIONAL IN PBYTE pMsgName, IN PDNS_HEADER pMsgHead, OPTIONAL IN PBYTE pMsgEnd, OPTIONAL IN PSTR pszTrailer OPTIONAL );
INT DnsPrint_PacketRecord( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN PDNS_WIRE_RECORD pMsgRR, IN PDNS_HEADER pMsgHead, OPTIONAL IN PBYTE pMsgEnd OPTIONAL );
VOID DnsPrint_ParsedRecord( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN PDNS_PARSED_RR pParsedRR );
VOID DnsPrint_RawOctets( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN PSTR pszLineHeader, IN PCHAR pchData, IN DWORD dwLength );
VOID DnsPrint_ParsedMessage( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN PDNS_PARSED_MESSAGE pParsed );
VOID DnsPrint_HostentBlob( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN PHOSTENT_BLOB pBlob );
// // Print to string //
#define GUID_STRING_BUFFER_LENGTH (80)
DWORD DnsStringPrint_Guid( OUT PCHAR pBuffer, IN PGUID pGuid );
DWORD DnsStringPrint_RawOctets( OUT PCHAR pBuffer, IN PCHAR pchData, IN DWORD dwLength, IN PSTR pszLineHeader, IN DWORD dwLineLength );
// // Print related utilities //
INT Dns_WriteFormattedSystemTimeToBuffer( OUT PCHAR pBuffer, IN PSYSTEMTIME pSystemTime );
INT Dns_WritePacketNameToBuffer( OUT PCHAR pBuffer, OUT PCHAR * ppBufferOut, IN PBYTE pMsgName, IN PDNS_HEADER pMsgHead, OPTIONAL IN PBYTE pMsgEnd OPTIONAL );
PCHAR Dns_ResponseCodeString( IN INT ResponseCode );
PCHAR Dns_ResponseCodeExplanationString( IN INT ResponseCode );
PCHAR Dns_KeyFlagString( IN OUT PCHAR pszBuff, IN WORD flags );
PCHAR Dns_OpcodeString( IN INT Opcode );
CHAR Dns_OpcodeCharacter( IN INT Opcode );
PCHAR Dns_SectionNameString( IN INT iSection, IN INT iOpcode );
// // Record printing (rrprint.c) //
VOID DnsPrint_Record( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN PDNS_RECORD pRecord, IN PDNS_RECORD pPreviousRecord OPTIONAL );
VOID DnsPrint_RecordSet( IN PRINT_ROUTINE PrintRoutine, IN OUT PPRINT_CONTEXT pContext, IN PSTR pszHeader, IN PDNS_RECORD pRecord );
// // Macros to get correct string type (utf8\unicode) for printing. //
// Empty string for simple switching of UTF-8/Unicode print
extern DWORD DnsEmptyString;
#define pDnsEmptyString ( (PSTR) &DnsEmptyString ) #define pDnsEmptyWideString ( (PWSTR) &DnsEmptyString )
#define DNSSTRING_UTF8( fUnicode, String ) \ ( (fUnicode) ? pDnsEmptyString : (PSTR)(String) )
#define DNSSTRING_ANSI( fUnicode, String ) \ ( (fUnicode) ? pDnsEmptyString : (PSTR)(String) )
#define DNSSTRING_WIDE( fUnicode, String ) \ ( (fUnicode) ? (PWSTR)(String) : pDnsEmptyWideString )
#define RECSTRING_UTF8( pRR, String ) \ DNSSTRING_UTF8( IS_UNICODE_RECORD(pRR), (String) )
#define RECSTRING_WIDE( pRR, String ) \ DNSSTRING_WIDE( IS_UNICODE_RECORD(pRR), (String) )
#define PRINT_STRING_WIDE_CHARSET( String, CharSet ) \ ( ((CharSet)==DnsCharSetUnicode) ? (PWSTR)(String) : pDnsEmptyWideString )
#define PRINT_STRING_ANSI_CHARSET( String, CharSet ) \ ( ((CharSet)==DnsCharSetUnicode) ? pDnsEmptyString : (PSTR)(String) )
// // Debugging // // Debug routines. //
VOID Dns_StartDebugEx( IN DWORD DebugFlag, IN PSTR pszFlagFile, IN OUT PDWORD pdwExternalFlag, IN PSTR pszLogFile, IN DWORD WrapSize, IN BOOL fUseGlobalFile, IN BOOL fUseGlobalFlag, IN BOOL fSetGlobals );
VOID Dns_StartDebug( IN DWORD DebugFlag, IN PSTR pszFlagFile, IN OUT PDWORD pdwExternalFlag, IN PSTR pszLogFile, IN DWORD WrapSize );
VOID Dns_EndDebug( VOID );
VOID Dns_Assert( IN PSTR pszFile, IN INT LineNo, IN PSTR pszExpr );
VOID DnsDbg_PrintfToDebugger( IN PSTR Format, ... );
VOID DnsDbg_Printf( IN PSTR Format, ... );
VOID DnsDbg_PrintRoutine( IN OUT PPRINT_CONTEXT pContext, IN PSTR Format, ... );
VOID DnsDbg_Flush( VOID );
VOID DnsDbg_WrapLogFile( VOID );
VOID DnsDbg_CSEnter( IN PCRITICAL_SECTION pLock, IN PSTR pszLockName, IN PSTR pszFile, IN INT LineNo );
VOID DnsDbg_CSLeave( IN PCRITICAL_SECTION pLock, IN PSTR pszLockName, IN PSTR pszFile, IN INT LineNo );
// // Debug flag test // // We make the test against a pointer here which allows library // client application to point at a flag that may be dynamically // reset. //
extern PDWORD pDnsDebugFlag; #define IS_DNSDBG_ON(flag) (*pDnsDebugFlag & DNS_DBG_ ## flag)
// // Debugging Bit Flags // // These flags control gross output and are the same for all users //
#define DNS_DBG_BREAKPOINTS 0x00000001 #define DNS_DBG_DEBUGGER 0x00000002 #define DNS_DBG_FILE 0x00000004 #define DNS_DBG_EVENTLOG 0x00000008 #define DNS_DBG_EXCEPT 0x00000008
#define DNS_DBG_TIMESTAMP 0x10000000 #define DNS_DBG_CONSOLE 0x20000000 #define DNS_DBG_START_BREAK 0x40000000 #define DNS_DBG_FLUSH 0x80000000
#define DNS_DBG_ANY 0xffffffff #define DNS_DBG_ALL 0xffffffff #define DNS_DBG_OFF (0x0)
// // Flags specific to library //
#define DNS_DBG_IPARRAY 0x00000020 #define DNS_DBG_INIT 0x00000040 #define DNS_DBG_REGISTRY 0x00000040 #define DNS_DBG_SOCKET 0x00000040 #define DNS_DBG_WRITE 0x00000080 #define DNS_DBG_READ 0x00000080
#define DNS_DBG_RPC 0x00000100 #define DNS_DBG_STUB 0x00000100 #define DNS_DBG_RECV 0x00000200 #define DNS_DBG_SEND 0x00000400 #define DNS_DBG_TCP 0x00000800
#define DNS_DBG_TRACE 0x00001000 #define DNS_DBG_HOSTENT 0x00001000 #define DNS_DBG_UPDATE 0x00002000 #define DNS_DBG_SECURITY 0x00004000 #define DNS_DBG_QUERY 0x00008000
#define DNS_DBG_HEAP 0x00010000 #define DNS_DBG_HEAPDBG 0x00020000 #define DNS_DBG_NETINFO 0x00040000 #define DNS_DBG_RNR 0x00080000
// // High output detail debugging //
#define DNS_DBG_RECURSE2 0x00100000 #define DNS_DBG_UPDATE2 0x00200000 #define DNS_DBG_SECURITY2 0x00400000
#define DNS_DBG_RPC2 0x01000000 #define DNS_DBG_STUB2 0x01000000 #define DNS_DBG_INIT2 0x01000000 #define DNS_DBG_NETINFO2 0x01000000 #define DNS_DBG_PARSE2 0x01000000 #define DNS_DBG_LOOKUP2 0x02000000 #define DNS_DBG_WRITE2 0x04000000 #define DNS_DBG_READ2 0x04000000 #define DNS_DBG_LOCK 0x08000000 #define DNS_DBG_LOCKS 0x08000000 #define DNS_DBG_STRING 0x10000000
#define DNS_DBG_HEAP2 0x10000000 #define DNS_DBG_HEAP_CHECK 0x10000000
// // Debug macros // // Macros that include debug code in debug versions only, // these macro are NULL for retail versions. //
#if DBG
#define STATIC
#define DNS_PRINT(_a_) ( DnsDbg_Printf _a_ )
#define DnsPrintfPtrToFunc DnsDbg_PrintRoutine
#define IF_DNSDBG(flag) if ( IS_DNSDBG_ON(flag) ) #define ELSE_IF_DNSDBG(flag) else if ( IS_DNSDBG_ON(flag) ) #define ELSE else
#define DNSDBG(flag, _printlist_) \ IF_DNSDBG( flag ) \ { \ ( DnsDbg_Printf _printlist_ ); \ }
// protect debug prints with print lock
#define DnsDbg_Lock() DnsPrint_Lock() #define DnsDbg_Unlock() DnsPrint_Unlock()
// // Probe //
#define PROBE(p) (*p)
// // Assert Macros //
#define DNS_ASSERT( expr ) \ { \ if ( !(expr) ) \ { \ Dns_Assert( __FILE__, __LINE__, # expr ); \ } \ }
#define TEST_ASSERT( expr ) DNS_ASSERT( expr )
#define FAIL( msg ) \ { \ DNS_PRINT(( "FAILURE: %s\n", msg )); \ DNS_ASSERT( FALSE ); \ }
// // Asserts on trailing else //
#define ELSE_ASSERT( expr ) \ else \ { \ DNS_ASSERT( expr ); \ }
#define ELSE_ASSERT_FALSE \ else \ { \ DNS_ASSERT( FALSE );\ }
#define ELSE_FAIL( msg ) \ else \ { \ FAIL( msg ); \ }
// // Assert and print message //
#define DNS_MSG_ASSERT( pMsg, expr ) \ { \ if ( !(expr) ) \ { \ debug_MessageBuffer( "FAILED MESSAGE:", (pMsg) ); \ Dns_Assert( __FILE__, __LINE__, # expr ); \ } \ }
// // Debug types and structures //
#define DnsPR DnsDbg_PrintRoutine
#define DnsDbg_String(a,b,c,d) DnsPrint_String(DnsPR,NULL,a,b,c,d) #define DnsDbg_UnicodeStringBytes(a,b,c) DnsPrint_UnicodeStringBytes(DnsPR,NULL,a,b,c) #define DnsDbg_Utf8StringBytes(a,b,c) DnsPrint_Utf8StringBytes(DnsPR,NULL,a,b,c) #define DnsDbg_StringArray(a,b,c,d) DnsPrint_StringArray(DnsPR,NULL,a,b,c,d) #define DnsDbg_Argv(a,b,c,d) DnsPrint_Argv(DnsPR,NULL,a,b,c,d) #define DnsDbg_DwordArray(a,b,c,d) DnsPrint_DwordArray(DnsPR,NULL,a,b,c,d) #define DnsDbg_IpAddressArray(a,b,c,d) DnsPrint_IpAddressArray(DnsPR,NULL,a,b,c,d) #define DnsDbg_IpArray(a,b,c) DnsPrint_IpArray(DnsPR,NULL,a,b,c) #define DnsDbg_Ip6Address(a,b,c) DnsPrint_Ip6Address(DnsPR,NULL,a,b,c) #define DnsDbg_Guid(a,b) DnsPrint_Guid(DnsPR,NULL,a,b)
#define DnsDbg_FdSet(a,b) DnsPrint_FdSet(DnsPR,NULL,a,b) #define DnsDbg_Sockaddr(a,b,c) DnsPrint_Sockaddr(DnsPR,NULL,a,0,b,c) #define DnsDbg_SocketAddress(a,b) DnsPrint_SocketAddress(DnsPR,NULL,a,0,b) #define DnsDbg_CsAddr(a,b) DnsPrint_CsAddr(DnsPR,NULL,a,0,b) #define DnsDbg_AfProtocolsArray(a,b,c) DnsPrint_AfProtocolsArray(DnsPR,NULL,a,b,c) #define DnsDbg_WsaQuerySet(a,b,c) DnsPrint_WsaQuerySet(DnsPR,NULL,a,b,c) #define DnsDbg_WsaNsClassInfo(a,b,c) DnsPrint_WsaNsClassInfo(DnsPR,NULL,a,b,c) #define DnsDbg_WsaServiceClassInfo(a,b,c) DnsPrint_WsaServiceClassInfo(DnsPR,NULL,a,b,c) #define DnsDbg_Hostent(a,b,c) DnsPrint_Hostent(DnsPR,NULL,a,b,c) #define DnsDbg_AddrInfo(a,b) DnsPrint_AddrInfo(DnsPR,NULL,a,0,b) #define DnsDbg_HostentBlob(a,b) DnsPrint_HostentBlob(DnsPR,NULL,a,b)
#define DnsDbg_DnsMessage(a,b) DnsPrint_DnsMessage(DnsPR,NULL,a,b) #define DnsDbg_Message(a,b) DnsPrint_Message(DnsPR,NULL,a,b) #define DnsDbg_MessageNoContext(a,b,c) DnsPrint_MessageNoContext(DnsPR,NULL,a,b,c) #define DnsDbg_Compression(a,b) DnsPrint_Compression(DnsPR,NULL,a,b) #define DnsDbg_PacketRecord(a,b,c,d) DnsPrint_PacketRecord(DnsPR,NULL,a,b,c,d) #define DnsDbg_PacketName(a,b,c,d,e) DnsPrint_PacketName(DnsPR,NULL,a,b,c,d,e) #define DnsDbg_ParsedMessage(a,b) DnsPrint_ParsedMessage(DnsPR,NULL,(a),(b))
#define DnsDbg_RawOctets(a,b,c,d) DnsPrint_RawOctets(DnsPR,NULL,a,b,c,d) #define DnsDbg_Record(a,b) DnsPrint_Record(DnsPR,NULL,a,b,NULL) #define DnsDbg_RecordSet(a,b) DnsPrint_RecordSet(DnsPR,NULL,a,b)
// backcompat special on sockaddr
#define DnsDbg_SockaddrIn(a,b,c) DnsPrint_Sockaddr(DnsPR,NULL,a,0,(PSOCKADDR)b,c)
// // Non-Debug //
#else
#define STATIC static
// // Define away debugging operations //
#define IF_DNSDBG(a) if (0) #define ELSE_IF_DNSDBG(a) if (0) #define ELSE if (0) #define DNSDBG(flag, _printlist_) #define DNS_PRINT(_printlist_)
#define DnsDbg_Lock() #define DnsDbg_Unlock()
#define DnsDbg_CSEnter(a,b,c,d) #define DnsDbg_CSLeave(a,b,c,d)
#define DnsDbg_String(a,b,c,d) #define DnsDbg_UnicodeStringBytes(a,b,c) #define DnsDbg_Utf8StringBytes(a,b,c) #define DnsDbg_DwordArray(a,b,c,d) #define DnsDbg_StringArray(a,b,c,d) #define DnsDbg_Argv(a,b,c,d) #define DnsDbg_IpAddressArray(a,b,c,d) #define DnsDbg_IpArray(a,b,c) #define DnsDbg_Ip6Address(a,b,c) #define DnsDbg_Guid(a,b)
#define DnsDbg_FdSet(a,b) #define DnsDbg_Sockaddr(a,b,c) #define DnsDbg_SocketAddress(a,b) #define DnsDbg_CsAddr(a,b) #define DnsDbg_AfProtocolsArray(a,b,c) #define DnsDbg_WsaQuerySet(a,b,c) #define DnsDbg_WsaNsClassInfo(a,b,c) #define DnsDbg_WsaServiceClassInfo(a,b,c) #define DnsDbg_Hostent(a,b,c) #define DnsDbg_AddrInfo(a,b) #define DnsDbg_HostentBlob(a,b)
#define DnsDbg_DnsMessage(a,b) #define DnsDbg_Message(a,b) #define DnsDbg_MessageNoContext(a,b,c) #define DnsDbg_Compression(a,b) #define DnsDbg_PacketRecord(a,b,c,d) #define DnsDbg_PacketName(a,b,c,d,e) #define DnsDbg_ParsedMessage(a,b)
#define DnsDbg_RawOctets(a,b,c,d) #define DnsDbg_Record(a,b) #define DnsDbg_RecordSet(a,b)
// backcompat special on sockaddr
#define DnsDbg_SockaddrIn(a,b,c)
// // Handle complilation of DnsPrintf used as passed parameter to // print routines //
#define DnsPrintfPtrToFunc printf
// // Eliminate ASSERTs in retail product //
#define DNS_ASSERT( expr ) #define TEST_ASSERT( expr ) #define ELSE_ASSERT( expr ) #define ELSE_ASSERT_FALSE #define DNS_MSG_ASSERT( expr, pMsg )
#define FAIL( msg ) #define ELSE_FAIL( msg )
#define PROBE(p)
#endif // non-DBG
#ifdef __cplusplus } #endif // __cplusplus
#endif // _DNSLIB_INCLUDED_
|