----------------------------------------------------------------------------- }
{
-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.
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;
function getv6localips:tbiniplist;
{$endif}
+function getsystemdnsservers:tbiniplist;
+function getsystemhostname:ansistring;
+
implementation
{$ifdef linux}
{$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}
+
+
+{$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.