func Addresses(nif net.Interface, v4 bool, v6 bool, retries int) ([]net.Addr, []net.Addr, error) { var v4Addrs, v6Addrs []net.Addr for n := retries; n >= 0; n-- { addrs, err := nif.Addrs() if err != nil { return nil, nil, err } v4Addrs, v6Addrs = partition(addrs) if v4 && v6 && len(v4Addrs) > 0 && len(v6Addrs) > 0 { break } else if v4 && len(v4Addrs) > 0 { v6Addrs = []net.Addr{} break } else if v6 && len(v6Addrs) > 0 { v4Addrs = []net.Addr{} break } if n > 0 { time.Sleep(1 * time.Second) } } return v4Addrs, v6Addrs, nil }
// 一个接口上的所有ip4地址 func addrsOfOneInterface(iface net.Interface) (addrs []*net.IPAddr) { ifaddrs, err := iface.Addrs() if (err != nil) || (len(ifaddrs) == 0) { return } for _, ifaddr := range ifaddrs { var ip net.IP switch v := ifaddr.(type) { case *net.IPNet: ip = v.IP case *net.IPAddr: ip = v.IP default: continue } if ip.IsLoopback() { return } ip = ip.To4() if ip != nil { addr, _ := net.ResolveIPAddr("ip", ip.String()) addrs = append(addrs, addr) } } return }
func AddressesOnInterface(iface *net.Interface) (*[]net.Addr, error) { addrs, err := iface.Addrs() if err != nil { return nil, err } return &addrs, nil }
func setSyscallIPMreq(mreq *syscall.IPMreq, ifi *net.Interface) error { if ifi == nil { return nil } ifat, err := ifi.Addrs() if err != nil { return err } for _, ifa := range ifat { switch v := ifa.(type) { case *net.IPAddr: if a := v.IP.To4(); a != nil { copy(mreq.Interface[:], a) goto done } case *net.IPNet: if a := v.IP.To4(); a != nil { copy(mreq.Interface[:], a) goto done } } } done: if bytes.Equal(mreq.Multiaddr[:], net.IPv4zero.To4()) { return errNoSuchMulticastInterface } return nil }
func updateHosts(iface *net.Interface) { addrs, err := iface.Addrs() checkErr(err) if len(addrs) == 0 { return } hostname, err := os.Hostname() checkErr(err) hosts := parseHosts() // Remove existing ips pointing to our hostname toRemove := []string{} for ip, addrs := range hosts { for _, addr := range addrs { if addr == hostname { toRemove = append(toRemove, ip) break } } } for _, ip := range toRemove { delete(hosts, ip) } // Add the weave ip(s) for _, addr := range addrs { if addr, ok := addr.(*net.IPNet); ok { ip := addr.IP.String() hosts[ip] = append(hosts[ip], hostname) } } writeHosts(hosts) }
func isGoodForMulticast(ifi *net.Interface) (net.IP, bool) { if ifi.Flags&net.FlagUp == 0 { return nil, false } // We need a unicast IPv4 address that can be used to specify // the IPv4 multicast interface. ifat, err := ifi.Addrs() if err != nil { return nil, false } if len(ifat) == 0 { return nil, false } var ip net.IP for _, ifa := range ifat { switch v := ifa.(type) { case *net.IPAddr: ip = v.IP case *net.IPNet: ip = v.IP default: continue } if ip.To4() == nil { ip = nil continue } break } if ip == nil { return nil, false } return ip, true }
func GetIfaceIP4Addr(iface *net.Interface) (net.IP, error) { addrs, err := iface.Addrs() if err != nil { return nil, err } // prefer non link-local addr var ll net.IP for _, addr := range addrs { // Attempt to parse the address in CIDR notation // and assert it is IPv4 ip, _, err := net.ParseCIDR(addr.String()) if err != nil || ip.To4() == nil { continue } if ip.IsGlobalUnicast() { return ip, nil } if ip.IsLinkLocalUnicast() { ll = ip } } if ll != nil { // didn't find global but found link-local. it'll do. return ll, nil } return nil, errors.New("No IPv4 address found for given interface") }
func getHostIPs(interfaceName string) ([]net.Addr, error) { hostInterfaces, err := net.Interfaces() if err != nil { return nil, err } var iface net.Interface for _, hostInterface := range hostInterfaces { if hostInterface.Name == interfaceName { iface = hostInterface break } } addrs, err := iface.Addrs() if err != nil { return nil, err } if len(addrs) == 0 { return nil, errors.New("no ip addresses assigned to interface") } return addrs, nil }
func ifaceToIp(iface *net.Interface) (string, error) { addrs, err := iface.Addrs() if err != nil { return "", err } 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 == nil || ip.IsLoopback() { continue } ip = ip.To4() if ip == nil { continue // not an ipv4 address } return ip.String(), nil } return "", errors.New("Node not connected to the network.") }
// isMulticastAvailable returns true if ifi is a multicast access // enabled network interface. It also returns a unicast IPv4 address // that can be used for listening on ifi. func isMulticastAvailable(ifi *net.Interface) (net.IP, bool) { if ifi.Flags&net.FlagUp == 0 || ifi.Flags&net.FlagMulticast == 0 { return nil, false } ifat, err := ifi.Addrs() if err != nil { return nil, false } if len(ifat) == 0 { return nil, false } var ip net.IP for _, ifa := range ifat { switch v := ifa.(type) { case *net.IPAddr: ip = v.IP case *net.IPNet: ip = v.IP default: continue } if ip.To4() == nil { ip = nil continue } break } return ip, true }
func (this *ssdpDefaultManager) ssdpUnicastDiscoverImpl(ifi *net.Interface, port string) (err error) { addrs, err := ifi.Addrs() if nil != err { return } else if 0 == len(addrs) { err = errors.New(fmt.Sprintf("No addresses found for interface %s", ifi.Name)) return } var lip net.IP for _, addr := range addrs { if nil != addr.(*net.IPNet).IP.DefaultMask() { lip = addr.(*net.IPNet).IP break } } laddr, err := net.ResolveUDPAddr(ssdpBroadcastVersion, net.JoinHostPort(lip.String(), port)) if nil != err { return } uc, err := net.ListenUDP(ssdpBroadcastVersion, laddr) if nil != err { return } this.unicast.addr = laddr this.unicast.conn = uc go this.ssdpDiscoverLoop(uc) <-this.readyChan return }
func getAddresses(iface net.Interface) (addresses map[string]interface{}, err error) { addresses = make(map[string]interface{}) addrs, err := iface.Addrs() if err != nil { return nil, err } for _, addr := range addrs { var ip net.IP addressInfo := make(map[string]string) switch v := addr.(type) { case *net.IPNet: ip = v.IP case *net.IPAddr: ip = v.IP } netmask := ip.DefaultMask() if netmask != nil { addressInfo["family"] = "inet" } else { addressInfo["family"] = "inet6" } addresses[ip.String()] = addressInfo } mac := iface.HardwareAddr if mac != nil { addressInfo := make(map[string]string) addressInfo["family"] = "lladdr" addresses[mac.String()] = addressInfo } return }
func (_ networkInterface) Addrs(intf *net.Interface) ([]net.Addr, error) { addrs, err := intf.Addrs() if err != nil { return nil, err } return addrs, nil }
func interfaceIP(iface *net.Interface) (net.IP, error) { addrs, err := iface.Addrs() if err != nil { return nil, err } fs := [](func(net.IP) bool){ net.IP.IsGlobalUnicast, net.IP.IsLinkLocalUnicast, net.IP.IsLoopback, } for _, f := range fs { for _, a := range addrs { ipaddr, ok := a.(*net.IPNet) if !ok { continue } ip := ipaddr.IP.To4() if ip == nil { continue } if f(ip) { return ip, nil } } } return nil, fmt.Errorf("interface %s has no usable unicast addresses", iface.Name) }
func getInterface(in net.Interface) ([]net.Addr, string) { addrs, err := in.Addrs() if err != nil { return nil, "" } if len(addrs) == 0 { return nil, "" } return addrs, in.Name }
// Start the mDNS server func (s *MDNSServer) Start(ifi *net.Interface) (err error) { // skip double initialization if s.running { return nil } // This is a bit of a kludge - per the RFC we should send responses from 5353, but that doesn't seem to work s.sendconn, err = net.ListenUDP("udp4", &net.UDPAddr{IP: net.IPv4zero, Port: 0}) if err != nil { return err } conn, err := LinkLocalMulticastListener(ifi) if err != nil { return err } if ifi == nil { s.localAddrs, err = net.InterfaceAddrs() } else { s.localAddrs, err = ifi.Addrs() } if err != nil { return err } handleLocal := s.makeHandler(dns.TypeA, func(zone ZoneLookup, r *dns.Msg, q *dns.Question) *dns.Msg { if ips, err := zone.LookupName(q.Name); err == nil { return makeAddressReply(r, q, ips) } return nil }) handleReverse := s.makeHandler(dns.TypePTR, func(zone ZoneLookup, r *dns.Msg, q *dns.Question) *dns.Msg { if names, err := zone.LookupInaddr(q.Name); err == nil { return makePTRReply(r, q, names) } return nil }) mux := dns.NewServeMux() mux.HandleFunc(s.zone.Domain(), handleLocal) mux.HandleFunc(RDNSDomain, handleReverse) s.srv = &dns.Server{ Listener: nil, PacketConn: conn, Handler: mux, } go s.srv.ActivateAndServe() s.running = true return err }
// ParseAdvertise parses the --cluster-advertise daemon config which accepts // <ip-address>:<port> or <interface-name>:<port> func ParseAdvertise(advertise string) (string, error) { var ( iface *net.Interface addrs []net.Addr err error ) addr, port, err := net.SplitHostPort(advertise) if err != nil { return "", fmt.Errorf("invalid --cluster-advertise configuration: %s: %v", advertise, err) } ip := net.ParseIP(addr) // If it is a valid ip-address, use it as is if ip != nil { return advertise, nil } // If advertise is a valid interface name, get the valid IPv4 address and use it to advertise ifaceName := addr iface, err = net.InterfaceByName(ifaceName) if err != nil { return "", fmt.Errorf("invalid cluster advertise IP address or interface name (%s) : %v", advertise, err) } addrs, err = iface.Addrs() if err != nil { return "", fmt.Errorf("unable to get advertise IP address from interface (%s) : %v", advertise, err) } if len(addrs) == 0 { return "", fmt.Errorf("no available advertise IP address in interface (%s)", advertise) } addr = "" for _, a := range addrs { ip, _, err := net.ParseCIDR(a.String()) if err != nil { return "", fmt.Errorf("error deriving advertise ip-address in interface (%s) : %v", advertise, err) } if ip.To4() == nil || ip.IsLoopback() { continue } addr = ip.String() break } if addr == "" { return "", fmt.Errorf("could not find a valid ip-address in interface %s", advertise) } addr = net.JoinHostPort(addr, port) return addr, nil }
func ipAssigned(iface *net.Interface, ip net.IP) bool { addrs, _ := iface.Addrs() for _, addr := range addrs { args := strings.SplitN(addr.String(), "/", 2) if args[0] == ip.String() { return true } } return false }
func scan(iface *net.Interface, interval time.Duration, queue NodeQueue) error { //look for IPv4 address on the interface var addr *net.IPNet addrs, err := iface.Addrs() if err != nil { return fmt.Errorf("could not get addresses: %s", err) } for _, a := range addrs { if ipnet, ok := a.(*net.IPNet); ok { if ip4 := ipnet.IP.To4(); ip4 != nil { addr = &net.IPNet{ IP: ip4, Mask: ipnet.Mask[len(ipnet.Mask)-4:], } break } } } // Sanity-check that the interface has a good address. if addr == nil { return fmt.Errorf("no good IP network found") } else if addr.IP[0] == 127 { return fmt.Errorf("skipping localhost") } else if addr.Mask[0] != 0xff || addr.Mask[1] != 0xff { return fmt.Errorf("mask means network is too large") } log.Printf("Using network range %v for interface %v", addr, iface.Name) // Open up a pcap handle for packet reads/writes. handle, err := pcap.OpenLive(iface.Name, 65536, true, pcap.BlockForever) if err != nil { return err } defer handle.Close() // Start up a goroutine to read in packet data. stop := make(chan bool) go readARP(handle, iface, stop, queue) defer close(stop) for { // Write our scan packets out to the handle. if err := writeARP(handle, iface, addr); err != nil { return fmt.Errorf("writing packets: %v", err) } time.Sleep(interval) } }
// scan scans an individual interface's local network for machines using ARP requests/replies. // // scan loops forever, sending packets out regularly. It returns an error if // it's ever unable to write a packet. func scan(iface *net.Interface) error { // We just look for IPv4 addresses, so try to find if the interface has one. var addr *net.IPNet if addrs, err := iface.Addrs(); err != nil { return err } else { for _, a := range addrs { if ipnet, ok := a.(*net.IPNet); ok { if ip4 := ipnet.IP.To4(); ip4 != nil { addr = &net.IPNet{ IP: ip4, Mask: ipnet.Mask[len(ipnet.Mask)-4:], } break } } } } // Sanity-check that the interface has a good address. if addr == nil { return fmt.Errorf("no good IP network found") } else if addr.IP[0] == 127 { return fmt.Errorf("skipping localhost") } else if addr.Mask[0] != 0xff || addr.Mask[1] != 0xff { return fmt.Errorf("mask means network is too large") } log.Printf("Using network range %v for interface %v", addr, iface.Name) // Open up a pcap handle for packet reads/writes. handle, err := pcap.OpenLive(iface.Name, 65536, true, pcap.BlockForever) if err != nil { return err } defer handle.Close() // Start up a goroutine to read in packet data. stop := make(chan struct{}) go readARP(handle, iface, stop) defer close(stop) for { // Write our scan packets out to the handle. if err := writeARP(handle, iface, addr); err != nil { log.Printf("error writing packets on %v: %v", iface.Name, err) return err } // We don't know exactly how long it'll take for packets to be // sent back to us, but 10 seconds should be more than enough // time ;) time.Sleep(10 * time.Second) } }
func defaultIP(iface *net.Interface) (net.IP, error) { addrs, err := iface.Addrs() if err != nil { return nil, err } for _, addr := range addrs { if ifa, ok := addr.(*net.IPNet); ok { if ifa.IP.To4() != nil { return ifa.IP, nil } } } return nil, fmt.Errorf("couldn't find a valid address :(") }
// Take in an interface name ("lo", "eth0", "any") passed from either // a config setting or by -interface command line flag and return the IP // address associated with it. // If no interface is provided use the default loopback interface (127.0.0.1). // If "any" is passed then listen on 0.0.0.0 func GetInterfaceIPAddress(listenInterface string) (string, error) { var ip net.IP if listenInterface == "" { ip = net.ParseIP("127.0.0.1") } else if listenInterface == "any" { ip = net.ParseIP("0.0.0.0") } else { //Get a list of interfaces availableInterfaces, err := net.Interfaces() if err != nil { return "", ContextError(err) } var selectedInterface net.Interface found := false for _, networkInterface := range availableInterfaces { if listenInterface == networkInterface.Name { NoticeInfo("Using interface: %s", networkInterface.Name) selectedInterface = networkInterface found = true break } } if !found { NoticeAlert("Interface not found: %s", listenInterface) ip = net.ParseIP("127.0.0.1") } else { netAddrs, err := selectedInterface.Addrs() if err != nil { return "", ContextError(err) } for _, ipAddr := range netAddrs { ip, _, err = net.ParseCIDR(ipAddr.String()) if err != nil { return "", ContextError(err) } if ip.To4() != nil { break } } } } NoticeInfo("Listening on IP address: %s", ip.String()) return ip.String(), nil }
// Get an IPv4 address for a given interface. func interfaceIP4(iface *net.Interface) net.IP { addrs, err := iface.Addrs() if err != nil { return nil } for _, n := range addrs { ip, _, err := net.ParseCIDR(n.String()) if err == nil { if ip4 := ip.To4(); ip4 != nil { return ip4 } } } return nil }
// Helper function to get the interfaces IP address. func ip(i net.Interface) (string, error) { addrs, err := i.Addrs() if err != nil { return "", err } for _, addr := range addrs { if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { if ipnet.IP.To4() != nil { return ipnet.IP.String(), nil } } } return "", errors.New("Cannot find IP address for interface") }
func GetIp(iface *net.Interface) string { addrs, _ := iface.Addrs() ipAddrs := []string{} for _, addr := range addrs { if ip, ok := addr.(*net.IPAddr); ok && !ip.IP.IsUnspecified() { ipAddrs = append(ipAddrs, addr.String()) } } if len(ipAddrs) > 0 { return ipAddrs[0] } else { return "" } }
func findIPInNetworkFromIface(dstIP net.IP, iface net.Interface) (net.IP, error) { addrs, err := iface.Addrs() if err != nil { return nil, err } for _, a := range addrs { if ipnet, ok := a.(*net.IPNet); ok { if ipnet.Contains(dstIP) { return ipnet.IP, nil } } } return nil, fmt.Errorf("iface: '%s' can't reach ip: '%s'", iface.Name, dstIP) }
// NewClient creates a new Client using the specified network interface. // NewClient retrieves the IPv4 address of the interface and binds a raw socket // to send and receive ARP packets. func NewClient(ifi *net.Interface) (*Client, error) { // Open raw socket to send and receive ARP packets using ethernet frames // we build ourselves p, err := raw.ListenPacket(ifi, raw.ProtocolARP) if err != nil { return nil, err } // Check for usable IPv4 addresses for the Client addrs, err := ifi.Addrs() if err != nil { return nil, err } return newClient(ifi, p, addrs) }
// selectNetwork attempts to find a network that contains the given IP address // on the given interface. If an appropriate network is not found, and there // no other errors, (nil, nil) is returned. func selectNetwork(iface *net.Interface, ip net.IP) (*net.IPNet, error) { addrs, err := iface.Addrs() if err != nil { return nil, fmt.Errorf("Failed to get addresses for interface %q: %v", iface.Name, err) } for _, addr := range addrs { ipStr := addr.String() _, ipNet, err := net.ParseCIDR(ipStr) if err != nil { return nil, fmt.Errorf("Failed to parse interface address %q - %v: %v", iface.Name, ipStr, err) } if ipNet.Contains(ip) { return ipNet, nil } } return nil, nil }
func GetIfaceIP4Addr(iface *net.Interface) (net.IP, error) { addrs, err := iface.Addrs() if err != nil { return nil, err } for _, addr := range addrs { // Attempt to parse the address in CIDR notation // and assert it is IPv4 ip, _, err := net.ParseCIDR(addr.String()) if err == nil && ip.To4() != nil { return ip.To4(), nil } } return nil, errors.New("No IPv4 address found for given interface") }
// findNetwork returns the network for the given IP address on the given // interface. If the address is not configured on the interface, an error is // returned. func findNetwork(iface *net.Interface, ip net.IP) (*net.IPNet, error) { addrs, err := iface.Addrs() if err != nil { return nil, fmt.Errorf("Failed to get addresses for interface %q: %v", iface.Name, err) } for _, addr := range addrs { ipStr := addr.String() ipAddr, ipNet, err := net.ParseCIDR(ipStr) if err != nil { return nil, fmt.Errorf("Failed to parse interface address %q - %v: %v", iface.Name, ipStr, err) } if ipAddr.Equal(ip) { return ipNet, nil } } return nil, fmt.Errorf("Failed to find IP %v on interface %q", ip, iface.Name) }