reorganization of system dns servers code
authorbeware <beware@bircd.org>
Thu, 24 Feb 2011 06:24:10 +0000 (06:24 +0000)
committerbeware <beware@bircd.org>
Thu, 24 Feb 2011 06:24:10 +0000 (06:24 +0000)
git-svn-id: file:///svnroot/lcore/trunk@97 b1de8a11-f9be-4011-bde0-cc7ace90066a

dnsasync.pas
dnscore.pas
dnssync.pas
lcorelocalips.pas

index 4efc20545d014802130f3a0df3eca20617ff7c93..b6e89417b3f94eff982ab846ac6f09a060e78d4c 100644 (file)
@@ -153,7 +153,7 @@ end;
 \r
 function tdnsasync.sendquery(socketno:integer;const packet:tdnspacket;len:integer):boolean;\r
 var\r
 \r
 function tdnsasync.sendquery(socketno:integer;const packet:tdnspacket;len:integer):boolean;\r
 var\r
-  destination : ansistring;\r
+  destination : tbinip;\r
   inaddr : tinetsockaddrv;\r
   trytolisten:integer;\r
 begin\r
   inaddr : tinetsockaddrv;\r
   trytolisten:integer;\r
 begin\r
@@ -185,11 +185,11 @@ begin
   end;\r
   if addr <> '' then begin\r
     dnsserverids[socketno] := -1;\r
   end;\r
   if addr <> '' then begin\r
     dnsserverids[socketno] := -1;\r
-    destination := addr\r
+    destination := ipstrtobinf(addr);\r
   end else begin\r
   end else begin\r
-    destination := getcurrentsystemnameserver(dnsserverids[socketno]);\r
+    destination := getcurrentsystemnameserverbin(dnsserverids[socketno]);\r
   end;\r
   end;\r
-  destinations[socketno] := ipstrtobinf(destination);\r
+  destinations[socketno] := destination;\r
 \r
   {$ifdef ipv6}{$ifdef win32}\r
   if destinations[socketno].family = AF_INET6 then if (requestaf = useaf_default) then requestaf := useaf_preferv6;\r
 \r
   {$ifdef ipv6}{$ifdef win32}\r
   if destinations[socketno].family = AF_INET6 then if (requestaf = useaf_default) then requestaf := useaf_preferv6;\r
@@ -255,8 +255,6 @@ begin
     exit;\r
   end;\r
 \r
     exit;\r
   end;\r
 \r
-  if (overridednsserver <> '') and (addr = '') then addr := overridednsserver;\r
-\r
   if overrideaf = useaf_default then begin\r
     {$ifdef ipv6}\r
       {$ifdef win32}if not (usewindns and (addr = '')) then{$endif}\r
   if overrideaf = useaf_default then begin\r
     {$ifdef ipv6}\r
       {$ifdef win32}if not (usewindns and (addr = '')) then{$endif}\r
@@ -299,7 +297,6 @@ end;
 \r
 procedure tdnsasync.reverselookup;\r
 begin\r
 \r
 procedure tdnsasync.reverselookup;\r
 begin\r
-  if (overridednsserver <> '') and (addr = '') then addr := overridednsserver;\r
   {$ifdef win32}\r
     if usewindns and (addr = '') then begin\r
       dwas := tdnswinasync.create;\r
   {$ifdef win32}\r
     if usewindns and (addr = '') then begin\r
       dwas := tdnswinasync.create;\r
@@ -316,7 +313,6 @@ end;
 \r
 procedure tdnsasync.customlookup;\r
 begin\r
 \r
 procedure tdnsasync.customlookup;\r
 begin\r
-  if (overridednsserver <> '') and (addr = '') then addr := overridednsserver;\r
   setstate_custom(name,querytype,states[0]);\r
   numsockused := 1;\r
   asyncprocess(0);\r
   setstate_custom(name,querytype,states[0]);\r
   numsockused := 1;\r
   asyncprocess(0);\r
