Просмотр исходного кода

# revisions: 44088,44296,44297,44302

git-svn-id: branches/fixes_3_2@47087 -
marco 4 лет назад
Родитель
Сommit
79b5d889e2
1 измененных файлов с 332 добавлено и 40 удалено
  1. 332 40
      packages/fcl-net/src/netdb.pp

+ 332 - 40
packages/fcl-net/src/netdb.pp

@@ -23,6 +23,9 @@ unit netdb;
   order to crash  your program.  So if you really want to depend on this
   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.
   in critical programs then you'd better fix a lot of code in here.
   Otherwise, it appears to work pretty well.
   Otherwise, it appears to work pretty well.
+
+  When compiling this unit with the FPC_USE_LIBC defined, the warning above
+  can be ignored, since the libc implementation should be robust.
 }
 }
 
 
 Interface
 Interface
@@ -49,15 +52,20 @@ Uses Sockets;
  {$DEFINE UNIX_ETC}
  {$DEFINE UNIX_ETC}
 {$ENDIF UNIX}
 {$ENDIF UNIX}
 
 
+{$if defined(android)}
+  {$define FPC_USE_LIBC}
+{$endif}
+
 Type
 Type
   THostAddr = in_addr;		// historical aliases for these.
   THostAddr = in_addr;		// historical aliases for these.
   THostAddr6= Tin6_addr;
   THostAddr6= Tin6_addr;
   TNetAddr  = THostAddr;	// but in net order.
   TNetAddr  = THostAddr;	// but in net order.
 
 
 Const
 Const
-  DNSPort        = 53;
   MaxResolveAddr = 10;
   MaxResolveAddr = 10;
-  SServicesFile  = 'services'; 
+{$ifndef FPC_USE_LIBC}
+  DNSPort        = 53;
+  SServicesFile  = 'services';
   SHostsFile     = 'hosts';
   SHostsFile     = 'hosts';
   SNetworksFile  = 'networks';
   SNetworksFile  = 'networks';
 {$IFDEF SFN_VERSION}
 {$IFDEF SFN_VERSION}
@@ -78,6 +86,7 @@ Const
 
 
 var
 var
   EtcPath: string;
   EtcPath: string;
+{$endif FPC_USE_LIBC}
 
 
 Type
 Type
   TDNSServerArray = Array of THostAddr;
   TDNSServerArray = Array of THostAddr;
@@ -124,7 +133,8 @@ Type
     Next : PHostListEntry;
     Next : PHostListEntry;
   end;
   end;
 
 
-Var  
+{$ifndef FPC_USE_LIBC}
+Var
   DNSServers            : TDNSServerArray;
   DNSServers            : TDNSServerArray;
   DNSOptions            : String;
   DNSOptions            : String;
   DefaultDomainList     : String;
   DefaultDomainList     : String;
@@ -137,46 +147,60 @@ Function GetDNSServers : Integer;
 {$else}
 {$else}
 Function GetDNSServers(FN : String) : Integer;
 Function GetDNSServers(FN : String) : Integer;
 {$endif android}
 {$endif android}
+{$endif FPC_USE_LIBC}
 
 
+// Addresses are returned in the net byte order
 Function ResolveName(HostName : String; Var Addresses : Array of THostAddr) : Integer;
 Function ResolveName(HostName : String; Var Addresses : Array of THostAddr) : Integer;
 Function ResolveName6(HostName : String; Var Addresses : Array of THostAddr6) : Integer;
 Function ResolveName6(HostName : String; Var Addresses : Array of THostAddr6) : Integer;
 
 
-
+// HostAddr is specified in the host byte order
 Function ResolveAddress(HostAddr : THostAddr; Var Addresses : Array of String) : Integer;
 Function ResolveAddress(HostAddr : THostAddr; Var Addresses : Array of String) : Integer;
 Function ResolveAddress6(HostAddr: THostAddr6; var Addresses: Array of string) : Integer;
 Function ResolveAddress6(HostAddr: THostAddr6; var Addresses: Array of string) : Integer;
 
 
 function IN6_IS_ADDR_V4MAPPED(HostAddr: THostAddr6): boolean;
 function IN6_IS_ADDR_V4MAPPED(HostAddr: THostAddr6): boolean;
 
 
