Beispiel #1
0
// writeThenReadPayload transmits IPv4 datagram payloads to the
// loopback address or interface and captures the loopback'd datagram
// payloads.
func writeThenReadPayload(t *testing.T, i int, c *ipv4.PacketConn, wb []byte, dst net.Addr) []byte {
	rb := make([]byte, 1500)
	c.SetTOS(i + 1)
	var ip net.IP
	switch v := dst.(type) {
	case *net.UDPAddr:
		ip = v.IP
	case *net.IPAddr:
		ip = v.IP
	}
	if ip.IsMulticast() {
		c.SetMulticastTTL(i + 1)
	} else {
		c.SetTTL(i + 1)
	}
	c.SetDeadline(time.Now().Add(100 * time.Millisecond))
	if _, err := c.WriteTo(wb, nil, dst); err != nil {
		t.Fatalf("ipv4.PacketConn.WriteTo failed: %v", err)
	}
	n, cm, _, err := c.ReadFrom(rb)
	if err != nil {
		t.Fatalf("ipv4.PacketConn.ReadFrom failed: %v", err)
	}
	t.Logf("rcvd cmsg: %v", cm)
	return rb[:n]
}
Beispiel #2
0
// NewIPHAConn creates a new IPHAConn.
func NewIPHAConn(laddr, raddr net.IP) (HAConn, error) {
	sendConn, err := IPConn(laddr, raddr)
	if err != nil {
		return nil, err
	}

	// For IPv6 unicast and multicast, and for IPv4 unicast, we can use the same IPConn for both
	// sending and receiving. For IPv4 multicast, we need a separate listener for receiving.
	recvConn := sendConn
	if raddr.IsMulticast() {
		if raddr.To4() != nil {
			log.Infof("Using IPv4 multicast")
			if recvConn, err = ListenMulticastIPv4(raddr, laddr); err != nil {
				return nil, err
			}
		} else {
			log.Infof("Using IPv6 multicast")
			if err = JoinMulticastIPv6(recvConn, raddr, laddr); err != nil {
				return nil, err
			}
		}
	}

	return &IPHAConn{
		sendConn: sendConn,
		recvConn: recvConn,
		laddr:    laddr,
		raddr:    raddr,
	}, nil
}
Beispiel #3
0
func validateRemoteAddr(ip net.IP) bool {
	if ip == nil {
		return false
	}
	if ip.IsInterfaceLocalMulticast() {
		return false
	}
	if ip.IsLinkLocalMulticast() {
		return false
	}
	if ip.IsLinkLocalUnicast() {
		return false
	}
	if ip.IsLoopback() {
		return false
	}
	if ip.IsMulticast() {
		return false
	}
	if ip.IsUnspecified() {
		return false
	}
	if isBroadcasty(ip) {
		return false
	}

	return true
}
// runPayloadTransponder transmits IPv4 datagram payloads to the
// loopback address or interface and captures the loopback'd datagram
// payloads.
func runPayloadTransponder(t *testing.T, c *ipv4.PacketConn, wb []byte, dst net.Addr) {
	cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
	rb := make([]byte, 1500)
	for i, toggle := range []bool{true, false, true} {
		if err := c.SetControlMessage(cf, toggle); err != nil {
			t.Fatalf("ipv4.PacketConn.SetControlMessage failed: %v", err)
		}
		c.SetTOS(i + 1)
		var ip net.IP
		switch v := dst.(type) {
		case *net.UDPAddr:
			ip = v.IP
		case *net.IPAddr:
			ip = v.IP
		}
		if ip.IsMulticast() {
			c.SetMulticastTTL(i + 1)
		} else {
			c.SetTTL(i + 1)
		}
		c.SetDeadline(time.Now().Add(100 * time.Millisecond))
		if _, err := c.Write(wb, nil, dst); err != nil {
			t.Fatalf("ipv4.PacketConn.Write failed: %v", err)
		}
		_, cm, _, err := c.Read(rb)
		if err != nil {
			t.Fatalf("ipv4.PacketConn.Read failed: %v", err)
		}
		t.Logf("rcvd cmsg: %v", cm)
	}
}
Beispiel #5
0
func InterfaceIPs() ([]*net.IPAddr, error) {
	var (
		addrs []*net.IPAddr
	)

	ifaces, err := net.Interfaces()
	if err != nil {
		return nil, err
	}
	for _, iface := range ifaces {
		iaddrs, err := iface.Addrs()
		if err != nil {
			return nil, err
		}

		for _, iaddr := range iaddrs {
			var (
				ip   net.IP
				zone string
			)

			switch x := iaddr.(type) {
			case *net.IPAddr:
				ip = x.IP
				zone = x.Zone
			case *net.IPNet:
				ip = x.IP
				zone = ""
			}

			if ip.IsMulticast() ||
				ip.IsUnspecified() ||
				ip.IsInterfaceLocalMulticast() ||
				ip.IsLinkLocalMulticast() ||
				ip.IsLinkLocalUnicast() {
				continue
			}

			if ipv4 := ip.To4(); ipv4 != nil {
				ip = ipv4
			}

			addrs = append(addrs, &net.IPAddr{
				IP:   ip,
				Zone: zone,
			})
		}
	}

	return addrs, nil
}
Beispiel #6
0
//validNodeIP verifies that the provided ip is not a loopback or multicast address
//and checks whether the ip is in the configured network limits range.
func (s *Server) validNodeIP(i net.IP) bool {
	switch {
	case i.IsLoopback():
		return false
	case i.IsMulticast():
		return false
	}
	inRange := false
	for _, n := range s.netlimits {
		if n.Contains(i) {
			inRange = true
		}
	}
	return inRange
}
Beispiel #7
0
// GetMyIP uses hueristics and guessing to find a usable IP for the current host by iterating over interfaces and
// addresses assigned to those interfaces until one is found that is "up", not a loopback, nor a broadcast. if no
// address can be found then return an empty string
func GetMyIP() (string, error) {
	ifaces, err := net.Interfaces()
	if err != nil {
		return "", err
	}

	for _, iface := range ifaces {
		if iface.Flags&net.FlagUp == 0 {
			continue // down
		}
		if iface.Flags&(net.FlagLoopback) != 0 {
			continue // broadcast or loopback
		}
		addrs, err := iface.Addrs()
		if err != nil {
			return "", err
		}
		var ip net.IP
		for _, addr := range addrs {
			switch v := addr.(type) {
			case *net.IPNet:
				ip = v.IP
			case *net.IPAddr:
				ip = v.IP
			}

			if ip == nil || ip.IsLoopback() || ip.IsMulticast() {
				continue
			}
			if ip.To4() == nil {
				continue // not v4
			}
			return ip.String(), nil
		}
	}
	return "", nil
}
Beispiel #8
0
// IPConn creates a net.IPConn using the given local and remote addresses using IP protocol
// 112 (VRRP).
func IPConn(localAddr, remoteAddr net.IP) (*net.IPConn, error) {
	c, err := net.ListenIP("ip:112", &net.IPAddr{IP: localAddr})
	if err != nil {
		return nil, err
	}

	f, err := c.File()
	if err != nil {
		return nil, err
	}
	defer f.Close()

	ip4 := localAddr.To4()
	switch {
	case ip4 != nil && !remoteAddr.IsMulticast():
		// IPv4 unicast
		// TTL = 255 per VRRP spec
		if err := setsockopt(f, syscall.IPPROTO_IP, syscall.IP_TTL, 255); err != nil {
			return nil, err
		}

	case ip4 != nil && remoteAddr.IsMulticast():
		// IPv4 multicast
		// TTL = 255 per VRRP spec
		if err := setsockopt(f, syscall.IPPROTO_IP, syscall.IP_MULTICAST_TTL, 255); err != nil {
			return nil, err
		}
		// We don't want to receive our own messages.
		if err := setsockopt(f, syscall.IPPROTO_IP, syscall.IP_MULTICAST_LOOP, 0); err != nil {
			return nil, err
		}

	case ip4 == nil && !remoteAddr.IsMulticast():
		// IPv6 unicast
		// HOPLIMIT = 255 per VRRP spec
		if err := setsockopt(f, syscall.IPPROTO_IPV6, syscall.IPV6_UNICAST_HOPS, 255); err != nil {
			return nil, err
		}

	case ip4 == nil && remoteAddr.IsMulticast():
		// IPv6 multicast
		// HOPLIMIT = 255 per VRRP spec
		if err := setsockopt(f, syscall.IPPROTO_IPV6, syscall.IPV6_MULTICAST_HOPS, 255); err != nil {
			return nil, err
		}
		// We don't want to receive our own messages.
		if err := setsockopt(f, syscall.IPPROTO_IPV6, syscall.IPV6_MULTICAST_LOOP, 0); err != nil {
			return nil, err
		}

	}

	if ip4 == nil {
		// IPv6 unicast and multicast
		// Request that the ancillary data for received packets include the hop limit and the
		// destination address.

		// TODO(angusc): syscall.IPV6_RECVHOPLIMIT and syscall.IPV6_RECVPKTINFO are prefered but they
		// don't work on lucid.
		if err := setsockopt(f, syscall.IPPROTO_IPV6, syscall.IPV6_2292HOPLIMIT, 1); err != nil {
			return nil, err
		}
		if err := setsockopt(f, syscall.IPPROTO_IPV6, syscall.IPV6_2292PKTINFO, 1); err != nil {
			return nil, err
		}
	}

	log.Infof("ha.IPConn: laddr=%v, raddr=%v", localAddr, remoteAddr)
	return c, nil
}