From d193c164b78a77570960a6fea589a3ccb3f080b6 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 2 Nov 2021 12:50:46 +0100 Subject: [PATCH] dnsapi: Build the DNS reply records on the PE side. Signed-off-by: Alexandre Julliard --- dlls/dnsapi/dnsapi.h | 2 +- dlls/dnsapi/libresolv.c | 555 +--------------------------------------- dlls/dnsapi/query.c | 26 +- include/windns.h | 48 +++- 4 files changed, 76 insertions(+), 555 deletions(-) diff --git a/dlls/dnsapi/dnsapi.h b/dlls/dnsapi/dnsapi.h index a356d24b1f0..2558390674a 100644 --- a/dlls/dnsapi/dnsapi.h +++ b/dlls/dnsapi/dnsapi.h @@ -125,7 +125,7 @@ struct resolv_funcs { DNS_STATUS (CDECL *get_searchlist)( DNS_TXT_DATAW *list, DWORD *len ); DNS_STATUS (CDECL *get_serverlist)( USHORT family, DNS_ADDR_ARRAY *addrs, DWORD *len ); - DNS_STATUS (CDECL *query)( const char *name, WORD type, DWORD options, DNS_RECORDA **result ); + DNS_STATUS (CDECL *query)( const char *name, WORD type, DWORD options, void *buf, DWORD *len ); DNS_STATUS (CDECL *set_serverlist)( const IP4_ARRAY *addrs ); }; diff --git a/dlls/dnsapi/libresolv.c b/dlls/dnsapi/libresolv.c index e72e86ad1b1..85b4c0d1aa8 100644 --- a/dlls/dnsapi/libresolv.c +++ b/dlls/dnsapi/libresolv.c @@ -109,90 +109,6 @@ static DWORD dnsapi_umbstowcs( const char *src, WCHAR *dst, DWORD dstlen ) } } -const char *debugstr_type( unsigned short type ) -{ - const char *str; - - switch (type) - { -#define X(x) case (x): str = #x; break; - X(DNS_TYPE_ZERO) - X(DNS_TYPE_A) - X(DNS_TYPE_NS) - X(DNS_TYPE_MD) - X(DNS_TYPE_MF) - X(DNS_TYPE_CNAME) - X(DNS_TYPE_SOA) - X(DNS_TYPE_MB) - X(DNS_TYPE_MG) - X(DNS_TYPE_MR) - X(DNS_TYPE_NULL) - X(DNS_TYPE_WKS) - X(DNS_TYPE_PTR) - X(DNS_TYPE_HINFO) - X(DNS_TYPE_MINFO) - X(DNS_TYPE_MX) - X(DNS_TYPE_TEXT) - X(DNS_TYPE_RP) - X(DNS_TYPE_AFSDB) - X(DNS_TYPE_X25) - X(DNS_TYPE_ISDN) - X(DNS_TYPE_RT) - X(DNS_TYPE_NSAP) - X(DNS_TYPE_NSAPPTR) - X(DNS_TYPE_SIG) - X(DNS_TYPE_KEY) - X(DNS_TYPE_PX) - X(DNS_TYPE_GPOS) - X(DNS_TYPE_AAAA) - X(DNS_TYPE_LOC) - X(DNS_TYPE_NXT) - X(DNS_TYPE_EID) - X(DNS_TYPE_NIMLOC) - X(DNS_TYPE_SRV) - X(DNS_TYPE_ATMA) - X(DNS_TYPE_NAPTR) - X(DNS_TYPE_KX) - X(DNS_TYPE_CERT) - X(DNS_TYPE_A6) - X(DNS_TYPE_DNAME) - X(DNS_TYPE_SINK) - X(DNS_TYPE_OPT) - X(DNS_TYPE_UINFO) - X(DNS_TYPE_UID) - X(DNS_TYPE_GID) - X(DNS_TYPE_UNSPEC) - X(DNS_TYPE_ADDRS) - X(DNS_TYPE_TKEY) - X(DNS_TYPE_TSIG) - X(DNS_TYPE_IXFR) - X(DNS_TYPE_AXFR) - X(DNS_TYPE_MAILB) - X(DNS_TYPE_MAILA) - X(DNS_TYPE_ANY) - X(DNS_TYPE_WINS) - X(DNS_TYPE_WINSR) -#undef X - default: - return wine_dbg_sprintf( "0x%04x", type ); - } - - return wine_dbg_sprintf( "%s", str ); -} - -static const char *debugstr_section( ns_sect section ) -{ - switch (section) - { - case ns_s_qd: return "Question"; - case ns_s_an: return "Answer"; - case ns_s_ns: return "Authority"; - case ns_s_ar: return "Additional"; - default: - return wine_dbg_sprintf( "0x%02x", section ); - } -} - /* call res_init() just once because of a bug in Mac OS X 10.4 */ /* call once per thread on systems that have per-thread _res */ static void init_resolver( void ) @@ -239,27 +155,6 @@ static unsigned long map_options( DWORD options ) return ret; } -static DNS_STATUS map_error( int error ) -{ - switch (error) - { - case ns_r_noerror: return ERROR_SUCCESS; - case ns_r_formerr: return DNS_ERROR_RCODE_FORMAT_ERROR; - case ns_r_servfail: return DNS_ERROR_RCODE_SERVER_FAILURE; - case ns_r_nxdomain: return DNS_ERROR_RCODE_NAME_ERROR; - case ns_r_notimpl: return DNS_ERROR_RCODE_NOT_IMPLEMENTED; - case ns_r_refused: return DNS_ERROR_RCODE_REFUSED; - case ns_r_yxdomain: return DNS_ERROR_RCODE_YXDOMAIN; - case ns_r_yxrrset: return DNS_ERROR_RCODE_YXRRSET; - case ns_r_nxrrset: return DNS_ERROR_RCODE_NXRRSET; - case ns_r_notauth: return DNS_ERROR_RCODE_NOTAUTH; - case ns_r_notzone: return DNS_ERROR_RCODE_NOTZONE; - default: - FIXME( "unmapped error code: %d\n", error ); - return DNS_ERROR_RCODE_NOT_IMPLEMENTED; - } -} - static DNS_STATUS map_h_errno( int error ) { switch (error) @@ -472,462 +367,18 @@ static DNS_STATUS CDECL resolv_set_serverlist( const IP4_ARRAY *addrs ) return ERROR_SUCCESS; } -static char *dname_from_msg( ns_msg msg, const unsigned char *pos ) -{ - char *str, dname[NS_MAXDNAME] = "."; - - /* returns *compressed* length, ignore it */ - ns_name_uncompress( ns_msg_base(msg), ns_msg_end(msg), pos, dname, sizeof(dname) ); - - if ((str = RtlAllocateHeap( GetProcessHeap(), 0, strlen(dname) + 1 ))) strcpy( str, dname ); - return str; -} - -static char *str_from_rdata( const unsigned char *rdata ) -{ - char *str; - unsigned int len = rdata[0]; - - if ((str = RtlAllocateHeap( GetProcessHeap(), 0, len + 1 ))) - { - memcpy( str, ++rdata, len ); - str[len] = 0; - } - return str; -} - -static unsigned int get_record_size( const ns_rr *rr ) -{ - const unsigned char *pos = rr->rdata; - unsigned int num = 0, size = sizeof(DNS_RECORDA); - - switch (rr->type) - { - case ns_t_key: - { - pos += sizeof(WORD) + sizeof(BYTE) + sizeof(BYTE); - size += rr->rdata + rr->rdlength - pos - 1; - break; - } - case ns_t_sig: - { - pos += sizeof(PCHAR) + sizeof(WORD) + 2 * sizeof(BYTE); - pos += 3 * sizeof(DWORD) + 2 * sizeof(WORD); - size += rr->rdata + rr->rdlength - pos - 1; - break; - } - case ns_t_hinfo: - case ns_t_isdn: - case ns_t_txt: - case ns_t_x25: - { - while (pos[0] && pos < rr->rdata + rr->rdlength) - { - num++; - pos += pos[0] + 1; - } - size += (num - 1) * sizeof(PCHAR); - break; - } - case ns_t_null: - case ns_t_opt: - { - size += rr->rdlength - 1; - break; - } - case ns_t_nxt: - case ns_t_wks: - case 0xff01: /* WINS */ - { - FIXME( "unhandled type: %s\n", debugstr_type( rr->type ) ); - break; - } - default: - break; - } - return size; -} - -static DNS_STATUS copy_rdata( ns_msg msg, const ns_rr *rr, DNS_RECORDA *r, WORD *dlen ) +static DNS_STATUS CDECL resolv_query( const char *name, WORD type, DWORD options, void *answer, DWORD *retlen ) { DNS_STATUS ret = ERROR_SUCCESS; - const unsigned char *pos = rr->rdata; - unsigned int i, size; - - switch (rr->type) - { - case ns_t_a: - { - r->Data.A.IpAddress = *(const DWORD *)pos; - *dlen = sizeof(DNS_A_DATA); - break; - } - case ns_t_aaaa: - { - for (i = 0; i < sizeof(IP6_ADDRESS)/sizeof(DWORD); i++) - { - r->Data.AAAA.Ip6Address.IP6Dword[i] = *(const DWORD *)pos; - pos += sizeof(DWORD); - } - - *dlen = sizeof(DNS_AAAA_DATA); - break; - } - case ns_t_key: - { - /* FIXME: byte order? */ - r->Data.KEY.wFlags = *(const WORD *)pos; pos += sizeof(WORD); - r->Data.KEY.chProtocol = *pos++; - r->Data.KEY.chAlgorithm = *pos++; - - size = rr->rdata + rr->rdlength - pos; - r->Data.KEY.wKeyLength = size; - - for (i = 0; i < size; i++) - r->Data.KEY.Key[i] = *pos++; - - *dlen = sizeof(DNS_KEY_DATA) + (size - 1) * sizeof(BYTE); - break; - } - case ns_t_rp: - case ns_t_minfo: - { - r->Data.MINFO.pNameMailbox = dname_from_msg( msg, pos ); - if (!r->Data.MINFO.pNameMailbox) return ERROR_NOT_ENOUGH_MEMORY; - - if (ns_name_skip( &pos, ns_msg_end( msg ) ) < 0) - return DNS_ERROR_BAD_PACKET; - - r->Data.MINFO.pNameErrorsMailbox = dname_from_msg( msg, pos ); - if (!r->Data.MINFO.pNameErrorsMailbox) - { - RtlFreeHeap( GetProcessHeap(), 0, r->Data.MINFO.pNameMailbox ); - return ERROR_NOT_ENOUGH_MEMORY; - } - - *dlen = sizeof(DNS_MINFO_DATAA); - break; - } - case ns_t_afsdb: - case ns_t_rt: - case ns_t_mx: - { - r->Data.MX.wPreference = ntohs( *(const WORD *)pos ); - r->Data.MX.pNameExchange = dname_from_msg( msg, pos + sizeof(WORD) ); - if (!r->Data.MX.pNameExchange) return ERROR_NOT_ENOUGH_MEMORY; - - *dlen = sizeof(DNS_MX_DATAA); - break; - } - case ns_t_null: - { - r->Data.Null.dwByteCount = rr->rdlength; - memcpy( r->Data.Null.Data, rr->rdata, rr->rdlength ); - - *dlen = sizeof(DNS_NULL_DATA) + rr->rdlength - 1; - break; - } - case ns_t_opt: - { - r->Data.OPT.wDataLength = rr->rdlength; - r->Data.OPT.wPad = 0; - memcpy( r->Data.OPT.Data, rr->rdata, rr->rdlength ); - - *dlen = sizeof(DNS_OPT_DATA) + rr->rdlength - 1; - break; - } - case ns_t_cname: - case ns_t_ns: - case ns_t_mb: - case ns_t_md: - case ns_t_mf: - case ns_t_mg: - case ns_t_mr: - case ns_t_ptr: - { - r->Data.PTR.pNameHost = dname_from_msg( msg, pos ); - if (!r->Data.PTR.pNameHost) return ERROR_NOT_ENOUGH_MEMORY; - - *dlen = sizeof(DNS_PTR_DATAA); - break; - } - case ns_t_sig: - { - r->Data.SIG.pNameSigner = dname_from_msg( msg, pos ); - if (!r->Data.SIG.pNameSigner) return ERROR_NOT_ENOUGH_MEMORY; - - if (ns_name_skip( &pos, ns_msg_end( msg ) ) < 0) - return DNS_ERROR_BAD_PACKET; - - /* FIXME: byte order? */ - r->Data.SIG.wTypeCovered = *(const WORD *)pos; pos += sizeof(WORD); - r->Data.SIG.chAlgorithm = *pos++; - r->Data.SIG.chLabelCount = *pos++; - r->Data.SIG.dwOriginalTtl = *(const DWORD *)pos; pos += sizeof(DWORD); - r->Data.SIG.dwExpiration = *(const DWORD *)pos; pos += sizeof(DWORD); - r->Data.SIG.dwTimeSigned = *(const DWORD *)pos; pos += sizeof(DWORD); - r->Data.SIG.wKeyTag = *(const WORD *)pos; - - size = rr->rdata + rr->rdlength - pos; - r->Data.SIG.wSignatureLength = size; - - for (i = 0; i < size; i++) - r->Data.SIG.Signature[i] = *pos++; - - *dlen = sizeof(DNS_SIG_DATAA) + (size - 1) * sizeof(BYTE); - break; - } - case ns_t_soa: - { - r->Data.SOA.pNamePrimaryServer = dname_from_msg( msg, pos ); - if (!r->Data.SOA.pNamePrimaryServer) return ERROR_NOT_ENOUGH_MEMORY; - - if (ns_name_skip( &pos, ns_msg_end( msg ) ) < 0) - return DNS_ERROR_BAD_PACKET; - - r->Data.SOA.pNameAdministrator = dname_from_msg( msg, pos ); - if (!r->Data.SOA.pNameAdministrator) - { - RtlFreeHeap( GetProcessHeap(), 0, r->Data.SOA.pNamePrimaryServer ); - return ERROR_NOT_ENOUGH_MEMORY; - } - - if (ns_name_skip( &pos, ns_msg_end( msg ) ) < 0) - return DNS_ERROR_BAD_PACKET; - - r->Data.SOA.dwSerialNo = ntohl( *(const DWORD *)pos ); pos += sizeof(DWORD); - r->Data.SOA.dwRefresh = ntohl( *(const DWORD *)pos ); pos += sizeof(DWORD); - r->Data.SOA.dwRetry = ntohl( *(const DWORD *)pos ); pos += sizeof(DWORD); - r->Data.SOA.dwExpire = ntohl( *(const DWORD *)pos ); pos += sizeof(DWORD); - r->Data.SOA.dwDefaultTtl = ntohl( *(const DWORD *)pos ); pos += sizeof(DWORD); - - *dlen = sizeof(DNS_SOA_DATAA); - break; - } - case ns_t_srv: - { - r->Data.SRV.wPriority = ntohs( *(const WORD *)pos ); pos += sizeof(WORD); - r->Data.SRV.wWeight = ntohs( *(const WORD *)pos ); pos += sizeof(WORD); - r->Data.SRV.wPort = ntohs( *(const WORD *)pos ); pos += sizeof(WORD); - - r->Data.SRV.pNameTarget = dname_from_msg( msg, pos ); - if (!r->Data.SRV.pNameTarget) return ERROR_NOT_ENOUGH_MEMORY; - - *dlen = sizeof(DNS_SRV_DATAA); - break; - } - case ns_t_hinfo: - case ns_t_isdn: - case ns_t_x25: - case ns_t_txt: - { - i = 0; - while (pos[0] && pos < rr->rdata + rr->rdlength) - { - r->Data.TXT.pStringArray[i] = str_from_rdata( pos ); - if (!r->Data.TXT.pStringArray[i]) - { - while (i > 0) RtlFreeHeap( GetProcessHeap(), 0, r->Data.TXT.pStringArray[--i] ); - return ERROR_NOT_ENOUGH_MEMORY; - } - i++; - pos += pos[0] + 1; - } - r->Data.TXT.dwStringCount = i; - *dlen = sizeof(DNS_TXT_DATAA) + (i - 1) * sizeof(PCHAR); - break; - } - case ns_t_atma: - case ns_t_loc: - case ns_t_nxt: - case ns_t_tsig: - case ns_t_wks: - case 0x00f9: /* TKEY */ - case 0xff01: /* WINS */ - case 0xff02: /* WINSR */ - default: - FIXME( "unhandled type: %s\n", debugstr_type( rr->type ) ); - return DNS_ERROR_RCODE_NOT_IMPLEMENTED; - } - - return ret; -} - -static inline char *heap_strdup( const char *src ) -{ - char *dst; - if (!src) return NULL; - if ((dst = RtlAllocateHeap( GetProcessHeap(), 0, (strlen( src ) + 1) * sizeof(char) ))) strcpy( dst, src ); - return dst; -} - -static DNS_STATUS copy_record( ns_msg msg, ns_sect section, unsigned short num, DNS_RECORDA **recp ) -{ - DNS_STATUS ret; - DNS_RECORDA *record; - WORD dlen; - ns_rr rr; - - if (ns_parserr( &msg, section, num, &rr ) < 0) - return DNS_ERROR_BAD_PACKET; - - if (!(record = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, get_record_size( &rr ) ))) - return ERROR_NOT_ENOUGH_MEMORY; - - if (!(record->pName = heap_strdup( rr.name ))) - { - RtlFreeHeap( GetProcessHeap(), 0, record ); - return ERROR_NOT_ENOUGH_MEMORY; - } - - record->wType = rr.type; - record->Flags.S.Section = section; - record->Flags.S.CharSet = DnsCharSetUtf8; - record->dwTtl = rr.ttl; - - if ((ret = copy_rdata( msg, &rr, record, &dlen ))) - { - RtlFreeHeap( GetProcessHeap(), 0, record->pName ); - RtlFreeHeap( GetProcessHeap(), 0, record ); - return ret; - } - record->wDataLength = dlen; - *recp = record; - - TRACE( "found %s record in %s section\n", debugstr_type( rr.type ), debugstr_section( section ) ); - return ERROR_SUCCESS; -} - -static void free_record_list( DNS_RECORD *list ) -{ - DNS_RECORD *r, *next; - unsigned int i; - - for (r = list; (list = r); r = next) - { - RtlFreeHeap( GetProcessHeap(), 0, r->pName ); - - switch (r->wType) - { - case DNS_TYPE_HINFO: - case DNS_TYPE_ISDN: - case DNS_TYPE_TEXT: - case DNS_TYPE_X25: - { - for (i = 0; i < r->Data.TXT.dwStringCount; i++) - RtlFreeHeap( GetProcessHeap(), 0, r->Data.TXT.pStringArray[i] ); - break; - } - case DNS_TYPE_MINFO: - case DNS_TYPE_RP: - { - RtlFreeHeap( GetProcessHeap(), 0, r->Data.MINFO.pNameMailbox ); - RtlFreeHeap( GetProcessHeap(), 0, r->Data.MINFO.pNameErrorsMailbox ); - break; - } - case DNS_TYPE_AFSDB: - case DNS_TYPE_RT: - case DNS_TYPE_MX: - { - RtlFreeHeap( GetProcessHeap(), 0, r->Data.MX.pNameExchange ); - break; - } - case DNS_TYPE_NXT: - { - RtlFreeHeap( GetProcessHeap(), 0, r->Data.NXT.pNameNext ); - break; - } - case DNS_TYPE_CNAME: - case DNS_TYPE_MB: - case DNS_TYPE_MD: - case DNS_TYPE_MF: - case DNS_TYPE_MG: - case DNS_TYPE_MR: - case DNS_TYPE_NS: - case DNS_TYPE_PTR: - { - RtlFreeHeap( GetProcessHeap(), 0, r->Data.PTR.pNameHost ); - break; - } - case DNS_TYPE_SIG: - { - RtlFreeHeap( GetProcessHeap(), 0, r->Data.SIG.pNameSigner ); - break; - } - case DNS_TYPE_SOA: - { - RtlFreeHeap( GetProcessHeap(), 0, r->Data.SOA.pNamePrimaryServer ); - RtlFreeHeap( GetProcessHeap(), 0, r->Data.SOA.pNameAdministrator ); - break; - } - case DNS_TYPE_SRV: - { - RtlFreeHeap( GetProcessHeap(), 0, r->Data.SRV.pNameTarget ); - break; - } - default: break; - } - - next = r->pNext; - RtlFreeHeap( GetProcessHeap(), 0, r ); - } -} - -#define DNS_MAX_PACKET_SIZE 4096 -static DNS_STATUS CDECL resolv_query( const char *name, WORD type, DWORD options, DNS_RECORDA **result ) -{ - DNS_STATUS ret = DNS_ERROR_RCODE_NOT_IMPLEMENTED; - unsigned int i, num; - unsigned char answer[DNS_MAX_PACKET_SIZE]; - ns_sect sections[] = { ns_s_an, ns_s_ar }; - ns_msg msg; - DNS_RECORDA *record = NULL; - DNS_RRSET rrset; int len; - DNS_RRSET_INIT( rrset ); - init_resolver(); _res.options |= map_options( options ); - if ((len = res_query( name, ns_c_in, type, answer, sizeof(answer) )) < 0) - { + if ((len = res_query( name, ns_c_in, type, answer, *retlen )) < 0) ret = map_h_errno( h_errno ); - goto exit; - } - - if (ns_initparse( answer, len, &msg ) < 0) - { - ret = DNS_ERROR_BAD_PACKET; - goto exit; - } - -#define RCODE_MASK 0x0f - if ((msg._flags & RCODE_MASK) != ns_r_noerror) - { - ret = map_error( msg._flags & RCODE_MASK ); - goto exit; - } - - for (i = 0; i < ARRAY_SIZE(sections); i++) - { - for (num = 0; num < ns_msg_count( msg, sections[i] ); num++) - { - ret = copy_record( msg, sections[i], num, &record ); - if (ret != ERROR_SUCCESS) goto exit; - - DNS_RRSET_ADD( rrset, (DNS_RECORD *)record ); - } - } - -exit: - DNS_RRSET_TERMINATE( rrset ); - - if (ret != ERROR_SUCCESS) - free_record_list( rrset.pFirstRR ); else - *result = (DNS_RECORDA *)rrset.pFirstRR; - + *retlen = len; return ret; } diff --git a/dlls/dnsapi/query.c b/dlls/dnsapi/query.c index 3f2e82eb9c1..46405d344a8 100644 --- a/dlls/dnsapi/query.c +++ b/dlls/dnsapi/query.c @@ -168,6 +168,8 @@ DNS_STATUS WINAPI DnsQuery_UTF8( PCSTR name, WORD type, DWORD options, PVOID ser PDNS_RECORDA *result, PVOID *reserved ) { DNS_STATUS ret = DNS_ERROR_RCODE_NOT_IMPLEMENTED; + unsigned char answer[4096]; + DWORD len = sizeof(answer); TRACE( "(%s,%s,0x%08x,%p,%p,%p)\n", debugstr_a(name), debugstr_type( type ), options, servers, result, reserved ); @@ -177,7 +179,29 @@ DNS_STATUS WINAPI DnsQuery_UTF8( PCSTR name, WORD type, DWORD options, PVOID ser if ((ret = resolv_funcs->set_serverlist( servers ))) return ret; - ret = resolv_funcs->query( name, type, options, result ); + ret = resolv_funcs->query( name, type, options, answer, &len ); + if (!ret) + { + DNS_MESSAGE_BUFFER *buffer = (DNS_MESSAGE_BUFFER *)answer; + + if (len < sizeof(buffer->MessageHead)) return DNS_ERROR_BAD_PACKET; + DNS_BYTE_FLIP_HEADER_COUNTS( &buffer->MessageHead ); + switch (buffer->MessageHead.ResponseCode) + { + case DNS_RCODE_NOERROR: ret = DnsExtractRecordsFromMessage_UTF8( buffer, len, result ); break; + case DNS_RCODE_FORMERR: ret = DNS_ERROR_RCODE_FORMAT_ERROR; break; + case DNS_RCODE_SERVFAIL: ret = DNS_ERROR_RCODE_SERVER_FAILURE; break; + case DNS_RCODE_NXDOMAIN: ret = DNS_ERROR_RCODE_NAME_ERROR; break; + case DNS_RCODE_NOTIMPL: ret = DNS_ERROR_RCODE_NOT_IMPLEMENTED; break; + case DNS_RCODE_REFUSED: ret = DNS_ERROR_RCODE_REFUSED; break; + case DNS_RCODE_YXDOMAIN: ret = DNS_ERROR_RCODE_YXDOMAIN; break; + case DNS_RCODE_YXRRSET: ret = DNS_ERROR_RCODE_YXRRSET; break; + case DNS_RCODE_NXRRSET: ret = DNS_ERROR_RCODE_NXRRSET; break; + case DNS_RCODE_NOTAUTH: ret = DNS_ERROR_RCODE_NOTAUTH; break; + case DNS_RCODE_NOTZONE: ret = DNS_ERROR_RCODE_NOTZONE; break; + default: ret = DNS_ERROR_RCODE_NOT_IMPLEMENTED; break; + } + } if (ret == DNS_ERROR_RCODE_NAME_ERROR && type == DNS_TYPE_A && !(options & DNS_QUERY_NO_NETBT)) diff --git a/include/windns.h b/include/windns.h index 9796a299d04..b0b14df1b4f 100644 --- a/include/windns.h +++ b/include/windns.h @@ -108,6 +108,18 @@ extern "C" { #define DNS_QUERY_DNSSEC_CHECKING_DISABLED 0x02000000 #define DNS_QUERY_RESERVED 0xff000000 +#define INLINE_WORD_FLIP(out, in) { WORD _in = (in); (out) = (_in << 8) | (_in >> 8); } +#define INLINE_HTONS(out, in) INLINE_WORD_FLIP(out, in) +#define INLINE_NTOHS(out, in) INLINE_WORD_FLIP(out, in) + +#define DNS_BYTE_FLIP_HEADER_COUNTS(header) { \ + DNS_HEADER *_head = (header); \ + INLINE_HTONS( _head->Xid, _head->Xid ); \ + INLINE_HTONS( _head->QuestionCount, _head->QuestionCount ); \ + INLINE_HTONS( _head->AnswerCount, _head->AnswerCount ); \ + INLINE_HTONS( _head->NameServerCount, _head->NameServerCount ); \ + INLINE_HTONS( _head->AdditionalCount, _head->AdditionalCount ); } + typedef enum _DNS_NAME_FORMAT { DnsNameDomain, @@ -182,7 +194,11 @@ typedef struct #define DNS_ADDRESS_STRING_LENGTH IP6_ADDRESS_STRING_LENGTH #define IP4_ADDRESS_STRING_BUFFER_LENGTH IP4_ADDRESS_STRING_LENGTH #define IP6_ADDRESS_STRING_BUFFER_LENGTH IP6_ADDRESS_STRING_LENGTH -#define DNS_MAX_NAME_BUFFER_LENGTH 256 + +#define DNS_MAX_NAME_LENGTH 255 +#define DNS_MAX_LABEL_LENGTH 63 +#define DNS_MAX_NAME_BUFFER_LENGTH (DNS_MAX_NAME_LENGTH + 1) +#define DNS_MAX_LABEL_BUFFER_LENGTH (DNS_MAX_LABEL_LENGTH + 1) typedef struct _IP4_ARRAY { @@ -190,6 +206,36 @@ typedef struct _IP4_ARRAY IP4_ADDRESS AddrArray[1]; } IP4_ARRAY, *PIP4_ARRAY; +#define DNS_OPCODE_QUERY 0 +#define DNS_OPCODE_IQUERY 1 +#define DNS_OPCODE_SERVER_STATUS 2 +#define DNS_OPCODE_UNKNOWN 3 +#define DNS_OPCODE_NOTIFY 4 +#define DNS_OPCODE_UPDATE 5 + +#define DNS_RCODE_NOERROR 0 +#define DNS_RCODE_FORMERR 1 +#define DNS_RCODE_SERVFAIL 2 +#define DNS_RCODE_NXDOMAIN 3 +#define DNS_RCODE_NOTIMPL 4 +#define DNS_RCODE_REFUSED 5 +#define DNS_RCODE_YXDOMAIN 6 +#define DNS_RCODE_YXRRSET 7 +#define DNS_RCODE_NXRRSET 8 +#define DNS_RCODE_NOTAUTH 9 +#define DNS_RCODE_NOTZONE 10 +#define DNS_RCODE_MAX 15 +#define DNS_RCODE_BADVERS 16 +#define DNS_RCODE_BADSIG 16 +#define DNS_RCODE_BADKEY 17 +#define DNS_RCODE_BADTIME 18 + +#define DNS_RCODE_NO_ERROR DNS_RCODE_NOERROR +#define DNS_RCODE_FORMAT_ERROR DNS_RCODE_FORMERR +#define DNS_RCODE_SERVER_FAILURE DNS_RCODE_SERVFAIL +#define DNS_RCODE_NAME_ERROR DNS_RCODE_NXDOMAIN +#define DNS_RCODE_NOT_IMPLEMENTED DNS_RCODE_NOTIMPL + #include typedef struct _DNS_HEADER {