index 18e40c9f8c9ea8067ae55b48c23f133fea36caec..fa9eee2fc0a76c40a6eafdf764ab6e6b69ebe33f 100644 (file)
@@ -188,7 +188,8 @@ procedure populatednsserverlist;
 procedure cleardnsservercache;\r
 \r
 var\r
 procedure cleardnsservercache;\r
 \r
 var\r
-  dnsserverlist : tstringlist;\r
+  dnsserverlist : tbiniplist;\r
+  dnsserverlag:tlist;\r
 //  currentdnsserverno : integer;\r
 \r
 \r
 //  currentdnsserverno : integer;\r
 \r
 \r
@@ -196,6 +197,7 @@ var
 //id to the id of that nameserver. id should later be used to report how laggy\r
 //the servers response was and if it was timed out.\r
 function getcurrentsystemnameserver(var id:integer) :ansistring;\r
 //id to the id of that nameserver. id should later be used to report how laggy\r
 //the servers response was and if it was timed out.\r
 function getcurrentsystemnameserver(var id:integer) :ansistring;\r
+function getcurrentsystemnameserverbin(var id:integer) :tbinip;\r
 procedure reportlag(id:integer;lag:integer); //lag should be in microseconds and should be -1 to report a timeout\r
 \r
 //var\r
 procedure reportlag(id:integer;lag:integer); //lag should be in microseconds and should be -1 to report a timeout\r
 \r
 //var\r
@@ -219,9 +221,6 @@ function getquerytype(s:ansistring):integer;
 implementation\r
 \r
 uses\r
 implementation\r
 \r
 uses\r
-  {$ifdef win32}\r
-    windows,\r
-  {$endif}\r
   lcorelocalips,\r
   sysutils;\r
 \r
   lcorelocalips,\r
   sysutils;\r
 \r
@@ -605,132 +604,59 @@ recursed:
 failure:\r
   setstate_failure(state);\r
 end;\r
 failure:\r
   setstate_failure(state);\r
 end;\r
-{$ifdef win32}\r
-  const\r
-    MAX_HOSTNAME_LEN = 132;\r
-    MAX_DOMAIN_NAME_LEN = 132;\r
-    MAX_SCOPE_ID_LEN = 260    ;\r
-    MAX_ADAPTER_NAME_LENGTH = 260;\r
-    MAX_ADAPTER_ADDRESS_LENGTH = 8;\r
-    MAX_ADAPTER_DESCRIPTION_LENGTH = 132;\r
-    ERROR_BUFFER_OVERFLOW = 111;\r
-    MIB_IF_TYPE_ETHERNET = 6;\r
-    MIB_IF_TYPE_TOKENRING = 9;\r
-    MIB_IF_TYPE_FDDI = 15;\r
-    MIB_IF_TYPE_PPP = 23;\r
-    MIB_IF_TYPE_LOOPBACK = 24;\r
-    MIB_IF_TYPE_SLIP = 28;\r
-\r
-\r
-  type\r
-    tip_addr_string=packed record\r
-      Next :pointer;\r
-      IpAddress : array[0..15] of ansichar;\r
-      ipmask    : array[0..15] of ansichar;\r
-      context   : dword;\r
-    end;\r
-    pip_addr_string=^tip_addr_string;\r
-    tFIXED_INFO=packed record\r
-       HostName         : array[0..MAX_HOSTNAME_LEN-1] of ansichar;\r
-       DomainName       : array[0..MAX_DOMAIN_NAME_LEN-1] of ansichar;\r
-       currentdnsserver : pip_addr_string;\r
-       dnsserverlist    : tip_addr_string;\r
-       nodetype         : longint;\r
-       ScopeId          : array[0..MAX_SCOPE_ID_LEN + 4] of ansichar;\r
-       enablerouting    : longbool;\r
-       enableproxy      : longbool;\r
-       enabledns        : longbool;\r
-    end;\r
-    pFIXED_INFO=^tFIXED_INFO;\r
 \r
 \r
