package host import ( "net" "os" "git.giaever.org/joachimmg/go-log.git/log" "git.giaever.org/joachimmg/m-dns/errors" ) type IPvType int const ( IPv4 IPvType = iota << 1 IPv6 IPvType = iota << 1 NoIP IPvType = iota << 1 ) type HostIP interface { String() string Type() (net.IP, IPvType) AsIP() net.IP } type IP net.IP func (i IP) String() string { return i.AsIP().String() } func (i IP) AsIP() net.IP { return net.IP(i) } func (i IP) Type() (net.IP, IPvType) { if ip := i.AsIP().To4(); ip != nil { switch ip.String() { case "127.0.0.1", net.IPv4zero.String(), net.IPv4bcast.String(), net.IPv4allsys.String(), net.IPv4allrouter.String(): return nil, NoIP default: return ip, IPv4 } } if ip := i.AsIP().To16(); ip != nil { switch ip.String() { case net.IPv6zero.String(), net.IPv6loopback.String(), net.IPv6unspecified.String(), net.IPv6linklocalallnodes.String(), net.IPv6linklocalallrouters.String(), net.IPv6interfacelocalallnodes.String(): return nil, NoIP default: return ip, IPv6 } } return nil, NoIP } func (i IP) validForHostname(hn HostString) (IP, error) { log.Traceln(errors.HostIP, i, hn) if _, t := i.Type(); t == NoIP { log.Traceln(errors.HostIP, errors.HostIPIsInvalid) return nil, errors.HostIPIsInvalid } f := false if lhn, _ := os.Hostname(); lhn == hn.String() { addrs, err := net.InterfaceAddrs() if err != nil { log.Traceln(errors.HostIP, err) return nil, err } for _, addr := range addrs { if addr.(*net.IPNet).Contains(i.AsIP()) { f = true break } } } else { addrs, err := net.LookupIP(hn.String()) if err != nil { log.Traceln(errors.HostIP, err) return nil, err } for _, addr := range addrs { if addr.String() == i.String() { f = true } } } if f == false { log.Traceln(errors.HostIP, errors.HostIPIsInvalid) return nil, errors.HostIPIsInvalid } return i, nil }