+// H.Addr is returned in the net byte order
 Function ResolveHostByName(HostName : String; Var H : THostEntry) : Boolean;
 Function ResolveHostByName(HostName : String; Var H : THostEntry) : Boolean;
+// HostAddr is specified in the host byte order
 Function ResolveHostByAddr(HostAddr : THostAddr; Var H : THostEntry) : Boolean;
 Function ResolveHostByAddr(HostAddr : THostAddr; Var H : THostEntry) : Boolean;
 
 
 Function ResolveHostByName6(Hostname : String; Var H : THostEntry6) : Boolean;
 Function ResolveHostByName6(Hostname : String; Var H : THostEntry6) : Boolean;
 Function ResolveHostByAddr6(HostAddr : THostAddr6; Var H : THostEntry6) : Boolean;
 Function ResolveHostByAddr6(HostAddr : THostAddr6; Var H : THostEntry6) : Boolean;
 
 
+// H.Addr is returned in the host byte order
 Function GetHostByName(HostName: String;  Var H : THostEntry) : boolean;
 Function GetHostByName(HostName: String;  Var H : THostEntry) : boolean;
+// Addr is specified in the host byte order
 Function GetHostByAddr(Addr: THostAddr;  Var H : THostEntry) : boolean;
 Function GetHostByAddr(Addr: THostAddr;  Var H : THostEntry) : boolean;
 
 
+// N.Addr is returned in the net byte order
 Function GetNetworkByName(NetName: String; Var N : TNetworkEntry) : boolean;
 Function GetNetworkByName(NetName: String; Var N : TNetworkEntry) : boolean;
+// Addr is specified in the host byte order
 Function GetNetworkByAddr(Addr: THostAddr; Var N : TNetworkEntry) : boolean;
 Function GetNetworkByAddr(Addr: THostAddr; Var N : TNetworkEntry) : boolean;
 
 
+// E.Port is returned in the host byte order
 Function GetServiceByName(Const Name,Proto : String; Var E : TServiceEntry) : Boolean;
 Function GetServiceByName(Const Name,Proto : String; Var E : TServiceEntry) : Boolean;
+// Port is specified in the host byte order
 Function GetServiceByPort(Port : Word;Const Proto : String; Var E : TServiceEntry) : Boolean;
 Function GetServiceByPort(Port : Word;Const Proto : String; Var E : TServiceEntry) : Boolean;
 
 
 Function GetProtocolByName(ProtoName: String;  Var H : TProtocolEntry) : boolean;
 Function GetProtocolByName(ProtoName: String;  Var H : TProtocolEntry) : boolean;
 Function GetProtocolByNumber(proto: Integer;  Var H : TProtocolEntry) : boolean;
 Function GetProtocolByNumber(proto: Integer;  Var H : TProtocolEntry) : boolean;
 
 
-
-
+{$ifndef FPC_USE_LIBC}
 Function ProcessHosts(FileName : String) : PHostListEntry;
 Function ProcessHosts(FileName : String) : PHostListEntry;
 Function FreeHostsList(var List : PHostListEntry) : Integer;
 Function FreeHostsList(var List : PHostListEntry) : Integer;
 Procedure HostsListToArray(var List : PHostListEntry; Var Hosts : THostEntryArray; FreeList : Boolean);
 Procedure HostsListToArray(var List : PHostListEntry; Var Hosts : THostEntryArray; FreeList : Boolean);
+{$endif FPC_USE_LIBC}
 
 
 Implementation
 Implementation
 
 
 uses 
 uses 
+{$ifdef FPC_USE_LIBC}
+   cNetDB,
+{$endif FPC_USE_LIBC}
    BaseUnix,
    BaseUnix,
    sysutils;
    sysutils;
 
 
