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;
 

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to