X-Git-Url: http://www.lcore.org/git/lcore.git/blobdiff_plain/968c333d05db5d5ecf3599f8e304c67e64f21159..69598fec083b67c8567293c7b8a397b64175bd45:/lcorelocalips.pas?ds=inline diff --git a/lcorelocalips.pas b/lcorelocalips.pas index d275012..710fbfa 100644 --- a/lcorelocalips.pas +++ b/lcorelocalips.pas @@ -36,7 +36,9 @@ notes: } unit lcorelocalips; - +{$ifdef fpc} + {$mode delphi} +{$endif} interface uses binipstuff,pgtypes; @@ -51,10 +53,16 @@ function getv6localips:tbiniplist; function getsystemdnsservers:tbiniplist; +function have_ipv6_connectivity:boolean; + {$ifdef mswindows} function gethostname:ansistring; +function getlocalipforip(const ip:tbinip):tbinip; {$endif} +const + v6_check_ip='2001:200::'; //a globally routeable v6 IP that is used in "get local IP for IP" etc, it should never actually be communicated with. + implementation {$ifdef unix} @@ -270,7 +278,7 @@ begin end; try - ip := getlocalipforip(ipstrtobinf('2001:200::')); + ip := getlocalipforip(ipstrtobinf(v6_check_ip)); if (ip.family = AF_INET6) then biniplist_add(result,ip); except end; @@ -400,6 +408,54 @@ begin {$endif} end; + +function have_ipv6_connectivity:boolean; +var + l:tbiniplist; + a:integer; + ip:tbinip; + ipmask_global,ipmask_6to4,ipmask_teredo:tbinip; + +function ip_is_suitable_v6:boolean; +begin + result := false; + if (ip.family <> AF_INET6) then exit; + if not comparebinipmask(ip,ipmask_global,3) then exit; + if comparebinipmask(ip,ipmask_teredo,32) then exit; + if comparebinipmask(ip,ipmask_6to4,16) then exit; + result := true; +end; + +begin + result := false; + + ipstrtobin('2000::',ipmask_global); + ipstrtobin('2001::',ipmask_teredo); + ipstrtobin('2002::',ipmask_6to4); + + {$ifdef mswindows} + //better way on windows to check for ipv6 that works (returns no ipv6) if a v6 IP is assigned, but there is no connectivity + try + ip := getlocalipforip(ipstrtobinf(v6_check_ip)); + if ip_is_suitable_v6 then result := true; + except + end; + {$else} {unix} + + l := getv6localips; + if biniplist_getcount(l) = 0 then exit; + + {if there is any v6 IP which is globally routable and not 6to4 and not teredo, prefer v6} + for a := biniplist_getcount(l)-1 downto 0 do begin + ip := biniplist_get(l,a); + if not ip_is_suitable_v6 then continue; + result := true; + exit; + end; + {$endif} +end; + + {$ifdef mswindows} function gethostname:ansistring; var