-  var\r
-    iphlpapi : thandle;\r
-    getnetworkparams : function(pFixedInfo : PFIXED_INFO;OutBufLen : plongint) : longint;stdcall;\r
-{$endif}\r
+\r
 procedure populatednsserverlist;\r
 var\r
 procedure populatednsserverlist;\r
 var\r
-  {$ifdef win32}\r
-    fixed_info : pfixed_info;\r
-    fixed_info_len : longint;\r
-    currentdnsserver : pip_addr_string;\r
-  {$else}\r
-    t:textfile;\r
-    s:ansistring;\r
-    a:integer;\r
-  {$endif}\r
+  a:integer;\r
 begin\r
 begin\r
-  //result := '';\r
-  if assigned(dnsserverlist) then begin\r
-    dnsserverlist.clear;\r
+  if assigned(dnsserverlag) then begin\r
+    dnsserverlag.clear;\r
   end else begin\r
   end else begin\r
-    dnsserverlist := tstringlist.Create;\r
+    dnsserverlag := tlist.Create;\r
   end;\r
   end;\r
-  {$ifdef win32}\r
-    if iphlpapi=0 then iphlpapi := loadlibrary('iphlpapi.dll');\r
-    if not assigned(getnetworkparams) then @getnetworkparams := getprocaddress(iphlpapi,'GetNetworkParams');\r
-    if not assigned(getnetworkparams) then exit;\r
-    fixed_info_len := 0;\r
-    if GetNetworkParams(nil,@fixed_info_len)<>ERROR_BUFFER_OVERFLOW then exit;\r
-    //fixed_info_len :=sizeof(tfixed_info);\r
-    getmem(fixed_info,fixed_info_len);\r
-    if GetNetworkParams(fixed_info,@fixed_info_len)<>0 then begin\r
-      freemem(fixed_info);\r
-      exit;\r
-    end;\r
-    currentdnsserver := @(fixed_info.dnsserverlist);\r
-    while assigned(currentdnsserver) do begin\r
-      dnsserverlist.Add(currentdnsserver.IpAddress);\r
-      currentdnsserver := currentdnsserver.next;\r
-    end;\r
-    freemem(fixed_info);\r
-  {$else}\r
-    filemode := 0;\r
-    assignfile(t,'/etc/resolv.conf');\r
-    {$i-}reset(t);{$i+}\r
-    if ioresult <> 0 then exit;\r
-\r
-    while not eof(t) do begin\r
-      readln(t,s);\r
-      if not (copy(s,1,10) = 'nameserver') then continue;\r
-      s := copy(s,11,500);\r
-      while s <> '' do begin\r
-        if (s[1] = #32) or (s[1] = #9) then s := copy(s,2,500) else break;\r
-      end;\r
-      a := pos(' ',s);\r
-      if a <> 0 then s := copy(s,1,a-1);\r
-      a := pos(#9,s);\r
-      if a <> 0 then s := copy(s,1,a-1);\r
-      //result := s;\r
-      //if result <> '' then break;\r
-      dnsserverlist.Add(s);\r
-    end;\r
-    close(t);\r
-  {$endif}\r
+\r
+  dnsserverlist := getsystemdnsservers;\r
+  for a := biniplist_getcount(dnsserverlist)-1 downto 0 do dnsserverlag.Add(nil);\r
 end;\r
 \r
 procedure cleardnsservercache;\r
 begin\r
 end;\r
 \r
 procedure cleardnsservercache;\r
 begin\r
-  if assigned(dnsserverlist) then begin\r
-    dnsserverlist.destroy;\r
-    dnsserverlist := nil;\r
+  if assigned(dnsserverlag) then begin\r
+    dnsserverlag.destroy;\r
+    dnsserverlag := nil;\r
+    dnsserverlist := '';\r
   end;\r
 end;\r
 \r
   end;\r
 end;\r
 \r
-function getcurrentsystemnameserver(var id:integer):ansistring;\r
+function getcurrentsystemnameserverbin(var id:integer):tbinip;\r
 var\r
   counter : integer;\r
 var\r
   counter : integer;\r
-\r
 begin\r
 begin\r
-  if not assigned(dnsserverlist) then populatednsserverlist;\r
-  if dnsserverlist.count=0 then raise exception.create('no dns servers availible');\r
-  id := 0;\r
-  if dnsserverlist.count >1 then begin\r
+  {override the name server choice here, instead of overriding it whereever it's called\r
+  setting ID to -1 causes it to be ignored in reportlag}\r
+  if (overridednsserver <> '') then begin\r
+    result := ipstrtobinf(overridednsserver);\r
+    if result.family <> 0 then begin\r
+      id := -1;\r
+      exit;\r
+    end;\r
+  end;\r
 \r
 \r
-    for counter := 1 to dnsserverlist.count-1 do begin\r
-      if taddrint(dnsserverlist.objects[counter]) < taddrint(dnsserverlist.objects[id]) then id := counter;\r
+  if not assigned(dnsserverlag) then populatednsserverlist;\r
+  if dnsserverlag.count=0 then raise exception.create('no dns servers availible');\r
+  id := 0;\r
+  if dnsserverlag.count >1 then begin\r
+    for counter := dnsserverlag.count-1 downto 1 do begin\r
+      if taddrint(dnsserverlag[counter]) < taddrint(dnsserverlag[id]) then id := counter;\r
     end;\r
   end;\r
     end;\r
   end;\r
-  result := dnsserverlist[id]\r
+  result := biniplist_get(dnsserverlist,id);\r
+end;\r
+\r
+function getcurrentsystemnameserver(var id:integer):ansistring;\r
+begin\r
+  result := ipbintostr(getcurrentsystemnameserverbin(id));\r
 end;\r
 \r
 procedure reportlag(id:integer;lag:integer); //lag should be in microseconds and should be -1 to report a timeout\r
 end;\r
 \r
 procedure reportlag(id:integer;lag:integer); //lag should be in microseconds and should be -1 to report a timeout\r
@@ -738,12 +664,12 @@ var
   counter : integer;\r
   temp : integer;\r
 begin\r
   counter : integer;\r
   temp : integer;\r
 begin\r
-  if (id < 0) or (id >= dnsserverlist.count) then exit;\r
+  if (id < 0) or (id >= dnsserverlag.count) then exit;\r
   if lag = -1 then lag := timeoutlag;\r
   if lag = -1 then lag := timeoutlag;\r
-  for counter := 0 to dnsserverlist.count-1 do begin\r
-    temp := taddrint(dnsserverlist.objects[counter]) *15;\r
+  for counter := 0 to dnsserverlag.count-1 do begin\r
+    temp := taddrint(dnsserverlag[counter]) *15;\r
     if counter=id then temp := temp + lag;\r
     if counter=id then temp := temp + lag;\r
-    dnsserverlist.objects[counter] := tobject(temp div 16);\r
+    dnsserverlag[counter] := tobject(temp div 16);\r
   end;\r
 \r
 end;\r
   end;\r
 \r
 end;\r
index c603b9267a892b071ec96631dca3fa4e5d371539..1a506d5a93a92676ae1e39695f53554613f2c89b 100644 (file)
@@ -109,7 +109,7 @@ end;
 \r
 function sendquery(socknum:integer;const packet:tdnspacket;len:integer):boolean;\r
 var\r
 \r
 function sendquery(socknum:integer;const packet:tdnspacket;len:integer):boolean;\r
 var\r
-  addr       : ansistring;\r
+  ip       : tbinip;\r
   port       : ansistring;\r
   inaddr     : TInetSockAddrV;\r
 begin\r
   port       : ansistring;\r
   inaddr     : TInetSockAddrV;\r
 begin\r
@@ -117,14 +117,14 @@ begin
   result := false;\r
   if len = 0 then exit; {no packet}\r
 \r
   result := false;\r
   if len = 0 then exit; {no packet}\r
 \r
-  if overridednsserver <> '' then addr := overridednsserver else addr := getcurrentsystemnameserver(id);\r
+  ip := getcurrentsystemnameserverbin(id);\r
 \r
   {$ifdef ipv6}{$ifdef win32}\r
   if toaddr[socknum].family = AF_INET6 then if (useaf = 0) then useaf := useaf_preferv6;\r
   {$endif}{$endif}\r
 \r
   port := toport;\r
 \r
   {$ifdef ipv6}{$ifdef win32}\r
   if toaddr[socknum].family = AF_INET6 then if (useaf = 0) then useaf := useaf_preferv6;\r
   {$endif}{$endif}\r
 \r
   port := toport;\r
-  toaddr[socknum] := ipstrtobinf(addr);\r
+  toaddr[socknum] := ip;\r
   makeinaddrv(toaddr[socknum],port,inaddr);\r
 \r
   sendto(fd[socknum],packet,len,0,inaddr,inaddrsize(inaddr));\r
   makeinaddrv(toaddr[socknum],port,inaddr);\r
 \r
   sendto(fd[socknum],packet,len,0,inaddr,inaddrsize(inaddr));\r
@@ -137,16 +137,14 @@ var
   inAddrtemp : TInetSockAddrV;\r
   a:integer;\r
   biniptemp:tbinip;\r
   inAddrtemp : TInetSockAddrV;\r
   a:integer;\r
   biniptemp:tbinip;\r
-  addr:ansistring;\r
+\r
 begin\r
   //init both sockets smultaneously, always, so they get succesive fd's\r
   if fd[0] > 0 then exit;\r
 \r
 begin\r
   //init both sockets smultaneously, always, so they get succesive fd's\r
   if fd[0] > 0 then exit;\r
 \r
-  if overridednsserver <> '' then addr := overridednsserver else addr := getcurrentsystemnameserver(id);\r
+  biniptemp := getcurrentsystemnameserverbin(id);\r
   //must get the DNS server here so we know to init v4 or v6\r
 \r
   //must get the DNS server here so we know to init v4 or v6\r
 \r
-  ipstrtobin(addr,biniptemp);\r
-\r
   if biniptemp.family = AF_INET6 then biniptemp := ipstrtobinf('::') else biniptemp := ipstrtobinf('0.0.0.0');\r
 \r
 \r
   if biniptemp.family = AF_INET6 then biniptemp := ipstrtobinf('::') else biniptemp := ipstrtobinf('0.0.0.0');\r
 \r
 \r
@@ -255,7 +253,7 @@ begin
         fillchar(state[socknum].recvpacket,sizeof(state[socknum].recvpacket),0);\r
         msectotimeval(lag,(currenttime-sendquerytime[socknum]) and tsmask);\r
 \r
         fillchar(state[socknum].recvpacket,sizeof(state[socknum].recvpacket),0);\r
         msectotimeval(lag,(currenttime-sendquerytime[socknum]) and tsmask);\r
 \r
-        if overridednsserver = '' then reportlag(id,(lag.tv_sec*1000000)+lag.tv_usec);\r
+        reportlag(id,(lag.tv_sec*1000000)+lag.tv_usec);\r
 \r
         SrcLen := SizeOf(Src);\r
         state[socknum].recvpacketlen := recvfrom(fd[socknum],state[socknum].recvpacket, SizeOf(state[socknum].recvpacket),0,Srcx,SrcLen);\r
 \r
         SrcLen := SizeOf(Src);\r
         state[socknum].recvpacketlen := recvfrom(fd[socknum],state[socknum].recvpacket, SizeOf(state[socknum].recvpacket),0,Srcx,SrcLen);\r
@@ -278,7 +276,7 @@ begin
 \r
       currenttime := getts;\r
 \r
 \r
       currenttime := getts;\r
 \r
-      if overridednsserver = '' then reportlag(id,-1);\r
+      reportlag(id,-1);\r
       if (currenttime >= endtime) and ((not wrapmode) or (currenttime < starttime)) then begin\r
         exit;\r
       end else begin\r
       if (currenttime >= endtime) and ((not wrapmode) or (currenttime < starttime)) then begin\r
         exit;\r
       end else begin\r
index 7e03c1bc606541b091226989edf2012a89c91aa7..d20a04f3de223053b4f53d35975e658268edef50 100644 (file)
@@ -4,7 +4,10 @@
   ----------------------------------------------------------------------------- }
 
 {
   ----------------------------------------------------------------------------- }
 
 {
-unit to get IP addresses assigned to local interfaces.
+unit to get various local system config
+
+
+- get IP addresses assigned to local interfaces.
 both IPv4 and IPv6, or one address family in isolation.
 works on both windows and linux.
 
 both IPv4 and IPv6, or one address family in isolation.
 works on both windows and linux.
 
@@ -17,6 +20,12 @@ notes:
   an app that doesn't want link local IPs has to filter them out.
   windows XP returns only one, global scope, v6 IP, due to shortcomings.
 
   an app that doesn't want link local IPs has to filter them out.
   windows XP returns only one, global scope, v6 IP, due to shortcomings.
 
+
+
+- get system DNS servers
+
+- get system hostname
+
 }
 
 unit lcorelocalips;
 }
 
 unit lcorelocalips;
