You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
2.6 KiB
138 lines
2.6 KiB
/* |
|
Package giplib implements simple routines for |
|
retrieving one's IPv4 and IPv6 addresses from |
|
various DNS providers. For now it implements |
|
OpenDNS for IPv4 and IPv6, Google for IPv4 and |
|
IPv6 and Akamai for IPv4 |
|
*/ |
|
package giplib |
|
|
|
import ( |
|
"github.com/miekg/dns" |
|
) |
|
|
|
var ( |
|
c *dns.Client |
|
m *dns.Msg |
|
ipv4, ipv6 string |
|
) |
|
|
|
/* |
|
dig {-4,-6} +short myip.opendns.com @resolver1.opendns.com |
|
dig {-4,-6} TXT +short o-o.myaddr.l.google.com @ns1.google.com |
|
dig -4 @ns1-1.akamaitech.net whoami.akamai.net +short |
|
*/ |
|
|
|
func init() { |
|
c = new(dns.Client) |
|
m = &dns.Msg{ |
|
MsgHdr: dns.MsgHdr{ |
|
RecursionDesired: true, |
|
}, |
|
Question: make([]dns.Question, 1), |
|
} |
|
|
|
} |
|
|
|
//GetOpenDNS4 will retrieve the IPv4 public IP as seen by OpenDNS |
|
func GetOpenDNS4() string { |
|
nameserver := dns.Fqdn("ns1-1.akamaitech.net") + ":53" |
|
c.Net = "udp4" |
|
m.SetQuestion("whoami.akamai.net.", dns.TypeA) |
|
r4, _, e4 := c.Exchange(m, nameserver) |
|
|
|
if e4 != nil { |
|
ipv4 = "" |
|
} else { |
|
ipv4 = getIP(r4.Answer) |
|
} |
|
|
|
return ipv4 |
|
} |
|
|
|
//GetOpenDNS6 will retrieve the IPv6 IP as seen by OpenDNS |
|
func GetOpenDNS6() string { |
|
nameserver := dns.Fqdn("resolver1.opendns.com") + ":53" |
|
|
|
c.Net = "udp6" |
|
m.SetQuestion("myip.opendns.com.", dns.TypeAAAA) |
|
r6, _, e6 := c.Exchange(m, nameserver) |
|
|
|
if e6 != nil { |
|
ipv6 = "" |
|
} else { |
|
ipv6 = getIP(r6.Answer) |
|
} |
|
|
|
return ipv6 |
|
} |
|
|
|
//GetGoogle4 will retrieve the IPv4 public IP as seen by Google |
|
func GetGoogle4() string { |
|
nameserver := dns.Fqdn("ns1.google.com") + ":53" |
|
|
|
c.Net = "udp4" |
|
m.SetQuestion("o-o.myaddr.l.google.com.", dns.TypeTXT) |
|
r4, _, e4 := c.Exchange(m, nameserver) |
|
|
|
if e4 != nil { |
|
ipv4 = "" |
|
} else { |
|
ipv4 = getIP(r4.Answer) |
|
} |
|
|
|
return ipv4 |
|
} |
|
|
|
//GetGoogle6 will retrieve the IPv6 IP as seen by Google |
|
func GetGoogle6() string { |
|
nameserver := dns.Fqdn("ns1.google.com") + ":53" |
|
|
|
c.Net = "udp6" |
|
m.SetQuestion("o-o.myaddr.l.google.com.", dns.TypeTXT) |
|
r6, _, e6 := c.Exchange(m, nameserver) |
|
|
|
if e6 != nil { |
|
ipv6 = "" |
|
} else { |
|
ipv6 = getIP(r6.Answer) |
|
} |
|
|
|
return ipv6 |
|
} |
|
|
|
//GetAkamai4 will retrieve the IPv4 public IP as seen by Akamai |
|
func GetAkamai4() string { |
|
nameserver := dns.Fqdn("ns1.google.com") + ":53" |
|
|
|
c.Net = "udp4" |
|
m.SetQuestion("o-o.myaddr.l.google.com.", dns.TypeTXT) |
|
r4, _, e4 := c.Exchange(m, nameserver) |
|
|
|
if e4 != nil { |
|
ipv4 = "" |
|
} else { |
|
ipv4 = getIP(r4.Answer) |
|
} |
|
|
|
return ipv4 |
|
|
|
} |
|
|
|
func getIP(ra []dns.RR) string { |
|
//the answer will always be one IP or none |
|
var ip string |
|
for _, ansa := range ra { |
|
switch ansb := ansa.(type) { |
|
case *dns.A: |
|
ip = ansb.A.String() |
|
case *dns.AAAA: |
|
ip = ansb.AAAA.String() |
|
case *dns.TXT: |
|
// we always expect only one IP in the field |
|
ip = ansb.Txt[0] |
|
} |
|
} |
|
|
|
return ip |
|
}
|
|
|