func GetPort(address net.IP) string { if address.Equal(net.IPv4(127, 0, 0, 1)) { return ":8000" //It would be silly to do something funny on your own computer } port := ComputeHash(address) return ":" + strconv.Itoa(port) }
// NewProxier returns a new Proxier given a LoadBalancer and an address on // which to listen. Because of the iptables logic, It is assumed that there // is only a single Proxier active on a machine. func NewProxier(loadBalancer LoadBalancer, listenIP net.IP, iptables iptables.Interface) *Proxier { if listenIP.Equal(localhostIPv4) || listenIP.Equal(localhostIPv6) { glog.Errorf("Can't proxy only on localhost - iptables can't do it") return nil } hostIP, err := chooseHostInterface() if err != nil { glog.Errorf("Failed to select a host interface: %v", err) return nil } glog.Infof("Initializing iptables") // Clean up old messes. Ignore erors. iptablesDeleteOld(iptables) // Set up the iptables foundations we need. if err := iptablesInit(iptables); err != nil { glog.Errorf("Failed to initialize iptables: %v", err) return nil } // Flush old iptables rules (since the bound ports will be invalid after a restart). // When OnUpdate() is first called, the rules will be recreated. if err := iptablesFlush(iptables); err != nil { glog.Errorf("Failed to flush iptables: %v", err) return nil } return &Proxier{ loadBalancer: loadBalancer, serviceMap: make(map[string]*serviceInfo), listenIP: listenIP, iptables: iptables, hostIP: hostIP, } }
// Validate given node IP belongs to the current host func (kl *Kubelet) validateNodeIP() error { if kl.nodeIP == nil { return nil } // Honor IP limitations set in setNodeStatus() if kl.nodeIP.IsLoopback() { return fmt.Errorf("nodeIP can't be loopback address") } if kl.nodeIP.To4() == nil { return fmt.Errorf("nodeIP must be IPv4 address") } addrs, err := net.InterfaceAddrs() 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.Equal(kl.nodeIP) { return nil } } return fmt.Errorf("Node IP: %q not found in the host's network interfaces", kl.nodeIP.String()) }
func ipIsLocal(ip net.IP) bool { if ip.To4() == nil { return ip.Equal(net.IPv6loopback) } return v4Loopback.Contains(ip) }
func (c *EtcdConfig) verifyIP(ip net.IP, source string) { fmt.Printf("IP '%s' found in '%s'\n", ip.String(), source) // valid ip address found from source. Verify that it exists if iface, ip_net, ipverify, err := LocalNetForIp(ip); err != nil { fmt.Printf("%s\n", err.Error()) } else if !ip.Equal(ipverify) { fmt.Printf("IP address on interface %s: %s does not match ip from %s: %s\n", iface.Name, ipverify, c.AddrSource, ip) } else { fmt.Printf("IP '%s' verified, on interface '%s' net '%s'\n", ip.String(), iface.Name, ip_net.String()) set := false // set local defaults appropriately if c.ClientAddr == "" { c.ClientAddr = ip.String() set = true } if c.PeerAddr == "" { c.PeerAddr = ip.String() set = true } if set { c.Interface = iface } } }
func (rb *HostgwBackend) Init(extIface *net.Interface, extIaddr net.IP, extEaddr net.IP) (*backend.SubnetDef, error) { rb.extIface = extIface rb.extIaddr = extIaddr if !extIaddr.Equal(extEaddr) { return nil, fmt.Errorf("your PublicIP differs from interface IP, meaning that probably you're on a NAT, which is not supported by host-gw backend") } attrs := subnet.LeaseAttrs{ PublicIP: ip.FromIP(extIaddr), BackendType: "host-gw", } l, err := rb.sm.AcquireLease(rb.ctx, rb.network, &attrs) switch err { case nil: rb.lease = l case context.Canceled, context.DeadlineExceeded: return nil, err default: return nil, fmt.Errorf("failed to acquire lease: %v", err) } /* NB: docker will create the local route to `sn` */ return &backend.SubnetDef{ Net: l.Subnet, MTU: extIface.MTU, }, nil }
// Build a slice of iptables args for a portal rule. func iptablesPortalArgs(destIP net.IP, destPort int, protocol api.Protocol, proxyIP net.IP, proxyPort int, service string) []string { args := []string{ "-m", "comment", "--comment", service, "-p", strings.ToLower(string(protocol)), "-d", destIP.String(), "--dport", fmt.Sprintf("%d", destPort), } // This is tricky. If the proxy is bound (see Proxier.listenAddress) // to 0.0.0.0 ("any interface") or 127.0.0.1, we can use REDIRECT, // which will bring packets back to the host's loopback interface. If // the proxy is bound to any other interface, then it is not listening // on the hosts's loopback, so we have to use DNAT to that specific // IP. We can not simply use DNAT to 127.0.0.1 in the first case // because from within a container, 127.0.0.1 is the container's // loopback interface, not the host's. // // Why would anyone bind to an address that is not inclusive of // localhost? Apparently some cloud environments have their public IP // exposed as a real network interface AND do not have firewalling. We // don't want to expose everything out to the world. // // Unfortunately, I don't know of any way to listen on some (N > 1) // interfaces but not ALL interfaces, short of doing it manually, and // this is simpler than that. if proxyIP.Equal(zeroIP) || proxyIP.Equal(localhostIP) { args = append(args, "-j", "REDIRECT", "--to-ports", fmt.Sprintf("%d", proxyPort)) } else { args = append(args, "-j", "DNAT", "--to-destination", fmt.Sprintf("%s:%d", proxyIP.String(), proxyPort)) } return args }
func buildDirectors(gDirects string) []directorFunc { // Generates a list of directorFuncs that are have "cached" values within // the scope of the functions. directorCidrs := strings.Split(gDirects, ",") directorFuncs := make([]directorFunc, len(directorCidrs)) for idx, directorCidr := range directorCidrs { //dstring := director var dfunc directorFunc if strings.Contains(directorCidr, "/") { _, directorIpNet, err := net.ParseCIDR(directorCidr) if err != nil { panic(fmt.Sprintf("\nUnable to parse CIDR string : %s : %s\n", directorCidr, err)) } dfunc = func(ptestip *net.IP) bool { testIp := *ptestip return directorIpNet.Contains(testIp) } directorFuncs[idx] = dfunc } else { var directorIp net.IP directorIp = net.ParseIP(directorCidr) dfunc = func(ptestip *net.IP) bool { var testIp net.IP testIp = *ptestip return testIp.Equal(directorIp) } directorFuncs[idx] = dfunc } } return directorFuncs }
// Build a slice of iptables args for a from-host portal rule. func (proxier *Proxier) iptablesHostPortalArgs(destIP net.IP, addDstLocalMatch bool, destPort int, protocol api.Protocol, proxyIP net.IP, proxyPort int, service proxy.ServicePortName) []string { args := iptablesCommonPortalArgs(destIP, false, addDstLocalMatch, destPort, protocol, service) // This is tricky. // // If the proxy is bound (see Proxier.listenIP) to 0.0.0.0 ("any // interface") we want to do the same as from-container traffic and use // REDIRECT. Except that it doesn't work (empirically). REDIRECT on // local packets sends the traffic to localhost (special case, but it is // documented) but the response comes from the eth0 IP (not sure why, // truthfully), which makes DNS unhappy. // // So we have to use DNAT. DNAT to 127.0.0.1 can't work for the same // reason. // // So we do our best to find an interface that is not a loopback and // DNAT to that. This works (again, empirically). // // If the proxy is bound to a specific IP, then we have to use DNAT to // that IP. Unlike the previous case, this works because the proxy is // ONLY listening on that IP, not the bridge. // // If the proxy is bound to localhost only, this should work, but we // don't allow it for now. if proxyIP.Equal(zeroIPv4) || proxyIP.Equal(zeroIPv6) { proxyIP = proxier.hostIP } // TODO: Can we DNAT with IPv6? args = append(args, "-j", "DNAT", "--to-destination", net.JoinHostPort(proxyIP.String(), strconv.Itoa(proxyPort))) return args }
func HardwareAddrByIP(x net.IP) (*net.HardwareAddr, error) { file, err := os.Open("/proc/net/arp") if err != nil { return nil, err } defer file.Close() scanner := bufio.NewScanner(file) for scanner.Scan() { fields := strings.Fields(scanner.Text()) if x.Equal(net.ParseIP(fields[0])) { addr, err := net.ParseMAC(fields[3]) if err != nil { continue } return &addr, nil } } if err := scanner.Err(); err != nil { return nil, err } return nil, errors.New("no mac address found") }
func netIP4ToInterface(ip net.IP) (*net.Interface, error) { ift, err := net.Interfaces() if err != nil { return nil, err } for _, ifi := range ift { ifat, err := ifi.Addrs() if err != nil { return nil, err } for _, ifa := range ifat { switch ifa := ifa.(type) { case *net.IPAddr: if ip.Equal(ifa.IP) { return &ifi, nil } case *net.IPNet: if ip.Equal(ifa.IP) { return &ifi, nil } } } } return nil, errNoSuchInterface }
func InterfaceByIP(x net.IP) (*net.Interface, error) { ifaces, err := net.Interfaces() if err != nil { return nil, err } for _, iface := range ifaces { addrs, err := iface.Addrs() if err != nil { continue } 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 x.Equal(ip.To4()) { return &iface, nil } } } return nil, errors.New("no such network interface") }
func TestInetCidrTranscodeIP(t *testing.T) { t.Parallel() conn := mustConnect(t, *defaultConnConfig) defer closeConn(t, conn) tests := []struct { sql string value net.IP }{ {"select $1::inet", net.ParseIP("0.0.0.0")}, {"select $1::inet", net.ParseIP("127.0.0.1")}, {"select $1::inet", net.ParseIP("12.34.56.0")}, {"select $1::inet", net.ParseIP("255.255.255.255")}, {"select $1::inet", net.ParseIP("::1")}, {"select $1::inet", net.ParseIP("2607:f8b0:4009:80b::200e")}, {"select $1::cidr", net.ParseIP("0.0.0.0")}, {"select $1::cidr", net.ParseIP("127.0.0.1")}, {"select $1::cidr", net.ParseIP("12.34.56.0")}, {"select $1::cidr", net.ParseIP("255.255.255.255")}, {"select $1::cidr", net.ParseIP("::1")}, {"select $1::cidr", net.ParseIP("2607:f8b0:4009:80b::200e")}, } for i, tt := range tests { var actual net.IP err := conn.QueryRow(tt.sql, tt.value).Scan(&actual) if err != nil { t.Errorf("%d. Unexpected failure: %v (sql -> %v, value -> %v)", i, err, tt.sql, tt.value) continue } if !actual.Equal(tt.value) { t.Errorf("%d. Expected %v, got %v (sql -> %v)", i, tt.value, actual, tt.sql) } ensureConnValid(t, conn) } failTests := []struct { sql string value net.IPNet }{ {"select $1::inet", mustParseCIDR(t, "192.168.1.0/24")}, {"select $1::cidr", mustParseCIDR(t, "192.168.1.0/24")}, } for i, tt := range failTests { var actual net.IP err := conn.QueryRow(tt.sql, tt.value).Scan(&actual) if !strings.Contains(err.Error(), "Cannot decode netmask") { t.Errorf("%d. Expected failure cannot decode netmask, but got: %v (sql -> %v, value -> %v)", i, err, tt.sql, tt.value) continue } ensureConnValid(t, conn) } }
func (v *ripVrf) nexthopGet(prefix *net.IPNet, nexthop net.IP) (int, *ripNet) { for i, n := range v.nets { if nexthop.Equal(n.nexthop) == addr.NetEqual(prefix, &n.addr) { return i, n } } return -1, nil }
func ipInSlice(needle net.IP, haystack []net.IP) bool { for _, straw := range haystack { if needle.Equal(straw) { return true } } return false }
func (i *Ipam) ReleaseAddress(poolID string, address net.IP) error { i.logReq("ReleaseAddress", poolID, address) if subnet, _, err := splitPoolID(poolID); err != nil { return err } else if address.Equal(subnet.IP) { // is it the gateway address we faked earlier? return nil } return i.weave.ReleaseIPsFor(address.String()) }
// Build a slice of iptables args for a from-host public-port rule. // See iptablesHostPortalArgs // TODO: Should we just reuse iptablesHostPortalArgs? func (proxier *Proxier) iptablesHostNodePortArgs(nodePort int, protocol api.Protocol, proxyIP net.IP, proxyPort int, service proxy.ServicePortName) []string { args := iptablesCommonPortalArgs(nil, false, false, nodePort, protocol, service) if proxyIP.Equal(zeroIPv4) || proxyIP.Equal(zeroIPv6) { proxyIP = proxier.hostIP } // TODO: Can we DNAT with IPv6? args = append(args, "-j", "DNAT", "--to-destination", net.JoinHostPort(proxyIP.String(), strconv.Itoa(proxyPort))) return args }
func InterfaceForAddr(addr net.Addr) *Interface { var ip net.IP if ipAddr, ok := addr.(*net.IPNet); ok { ip = ipAddr.IP } else if tcpAddr, ok := addr.(*net.TCPAddr); ok { ip = tcpAddr.IP } else { return nil } ifaces, err := net.Interfaces() if err != nil { return nil } var ibIface *Interface for i := range ifaces { iface := &ifaces[i] // hack until ifi_type in ifinfomsg is available in Go if len(iface.HardwareAddr) != 20 { continue } guidKey := string([]byte(iface.HardwareAddr[12:])) var ok bool ibIface, ok = guidToInterface[guidKey] if !ok || iface == nil { continue } ifaceAddrs, err := iface.Addrs() if err != nil || len(ifaceAddrs) == 0 { continue } found := false for _, ifaceAddr := range ifaceAddrs { ifaceIPNet := ifaceAddr.(*net.IPNet) if ifaceIPNet.IP.To4() == nil { continue } if ip.Equal(ifaceIPNet.IP) { found = true break } } if found { break } else { ibIface = nil } } return ibIface }
func IpsEqual(ip1 net.IP, ip2 net.IP) bool { if ip1.Equal(ip2) { return true } /* the go std library Equal doesn't recognize [::] == 0.0.0.0, since it * tests for the ipv4 prefix, which isn't present in [::]. However, * they are in fact equal. Let's test for this case too. */ return isZeroIP(ip1) && isZeroIP(ip2) }
func splitRange(parentRange *ip.Range, firstIP net.IP, lastIP net.IP) (before, reserved, after *ip.Range) { if !firstIP.Equal(parentRange.FirstIP) { before = ip.NewRange(parentRange.FirstIP, decrementIP4(firstIP)) } if !lastIP.Equal(parentRange.LastIP) { after = ip.NewRange(incrementIP4(lastIP), parentRange.LastIP) } reserved = ip.NewRange(firstIP, lastIP) return }
func (c *con) GetListenAddresses() (addresses []*net.UDPAddr) { addresses = make([]*net.UDPAddr, 0) select { case <-c.done: return default: } port := c.Port interfaces := util.GetUnicastInterfaces() ips := make([]net.IP, 0) for _, ifc := range interfaces { addrs, err := ifc.Addrs() if err != nil { c.Warnf("Error getting addresses from interface (%v): %v", ifc, err) continue } for _, a := range addrs { var ip net.IP switch v := a.(type) { case *net.IPNet: ip = v.IP case *net.IPAddr: ip = v.IP default: continue } if ip.To4() == nil { continue } found := false for _, oldA := range ips { if ip.Equal(oldA) { found = true break } } if !found { ips = append(ips, ip) } } } for _, ip := range ips { addresses = append(addresses, &net.UDPAddr{IP: ip, Port: port}) } return }
func getHostOnlyNetwork(nets map[string]*hostOnlyNetwork, hostIP net.IP, netmask net.IPMask) *hostOnlyNetwork { for _, n := range nets { // Second part of this conditional handles a race where // VirtualBox returns us the incorrect netmask value for the // newly created interface. if hostIP.Equal(n.IPv4.IP) && (netmask.String() == n.IPv4.Mask.String() || n.IPv4.Mask.String() == buggyNetmask) { return n } } return nil }
func TestUnmarshalInetCopyBytes(t *testing.T) { data := []byte{127, 0, 0, 1} var ip net.IP if err := unmarshalInet(NativeType{proto: 2, typ: TypeInet}, data, &ip); err != nil { t.Fatal(err) } copy(data, []byte{0xFF, 0xFF, 0xFF, 0xFF}) ip2 := net.IP(data) if !ip.Equal(net.IPv4(127, 0, 0, 1)) { t.Fatalf("IP memory shared with data: ip=%v ip2=%v", ip, ip2) } }
func (icmp *Icmp) isLocalIp(ip net.IP) bool { if ip.IsLoopback() { return true } for _, localIp := range icmp.localIps { if ip.Equal(localIp) { return true } } return false }
// Build a slice of iptables args for a from-container public-port rule. // See iptablesContainerPortalArgs // TODO: Should we just reuse iptablesContainerPortalArgs? func (proxier *Proxier) iptablesContainerNodePortArgs(nodePort int, protocol api.Protocol, proxyIP net.IP, proxyPort int, service proxy.ServicePortName) []string { args := iptablesCommonPortalArgs(nil, false, false, nodePort, protocol, service) if proxyIP.Equal(zeroIPv4) || proxyIP.Equal(zeroIPv6) { // TODO: Can we REDIRECT with IPv6? args = append(args, "-j", "REDIRECT", "--to-ports", fmt.Sprintf("%d", proxyPort)) } else { // TODO: Can we DNAT with IPv6? args = append(args, "-j", "DNAT", "--to-destination", net.JoinHostPort(proxyIP.String(), strconv.Itoa(proxyPort))) } return args }
func isBadIPv4(ip net.IP) bool { if ip.To4() == nil { panic("cannot be called for IPv6") } if ip.Equal(net.IPv4bcast) || !ip.IsGlobalUnicast() || netPrivateClassA.Contains(ip) || netPrivateClassB.Contains(ip) || netPrivateClassC.Contains(ip) || netTestNet.Contains(ip) || net6To4Relay.Contains(ip) { return true } return false }
func (icmp *icmpPlugin) isLocalIP(ip net.IP) bool { if ip.IsLoopback() { return true } for _, localIP := range icmp.localIps { if ip.Equal(localIP) { return true } } return false }
func getHostOnlyNetwork(hostIP net.IP, netmask net.IPMask) (*hostOnlyNetwork, error) { nets, err := listHostOnlyNetworks() if err != nil { return nil, err } for _, n := range nets { if hostIP.Equal(n.IPv4.IP) && netmask.String() == n.IPv4.Mask.String() { return n, nil } } return nil, nil }
// NewProxier returns a new Proxier given a LoadBalancer and an address on // which to listen. Because of the iptables logic, It is assumed that there // is only a single Proxier active on a machine. An error will be returned if // the proxier cannot be started due to an invalid ListenIP (loopback) or // if iptables fails to update or acquire the initial lock. Once a proxier is // created, it will keep iptables up to date in the background and will not // terminate if a particular iptables call fails. func NewProxier(loadBalancer LoadBalancer, listenIP net.IP, iptables iptables.Interface) (*Proxier, error) { if listenIP.Equal(localhostIPv4) || listenIP.Equal(localhostIPv6) { return nil, ErrProxyOnLocalhost } hostIP, err := util.ChooseHostInterface() if err != nil { return nil, fmt.Errorf("failed to select a host interface: %v", err) } glog.V(2).Infof("Setting proxy IP to %v and initializing iptables", hostIP) return createProxier(loadBalancer, listenIP, iptables, hostIP) }
func isFromMe(ip net.IP) bool { addrs, e := net.InterfaceAddrs() if e != nil { log.Error(e) } for _, a := range addrs { if ipnet, ok := a.(*net.IPNet); ok { if ip.Equal(ipnet.IP) { return true } } } return false }