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

/*
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
}