{***************************************************************************}
{* SysQuadrat *}
{* *}
{* ProgramId: Resolv *}
{* Date : 12.02.2002 *}
{* Time : 23:00 *}
{* (c) 2002 by M. Weinert *}
{***************************************************************************}
{* Sorry these functions begin all with sys2 ;-) This unit is licensed by *}
{* the GPL. *}
{* With these functions you can get variuos types of dns-records. If you *}
{* enhance this please send me the patches and I will apply them. Thanks. *}
{* *}
{* if you have any questions enhancements you can contact me at: *}
{* weinert klammeraffe sys2.de *}
{***************************************************************************}
unit resolv;
INTERFACE
{$LINKLIB resolv}
{$LINKLIB c}
uses inet,strings,sysutils;
Function Sys2_GetHostName(tz: ShortString):ShortString; // IP => HostName
Function Sys2_GetHostAddr(tz: ShortString):ShortString; // Hostname => IP
Function Sys2_GetAlias (tz: ShortString):ShortString; //
Function Sys2_GetMXAddr (tz: ShortString):ShortString; // Host => MX-IP (CSV)
function htons(x:Word):Word; cdecl; external;
function ntohs(x:Word):Word; cdecl; external;
IMPLEMENTATION
Const
t_invalid = 0; {* Cookie. *}
t_a = 1; {* Host address. *}
t_ns = 2; {* Authoritative server. *}
t_md = 3; {* Mail destination. *}
t_mf = 4; {* Mail forwarder. *}
t_cname = 5; {* Canonical name. *}
t_soa = 6; {* Start of authority zone. *}
t_mb = 7; {* Mailbox domain name. *}
t_mg = 8; {* Mail group member. *}
t_mr = 9; {* Mail rename name. *}
t_null = 10; {* Null resource record. *}
t_wks = 11; {* Well known service. *}
t_ptr = 12; {* Domain name pointer. *}
t_hinfo = 13; {* Host information. *}
t_minfo = 14; {* Mailbox information. *}
t_mx = 15; {* Mail routing information. *}
t_txt = 16; {* Text strings. *}
t_rp = 17; {* Responsible person. *}
t_afsdb = 18; {* AFS cell database. *}
t_x25 = 19; {* X_25 calling address. *}
t_isdn = 20; {* ISDN calling address. *}
t_rt = 21; {* Router. *}
t_nsap = 22; {* NSAP address. *}
t_nsap_ptr = 23; {* Reverse NSAP lookup (deprecated). *}
t_sig = 24; {* Security signature. *}
t_key = 25; {* Security key. *}
t_px = 26; {* X.400 mail mapping. *}
t_gpos = 27; {* Geographical position (withdrawn). *}
t_aaaa = 28; {* Ip6 Address. *}
t_loc = 29; {* Location Information. *}
t_nxt = 30; {* Next domain (security). *}
t_eid = 31; {* Endpoint identifier. *}
t_nimloc = 32; {* Nimrod Locator. *}
t_srv = 33; {* Server Selection. *}
t_atma = 34; {* ATM Address *}
t_naptr = 35; {* Naming Authority PoinTeR *}
t_kx = 36; {* Key Exchange *}
t_cert = 37; {* Certification record *}
t_a6 = 38; {* IPv6 address (deprecates AAAA) *}
t_dname = 39; {* Non-terminal DNAME (for IPv6) *}
t_sink = 40; {* Kitchen sink (experimentatl) *}
t_opt = 41; {* EDNS0 option (meta-RR) *}
t_tsig = 250; {* Transaction signature. *}
t_ixfr = 251; {* Incremental zone transfer. *}
t_axfr = 252; {* Transfer zone of authority. *}
t_mailb = 253; {* Transfer mailbox records. *}
t_maila = 254; {* Transfer mail agent records. *}
t_any = 255; {* Wildcard match. *}
t_zxfr = 256; {* BIND-specific, nonstandard. *}
t_max = 65536;
c_invalid = 0; {* Cookie. *}
c_in = 1; {* Internet. *}
c_2 = 2; {* unallocated/unsupported. *}
c_chaos = 3; {* MIT Chaos-net. *}
c_hs = 4; {* MIT Hesiod. *}
{* Query class values which do not appear in resource records *}
c_none = 254; {* for prereq. sections in update requests *}
c_any = 255; {* Wildcard match. *}
c_max = 65536;
// Additional Definitions.
MAXPACKET = 8192; { BIND maximum packet size }
MAXMXHOSTS = 5; { max number of MX records returned }
MXBUFFERSIZE = (128 * MAXMXHOSTS); { }
HFIXEDSZ = 12;
// Here we have the Header for an answer from res_query
type
HEADER = record // Header Answer
id : word; // Id of Answer 2
// I commented this out, maybe one day we will handle the bitfield
{* qr : Boolean; // ResponseFlag
opcode : Array[1..4] of Boolean; // Purpose of Message
aa : Boolean; // Authoritive Answer
tc : Boolean; // Truncated Message }
bf1 : byte; // Bitmapped
{* rd : Boolean; // recursion desired 3
ra : Boolean; // recursion avail
unused: Boolean; // Unused Bit
ad : Boolean; // authentic data from named
cd : Boolean; // checking disabled by resolver
rcode: Array[1..4] of Boolean; // Response Code 4 }
bf2 : Byte; // Bitmapped
// High byte first.
qdcount: Word; // number of question entries 6
ancount: Word; // answer entries
nscount: Word; // named entries
arcount: Word; // resource entries
end;
PHeader = ^HEADER;
query = record
hdr : HEADER;
qbuf : Array[1..MAXPACKET] of Char;
end;
pquery = ^query;
exp_an = record
r_type : Word;
r_class: Word;
r_ttllo: Word;
r_ttlhi: Word;
r_len : Word;
end;
pexp_an = ^exp_an;
function res_query (name : pchar ; Q_Class,Q_Type : integer;
Answer : pquery; AnswerLength: Integer):Integer; cdecl; external;
function dn_expand (msg, eomorig,comp_dn,exp_dn : PChar; leng : Integer):Integer; cdecl; external;
Function Sys2_GetHostAddr(tz: ShortString):ShortString;
Var
Host : Thost;
begin
Host.NameLookup(tz);
Sys2_GetHostAddr:=HostAddrToStr(Host.IPAddress);
end;
Function Sys2_GetHostName(tz: ShortString):ShortString; // IP => HostName
Var
Host : Thost;
begin
Host.AddressLookup(StrToHostAddr(tz));
Sys2_GetHostname:=Host.Name;
end;
// Not started yet. Not important for me ;-)
Function Sys2_GetAlias (tz: ShortString):ShortString; //
begin
Sys2_GetAlias:='';
end;
// This function returns (hopefully) ALL mx-Servers like this:
// server.sys2.de,10,mail.sys2.de,20
// csv
// Sorry badly documentated
function Sys2_GetMXAddr (tz:ShortString):ShortString;
var
dname : Pchar;
msg_text : Pchar;
pbuf : Pchar;
pmx_rec : Pchar;
p1 : Pchar;
answer : query;
answerhead : PHeader;
answer_len : Integer;
acount,qcount : LongInt;
rs,i : Integer;
buf : Array[1..MAXPACKET] of Char;
r : exp_an;
pr : pexp_an;
mx_prio : Word;
t_zeile : ShortString;
begin
t_Zeile:='';
pBuf:=@buf;
pr:=@r;
dname:=StrAlloc(Length(tz)+1);
Dname:=StrPCopy(Dname,tz); // Search DNAME
answer_len:=MAXPACKET;
rs:=res_query(Dname, C_IN, T_MX, @answer, answer_len);
if rs<0 then begin
Sys2_GetMXAddr:='';
exit;
end
else begin
answerhead:=@answer; // Header of Answer
msg_text:=@answer+SizeOf(Header); // Resulttext P=query
acount:=ntohs(answerhead^.ancount); // No of Answers
qcount:=ntohs(answerhead^.qdcount); // No of Queries
pmx_rec:=@answer;
while qcount>0 do begin // First one is our Answer.
msg_text:=msg_text+dn_expand(pmx_rec,pmx_rec+MAXPACKET,msg_text,pbuf,MAXPACKET);
dec(qcount);
msg_text:=msg_text+4;
end;
for i:=1 to acount do begin
msg_text:=msg_text+dn_expand(pmx_rec,pmx_rec+MAXPACKET,msg_text,pbuf,MAXPACKET);
pr:=pexp_an(msg_text); // TypeCasting !!!
r:=pr^;
if htons(r.r_type)=T_MX then begin
p1:=PChar(msg_text+10);
mx_prio:=(byte(p1^))*256;
inc(p1);
mx_prio:=byte(p1^);
inc(p1);
dn_expand(pmx_rec,pmx_rec+MAXPACKET,p1,pbuf,MAXPACKET);
t_zeile:=t_zeile+StrPas(pbuf)+','+IntToStr(mx_prio)+',';
end;
msg_text:=msg_text+10+ntohs(r.r_len);
end;
end;
Delete(T_Zeile,Length(T_Zeile),1);
Sys2_GetMXAddr:=t_Zeile;
end; // End of function
end.
Druckversionzuletzt geändert am 25.02.2004
|