+{$ifndef FPC_USE_LIBC}
 var
 var
   DefaultDomainListArr : array of string;
   DefaultDomainListArr : array of string;
   NDots: Integer;
   NDots: Integer;
@@ -1128,7 +1152,7 @@ Var
 begin
 begin
   CheckResolveFile;
   CheckResolveFile;
   Result:=0;
   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';
+  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.arpa';
   for i := 7 downto 0 do begin
   for i := 7 downto 0 do begin
     S[5+(7-i)*8] := hexdig[1+(HostAddr.u6_addr16[i] and $000F) shr 00];
     S[5+(7-i)*8] := hexdig[1+(HostAddr.u6_addr16[i] and $000F) shr 00];
     S[7+(7-i)*8] := hexdig[1+(HostAddr.u6_addr16[i] and $00F0) shr 04];
     S[7+(7-i)*8] := hexdig[1+(HostAddr.u6_addr16[i] and $00F0) shr 04];
@@ -1143,17 +1167,6 @@ begin
     end;
     end;
 end;
 end;
 
 
-function IN6_IS_ADDR_V4MAPPED(HostAddr: THostAddr6): boolean;
-begin
-  Result := 
-   (HostAddr.u6_addr16[0] = 0) and
-   (HostAddr.u6_addr16[1] = 0) and
-   (HostAddr.u6_addr16[2] = 0) and
-   (HostAddr.u6_addr16[3] = 0) and
-   (HostAddr.u6_addr16[4] = 0) and
-   (HostAddr.u6_addr16[5] = $FFFF);
-end;
-
 Function HandleAsFullyQualifiedName(const HostName: String) : Boolean;
 Function HandleAsFullyQualifiedName(const HostName: String) : Boolean;
 var
 var
   I,J : Integer;
   I,J : Integer;
@@ -1321,7 +1334,7 @@ Function GetNextProtoEntry(var F : Text; Var H : TProtocolEntry): boolean;
 Var
 Var
   Line,S : String;
   Line,S : String;
   I      : integer;
   I      : integer;
-  
+
 begin
 begin
   Result:=False;
   Result:=False;
   Repeat
   Repeat
@@ -1330,7 +1343,7 @@ begin
     S:=NextWord(Line);
     S:=NextWord(Line);
     If (S<>'') then
     If (S<>'') then
       begin
       begin
-        H.Name:=S;	
+        H.Name:=S;
         S:=NextWord(Line);
         S:=NextWord(Line);
 	i:=strtointdef(s,-1);
 	i:=strtointdef(s,-1);
         If (i<>-1) then
         If (i<>-1) then
@@ -1344,19 +1357,19 @@ begin
               If (H.Aliases='') then
               If (H.Aliases='') then
                 H.Aliases:=S
                 H.Aliases:=S
               else
               else
-                H.Aliases:=H.Aliases+','+S;  
+                H.Aliases:=H.Aliases+','+S;
           until (S='');
           until (S='');
           end;
           end;
       end;
       end;
   until Result or EOF(F);
   until Result or EOF(F);
-end;  
+end;
 
 
 Function FindProtoEntryInProtoFile(N: String; prot: integer; Var H : TProtocolEntry) : boolean;
 Function FindProtoEntryInProtoFile(N: String; prot: integer; Var H : TProtocolEntry) : boolean;
 
 
 Var
 Var
   F : Text;
   F : Text;
   HE : TProtocolEntry;
   HE : TProtocolEntry;
-  
+
 begin
 begin
   Result:=False;
   Result:=False;
   If FileExists (EtcPath + SProtocolFile) then
   If FileExists (EtcPath + SProtocolFile) then
@@ -1373,7 +1386,7 @@ begin
           Result:=MatchNameOrAlias(N,HE.Name,HE.Aliases)
           Result:=MatchNameOrAlias(N,HE.Name,HE.Aliases)
         else
         else
           Result:=prot=he.number;
           Result:=prot=he.number;
-        end; 
+        end;
       Close(f);
       Close(f);
       If Result then
       If Result then
         begin
         begin
