reorganization of system dns servers code
[lcore.git] / lcorelocalips.pas
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.