pkg/tools/ip.go (120 lines of code) (raw):

// Licensed to Apache Software Foundation (ASF) under one or more contributor // license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright // ownership. Apache Software Foundation (ASF) licenses this file to you under // the Apache License, Version 2.0 (the "License"); you may // not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. package tools import ( "fmt" "net" "os" ) var ( host *hostInfo ) func init() { host = queryHostInfo() } // DefaultHostIPAddress IP address of machine func DefaultHostIPAddress() string { return host.defaultIPAddr } // HostIPAddressV4 found the IPV4 address from appoint net interface name func HostIPAddressV4(name string) string { address := host.ipAddresses[name] if address == nil { return "" } return address.ipV4 } // HostIPAddressV6 found the IPV6 address from appoint net interface name func HostIPAddressV6(name string) string { address := host.ipAddresses[name] if address == nil { return "" } return address.ipV6 } // IsLocalHostAddress is the address from local func IsLocalHostAddress(address string) bool { for _, h := range host.ipAddresses { if h.ipV4 == address || h.ipV6 == address { return true } } return false } // Hostname of machine func Hostname() string { return host.name } type hostInfo struct { // hostname name string // ip address ipAddresses map[string]*hostIPAddress defaultIPAddr string } type hostIPAddress struct { ipV4 string ipV6 string } func queryHostInfo() *hostInfo { addresses, def, err := localIPAddress0() if err != nil { panic(err) } name, err := hostname0() if err != nil { panic(err) } return &hostInfo{name: name, ipAddresses: addresses, defaultIPAddr: def} } func hostname0() (string, error) { return os.Hostname() } func localIPAddress0() (ipAddresses map[string]*hostIPAddress, defAddr string, err error) { ifaces, err := net.Interfaces() if err != nil { return nil, "", err } // handle err ipAddresses = make(map[string]*hostIPAddress) var defV4, defV6 string for _, i := range ifaces { if i.Flags&net.FlagLoopback != 0 { continue } addrs, err := i.Addrs() if err != nil { return nil, "", err } ipv4, ipv6 := analyzeIPAddresses(addrs) if ipv4 != "" || ipv6 != "" { if defV4 == "" { defV4 = ipv4 } if defV6 == "" { defV6 = ipv6 } ipAddresses[i.Name] = &hostIPAddress{ipV4: ipv4, ipV6: ipv6} } } if len(ipAddresses) == 0 { return nil, "", fmt.Errorf("not found") } if defV4 != "" { defAddr = defV4 } else { defAddr = defV6 } return ipAddresses, defAddr, nil } func analyzeIPAddresses(addrs []net.Addr) (ipv4, ipv6 string) { for _, addr := range addrs { var ip net.IP switch v := addr.(type) { case *net.IPNet: ip = v.IP case *net.IPAddr: ip = v.IP } if ip.IsLoopback() { continue } if ip.To4() != nil { ipv4 = ip.To4().String() } if ip.To16() != nil { ipv6 = ip.To16().String() } } return ipv4, ipv6 }