func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) {
	switch runtime.GOOS {
	case "nacl", "plan9", "windows":
		t.Skipf("not supported on %s", runtime.GOOS)
	}
	if testing.Short() {
		t.Skip("to avoid external network")
	}

	for _, gaddr := range udpMultipleGroupListenerTests {
		c1, err := net.ListenPacket("udp4", "224.0.0.0:1024") // wildcard address with reusable port
		if err != nil {
			t.Fatal(err)
		}
		defer c1.Close()

		c2, err := net.ListenPacket("udp4", "224.0.0.0:1024") // wildcard address with reusable port
		if err != nil {
			t.Fatal(err)
		}
		defer c2.Close()

		var ps [2]*ipv4.PacketConn
		ps[0] = ipv4.NewPacketConn(c1)
		ps[1] = ipv4.NewPacketConn(c2)
		var mift []*net.Interface

		ift, err := net.Interfaces()
		if err != nil {
			t.Fatal(err)
		}
		for i, ifi := range ift {
			if _, ok := nettest.IsMulticastCapable("ip4", &ifi); !ok {
				continue
			}
			for _, p := range ps {
				if err := p.JoinGroup(&ifi, gaddr); err != nil {
					t.Fatal(err)
				}
			}
			mift = append(mift, &ift[i])
		}
		for _, ifi := range mift {
			for _, p := range ps {
				if err := p.LeaveGroup(ifi, gaddr); err != nil {
					t.Fatal(err)
				}
			}
		}
	}
}
Example #2
0
// testOSVM creates a virtualMachine which uses the OS's BPF VM by injecting
// packets into a UDP listener with a BPF program attached to it.
func testOSVM(t *testing.T, filter []bpf.Instruction) (virtualMachine, func()) {
	l, err := net.ListenPacket("udp4", "127.0.0.1:0")
	if err != nil {
		t.Fatalf("failed to open OS VM UDP listener: %v", err)
	}

	prog, err := bpf.Assemble(filter)
	if err != nil {
		t.Fatalf("failed to compile BPF program: %v", err)
	}

	p := ipv4.NewPacketConn(l)
	if err = p.SetBPF(prog); err != nil {
		t.Fatalf("failed to attach BPF program to listener: %v", err)
	}

	s, err := net.Dial("udp4", l.LocalAddr().String())
	if err != nil {
		t.Fatalf("failed to dial connection to listener: %v", err)
	}

	done := func() {
		_ = s.Close()
		_ = l.Close()
	}

	return &osVirtualMachine{
		l: l,
		s: s,
	}, done
}
Example #3
0
// NewHTTPUClient creates a new HTTPUClient, opening up a new UDP socket for the
// purpose.
func NewHTTPUClient() (*HTTPUClient, error) {
	conn, err := net.ListenPacket("udp4", ":0")
	if err != nil {
		return nil, err
	}
	return &HTTPUClient{conn: ipv4.NewPacketConn(conn)}, nil
}
Example #4
0
// ServeIf does the same job as Serve(), but listens and responds on the
// specified network interface (by index).  It also doubles as an example of
// how to leverage the dhcp4.ServeConn interface.
//
// If your target only has one interface, use Serve(). ServeIf() requires an
// import outside the std library.  Serving DHCP over multiple interfaces will
// require your own dhcp4.ServeConn, as listening to broadcasts utilises all
// interfaces (so you cannot have more than on listener).
func ServeIf(ifIndex int, conn net.PacketConn, handler Handler) error {
	p := ipv4.NewPacketConn(conn)
	if err := p.SetControlMessage(ipv4.FlagInterface, true); err != nil {
		return err
	}
	return Serve(&serveIfConn{ifIndex: ifIndex, conn: p}, handler)
}
Example #5
0
func mcastOpen(bindAddr net.IP, port int, ifname string) (*ipv4.PacketConn, *net.UDPConn, error) {
	s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
	if err != nil {
		log.Fatal(err)
	}
	if err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); err != nil {
		log.Fatal(err)
	}
	//syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEPORT, 1)
	if err := syscall.SetsockoptString(s, syscall.SOL_SOCKET, syscall.SO_BINDTODEVICE, ifname); err != nil {
		log.Fatal(err)
	}

	lsa := syscall.SockaddrInet4{Port: port}
	copy(lsa.Addr[:], bindAddr.To4())

	if err := syscall.Bind(s, &lsa); err != nil {
		syscall.Close(s)
		log.Fatal(err)
	}
	f := os.NewFile(uintptr(s), "")
	c, err := net.FilePacketConn(f)
	f.Close()
	if err != nil {
		log.Fatal(err)
	}
	u := c.(*net.UDPConn)
	p := ipv4.NewPacketConn(c)

	return p, u, nil
}
Example #6
0
func TestSetICMPFilter(t *testing.T) {
	switch runtime.GOOS {
	case "linux":
	default:
		t.Skipf("not supported on %q", runtime.GOOS)
	}
	if os.Getuid() != 0 {
		t.Skip("must be root")
	}

	c, err := net.ListenPacket("ip4:icmp", "127.0.0.1")
	if err != nil {
		t.Fatal(err)
	}
	defer c.Close()

	p := ipv4.NewPacketConn(c)

	var f ipv4.ICMPFilter
	f.SetAll(true)
	f.Accept(ipv4.ICMPTypeEcho)
	f.Accept(ipv4.ICMPTypeEchoReply)
	if err := p.SetICMPFilter(&f); err != nil {
		t.Fatal(err)
	}
	kf, err := p.ICMPFilter()
	if err != nil {
		t.Fatal(err)
	}
	if !reflect.DeepEqual(kf, &f) {
		t.Fatalf("got %#v; want %#v", kf, f)
	}
}
Example #7
0
func main() {
	flag.Parse()

	c, err := net.ListenPacket("udp", net.JoinHostPort(*group, "0"))
	if err != nil {
		log.Fatal(err)
	}
	p := ipv4.NewPacketConn(c)
	defer p.Close()
	dst, err := net.ResolveUDPAddr("udp", net.JoinHostPort(*group, *port))
	if err != nil {
		log.Fatal(err)
	}

	log.Println(c.LocalAddr())
	go sender(p, dst)

	sig := make(chan os.Signal)
	signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
	for {
		select {
		case <-sig:
			os.Exit(0)
		}
	}
}
func TestPacketConnUnicastSocketOptions(t *testing.T) {
	switch runtime.GOOS {
	case "nacl", "plan9":
		t.Skipf("not supported on %s", runtime.GOOS)
	}
	ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
	if ifi == nil {
		t.Skipf("not available on %s", runtime.GOOS)
	}

	m, ok := nettest.SupportsRawIPSocket()
	for _, tt := range packetConnUnicastSocketOptionTests {
		if tt.net == "ip4" && !ok {
			t.Log(m)
			continue
		}
		c, err := net.ListenPacket(tt.net+tt.proto, tt.addr)
		if err != nil {
			t.Fatal(err)
		}
		defer c.Close()

		testUnicastSocketOptions(t, ipv4.NewPacketConn(c))
	}
}
Example #9
0
func (s *serfDiscovery) Start() error {
	conn, err := net.ListenPacket("udp4", "0.0.0.0:1024")
	if err != nil {
		return err
	}

	s.pconn = ipv4.NewPacketConn(conn)
	if err := s.pconn.JoinGroup(s.iface, &net.UDPAddr{IP: s.group}); err != nil {
		conn.Close()
		return err
	}

	if err := s.pconn.SetControlMessage(ipv4.FlagDst, true); err != nil {
		conn.Close()
		return err
	}

	go func() {
		<-s.stop
		conn.Close()
	}()

	go func() {
		b := make([]byte, 1500)
		for {
			_, cm, src, err := s.pconn.ReadFrom(b)
			if err != nil {
				if strings.Contains(err.Error(), "closed network connection") {
					log.Printf("Closed connection, stopping discovery listener...")
					return
				}

				log.Printf("Failed to read packet: %s", err)
				continue
			}

			if cm.Dst.IsMulticast() {
				if cm.Dst.Equal(s.group) {
					sip, _, err := net.SplitHostPort(src.String())
					if err != nil {
						log.Printf("Multicast src '%s' has unexpected format: %s", src, err)
					}

					if sip == s.self.String() {
						continue
					}

					err = s.serf.Join(sip)
					if err != nil {
						log.Printf("Failed to join serf gossip at '%s': %s ", sip, err)
					}
				} else {
					continue
				}
			}
		}
	}()

	return nil
}
Example #10
0
func TestPacketConnMulticastSocketOptions(t *testing.T) {
	switch runtime.GOOS {
	case "nacl", "plan9", "solaris":
		t.Skipf("not supported on %s", runtime.GOOS)
	}
	ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
	if ifi == nil {
		t.Skipf("not available on %s", runtime.GOOS)
	}

	m, ok := nettest.SupportsRawIPSocket()
	for _, tt := range packetConnMulticastSocketOptionTests {
		if tt.net == "ip4" && !ok {
			t.Log(m)
			continue
		}
		c, err := net.ListenPacket(tt.net+tt.proto, tt.addr)
		if err != nil {
			t.Fatal(err)
		}
		defer c.Close()
		p := ipv4.NewPacketConn(c)
		defer p.Close()

		if tt.src == nil {
			testMulticastSocketOptions(t, p, ifi, tt.grp)
		} else {
			testSourceSpecificMulticastSocketOptions(t, p, ifi, tt.grp, tt.src)
		}
	}
}
Example #11
0
// ListenPacket listens for incoming ICMP packets addressed to
// address. See net.Dial for the syntax of address.
//
// For non-privileged datagram-oriented ICMP endpoints, network must
// be "udp4" or "udp6". The endpoint allows to read, write a few
// limited ICMP messages such as echo request and echo reply.
// Currently only Darwin and Linux support this.
//
// Examples:
//	ListenPacket("udp4", "192.168.0.1")
//	ListenPacket("udp4", "0.0.0.0")
//	ListenPacket("udp6", "fe80::1%en0")
//	ListenPacket("udp6", "::")
//
// For privileged raw ICMP endpoints, network must be "ip4" or "ip6"
// followed by a colon and an ICMP protocol number or name.
//
// Examples:
//	ListenPacket("ip4:icmp", "192.168.0.1")
//	ListenPacket("ip4:1", "0.0.0.0")
//	ListenPacket("ip6:ipv6-icmp", "fe80::1%en0")
//	ListenPacket("ip6:58", "::")
func ListenPacket(network, address string) (*PacketConn, error) {
	var family, proto int
	switch network {
	case "udp4":
		family, proto = syscall.AF_INET, iana.ProtocolICMP
	case "udp6":
		family, proto = syscall.AF_INET6, iana.ProtocolIPv6ICMP
	default:
		i := last(network, ':')
		switch network[:i] {
		case "ip4":
			proto = iana.ProtocolICMP
		case "ip6":
			proto = iana.ProtocolIPv6ICMP
		}
	}
	var cerr error
	var c net.PacketConn
	switch family {
	case syscall.AF_INET, syscall.AF_INET6:
		s, err := syscall.Socket(family, syscall.SOCK_DGRAM, proto)
		if err != nil {
			return nil, os.NewSyscallError("socket", err)
		}
		if runtime.GOOS == "darwin" && family == syscall.AF_INET {
			if err := syscall.SetsockoptInt(s, iana.ProtocolIP, sysIP_STRIPHDR, 1); err != nil {
				syscall.Close(s)
				return nil, os.NewSyscallError("setsockopt", err)
			}
		}
		sa, err := sockaddr(family, address)
		if err != nil {
			syscall.Close(s)
			return nil, err
		}
		if err := syscall.Bind(s, sa); err != nil {
			syscall.Close(s)
			return nil, os.NewSyscallError("bind", err)
		}
		f := os.NewFile(uintptr(s), "datagram-oriented icmp")
		c, cerr = net.FilePacketConn(f)
		f.Close()
	default:
		c, cerr = net.ListenPacket(network, address)
	}
	if cerr != nil {
		return nil, cerr
	}
	switch proto {
	case iana.ProtocolICMP:
		return &PacketConn{c: c, p4: ipv4.NewPacketConn(c)}, nil
	case iana.ProtocolIPv6ICMP:
		return &PacketConn{c: c, p6: ipv6.NewPacketConn(c)}, nil
	default:
		return &PacketConn{c: c}, nil
	}
}
Example #12
0
func MulticastListener(port int, ifname string) (*MulticastSock, error) {

	/*
		s, err1 := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
		if err1 != nil {
			return nil, fmt.Errorf("MulticastListener: could not create socket(port=%d,ifname=%s): %v", port, ifname, err1)
		}
		if err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); err != nil {
			syscall.Close(s)
			return nil, fmt.Errorf("MulticastListener: could not set reuse addr socket(port=%d,ifname=%s): %v", port, ifname, err)
		}
		if ifname != "" {
			if err := syscall.SetsockoptString(s, syscall.SOL_SOCKET, syscall.SO_BINDTODEVICE, ifname); err != nil {
				syscall.Close(s)
				return nil, fmt.Errorf("MulticastListener: could not bind to device socket(port=%d,ifname=%s): %v", port, ifname, err)
			}
		}

		bindAddr := net.IP(net.IPv4(0, 0, 0, 0))
		lsa := syscall.SockaddrInet4{Port: port}
		copy(lsa.Addr[:], bindAddr.To4())

		if err := syscall.Bind(s, &lsa); err != nil {
			syscall.Close(s)
			return nil, fmt.Errorf("MulticastListener: could not bind socket to address %v,%d: %v", bindAddr, port, err)
		}
		f := os.NewFile(uintptr(s), "")
		c, err2 := net.FilePacketConn(f)
		f.Close()
		if err2 != nil {
			syscall.Close(s)
			return nil, fmt.Errorf("MulticastListener: could not get packet connection for socket(port=%d,ifname=%s): %v", port, ifname, err2)
		}
		u := c.(*net.UDPConn)
		p := ipv4.NewPacketConn(c)

		if err := p.SetControlMessage(ipv4.FlagTTL|ipv4.FlagSrc|ipv4.FlagDst|ipv4.FlagInterface, true); err != nil {
			return nil, fmt.Errorf("MulticastListener: could not set control message flags: %v", err)
		}

		return &MulticastSock{P: p, U: u}, nil
	*/

	c, err := udpConn(&net.UDPAddr{IP: net.IPv4zero, Port: port}, ifname)
	if err != nil {
		return nil, err
	}

	u := c.(*net.UDPConn)
	p := ipv4.NewPacketConn(c)

	if err := p.SetControlMessage(ipv4.FlagTTL|ipv4.FlagSrc|ipv4.FlagDst|ipv4.FlagInterface, true); err != nil {
		return nil, fmt.Errorf("MulticastListener: could not set control message flags: %v", err)
	}

	return &MulticastSock{P: p, U: u}, nil
}
Example #13
0
// setInterface is used to set the query interface, uses sytem
// default if not provided
func (c *client) setInterface(iface *net.Interface) error {
	p := ipv4.NewPacketConn(c.ipv4UnicastConn)
	if err := p.SetMulticastInterface(iface); err != nil {
		return err
	}
	p2 := ipv6.NewPacketConn(c.ipv6UnicastConn)
	if err := p2.SetMulticastInterface(iface); err != nil {
		return err
	}
	p = ipv4.NewPacketConn(c.ipv4MulticastConn)
	if err := p.SetMulticastInterface(iface); err != nil {
		return err
	}
	p2 = ipv6.NewPacketConn(c.ipv6MulticastConn)
	if err := p2.SetMulticastInterface(iface); err != nil {
		return err
	}
	return nil
}
Example #14
0
func TestPacketConnReadWriteUnicastUDP(t *testing.T) {
	switch runtime.GOOS {
	case "nacl", "plan9", "solaris", "windows":
		t.Skipf("not supported on %q", runtime.GOOS)
	}
	ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
	if ifi == nil {
		t.Skipf("not available on %q", runtime.GOOS)
	}

	c, err := net.ListenPacket("udp4", "127.0.0.1:0")
	if err != nil {
		t.Fatal(err)
	}
	defer c.Close()

	dst, err := net.ResolveUDPAddr("udp4", c.LocalAddr().String())
	if err != nil {
		t.Fatal(err)
	}
	p := ipv4.NewPacketConn(c)
	defer p.Close()
	cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
	wb := []byte("HELLO-R-U-THERE")

	for i, toggle := range []bool{true, false, true} {
		if err := p.SetControlMessage(cf, toggle); err != nil {
			if nettest.ProtocolNotSupported(err) {
				t.Logf("not supported on %q", runtime.GOOS)
				continue
			}
			t.Fatal(err)
		}
		p.SetTTL(i + 1)
		if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
			t.Fatal(err)
		}
		if n, err := p.WriteTo(wb, nil, dst); err != nil {
			t.Fatal(err)
		} else if n != len(wb) {
			t.Fatalf("got %v; want %v", n, len(wb))
		}
		rb := make([]byte, 128)
		if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
			t.Fatal(err)
		}
		if n, cm, _, err := p.ReadFrom(rb); err != nil {
			t.Fatal(err)
		} else if !bytes.Equal(rb[:n], wb) {
			t.Fatalf("got %v; want %v", rb[:n], wb)
		} else {
			t.Logf("rcvd cmsg: %v", cm)
		}
	}
}
Example #15
0
// NewPacketConn returns a PacketConn based on the specified net.PacketConn.
// It adds functionality to return the interface index from calls to ReadFrom
// and include the interface index argument in calls to WriteTo.
func NewPacketConn(pc net.PacketConn) (PacketConn, error) {
	ipv4pc := ipv4.NewPacketConn(pc)
	if err := ipv4pc.SetControlMessage(ipv4.FlagInterface, true); err != nil {
		return nil, err
	}

	p := packetConn{
		PacketConn: pc,
		ipv4pc:     ipv4pc,
	}

	return &p, nil
}
Example #16
0
func main() {
	var nic string

	flag.StringVar(&nic, "i", "", "")
	flag.Parse()

	iface, err := net.InterfaceByName(nic)
	if err != nil {
		panic(err)
	}

	addr, _ := iface.Addrs()
	ip, _, _ := net.ParseCIDR(addr[0].String())
	listenPort := fmt.Sprintf("%s:%d", ip, 10718)
	packet, err := net.ListenPacket("udp4", listenPort)
	if err != nil {
		panic(err)
	}
	defer packet.Close()

	p := ipv4.NewPacketConn(packet)
	if err := p.SetControlMessage(ipv4.FlagInterface, true); err != nil {
		panic(err)
	}

	buffer := make([]byte, 1500)
	for {
		_, cm, addr, err := p.ReadFrom(buffer)
		if err != nil {
			panic(err)
		}

		fmt.Printf("%v:\n", addr)
		fmt.Printf("%s\n", buffer)

		_, portStr, err := net.SplitHostPort(addr.String())
		if err != nil {
			panic(err)
		}

		port, _ := strconv.Atoi(portStr)
		addr = &net.UDPAddr{IP: net.IPv4bcast, Port: port}

		// nilをぶち込まないとエラーになる。。
		// panic: write udp4: invalid argument
		cm.Src = nil
		if _, e := p.WriteTo(buffer, cm, addr); e != nil {
			panic(e)
		}
	}
}
Example #17
0
func main() {
	flag.Parse()
	ip := net.ParseIP(*group)

	s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
	if err != nil {
		log.Fatal(err)
	}
	syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
	syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEPORT, 1)
	lsa := syscall.SockaddrInet4{Port: *port}
	copy(lsa.Addr[:], ip.To4())
	if err := syscall.Bind(s, &lsa); err != nil {
		syscall.Close(s)
		log.Fatal(err)
	}
	f := os.NewFile(uintptr(s), "")
	c, err := net.FilePacketConn(f)
	f.Close()
	if err != nil {
		log.Fatal(err)
	}
	p := ipv4.NewPacketConn(c)
	defer p.Close()

	ift, err := net.Interfaces()
	if err != nil {
		log.Fatal(err)
	}
	avail := net.FlagMulticast | net.FlagUp
	for _, ifi := range ift {
		if ifi.Flags&avail != avail {
			continue
		}
		if err := p.JoinGroup(&ifi, &net.UDPAddr{IP: ip}); err != nil {
			log.Println(err, "on", ifi)
		}
	}

	log.Println(c.LocalAddr())
	go receiver(c)

	sig := make(chan os.Signal)
	signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
	for {
		select {
		case <-sig:
			os.Exit(0)
		}
	}
}
Example #18
0
// Constructs server structure
func newServer(iface *net.Interface) (*Server, error) {
	// Create wildcard connections (because :5353 can be already taken by other apps)
	ipv4conn, err := net.ListenUDP("udp4", mdnsWildcardAddrIPv4)
	if err != nil {
		log.Printf("[ERR] bonjour: Failed to bind to udp4 port: %v", err)
	}
	ipv6conn, err := net.ListenUDP("udp6", mdnsWildcardAddrIPv6)
	if err != nil {
		log.Printf("[ERR] bonjour: Failed to bind to udp6 port: %v", err)
	}
	if ipv4conn == nil && ipv6conn == nil {
		return nil, fmt.Errorf("[ERR] bonjour: Failed to bind to any udp port!")
	}

	// Join multicast groups to receive announcements
	p1 := ipv4.NewPacketConn(ipv4conn)
	p2 := ipv6.NewPacketConn(ipv6conn)
	if iface != nil {
		if err := p1.JoinGroup(iface, &net.UDPAddr{IP: mdnsGroupIPv4}); err != nil {
			return nil, err
		}
		if err := p2.JoinGroup(iface, &net.UDPAddr{IP: mdnsGroupIPv6}); err != nil {
			return nil, err
		}
	} else {
		ifaces, err := net.Interfaces()
		if err != nil {
			return nil, err
		}
		errCount1, errCount2 := 0, 0
		for _, iface := range ifaces {
			if err := p1.JoinGroup(&iface, &net.UDPAddr{IP: mdnsGroupIPv4}); err != nil {
				errCount1++
			}
			if err := p2.JoinGroup(&iface, &net.UDPAddr{IP: mdnsGroupIPv6}); err != nil {
				errCount2++
			}
		}
		if len(ifaces) == errCount1 && len(ifaces) == errCount2 {
			return nil, fmt.Errorf("Failed to join multicast group on all interfaces!")
		}
	}

	s := &Server{
		ipv4conn: ipv4conn,
		ipv6conn: ipv6conn,
		ttl:      3200,
	}

	return s, nil
}
Example #19
0
func LocalMulticastPacketConn() (conn *ipv4.PacketConn, err error) {
	/*
	  lo,err := LoopbackInterface()
	  if err != nil {
	    return
	  }

	  maddrs, err := lo.MulticastAddrs()
	  if err != nil {
	    return
	  }

	  var bestAddr net.Addr
	  for _,maddr := range maddrs {
	    Trace.Printf("looking at: `%s`", maddr.String())
	    parsedIP := net.ParseIP(maddr.String())
	    if parsedIP == nil {
	      Error.Printf("could not parsed IP: `%s`", maddr.String())
	      continue
	    } else if parsedIP.To4() == nil {
	      continue
	    }
	    bestAddr = maddr
	    break
	  }
	  if bestAddr == nil {
	    err = fmt.Errorf("could not find a good address to bind to")
	    return
	  }

	  localMulticastSpec := fmt.Sprintf("%s:%d", bestAddr, 5555)
	*/

	// TODO fundamentally change how multicast is sent. I can't get the API to work
	// without creating a listener socket first but I shouldn't need it.
	// Had issues with running multiple services (heka and sdk_service) so I'm
	// going to the let the OS pick the port. `127.0.0.1:5556` used to work!
	localMulticastSpec := "127.0.0.1:"
	Trace.Printf("announce binding to port: `%s`", localMulticastSpec)

	udpConn, err := net.ListenPacket("udp", localMulticastSpec)
	if err != nil {
		Error.Printf("could not listen to `%s`", localMulticastSpec)
		return
	}
	Trace.Printf("udpConn.LocalAddr(): %s", udpConn.LocalAddr())

	conn = ipv4.NewPacketConn(udpConn)
	return
}
Example #20
0
File: ssdp.go Project: ronindev/dms
func makeConn(ifi net.Interface) (ret *net.UDPConn, err error) {
	ret, err = net.ListenMulticastUDP("udp", &ifi, NetAddr)
	if err != nil {
		return
	}
	p := ipv4.NewPacketConn(ret)
	if err := p.SetMulticastTTL(2); err != nil {
		log.Println(err)
	}
	if err := p.SetMulticastLoopback(true); err != nil {
		log.Println(err)
	}
	return
}
Example #21
0
func ServeProxyDHCP(port int, booter api.Booter) error {
	conn, err := net.ListenPacket("udp4", fmt.Sprintf(":%d", port))
	if err != nil {
		return err
	}
	defer conn.Close()
	l := ipv4.NewPacketConn(conn)
	if err = l.SetControlMessage(ipv4.FlagInterface, true); err != nil {
		return err
	}

	log.Log("ProxyDHCP", "Listening on port %d", port)
	buf := make([]byte, 1024)
	for {
		n, msg, addr, err := l.ReadFrom(buf)
		if err != nil {
			log.Log("ProxyDHCP", "Error reading from socket: %s", err)
			continue
		}

		udpAddr := addr.(*net.UDPAddr)
		udpAddr.IP = net.IPv4bcast

		req, err := ParseDHCP(buf[:n])
		if err != nil {
			log.Debug("ProxyDHCP", "ParseDHCP: %s", err)
			continue
		}

		if err = booter.ShouldBoot(req.MAC); err != nil {
			log.Debug("ProxyDHCP", "Not offering to boot %s: %s", req.MAC, err)
			continue
		}

		req.ServerIP, err = InterfaceIP(msg.IfIndex)
		if err != nil {
			log.Log("ProxyDHCP", "Couldn't find an IP address to use to reply to %s: %s", req.MAC, err)
			continue
		}

		log.Log("ProxyDHCP", "Offering to boot %s (via %s)", req.MAC, req.ServerIP)
		if _, err := l.WriteTo(OfferDHCP(req), &ipv4.ControlMessage{
			IfIndex: msg.IfIndex,
		}, udpAddr); err != nil {
			log.Log("ProxyDHCP", "Responding to %s: %s", req.MAC, err)
			continue
		}
	}
}
Example #22
0
func multicastRead(ifname, proto, addrPort string) error {

	iface, err1 := net.InterfaceByName(ifname)
	if err1 != nil {
		return err1
	}

	// open/bind socket
	conn, err2 := net.ListenPacket(proto, addrPort)
	if err2 != nil {
		return fmt.Errorf("join: %s/%s listen error: %v", proto, addrPort, err2)
	}

	// join multicast address
	p := ipv4.NewPacketConn(conn)
	if err := p.JoinGroup(iface, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 9)}); err != nil {
		conn.Close()
		return fmt.Errorf("join: join error: %v", err)
	}

	// is this needed for receive?
	if err := p.SetMulticastInterface(iface); err != nil {
		log.Printf("join: %s SetMulticastInterface(%s) error: %v", addrPort, iface.Name, err)
	}

	{
		ifi, err3 := p.MulticastInterface()
		if err3 != nil {
			log.Printf("join: %s %s multicastInterface error: %v", iface.Name, addrPort, err3)
		} else {
			if ifi == nil {
				log.Printf("join: %s %s multicastInterface=nil", iface.Name, addrPort)
			} else {
				log.Printf("join: %s %s multicastInterface=%s", iface.Name, addrPort, ifi.Name)
			}
		}
	}

	// request control messages
	if err := p.SetControlMessage(ipv4.FlagTTL|ipv4.FlagSrc|ipv4.FlagDst|ipv4.FlagInterface, true); err != nil {
		// warning only
		log.Printf("join: control message flags error: %v", err)
	}

	udpReader(p, iface.Name, addrPort)

	return nil
}
Example #23
0
func (a *announcer) Listen() error {
	if a.listening {
		return nil
	}

	interfaces := util.GetMulticastInterfaces()
	annSocket, err := net.ListenUDP("udp4", a.announceAddress)
	if err != nil {
		return err
	}

	annConn := ipv4.NewPacketConn(annSocket)

	for _, ifc := range interfaces {
		err = annConn.JoinGroup(ifc, a.announceAddress)
		if err != nil {
			return err
		}
	}

	go func() {
		defer annConn.Close()

		incomingBuf := make([]byte, 64*1024)

		for a.listening {
			n, _, src, err := annConn.ReadFrom(incomingBuf)
			if err != nil {
				log.Errorf("Error reading from connection (%v): %v", annConn, err)
				time.Sleep(time.Millisecond * 100)
				continue
			}

			if !checkProtocolId(incomingBuf[:n]) {
				continue
			}

			a.addPeer(src.(*net.UDPAddr))
		}
	}()

	return nil
}
Example #24
0
func ServePXE(pxeAddr string, httpPort int) error {
	conn, err := net.ListenPacket("udp4", pxeAddr)
	if err != nil {
		return err
	}
	defer conn.Close()
	l := ipv4.NewPacketConn(conn)
	if err = l.SetControlMessage(ipv4.FlagInterface, true); err != nil {
		return err
	}

	Log("PXE", "Listening on %s", pxeAddr)
	buf := make([]byte, 1024)
	for {
		n, msg, addr, err := l.ReadFrom(buf)
		if err != nil {
			Log("PXE", "Error reading from socket: %s", err)
			continue
		}

		req, err := ParsePXE(buf[:n])
		if err != nil {
			Debug("PXE", "ParsePXE: %s", err)
			continue
		}

		req.ServerIP, err = interfaceIP(msg.IfIndex)
		if err != nil {
			Log("PXE", "Couldn't find an IP address to use to reply to %s: %s", req.MAC, err)
			continue
		}
		req.HTTPServer = fmt.Sprintf("http://%s:%d/", req.ServerIP, httpPort)

		Log("PXE", "Chainloading %s (%s) to pxelinux (via %s)", req.MAC, req.ClientIP, req.ServerIP)

		if _, err := l.WriteTo(ReplyPXE(req), &ipv4.ControlMessage{
			IfIndex: msg.IfIndex,
		}, addr); err != nil {
			Log("PXE", "Responding to %s: %s", req.MAC, err)
			continue
		}
	}
}
func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) {
	switch runtime.GOOS {
	case "nacl", "plan9", "windows":
		t.Skipf("not supported on %s", runtime.GOOS)
	}
	if testing.Short() {
		t.Skip("to avoid external network")
	}

	gaddr := net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727
	type ml struct {
		c   *ipv4.PacketConn
		ifi *net.Interface
	}
	var mlt []*ml

	ift, err := net.Interfaces()
	if err != nil {
		t.Fatal(err)
	}
	for i, ifi := range ift {
		ip, ok := nettest.IsMulticastCapable("ip4", &ifi)
		if !ok {
			continue
		}
		c, err := net.ListenPacket("udp4", ip.String()+":"+"1024") // unicast address with non-reusable port
		if err != nil {
			t.Fatal(err)
		}
		defer c.Close()
		p := ipv4.NewPacketConn(c)
		if err := p.JoinGroup(&ifi, &gaddr); err != nil {
			t.Fatal(err)
		}
		mlt = append(mlt, &ml{p, &ift[i]})
	}
	for _, m := range mlt {
		if err := m.c.LeaveGroup(m.ifi, &gaddr); err != nil {
			t.Fatal(err)
		}
	}
}
func main() {

	group := net.IPv4(224, 0, 55, 56)
	dst := &net.UDPAddr{IP: group, Port: 5001}

	conn, c_err := net.ListenPacket("udp4", "0.0.0.0:5002")
	if c_err != nil {
		log.Fatal(c_err.Error())
	}
	defer conn.Close()

	p := ipv4.NewPacketConn(conn)
	p.SetMulticastTTL(1)
	for {
		if _, write_err := p.WriteTo([]byte("hello there"), nil, dst); write_err != nil {
			log.Fatal(write_err.Error())
		}
		time.Sleep(1 * time.Second)
	}
}
Example #27
0
func dial(ctx *Context) (MessageService, error) {
	group := net.ParseIP(ctx.Config.MessageService.BindGroup)
	ifaces, err := activeIfaces()
	if err != nil {
		return MessageService{}, err
	}

	myips, err := addressList(ifaces)
	if err != nil {
		return MessageService{}, err
	}

	c := make(chan Message)

	tcpAddr, err := net.ResolveTCPAddr("tcp4", ctx.Config.MessageService.BindAddress)
	if err != nil {
		return MessageService{}, err
	}

	port := tcpAddr.Port
	conn, err := net.ListenPacket("udp4", ctx.Config.MessageService.BindAddress)
	if err != nil {
		return MessageService{}, err
	}

	pconn := ipv4.NewPacketConn(conn)
	for _, iface := range ifaces {
		if err := pconn.JoinGroup(&iface, &net.UDPAddr{IP: group}); err != nil {
			return MessageService{}, err
		}
	}

	if err := pconn.SetControlMessage(ipv4.FlagDst, true); err != nil {
		return MessageService{}, err
	}

	pconn.SetTOS(0x0)
	pconn.SetTTL(16)

	return MessageService{group, port, conn, pconn, ifaces, ctx, ctx.Config.MessageService.Workers, c, myips}, nil
}
Example #28
0
File: client.go Project: rasky/mdns
// sendQuery is used to multicast a query out
func (c *client) sendQuery(q *dns.Msg, iface *net.Interface) error {
	buf, err := q.Pack()
	if err != nil {
		return err
	}
	if c.ipv4UnicastConn != nil {
		p := ipv4.NewPacketConn(c.ipv4UnicastConn)
		if iface != nil {
			p.SetMulticastInterface(iface)
		}
		p.WriteTo(buf, nil, ipv4Addr)
	}
	if c.ipv6UnicastConn != nil {
		p := ipv6.NewPacketConn(c.ipv6UnicastConn)
		if iface != nil {
			p.SetMulticastInterface(iface)
		}
		p.WriteTo(buf, nil, ipv6Addr)
	}
	return nil
}
Example #29
0
func BenchmarkReadWriteIPv4UDP(b *testing.B) {
	c, dst, err := benchmarkUDPListener()
	if err != nil {
		b.Fatal(err)
	}
	defer c.Close()

	p := ipv4.NewPacketConn(c)
	defer p.Close()
	cf := ipv4.FlagTTL | ipv4.FlagInterface
	if err := p.SetControlMessage(cf, true); err != nil {
		b.Fatal(err)
	}
	ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)

	wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		benchmarkReadWriteIPv4UDP(b, p, wb, rb, dst, ifi)
	}
}
Example #30
0
func ServePXE(pxePort, httpPort int) error {
	conn, err := net.ListenPacket("udp4", fmt.Sprintf(":%d", pxePort))
	if err != nil {
		return err
	}
	l := ipv4.NewPacketConn(conn)
	if err = l.SetControlMessage(ipv4.FlagInterface, true); err != nil {
		return err
	}

	Log("PXE", false, "Listening on port %d", pxePort)
	buf := make([]byte, 1024)
	for {
		n, msg, addr, err := l.ReadFrom(buf)
		if err != nil {
			Log("PXE", false, "Error reading from socket: %s", err)
			continue
		}

		req, err := ParsePXE(buf[:n])
		if err != nil {
			Log("PXE", true, "ParsePXE: %s", err)
			continue
		}

		// TODO: figure out the correct IP
		req.ServerIP, err = interfaceIP(msg.IfIndex)
		req.HTTPServer = fmt.Sprintf("http://%s:%d/", req.ServerIP, httpPort)

		Log("PXE", false, "Chainloading %s to pxelinux (via %s)", req.MAC, req.ServerIP)

		if _, err := l.WriteTo(ReplyPXE(req), &ipv4.ControlMessage{
			IfIndex: msg.IfIndex,
		}, addr); err != nil {
			Log("PXE", false, "Responding to %s: %s", req.MAC, err)
			continue
		}
	}
}