📄 jwawindns.pas
字号:
{******************************************************************************}
{ }
{ Domain Naming Services API interface Unit for Object Pascal }
{ }
{ Portions created by Microsoft are Copyright (C) 1995-2001 Microsoft }
{ Corporation. All Rights Reserved. }
{ }
{ The original file is: windns.h, released June 2000. The original Pascal }
{ code is: WinDNS.pas, released December 2000. The initial developer of the }
{ Pascal code is Marcel van Brakel (brakelm@chello.nl). }
{ }
{ Portions created by Marcel van Brakel are Copyright (C) 1999-2001 }
{ Marcel van Brakel. All Rights Reserved. }
{ }
{ Obtained through: Joint Endeavour of Delphi Innovators (Project JEDI) }
{ }
{ You may retrieve the latest version of this file at the Project JEDI home }
{ page, located at http://delphi-jedi.org or my personal homepage located at }
{ http://members.chello.nl/m.vanbrakel2 }
{ }
{ The contents of this file are used with permission, subject to the Mozilla }
{ Public License Version 1.1 (the "License"); you may not use this file except }
{ in compliance with the License. You may obtain a copy of the License at }
{ http://www.mozilla.org/MPL/MPL-1.1.html }
{ }
{ Software distributed under the License is distributed on an "AS IS" basis, }
{ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for }
{ the specific language governing rights and limitations under the License. }
{ }
{ Alternatively, the contents of this file may be used under the terms of the }
{ GNU Lesser General Public License (the "LGPL License"), in which case the }
{ provisions of the LGPL License are applicable instead of those above. }
{ If you wish to allow use of your version of this file only under the terms }
{ of the LGPL License and not to allow others to use your version of this file }
{ under the MPL, indicate your decision by deleting the provisions above and }
{ replace them with the notice and other provisions required by the LGPL }
{ License. If you do not delete the provisions above, a recipient may use }
{ your version of this file under either the MPL or the LGPL License. }
{ }
{ For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html }
{ }
{******************************************************************************}
{******************************************************************}
{ }
{ Notes (TODO): }
{ DnsRecordSetDetach() and DnsValidateName_X() didn't have a cc }
{ IP_ADDRESS_STRING_LENGTH is defined nowhere }
{ DNS_WINS_RECORD macro untranslatable due to IP_ADDRESS }
{ DNS_RRSET_ADD macro untranslatable }
{ }
{******************************************************************}
unit JwaWinDNS;
{$WEAKPACKAGEUNIT}
{$HPPEMIT ''}
{$HPPEMIT '#include "WinDNS.h"'}
{$HPPEMIT ''}
{$HPPEMIT 'typeded PDNS_RECORD *PPDNS_RECORD'}
{$HPPEMIT ''}
{$I WINDEFINES.INC}
interface
uses
JwaWinsock2, JwaWinType;
{.$DEFINE ATMA_E164}
type
IN6_ADDR = Pointer; // todo
//
// Define QWORD -- not yet defined globally
//
type
QWORD = Int64;
{$EXTERNALSYM QWORD}
//
// DNS public types
//
type
DNS_STATUS = Longint;
{$EXTERNALSYM DNS_STATUS}
PDNS_STATUS = ^DNS_STATUS;
{$EXTERNALSYM PDNS_STATUS}
TDnsStatus = DNS_STATUS;
PDnsStatus = PDNS_STATUS;
//
// IP Address
//
type
IP4_ADDRESS = DWORD;
{$EXTERNALSYM IP4_ADDRESS}
PIP4_ADDRESS = ^IP4_ADDRESS;
{$EXTERNALSYM PIP4_ADDRESS}
TIP4Address = IP4_ADDRESS;
PIP4Address = PIP4_ADDRESS;
const
SIZEOF_IP4_ADDRESS = 4;
{$EXTERNALSYM SIZEOF_IP4_ADDRESS}
IP4_ADDRESS_STRING_LENGTH = 15;
{$EXTERNALSYM IP4_ADDRESS_STRING_LENGTH}
IP4_ADDRESS_STRING_BUFFER_LENGTH = 16;
{$EXTERNALSYM IP4_ADDRESS_STRING_BUFFER_LENGTH}
//
// IP Address Array type
//
type
PIP4_ARRAY = ^IP4_ARRAY;
{$EXTERNALSYM PIP4_ARRAY}
_IP4_ARRAY = record
AddrCount: DWORD;
AddrArray: array [0..0] of IP4_ADDRESS;
end;
{$EXTERNALSYM _IP4_ARRAY}
IP4_ARRAY = _IP4_ARRAY;
{$EXTERNALSYM IP4_ARRAY}
TIp4Array = IP4_ARRAY;
PIp4Array = PIP4_ARRAY;
//
// IPv6 Address
//
PIP6_ADDRESS = ^IP6_ADDRESS;
{$EXTERNALSYM PIP6_ADDRESS}
IP6_ADDRESS = record
case Integer of
0: (IP6Qword: array [0..1] of QWORD);
1: (IP6Dword: array [0..3] of DWORD);
2: (IP6Word: array [0..7] of WORD);
3: (IP6Byte: array [0..15] of BYTE);
4: (In6: IN6_ADDR);
end;
{$EXTERNALSYM IP6_ADDRESS}
TIp6Address = IP6_ADDRESS;
PIp6Address = PIP6_ADDRESS;
// Backward compatibility
DNS_IP6_ADDRESS = IP6_ADDRESS;
{$EXTERNALSYM DNS_IP6_ADDRESS}
PDNS_IP6_ADDRESS = ^IP6_ADDRESS;
{$EXTERNALSYM PDNS_IP6_ADDRESS}
TDnsIp6Address = DNS_IP6_ADDRESS;
PDnsIp6Address = PDNS_IP6_ADDRESS;
//
// IP6 string max is 45 bytes
// - 6 WORDs in colon+hex (5 chars)
// - last DWORD as IP4 (15 chars)
//
const
IP6_ADDRESS_STRING_LENGTH = (47);
{$EXTERNALSYM IP6_ADDRESS_STRING_LENGTH}
IP6_ADDRESS_STRING_BUFFER_LENGTH = (48);
{$EXTERNALSYM IP6_ADDRESS_STRING_BUFFER_LENGTH}
// backcompat
IPV6_ADDRESS_STRING_LENGTH = IP6_ADDRESS_STRING_LENGTH;
{$EXTERNALSYM IPV6_ADDRESS_STRING_LENGTH}
//
// Inline byte flipping -- can be done in registers
//
procedure INLINE_WORD_FLIP(var Out: WORD; In_: WORD);
{$EXTERNALSYM INLINE_WORD_FLIP}
procedure INLINE_HTONS(var Out: WORD; In_: WORD);
{$EXTERNALSYM INLINE_HTONS}
procedure INLINE_NTOHS(var Out: WORD; In_: WORD);
{$EXTERNALSYM INLINE_NTOHS}
procedure INLINE_DWORD_FLIP(var Out: DWORD; In_: DWORD);
{$EXTERNALSYM INLINE_DWORD_FLIP}
procedure INLINE_NTOHL(var Out: DWORD; In_: DWORD);
{$EXTERNALSYM INLINE_NTOHL}
procedure INLINE_HTONL(var Out: DWORD; In_: DWORD);
{$EXTERNALSYM INLINE_HTONL}
//
// Inline byte flip and write to packet (unaligned)
//
procedure INLINE_WRITE_FLIPPED_WORD(pout: PWORD; In_: WORD);
{$EXTERNALSYM INLINE_WRITE_FLIPPED_WORD}
procedure INLINE_WRITE_FLIPPED_DWORD(pout: PDWORD; In_: DWORD);
{$EXTERNALSYM INLINE_WRITE_FLIPPED_DWORD}
//
// Basic DNS definitions
//
//
// DNS port for both UDP and TCP is 53.
//
const
DNS_PORT_HOST_ORDER = ($0035); // port 53
{$EXTERNALSYM DNS_PORT_HOST_ORDER}
DNS_PORT_NET_ORDER = ($3500);
{$EXTERNALSYM DNS_PORT_NET_ORDER}
//
// DNS UDP packets no more than 512 bytes
//
DNS_RFC_MAX_UDP_PACKET_LENGTH = (512);
{$EXTERNALSYM DNS_RFC_MAX_UDP_PACKET_LENGTH}
//
// DNS Names limited to 255, 63 in any one label
//
DNS_MAX_NAME_LENGTH = (255);
{$EXTERNALSYM DNS_MAX_NAME_LENGTH}
DNS_MAX_LABEL_LENGTH = (63);
{$EXTERNALSYM DNS_MAX_LABEL_LENGTH}
DNS_MAX_NAME_BUFFER_LENGTH = (256);
{$EXTERNALSYM DNS_MAX_NAME_BUFFER_LENGTH}
DNS_MAX_LABEL_BUFFER_LENGTH = (64);
{$EXTERNALSYM DNS_MAX_LABEL_BUFFER_LENGTH}
//
// Reverse lookup domain names
//
DNS_IP4_REVERSE_DOMAIN_STRING = ('in-addr.arpa.');
{$EXTERNALSYM DNS_IP4_REVERSE_DOMAIN_STRING}
//DNS_MAX_IP4_REVERSE_NAME_LENGTH = (IP_ADDRESS_STRING_LENGTH + 1 + SizeOf(DNS_IP4_REVERSE_DOMAIN_STRING));
//{$EXTERNALSYM DNS_MAX_IP4_REVERSE_NAME_LENGTH}
//DNS_MAX_IP4_REVERSE_NAME_BUFFER_LENGTH = (DNS_MAX_IP4_REVERSE_NAME_LENGTH + 1);
//{$EXTERNALSYM DNS_MAX_IP4_REVERSE_NAME_BUFFER_LENGTH}
DNS_IP6_REVERSE_DOMAIN_STRING = ('ip6.int.');
{$EXTERNALSYM DNS_IP6_REVERSE_DOMAIN_STRING}
DNS_MAX_IP6_REVERSE_NAME_LENGTH = (64 + SizeOf(DNS_IP6_REVERSE_DOMAIN_STRING));
{$EXTERNALSYM DNS_MAX_IP6_REVERSE_NAME_LENGTH}
DNS_MAX_IP6_REVERSE_NAME_BUFFER_LENGTH = (DNS_MAX_IP6_REVERSE_NAME_LENGTH + 1);
{$EXTERNALSYM DNS_MAX_IP6_REVERSE_NAME_BUFFER_LENGTH}
// Combined
DNS_MAX_REVERSE_NAME_LENGTH = DNS_MAX_IP6_REVERSE_NAME_LENGTH;
{$EXTERNALSYM DNS_MAX_REVERSE_NAME_LENGTH}
DNS_MAX_REVERSE_NAME_BUFFER_LENGTH = DNS_MAX_IP6_REVERSE_NAME_BUFFER_LENGTH;
{$EXTERNALSYM DNS_MAX_REVERSE_NAME_BUFFER_LENGTH}
//
// DNS Text string limited by size representable
// in a single byte length field
DNS_MAX_TEXT_STRING_LENGTH = (255);
{$EXTERNALSYM DNS_MAX_TEXT_STRING_LENGTH}
//
// DNS On-The-Wire Structures
//
//
// DNS Message Header
//
type
_DNS_HEADER = packed record
Xid: WORD;
Flags: Byte;
//BYTE RecursionDesired : 1;
//BYTE Truncation : 1;
//BYTE Authoritative : 1;
//BYTE Opcode : 4;
//BYTE IsResponse : 1;
Flags2: Byte;
//BYTE ResponseCode : 4;
//BYTE Reserved : 3;
//BYTE RecursionAvailable : 1;
QuestionCount: WORD;
AnswerCount: WORD;
NameServerCount: WORD;
AdditionalCount: WORD;
end;
{$EXTERNALSYM _DNS_HEADER}
DNS_HEADER = _DNS_HEADER;
{$EXTERNALSYM DNS_HEADER}
PDNS_HEADER = ^DNS_HEADER;
{$EXTERNALSYM PDNS_HEADER}
TDnsHeader = DNS_HEADER;
PDnsHeader = PDNS_HEADER;
//
// Flags as WORD
//
function DNS_HEADER_FLAGS(pHead: PDNS_HEADER): WORD;
{$EXTERNALSYM DNS_HEADER_FLAGS}
//
// Byte flip DNS header to\from host order.
//
// Note that this does NOT flip flags, as definition above defines
// flags as individual bytes for direct access to net byte order.
//
procedure DNS_BYTE_FLIP_HEADER_COUNTS(var pHeader: PDNS_HEADER);
{$EXTERNALSYM DNS_BYTE_FLIP_HEADER_COUNTS}
//
// Question name follows header
//
const
DNS_OFFSET_TO_QUESTION_NAME = SizeOf(DNS_HEADER);
{$EXTERNALSYM DNS_OFFSET_TO_QUESTION_NAME}
//
// Question immediately follows header so compressed question name
// 0xC000 | sizeof(DNS_HEADER)
DNS_COMPRESSED_QUESTION_NAME = ($C00C);
{$EXTERNALSYM DNS_COMPRESSED_QUESTION_NAME}
//
// Packet extraction macros
//
{
#define DNS_QUESTION_NAME_FROM_HEADER( _pHeader_ ) \
( (PCHAR)( (PDNS_HEADER)(_pHeader_) + 1 ) )
#define DNS_ANSWER_FROM_QUESTION( _pQuestion_ ) \
( (PCHAR)( (PDNS_QUESTION)(_pQuestion_) + 1 ) )
}
//
// DNS Question
//
type
PDNS_WIRE_QUESTION = ^DNS_WIRE_QUESTION;
{$EXTERNALSYM PDNS_WIRE_QUESTION}
_DNS_WIRE_QUESTION = packed record
// Preceded by question name
QuestionType: WORD;
QuestionClass: WORD;
end;
{$EXTERNALSYM _DNS_WIRE_QUESTION}
DNS_WIRE_QUESTION = _DNS_WIRE_QUESTION;
{$EXTERNALSYM DNS_WIRE_QUESTION}
TDnsWireQuestion = DNS_WIRE_QUESTION;
PDnsWireQuestion = PDNS_WIRE_QUESTION;
//
// DNS Resource Record
//
PDNS_WIRE_RECORD = ^DNS_WIRE_RECORD;
{$EXTERNALSYM PDNS_WIRE_RECORD}
_DNS_WIRE_RECORD = packed record
// Preceded by record owner name
RecordType: WORD;
RecordClass: WORD;
TimeToLive: DWORD;
DataLength: WORD;
// Followed by record data
end;
{$EXTERNALSYM _DNS_WIRE_RECORD}
DNS_WIRE_RECORD = _DNS_WIRE_RECORD;
{$EXTERNALSYM DNS_WIRE_RECORD}
TDnsWireRecord = DNS_WIRE_RECORD;
PDnsWireRecord = PDNS_WIRE_RECORD;
//
// DNS Query Types
//
const
DNS_OPCODE_QUERY = 0; // Query
{$EXTERNALSYM DNS_OPCODE_QUERY}
DNS_OPCODE_IQUERY = 1; // Obsolete: IP to name
{$EXTERNALSYM DNS_OPCODE_IQUERY}
DNS_OPCODE_SERVER_STATUS = 2; // Obsolete: DNS ping
{$EXTERNALSYM DNS_OPCODE_SERVER_STATUS}
DNS_OPCODE_UNKNOWN = 3; // Unknown
{$EXTERNALSYM DNS_OPCODE_UNKNOWN}
DNS_OPCODE_NOTIFY = 4; // Notify
{$EXTERNALSYM DNS_OPCODE_NOTIFY}
DNS_OPCODE_UPDATE = 5; // Dynamic Update
{$EXTERNALSYM DNS_OPCODE_UPDATE}
//
// DNS response codes.
//
// Sent in the "ResponseCode" field of a DNS_HEADER.
//
DNS_RCODE_NOERROR = 0;
{$EXTERNALSYM DNS_RCODE_NOERROR}
DNS_RCODE_FORMERR = 1; // Format error
{$EXTERNALSYM DNS_RCODE_FORMERR}
DNS_RCODE_SERVFAIL = 2; // Server failure
{$EXTERNALSYM DNS_RCODE_SERVFAIL}
DNS_RCODE_NXDOMAIN = 3; // Name error
{$EXTERNALSYM DNS_RCODE_NXDOMAIN}
DNS_RCODE_NOTIMPL = 4; // Not implemented
{$EXTERNALSYM DNS_RCODE_NOTIMPL}
DNS_RCODE_REFUSED = 5; // Refused
{$EXTERNALSYM DNS_RCODE_REFUSED}
DNS_RCODE_YXDOMAIN = 6; // Domain name should not exist
{$EXTERNALSYM DNS_RCODE_YXDOMAIN}
DNS_RCODE_YXRRSET = 7; // RR set should not exist
{$EXTERNALSYM DNS_RCODE_YXRRSET}
DNS_RCODE_NXRRSET = 8; // RR set does not exist
{$EXTERNALSYM DNS_RCODE_NXRRSET}
DNS_RCODE_NOTAUTH = 9; // Not authoritative for zone
{$EXTERNALSYM DNS_RCODE_NOTAUTH}
DNS_RCODE_NOTZONE = 10; // Name is not zone
{$EXTERNALSYM DNS_RCODE_NOTZONE}
DNS_RCODE_MAX = 15;
{$EXTERNALSYM DNS_RCODE_MAX}
//
// Extended RCODEs
//
DNS_RCODE_BADVERS = 16; // Bad EDNS version
{$EXTERNALSYM DNS_RCODE_BADVERS}
DNS_RCODE_BADSIG = 16; // Bad signature
{$EXTERNALSYM DNS_RCODE_BADSIG}
DNS_RCODE_BADKEY = 17; // Bad key
{$EXTERNALSYM DNS_RCODE_BADKEY}
DNS_RCODE_BADTIME = 18; // Bad timestamp
{$EXTERNALSYM DNS_RCODE_BADTIME}
//
// Mappings to friendly names
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -