On Sun, 2003-11-23 at 11:34, Johannes Berg wrote: > Also, netdb needs cleaning up, I'll do that soon and send another patch > then. I also forgot to add CNAME records to the ipv4 functions (which > will be just a code copy).
Done most of that, but generally the code in netdb is not very error-checking, so I added a warning. Attached is a new patch that also adds ResolveAddress6 to find name(s) for a given address. I also made the ntoh* and hton* function parameters constant and fixed up all code where they were used, the code was generally very confused as to what should happen with the argument, some code assumed the argument would be changed and some assumed it would only return the flipped value. I haven't had a chance to test any of the ipv6 stuff on a big-endian machine so I'd be very interested in hearing from someone who actually uses ipv6 on a big-endian machine, I would expect some problems. johannes -- http://www.sipsolutions.de/ GnuPG key: http://www.sipsolutions.de/keys/JohannesBerg.asc Key-ID: 9AB78CA5 Johannes Berg <[EMAIL PROTECTED]> Fingerprint = AD02 0176 4E29 C137 1DF6 08D2 FC44 CF86 9AB7 8CA5
Index: netdb.pp
===================================================================
RCS file: /FPC/CVS/fpc/packages/base/netdb/netdb.pp,v
retrieving revision 1.8
diff -u -r1.8 netdb.pp
--- netdb.pp 22 Nov 2003 23:17:50 -0000 1.8
+++ netdb.pp 23 Nov 2003 17:50:49 -0000
@@ -17,6 +17,14 @@
{$h+}
unit netdb;
+{
+ WARNING
+ This unit hardly does any error checking. For example, stringfromlabel
+ could easily be exploited by someone sending malicious UDP packets in
+ order to crash your program. So if you really want to depend on this
+ in critical programs then you'd better fix a lot of code in here.
+ Otherwise, it appears to work pretty well.
+}
Interface
@@ -69,6 +77,8 @@
Function ResolveAddress(HostAddr : THostAddr; Var Addresses : Array of String) : Integer;
+Function ResolveAddress6(HostAddr: THostAddr6; var Addresses: Array of string) : Integer;
+
Function ResolveHostByName(HostName : String; Var H : THostEntry) : Boolean;
Function ResolveHostByAddr(HostAddr : THostAddr; Var H : THostEntry) : Boolean;
@@ -146,7 +156,7 @@
Auxiliary functions.
---------------------------------------------------------------------}
-function htonl(i:integer):integer;
+function htonl(const i:integer):integer;
begin
{$ifdef ENDIAN_LITTLE}
result := (i shr 24) or (i shr 8 and $ff00) or (i shl 8 and $ff0000) or (i shl 24 and $ff000000);
@@ -155,7 +165,7 @@
{$endif}
end;
-Function htons(var W : Word) : word;
+Function htons(const W : Word) : word;
begin
{$ifdef ENDIAN_LITTLE}
@@ -163,10 +173,9 @@
{$else}
result := w;
{$endif}
- w := result;
end;
-Function ntohs(var W : Word) : Word;
+Function ntohs(const W : Word) : Word;
begin
{$ifdef ENDIAN_LITTLE}
@@ -174,17 +183,15 @@
{$else}
result := w;
{$endif}
- w := result;
end;
-function ntohl(i:integer):integer;
+function ntohl(const i:integer):integer;
begin
{$ifdef ENDIAN_LITTLE}
result := (i shr 24) or (i shr 8 and $ff00) or (i shl 8 and $ff0000) or (i shl 24 and $ff000000);
{$else}
result := i;
{$endif}
- i := result;
end;
{ ---------------------------------------------------------------------
@@ -307,10 +314,10 @@
Delete(Name,1,L);
Until (L=0);
P[Result]:=0;
- htons(rr);
+ rr := htons(rr);
Move(rr,P[Result+1],2);
Inc(Result,3);
- htons(QClass);
+ QClass := htons(QClass);
Move(qclass,P[Result],2);
Inc(Result,2);
end;
@@ -406,7 +413,7 @@
if (Flags2 and QF_RCODE)<>0 then
exit;
// Number of answers ?
- htons(Ancount);
+ AnCount := htons(Ancount);
If Ancount<1 then
Exit;
Result:=True;
@@ -422,7 +429,7 @@
Result:=0;
With Ans do
begin
- htons(qdcount);
+ qdcount := htons(qdcount);
i:=0;
q:=0;
While (Q<qdcount) and (i<l) do
@@ -479,8 +486,7 @@
With SA do
begin
family:=AF_INET;
- port:=DNSport;
- htons(port);
+ port:=htons(DNSport);
addr:=cardinal(HostToNet(DNSServers[Resolver]));
end;
sendto(sock,qry,qrylen+12,0,SA,SizeOf(SA));
@@ -508,14 +514,34 @@
Result:=True;
end;
-Function ResolveNameAt(Resolver : Integer; HostName : String; Var Addresses : Array of THostAddr) : Integer;
+function stringfromlabel(pl: TPayLoad; start: integer): string;
+var
+ l,i: integer;
+begin
+ result := '';
+ l := 0;
+ i := 0;
+ repeat
+ l := ord(pl[start]);
+ if l <> 0 then begin
+ setlength(result,length(result)+l);
+ move(pl[start+1],result[i+1],l);
+ result := result + '.';
+ inc(start,l); inc(start);
+ inc(i,l); inc(i);
+ end;
+ until l = 0;
+ if result[length(result)] = '.' then setlength(result,length(result)-1);
+end;
+
+Function ResolveNameAt(Resolver : Integer; HostName : String; Var Addresses : Array of THostAddr; Recurse: Integer) : Integer;
Var
Qry, Ans : TQueryData;
MaxAnswer,I,QryLen,
AnsLen,AnsStart : Longint;
RR : TRRData;
-
+ cname : string;
begin
Result:=0;
QryLen:=BuildPayLoad(Qry,HostName,DNSQRY_A,1);
@@ -530,13 +556,26 @@
I:=0;
While (I<=MaxAnswer) and NextRR(Ans.Payload,AnsStart,AnsLen,RR) do
begin
- if (Ntohs(RR.AType)=DNSQRY_A) and (1=NtoHS(RR.AClass)) then
- begin
- Move(Ans.PayLoad[AnsStart],Addresses[i],SizeOf(THostAddr));
- inc(Result);
- Inc(AnsStart,RR.RDLength);
+ if htons(rr.AClass) = 1 then
+ case ntohs(rr.AType) of
+ DNSQRY_A: begin
+ Move(Ans.PayLoad[AnsStart],Addresses[i],SizeOf(THostAddr));
+ inc(Result);
+ Inc(AnsStart,htons(RR.RDLength));
+ end;
+ DNSQRY_CNAME: begin
+ if Recurse >= MaxRecursion then begin
+ Result := -1;
+ exit;
+ end;
+ rr.rdlength := ntohs(rr.rdlength);
+ setlength(cname, rr.rdlength);
+ cname := stringfromlabel(ans.payload, ansstart);
+ Result := ResolveNameAt(Resolver, cname, Addresses, Recurse+1);
+ exit; // FIXME: what about other servers?!
+ end;
end;
- Inc(I);
+ Inc(I);
end;
end;
end;
@@ -552,31 +591,11 @@
Result:=0;
While (Result=0) and (I<=DNSServerCount) do
begin
- Result:=ResolveNameAt(I,HostName,Addresses);
+ Result:=ResolveNameAt(I,HostName,Addresses,0);
Inc(I);
end;
end;
-function stringfromlabel(pl: TPayLoad; start: integer): string;
-var
- l,i: integer;
-begin
- result := '';
- l := 0;
- i := 0;
- repeat
- l := ord(pl[start]);
- if l <> 0 then begin
- setlength(result,length(result)+l);
- move(pl[start+1],result[i+1],l);
- result := result + '.';
- inc(start,l); inc(start);
- inc(i,l); inc(i);
- end;
- until l = 0;
- if result[length(result)] = '.' then setlength(result,length(result)-1);
-end;
-
Function ResolveNameAt6(Resolver : Integer; HostName : String; Var Addresses : Array of THostAddr6; Recurse: Integer) : Integer;
Var
@@ -614,10 +633,8 @@
exit;
end;
rr.rdlength := ntohs(rr.rdlength);
- writeln(rr.rdlength);
setlength(cname, rr.rdlength);
cname := stringfromlabel(ans.payload, ansstart);
- writeln(cname);
Result := ResolveNameAt6(Resolver, cname, Addresses, Recurse+1);
exit; // FIXME: what about other servers?!
end;
@@ -669,6 +686,7 @@
begin
Names[i]:=BuildName(Ans.Payload,AnsStart,AnsLen);
inc(Result);
+ RR.RDLength := ntohs(RR.RDLength);
Inc(AnsStart,RR.RDLength);
end;
Inc(I);
@@ -694,6 +712,34 @@
Inc(I);
end;
end;
+
+Function ResolveAddress6(HostAddr : THostAddr6; Var Addresses : Array of String) : Integer;
+
+const
+ hexdig: string[16] = '0123456789abcdef';
+
+Var
+ I : Integer;
+ S : ShortString;
+
+begin
+ CheckResolveFile;
+ Result:=0;
+ S := '0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.int';
+ for i := 7 downto 0 do begin
+ S[5+(7-i)*8] := hexdig[1+(HostAddr[i] and $000F) shr 00];
+ S[7+(7-i)*8] := hexdig[1+(HostAddr[i] and $00F0) shr 04];
+ S[1+(7-i)*8] := hexdig[1+(HostAddr[i] and $0F00) shr 08];
+ S[3+(7-i)*8] := hexdig[1+(HostAddr[i] and $F000) shr 12];
+ end;
+ I := 1;
+ While (Result=0) and (I<=DNSServerCount) do
+ begin
+ Result:=ResolveAddressAt(I,S,Addresses);
+ Inc(I);
+ end;
+end;
+
Function ResolveHostByName(HostName : String; Var H : THostEntry) : Boolean;
signature.asc
Description: This is a digitally signed message part