@@ -33,6 +42,9 @@ function getv4localips:tbiniplist;
 function getv6localips:tbiniplist;
 {$endif}
 
 function getv6localips:tbiniplist;
 {$endif}
 
+function getsystemdnsservers:tbiniplist;
+function getsystemhostname:ansistring;
+
 implementation
 
 {$ifdef linux}
 implementation
 
 {$ifdef linux}
@@ -130,7 +142,7 @@ end;
 {$else}
 
 uses
 {$else}
 
 uses
-  sysutils,winsock,dnssync;
+  sysutils,windows,winsock,dnssync;
 
 {the following code's purpose is to determine what IP windows would come from, to reach an IP
 it can be abused to find if there's any global v6 IPs on a local interface}
 
 {the following code's purpose is to determine what IP windows would come from, to reach an IP
 it can be abused to find if there's any global v6 IPs on a local interface}
@@ -222,4 +234,150 @@ end;
 
 
 
 
 
 
+
+
+{$ifdef win32}
+  const
+    MAX_HOSTNAME_LEN = 132;
+    MAX_DOMAIN_NAME_LEN = 132;
+    MAX_SCOPE_ID_LEN = 260    ;
+    MAX_ADAPTER_NAME_LENGTH = 260;
+    MAX_ADAPTER_ADDRESS_LENGTH = 8;
+    MAX_ADAPTER_DESCRIPTION_LENGTH = 132;
+    ERROR_BUFFER_OVERFLOW = 111;
+    MIB_IF_TYPE_ETHERNET = 6;
+    MIB_IF_TYPE_TOKENRING = 9;
+    MIB_IF_TYPE_FDDI = 15;
+    MIB_IF_TYPE_PPP = 23;
+    MIB_IF_TYPE_LOOPBACK = 24;
+    MIB_IF_TYPE_SLIP = 28;
+
+
+  type
+    tip_addr_string=packed record
+      Next :pointer;
+      IpAddress : array[0..15] of ansichar;
+      ipmask    : array[0..15] of ansichar;
+      context   : dword;
+    end;
+    pip_addr_string=^tip_addr_string;
+    tFIXED_INFO=packed record
+       HostName         : array[0..MAX_HOSTNAME_LEN-1] of ansichar;
+       DomainName       : array[0..MAX_DOMAIN_NAME_LEN-1] of ansichar;
+       currentdnsserver : pip_addr_string;
+       dnsserverlist    : tip_addr_string;
+       nodetype         : longint;
+       ScopeId          : array[0..MAX_SCOPE_ID_LEN + 4] of ansichar;
+       enablerouting    : longbool;
+       enableproxy      : longbool;
+       enabledns        : longbool;
+    end;
+    pFIXED_INFO=^tFIXED_INFO;
+
+  var
+    iphlpapi : thandle;
+    getnetworkparams : function(pFixedInfo : PFIXED_INFO;OutBufLen : plongint) : longint;stdcall;
+
+function callGetNetworkParams:pFIXED_INFO;
+var
+    fixed_info : pfixed_info;
+    fixed_info_len : longint;
+begin
+  result := nil;
+  if iphlpapi=0 then iphlpapi := loadlibrary('iphlpapi.dll');
+    if not assigned(getnetworkparams) then @getnetworkparams := getprocaddress(iphlpapi,'GetNetworkParams');
+    if not assigned(getnetworkparams) then exit;
+    fixed_info_len := 0;
+    if GetNetworkParams(nil,@fixed_info_len)<>ERROR_BUFFER_OVERFLOW then exit;
+    //fixed_info_len :=sizeof(tfixed_info);
+    getmem(fixed_info,fixed_info_len);
+    if GetNetworkParams(fixed_info,@fixed_info_len)<>0 then begin
+      freemem(fixed_info);
+      exit;
+    end;
+    result := fixed_info;
+end;
+
+{$endif}
+
+function getsystemdnsservers:tbiniplist;
+var
+  {$ifdef win32}
+    fixed_info : pfixed_info;
+    currentdnsserver : pip_addr_string;
+  {$else}
+    t:textfile;
+    s:ansistring;
+    a:integer;
+  {$endif}
+  ip:tbinip;
+begin
+  //result := '';
+
+  result := biniplist_new;
+
+  {$ifdef win32}
+    fixed_info := callgetnetworkparams;
+    if fixed_info = nil then exit;
+
+    currentdnsserver := @(fixed_info.dnsserverlist);
+    while assigned(currentdnsserver) do begin
+      ip := ipstrtobinf(currentdnsserver.IpAddress);
+      if (ip.family <> 0) then biniplist_add(result,ip);
+      currentdnsserver := currentdnsserver.next;
+    end;
+    freemem(fixed_info);
+  {$else}
+    filemode := 0;
+    assignfile(t,'/etc/resolv.conf');
+    {$i-}reset(t);{$i+}
+    if ioresult <> 0 then exit;
+
+    while not eof(t) do begin
+      readln(t,s);
+      if not (copy(s,1,10) = 'nameserver') then continue;
+      s := copy(s,11,500);
+      while s <> '' do begin
+        if (s[1] = #32) or (s[1] = #9) then s := copy(s,2,500) else break;
+      end;
+      a := pos(' ',s);
+      if a <> 0 then s := copy(s,1,a-1);
+      a := pos(#9,s);
+      if a <> 0 then s := copy(s,1,a-1);
+
+      ip := ipstrtobinf(s);
+      if (ip.family <> 0) then biniplist_add(result,ip);
+    end;
+    closefile(t);
+  {$endif}
+end;
+
+
+function getsystemhostname:ansistring;
+var
+  {$ifdef win32}
+    fixed_info : pfixed_info;
+  {$else}
+    t:textfile;
+  {$endif}
+begin
+  result := '';
+  {$ifdef win32}
+    fixed_info := callgetnetworkparams;
+    if fixed_info = nil then exit;
+
+    result := fixed_info.hostname;
+    if fixed_info.domainname <> '' then result := result + '.'+fixed_info.domainname;
+
+    freemem(fixed_info);
+  {$else}
+    filemode := 0;
+    assignfile(t,'/etc/hostname');
+    {$i-}reset(t);{$i+}
+    if ioresult <> 0 then exit;
+    readln(t,result);
+    closefile(t);
+  {$endif}
+end;
+
 end.
 end.