@@ -1381,7 +1394,7 @@ begin
         H.number:=he.number;
         H.number:=he.number;
         H.Aliases:=HE.Aliases;
         H.Aliases:=HE.Aliases;
         end;
         end;
-      end;  
+      end;
     end;
     end;
 end;
 end;
 
 
@@ -1431,7 +1444,7 @@ Function GetNextNetworkEntry(var F : Text; Var N : TNetworkEntry): boolean;
 Var
 Var
   NN,Line,S : String;
   NN,Line,S : String;
   A : TNetAddr;
   A : TNetAddr;
-  
+
 begin
 begin
   Result:=False;
   Result:=False;
   Repeat
   Repeat
@@ -1448,17 +1461,17 @@ begin
         N.Addr.s_addr:=A.s_addr; // keep it host.
         N.Addr.s_addr:=A.s_addr; // keep it host.
         N.Name:=NN;
         N.Name:=NN;
         N.Aliases:='';
         N.Aliases:='';
-        end;      
+        end;
       end;
       end;
   until Result or EOF(F);
   until Result or EOF(F);
-end;  
+end;
 
 
 Function FindNetworkEntryInNetworksFile(Net: String; Addr: TNetAddr; Var N : TNetworkEntry) : boolean;
 Function FindNetworkEntryInNetworksFile(Net: String; Addr: TNetAddr; Var N : TNetworkEntry) : boolean;
 
 
 Var
 Var
   F : Text;
   F : Text;
   NE : TNetworkEntry;
   NE : TNetworkEntry;
-  
+
 begin
 begin
   Result:=False;
   Result:=False;
   If FileExists (EtcPath + SNetworksFile) then
   If FileExists (EtcPath + SNetworksFile) then
@@ -1475,7 +1488,7 @@ begin
           Result:=MatchNameOrAlias(Net,NE.Name,NE.Aliases)
           Result:=MatchNameOrAlias(Net,NE.Name,NE.Aliases)
         else
         else
           Result:=Cardinal(Addr)=Cardinal(NE.Addr);
           Result:=Cardinal(Addr)=Cardinal(NE.Addr);
-        end; 
+        end;
       Close(f);
       Close(f);
       If Result then
       If Result then
         begin
         begin
@@ -1483,12 +1496,12 @@ begin
         N.Addr:=nettohost(NE.Addr);
         N.Addr:=nettohost(NE.Addr);
         N.Aliases:=NE.Aliases;
         N.Aliases:=NE.Aliases;
         end;
         end;
-      end;  
+      end;
     end;
     end;
 end;
 end;
 
 
 Const NoNet : in_addr = (s_addr:0);
 Const NoNet : in_addr = (s_addr:0);
-  
+
 Function GetNetworkByName(NetName: String; Var N : TNetworkEntry) : boolean;
 Function GetNetworkByName(NetName: String; Var N : TNetworkEntry) : boolean;
 
 
 begin
 begin
@@ -1511,7 +1524,7 @@ Function GetNextServiceEntry(Var F : Text; Var E : TServiceEntry) : Boolean;
 Var
 Var
   Line,S : String;
   Line,S : String;
   P : INteger;
   P : INteger;
-  
+
 begin
 begin
   Result:=False;
   Result:=False;
   Repeat
   Repeat
@@ -1536,7 +1549,7 @@ begin
             If (S<>'') then
             If (S<>'') then
               If (Length(E.Aliases)=0) then
               If (Length(E.Aliases)=0) then
                 E.aliases:=S
                 E.aliases:=S
-              else  
+              else
                 E.Aliases:=E.Aliases+','+S;
                 E.Aliases:=E.Aliases+','+S;
           until (S='');
           until (S='');
           end;
           end;
@@ -1551,7 +1564,7 @@ Function FindServiceEntryInFile(Const Name,Proto : String; Port : Integer; Var E
 Var
 Var
   F : Text;
   F : Text;
   TE : TServiceEntry;
   TE : TServiceEntry;
-  
+
 begin
 begin
   Result:=False;
   Result:=False;
   If FileExists (EtcPath + SServicesFile) then
   If FileExists (EtcPath + SServicesFile) then
@@ -1566,11 +1579,11 @@ begin
         begin
         begin
         If (Port=-1) then
         If (Port=-1) then
           Result:=MatchNameOrAlias(Name,TE.Name,TE.Aliases)
           Result:=MatchNameOrAlias(Name,TE.Name,TE.Aliases)
-        else 
+        else
           Result:=(Port=TE.Port);
           Result:=(Port=TE.Port);
         If Result and (Proto<>'') then
         If Result and (Proto<>'') then
           Result:=(Proto=TE.Protocol);
           Result:=(Proto=TE.Protocol);
-        end; 
+        end;
       Close(f);
       Close(f);
       If Result then
       If Result then
         begin
         begin
@@ -1579,20 +1592,20 @@ begin
         E.Protocol:=TE.Protocol;
         E.Protocol:=TE.Protocol;
         E.Aliases:=TE.Aliases;
         E.Aliases:=TE.Aliases;
         end;
         end;
-      end;  
+      end;
     end;
     end;
 end;
 end;
 
 
 Function GetServiceByName(Const Name,Proto : String; Var E : TServiceEntry) : Boolean;
 Function GetServiceByName(Const Name,Proto : String; Var E : TServiceEntry) : Boolean;
 
 
 begin
 begin
-  Result:=FindServiceEntryInFile(Name,Proto,-1,E);  
+  Result:=FindServiceEntryInFile(Name,Proto,-1,E);
 end;
 end;
 
 
 Function GetServiceByPort(Port : Word;Const Proto : String; Var E : TServiceEntry) : Boolean;
 Function GetServiceByPort(Port : Word;Const Proto : String; Var E : TServiceEntry) : Boolean;
 
 
 begin
 begin
-  Result:=FindServiceEntryInFile('',Proto,Port,E);  
+  Result:=FindServiceEntryInFile('',Proto,Port,E);
 end;
 end;
 
 
 { ---------------------------------------------------------------------
 { ---------------------------------------------------------------------
@@ -1640,9 +1653,288 @@ begin
   FreeHostsList(HostsList);
   FreeHostsList(HostsList);
 end;
 end;
 
 
+{$else FPC_USE_LIBC}
+
+{ ---------------------------------------------------------------------
+    Implementation based on libc
+  ---------------------------------------------------------------------}
+
+Function ResolveName(const HostName : String; Addresses: pointer; MaxAddresses, Family: integer) : Integer;
+var
+  h: TAddrInfo;
+  res, ai: PAddrInfo;
+begin
+  Result:=-1;
+  if MaxAddresses = 0 then
+    exit;
+  FillChar(h, SizeOf(h), 0);
+  h.ai_family:=Family;
+  h.ai_socktype:=SOCK_STREAM;
+  res:=nil;
+  if (getaddrinfo(PChar(HostName), nil, @h, @res) <> 0) or (res = nil) then
+    exit;
+  Result:=0;
+  ai:=res;
+  repeat
+    if ai^.ai_family = Family then begin
+      if Family = AF_INET then begin
+        Move(PInetSockAddr(ai^.ai_addr)^.sin_addr, Addresses^, SizeOf(TInAddr));
+        Inc(PInAddr(Addresses));
+      end
+      else begin
+        Move(PInetSockAddr6(ai^.ai_addr)^.sin6_addr, Addresses^, SizeOf(TIn6Addr));
+        Inc(PIn6Addr(Addresses));
+      end;
+      Inc(Result);
+    end;
+    ai:=ai^.ai_next;
+  until (ai = nil) or (Result >= MaxAddresses);
+  freeaddrinfo(res);
+end;
+
+Function ResolveName(HostName : String; Var Addresses : Array of THostAddr) : Integer;
+begin
+  Result:=ResolveName(HostName, @Addresses, Length(Addresses), AF_INET);
+end;
+
+Function ResolveName6(HostName : String; Var Addresses : Array of THostAddr6) : Integer;
+begin
+  Result:=ResolveName(HostName, @Addresses, Length(Addresses), AF_INET6);
+end;
+
+Function ResolveAddress(Addr : pointer; AddrLen: integer; Var Names : Array of String) : Integer;
+var
+  n: ansistring;
+begin
+  Result:=-1;
+  if Length(Names) = 0 then
+    exit;
+  n:='';
+  SetLength(n, NI_MAXHOST);
+  if getnameinfo(Addr, AddrLen, @n[1], Length(n), nil, 0, 0) = 0 then begin
+    Names[Low(Names)]:=PAnsiChar(n);
+    Result:=1;
+  end;
+end;
+
+Function ResolveAddress(HostAddr : THostAddr; Var Addresses : Array of String) : Integer;
+var
+  a: TInetSockAddr;
+begin
+  FillChar(a, SizeOf(a), 0);
+  a.sin_family:=AF_INET;
+  a.sin_addr.s_addr:=htonl(HostAddr.s_addr);
+  Result:=ResolveAddress(@a, SizeOf(a), Addresses);
+end;
+
+Function ResolveAddress6(HostAddr: THostAddr6; var Addresses: Array of string) : Integer;
+var
+  a: TInetSockAddr6;
+begin
+  FillChar(a, SizeOf(a), 0);
+  a.sin6_family:=AF_INET6;
+  Move(HostAddr, a.sin6_addr, SizeOf(TInetSockAddr6));
+  Result:=ResolveAddress(@a, SizeOf(a), Addresses);
+end;
+
+Function ResolveHostByName(HostName : String; Var H : THostEntry) : Boolean;
+Var
+  Address : Array[1..1] of THostAddr;
+begin
+  Result:=ResolveName(HostName,Address) > 0;
+  if Result then begin
+    H.Name:=HostName;
+    H.Addr:=Address[1];
+    H.aliases:='';
+  end;
+end;
+
+Function ResolveHostByName6(Hostname : String; Var H : THostEntry6) : Boolean;
+Var
+  Address : Array[1..1] of THostAddr6;
+begin
+  Result:=ResolveName6(HostName,Address) > 0;
+  if Result then begin
+    H.Name:=HostName;
+    H.Addr:=Address[1];
+    H.aliases:='';
+  end;
+end;
+
+Function ResolveHostByAddr(HostAddr : THostAddr; Var H : THostEntry) : Boolean;
+Var
+  Names : Array[1..MaxResolveAddr] of String;
+  I,L : Integer;
+begin
+  L:=ResolveAddress(HostAddr,Names);
+  Result:=(L>0);
+  If Result then
+    begin
+    H.Name:=Names[1];
+    H.Addr:=HostAddr;
+    H.Aliases:='';
+    If (L>1) then
+      For I:=2 to L do
+        If (I=2) then
+          H.Aliases:=Names[i]
+        else
+          H.Aliases:=H.Aliases+','+Names[i];
+    end;
+end;
+
+Function ResolveHostByAddr6(HostAddr : THostAddr6; Var H : THostEntry6) : Boolean;
+Var
+  Names : Array[1..MaxResolveAddr] of String;
+  I,L : Integer;
+begin
+  L:=ResolveAddress6(HostAddr,Names);
+  Result:=(L>0);
+  If Result then
+    begin
+    H.Name:=Names[1];
+    H.Addr:=HostAddr;
+    H.Aliases:='';
+    If (L>1) then
+      For I:=2 to L do
+        If (I=2) then
+          H.Aliases:=Names[i]
+        else
+          H.Aliases:=H.Aliases+','+Names[i];
+    end;
+end;
+
+Function GetHostByName(HostName: String;  Var H : THostEntry) : boolean;
+begin
+  Result:=False;
+end;
+
+Function GetHostByAddr(Addr: THostAddr;  Var H : THostEntry) : boolean;
+begin
+  Result:=False;
+end;
+
+function PPCharToString(list: PPChar): string;
+begin
+  Result:='';
+  if list = nil then
+    exit;
+  while list^ <> nil do begin
+    if Length(Result) = 0 then
+      Result:=list^
+    else
+      Result:=Result + ',' + list^;
+    Inc(list);
+  end;
+end;
+
+Function GetNetworkByName(NetName: String; Var N : TNetworkEntry) : boolean;
+var
+  ne: PNetEnt;
+begin
+  ne:=getnetbyname(PAnsiChar(NetName));
+  Result:=ne <> nil;
+  if Result then begin
+    N.Name:=ne^.n_name;
+    N.Addr.s_addr:=ne^.n_net;
+    N.Aliases:=PPCharToString(ne^.n_aliases);
+  end;
+end;
+
+Function GetNetworkByAddr(Addr: THostAddr; Var N : TNetworkEntry) : boolean;
+var
+  ne: PNetEnt;
+begin
+  ne:=getnetbyaddr(htonl(Addr.s_addr), AF_INET);
+  Result:=ne <> nil;
+  if Result then begin
+    N.Name:=ne^.n_name;
+    N.Addr.s_addr:=ne^.n_net;
+    N.Aliases:=PPCharToString(ne^.n_aliases);
+  end;
+end;
+
+Function GetServiceByName(Const Name,Proto : String; Var E : TServiceEntry) : Boolean;
+var
+  se: PServEnt;
+begin
+  se:=getservbyname(PAnsiChar(Name), PAnsiChar(Proto));
+  Result:=se <> nil;
+  if Result then begin
+    E.Name:=se^.s_name;
+    E.Port:=NToHs(se^.s_port);
+    E.Protocol:=se^.s_proto;
+    E.Aliases:=PPCharToString(se^.s_aliases);
+  end;
+end;
+
+Function GetServiceByPort(Port : Word;Const Proto : String; Var E : TServiceEntry) : Boolean;
+var
+  se: PServEnt;
+begin
+  se:=getservbyport(htons(Port), PAnsiChar(Proto));
+  Result:=se <> nil;
+  if Result then begin
+    E.Name:=se^.s_name;
+    E.Port:=NToHs(se^.s_port);
+    E.Protocol:=se^.s_proto;
+    E.Aliases:=PPCharToString(se^.s_aliases);
+  end;
+end;
+
+Function GetProtocolByName(ProtoName: String;  Var H : TProtocolEntry) : boolean;
+var
+  pe: PProtoEnt;
+begin
+  pe:=getprotobyname(PAnsiChar(ProtoName));
+  Result:=pe <> nil;
+  if Result then begin
+    H.Name:=pe^.p_name;
+    H.Number:=pe^.p_proto;
+    h.Aliases:=PPCharToString(pe^.p_aliases);
+  end;
+end;
+
+Function GetProtocolByNumber(proto: Integer;  Var H : TProtocolEntry) : boolean;
+var
+  pe: PProtoEnt;
+begin
+  pe:=getprotobynumber(proto);
+  Result:=pe <> nil;
+  if Result then begin
+    H.Name:=pe^.p_name;
+    H.Number:=pe^.p_proto;
+    h.Aliases:=PPCharToString(pe^.p_aliases);
+  end;
+end;
+
+Procedure InitResolver; inline;
+begin
+end;
+
+Procedure DoneResolver; inline;
+begin
+end;
+
+{$endif FPC_USE_LIBC}
+
+{ ---------------------------------------------------------------------
+    Common routines
+  ---------------------------------------------------------------------}
+
+function IN6_IS_ADDR_V4MAPPED(HostAddr: THostAddr6): boolean;
+begin
+  Result :=
+   (HostAddr.u6_addr16[0] = 0) and
+   (HostAddr.u6_addr16[1] = 0) and
+   (HostAddr.u6_addr16[2] = 0) and
+   (HostAddr.u6_addr16[3] = 0) and
+   (HostAddr.u6_addr16[4] = 0) and
+   (HostAddr.u6_addr16[5] = $FFFF);
+end;
 
 
 Initialization
 Initialization
   InitResolver;
   InitResolver;
 Finalization
 Finalization
   DoneResolver;  
   DoneResolver;  
 end.
 end.
+