func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) { switch runtime.GOOS { case "plan9", "windows": t.Skipf("not supported on %q", 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.Fatalf("net.ListenPacket failed: %v", err) } defer c1.Close() c2, err := net.ListenPacket("udp4", "224.0.0.0:1024") // wildcard address with reusable port if err != nil { t.Fatalf("net.ListenPacket failed: %v", 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.Fatalf("net.Interfaces failed: %v", 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.Fatalf("ipv4.PacketConn.JoinGroup %v on %v failed: %v", gaddr, ifi, err) } } mift = append(mift, &ift[i]) } for _, ifi := range mift { for _, p := range ps { if err := p.LeaveGroup(ifi, gaddr); err != nil { t.Fatalf("ipv4.PacketConn.LeaveGroup %v on %v failed: %v", gaddr, ifi, err) } } } } }
func TestUDPMultipleConnWithMultipleGroupListeners(t *testing.T) { if testing.Short() || !*testExternal { t.Logf("skipping test to avoid external network") return } for _, tt := range udpMultipleGroupListenerTests { // listen to a group address, actually a wildcard address // with reusable port c1, err := net.ListenPacket("udp4", "224.0.0.0:1024") // see RFC 4727 if err != nil { t.Fatalf("net.ListenPacket failed: %v", err) } defer c1.Close() c2, err := net.ListenPacket("udp4", "224.0.0.0:1024") // see RFC 4727 if err != nil { t.Fatalf("net.ListenPacket failed: %v", 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.Fatalf("net.Interfaces failed: %v", err) } for i, ifi := range ift { if _, ok := isGoodForMulticast(&ifi); !ok { continue } for _, p := range ps { if err := p.JoinGroup(&ifi, tt.gaddr); err != nil { t.Fatalf("ipv4.PacketConn.JoinGroup %v on %v failed: %v", tt.gaddr, ifi, err) } } mift = append(mift, &ift[i]) } for _, ifi := range mift { for _, p := range ps { if err := p.LeaveGroup(ifi, tt.gaddr); err != nil { t.Fatalf("ipv4.PacketConn.LeaveGroup %v on %v failed: %v", tt.gaddr, ifi, err) } } } } }
func TestReadWriteMulticastIPPayloadUDP(t *testing.T) { if testing.Short() || !*testExternal { t.Logf("skipping test to avoid external network") return } c, err := net.ListenPacket("udp4", "224.0.0.0:1024") // see RFC 4727 if err != nil { t.Fatalf("net.ListenPacket failed: %v", err) } defer c.Close() ifi := loopbackInterface() if ifi == nil { t.Logf("skipping test; an appropriate interface not found") return } dst, err := net.ResolveUDPAddr("udp4", "224.0.0.254:1024") // see RFC 4727 if err != nil { t.Fatalf("net.ResolveUDPAddr failed: %v", err) } p := ipv4.NewPacketConn(c) if err := p.JoinGroup(ifi, dst); err != nil { t.Fatalf("ipv4.PacketConn.JoinGroup on %v failed: %v", ifi, err) } if err := p.SetMulticastInterface(ifi); err != nil { t.Fatalf("ipv4.PacketConn.SetMulticastInterface failed: %v", err) } if err := p.SetMulticastLoopback(true); err != nil { t.Fatalf("ipv4.PacketConn.SetMulticastLoopback failed: %v", err) } runPayloadTransponder(t, p, []byte("HELLO-R-U-THERE"), dst) }
// 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) }
func TestReadWriteMulticastIPPayloadICMP(t *testing.T) { if testing.Short() || !*testExternal { t.Logf("skipping test to avoid external network") return } if os.Getuid() != 0 { t.Logf("skipping test; must be root") return } c, err := net.ListenPacket("ip4:icmp", "0.0.0.0") if err != nil { t.Fatalf("net.ListenPacket failed: %v", err) } defer c.Close() ifi := loopbackInterface() if ifi == nil { t.Logf("skipping test; an appropriate interface not found") return } dst, err := net.ResolveIPAddr("ip4", "224.0.0.254") // see RFC 4727 if err != nil { t.Fatalf("net.ResolveIPAddr failed: %v", err) } p := ipv4.NewPacketConn(c) if err := p.JoinGroup(ifi, dst); err != nil { t.Fatalf("ipv4.PacketConn.JoinGroup on %v failed: %v", ifi, err) } if err := p.SetMulticastInterface(ifi); err != nil { t.Fatalf("ipv4.PacketConn.SetMulticastInterface failed: %v", err) } cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface for i, toggle := range []bool{true, false, true} { wb, err := (&icmpMessage{ Type: icmpv4EchoRequest, Code: 0, Body: &icmpEcho{ ID: os.Getpid() & 0xffff, Seq: i + 1, Data: []byte("HELLO-R-U-THERE"), }, }).Marshal() if err != nil { t.Fatalf("icmpMessage.Marshal failed: %v", err) } if err := p.SetControlMessage(cf, toggle); err != nil { t.Fatalf("ipv4.PacketConn.SetControlMessage failed: %v", err) } rb := writeThenReadPayload(t, i, p, wb, dst) m, err := parseICMPMessage(rb) if err != nil { t.Fatalf("parseICMPMessage failed: %v", err) } if m.Type != icmpv4EchoReply || m.Code != 0 { t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, icmpv4EchoReply, 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 }
// args: // - addr: multicast group/address to listen to // - port: port number; addr:port builds the mcast socket // - iface: name of network interface to listen to // - d_dl_sock: // - stopch: func ListenUDPMcast(addr, port, iface string, d_dl_sock *zmq.Socket, stopch chan bool) { eth, err := net.InterfaceByName(iface) if err != nil { fmt.Println("Error interface:", err.Error()) os.Exit(1) } group := net.ParseIP(addr) if group == nil { fmt.Println("Error: invalid group address:", addr) os.Exit(1) } // listen to all udp packets on mcast port c, err := net.ListenPacket("udp4", "0.0.0.0:"+port) if err != nil { fmt.Println("Error listening for mcast:", err.Error()) os.Exit(1) } // close the listener when the application closes defer c.Close() // join mcast group p := ipv4.NewPacketConn(c) if err := p.JoinGroup(eth, &net.UDPAddr{IP: group}); err != nil { fmt.Println("Error joining:", err.Error()) os.Exit(1) } fmt.Println("Listening on " + addr + ":" + port) // enable transmissons of control message if err := p.SetControlMessage(ipv4.FlagDst, true); err != nil { fmt.Println("Error control message", err.Error()) } c1 := devreader.MakeChannel(UMSocket{p, group}) LOOP: for { select { case v1 := <-c1: fmt.Println("received UDP multicast") // forward to coord node d_dl_sock.Send(string(v1), 0) case <-stopch: break LOOP } } }
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.Fatalf("net.ListenPacket failed: %v", err) } defer c.Close() dst, err := net.ResolveUDPAddr("udp4", c.LocalAddr().String()) if err != nil { t.Fatalf("net.ResolveUDPAddr failed: %v", err) } p := ipv4.NewPacketConn(c) defer p.Close() cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface for i, toggle := range []bool{true, false, true} { if err := p.SetControlMessage(cf, toggle); err != nil { if protocolNotSupported(err) { t.Skipf("not supported on %q", runtime.GOOS) } t.Fatalf("ipv4.PacketConn.SetControlMessage failed: %v", err) } p.SetTTL(i + 1) if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil { t.Fatalf("ipv4.PacketConn.SetWriteDeadline failed: %v", err) } if _, err := p.WriteTo([]byte("HELLO-R-U-THERE"), nil, dst); err != nil { t.Fatalf("ipv4.PacketConn.WriteTo failed: %v", err) } rb := make([]byte, 128) if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil { t.Fatalf("ipv4.PacketConn.SetReadDeadline failed: %v", err) } if _, cm, _, err := p.ReadFrom(rb); err != nil { t.Fatalf("ipv4.PacketConn.ReadFrom failed: %v", err) } else { t.Logf("rcvd cmsg: %v", cm) } } }
func TestUDPUnicastSockopt(t *testing.T) { for _, tt := range unicastSockoptTests { c, err := net.ListenPacket("udp4", "127.0.0.1:0") if err != nil { t.Errorf("net.ListenPacket failed: %v", err) return } defer c.Close() p := ipv4.NewPacketConn(c) if err := testUnicastSockopt(t, tt, p); err != nil { break } } }
func TestReadWriteUnicastIPPayloadUDP(t *testing.T) { c, err := net.ListenPacket("udp4", "127.0.0.1:0") if err != nil { t.Fatalf("net.ListenPacket failed: %v", err) } defer c.Close() dst, err := net.ResolveUDPAddr("udp4", c.LocalAddr().String()) if err != nil { t.Fatalf("net.ResolveUDPAddr failed: %v", err) } p := ipv4.NewPacketConn(c) runPayloadTransponder(t, p, []byte("HELLO-R-U-THERE"), dst) }
func TestUDPMulticastSockopt(t *testing.T) { if testing.Short() || !*testExternal { t.Skip("to avoid external network") } for _, tt := range multicastSockoptTests { c, err := net.ListenPacket("udp4", "0.0.0.0:0") if err != nil { t.Fatalf("net.ListenPacket failed: %v", err) } defer c.Close() p := ipv4.NewPacketConn(c) testMulticastSockopt(t, tt, p, &net.UDPAddr{IP: tt.gaddr}) } }
func (s *Ssdp) createSocket() error { group := net.IPv4(239, 255, 255, 250) interfaces, err := net.Interfaces() if err != nil { s.logger.Errorf("net.Interfaces error", err) return err } con, err := net.ListenPacket("udp4", "0.0.0.0:1900") if err != nil { s.logger.Errorf("net.ListenPacket error: %v", err) return err } p := ipv4.NewPacketConn(con) p.SetMulticastLoopback(true) didFindInterface := false for i, v := range interfaces { ef, err := v.Addrs() if err != nil { continue } hasRealAddress := false for k := range ef { asIp := net.ParseIP(ef[k].String()) if asIp.IsUnspecified() { continue } hasRealAddress = true break } if !hasRealAddress { continue } err = p.JoinGroup(&v, &net.UDPAddr{IP: group}) if err != nil { s.logger.Warnf("join group %d %v", i, err) continue } didFindInterface = true } if !didFindInterface { return errors.New("Unable to find a compatible network interface!") } s.socket.socket = p s.socket.rawSocket = con s.socket.readBytes = make([]byte, 2048) return nil }
func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) { switch runtime.GOOS { case "plan9", "windows": t.Skipf("not supported on %q", 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.Fatalf("net.Interfaces failed: %v", 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.Fatalf("net.ListenPacket with %v failed: %v", ip, err) } defer c.Close() p := ipv4.NewPacketConn(c) if err := p.JoinGroup(&ifi, &gaddr); err != nil { t.Fatalf("ipv4.PacketConn.JoinGroup on %v failed: %v", ifi, err) } mlt = append(mlt, &ml{p, &ift[i]}) } for _, m := range mlt { if err := m.c.LeaveGroup(m.ifi, &gaddr); err != nil { t.Fatalf("ipv4.PacketConn.LeaveGroup on %v failed: %v", m.ifi, err) } } }
func TestReadWriteUnicastIPPayloadICMP(t *testing.T) { if os.Getuid() != 0 { t.Logf("skipping test; must be root") return } c, err := net.ListenPacket("ip4:icmp", "0.0.0.0") if err != nil { t.Fatalf("net.ListenPacket failed: %v", err) } defer c.Close() dst, err := net.ResolveIPAddr("ip4", "127.0.0.1") if err != nil { t.Fatalf("ResolveIPAddr failed: %v", err) } p := ipv4.NewPacketConn(c) cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface for i, toggle := range []bool{true, false, true} { wb, err := (&icmpMessage{ Type: icmpv4EchoRequest, Code: 0, Body: &icmpEcho{ ID: os.Getpid() & 0xffff, Seq: i + 1, Data: []byte("HELLO-R-U-THERE"), }, }).Marshal() if err != nil { t.Fatalf("icmpMessage.Marshal failed: %v", err) } if err := p.SetControlMessage(cf, toggle); err != nil { t.Fatalf("ipv4.PacketConn.SetControlMessage failed: %v", err) } rb := writeThenReadPayload(t, i, p, wb, dst) m, err := parseICMPMessage(rb) if err != nil { t.Fatalf("parseICMPMessage failed: %v", err) } if m.Type != icmpv4EchoReply || m.Code != 0 { t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, icmpv4EchoReply, 0) } } }
func BenchmarkReadWriteIPv4UDP(b *testing.B) { c, dst, err := benchmarkUDPListener() if err != nil { b.Fatalf("benchmarkUDPListener failed: %v", err) } defer c.Close() p := ipv4.NewPacketConn(c) cf := ipv4.FlagTTL | ipv4.FlagInterface if err := p.SetControlMessage(cf, true); err != nil { b.Fatalf("ipv4.PacketConn.SetControlMessage failed: %v", err) } ifi := loopbackInterface() 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) } }
func TestReadWriteUnicastIPPayloadUDP(t *testing.T) { c, err := net.ListenPacket("udp4", "127.0.0.1:0") if err != nil { t.Fatalf("net.ListenPacket failed: %v", err) } defer c.Close() dst, err := net.ResolveUDPAddr("udp4", c.LocalAddr().String()) if err != nil { t.Fatalf("net.ResolveUDPAddr failed: %v", err) } p := ipv4.NewPacketConn(c) cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface for i, toggle := range []bool{true, false, true} { if err := p.SetControlMessage(cf, toggle); err != nil { t.Fatalf("ipv4.PacketConn.SetControlMessage failed: %v", err) } writeThenReadPayload(t, i, p, []byte("HELLO-R-U-THERE"), dst) } }
func TestUDPPerInterfaceSingleConnWithSingleGroupListener(t *testing.T) { if testing.Short() || !*testExternal { t.Logf("skipping test to avoid external network") return } 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.Fatalf("net.Interfaces failed: %v", err) } for i, ifi := range ift { ip, ok := isGoodForMulticast(&ifi) if !ok { continue } // listen to a unicast interface address c, err := net.ListenPacket("udp4", ip.String()+":"+"1024") // see RFC 4727 if err != nil { t.Fatalf("net.ListenPacket with %v failed: %v", ip, err) } defer c.Close() p := ipv4.NewPacketConn(c) if err := p.JoinGroup(&ifi, gaddr); err != nil { t.Fatalf("ipv4.PacketConn.JoinGroup on %v failed: %v", ifi, err) } mlt = append(mlt, &ml{p, &ift[i]}) } for _, m := range mlt { if err := m.c.LeaveGroup(m.ifi, gaddr); err != nil { t.Fatalf("ipv4.PacketConn.LeaveGroup on %v failed: %v", m.ifi, err) } } }
func TestReadWriteMulticastIPPayloadUDP(t *testing.T) { if testing.Short() || !*testExternal { t.Logf("skipping test to avoid external network") return } c, err := net.ListenPacket("udp4", "224.0.0.0:1024") // see RFC 4727 if err != nil { t.Fatalf("net.ListenPacket failed: %v", err) } defer c.Close() ifi := loopbackInterface() if ifi == nil { t.Logf("skipping test; an appropriate interface not found") return } dst, err := net.ResolveUDPAddr("udp4", "224.0.0.254:1024") // see RFC 4727 if err != nil { t.Fatalf("net.ResolveUDPAddr failed: %v", err) } p := ipv4.NewPacketConn(c) if err := p.JoinGroup(ifi, dst); err != nil { t.Fatalf("ipv4.PacketConn.JoinGroup on %v failed: %v", ifi, err) } if err := p.SetMulticastInterface(ifi); err != nil { t.Fatalf("ipv4.PacketConn.SetMulticastInterface failed: %v", err) } if err := p.SetMulticastLoopback(true); err != nil { t.Fatalf("ipv4.PacketConn.SetMulticastLoopback failed: %v", err) } cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface for i, toggle := range []bool{true, false, true} { if err := p.SetControlMessage(cf, toggle); err != nil { t.Fatalf("ipv4.PacketConn.SetControlMessage failed: %v", err) } writeThenReadPayload(t, i, p, []byte("HELLO-R-U-THERE"), dst) } }
func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) { switch runtime.GOOS { case "plan9", "windows": t.Skipf("not supported on %q", runtime.GOOS) } if testing.Short() || !*testExternal { t.Skip("to avoid external network") } for _, gaddr := range udpMultipleGroupListenerTests { c, err := net.ListenPacket("udp4", "0.0.0.0:0") // wildcard address with no reusable port if err != nil { t.Fatalf("net.ListenPacket failed: %v", err) } defer c.Close() p := ipv4.NewPacketConn(c) var mift []*net.Interface ift, err := net.Interfaces() if err != nil { t.Fatalf("net.Interfaces failed: %v", err) } for i, ifi := range ift { if _, ok := isMulticastAvailable(&ifi); !ok { continue } if err := p.JoinGroup(&ifi, gaddr); err != nil { t.Fatalf("ipv4.PacketConn.JoinGroup %v on %v failed: %v", gaddr, ifi, err) } mift = append(mift, &ift[i]) } for _, ifi := range mift { if err := p.LeaveGroup(ifi, gaddr); err != nil { t.Fatalf("ipv4.PacketConn.LeaveGroup %v on %v failed: %v", gaddr, ifi, err) } } } }
func TestReadWriteUnicastIPPayloadICMP(t *testing.T) { if os.Getuid() != 0 { t.Logf("skipping test; must be root") return } c, err := net.ListenPacket("ip4:icmp", "0.0.0.0") if err != nil { t.Fatalf("net.ListenPacket failed: %v", err) } defer c.Close() dst, err := net.ResolveIPAddr("ip4", "127.0.0.1") if err != nil { t.Fatalf("ResolveIPAddr failed: %v", err) } p := ipv4.NewPacketConn(c) id := os.Getpid() & 0xffff pld := newICMPEchoRequest(id, 1, 128, []byte("HELLO-R-U-THERE")) runPayloadTransponder(t, p, pld, dst) }
func TestPacketConnUnicastSocketOptions(t *testing.T) { switch runtime.GOOS { case "plan9": t.Skipf("not supported on %q", runtime.GOOS) } ifi := loopbackInterface() if ifi == nil { t.Skipf("not available on %q", runtime.GOOS) } for _, tt := range packetConnUnicastSocketOptionTests { if tt.net == "ip4" && os.Getuid() != 0 { t.Skip("must be root") } c, err := net.ListenPacket(tt.net+tt.proto, tt.addr) if err != nil { t.Fatalf("net.ListenPacket(%q, %q) failed: %v", tt.net+tt.proto, tt.addr, err) } defer c.Close() testUnicastSocketOptions(t, ipv4.NewPacketConn(c)) } }
func TestPacketConnMulticastSocketOptions(t *testing.T) { switch runtime.GOOS { case "nacl", "plan9", "solaris": t.Skipf("not supported on %q", runtime.GOOS) } ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback) if ifi == nil { t.Skipf("not available on %q", runtime.GOOS) } for _, tt := range packetConnMulticastSocketOptionTests { if tt.net == "ip4" && os.Getuid() != 0 { t.Skip("must be root") } c, err := net.ListenPacket(tt.net+tt.proto, tt.addr) if err != nil { t.Fatalf("net.ListenPacket failed: %v", err) } defer c.Close() testMulticastSocketOptions(t, ipv4.NewPacketConn(c), ifi, tt.gaddr) } }
func TestReadWriteMulticastIPPayloadICMP(t *testing.T) { if testing.Short() || !*testExternal { t.Logf("skipping test to avoid external network") return } if os.Getuid() != 0 { t.Logf("skipping test; must be root") return } c, err := net.ListenPacket("ip4:icmp", "0.0.0.0") if err != nil { t.Fatalf("net.ListenPacket failed: %v", err) } defer c.Close() ifi := loopbackInterface() if ifi == nil { t.Logf("skipping test; an appropriate interface not found") return } dst, err := net.ResolveIPAddr("ip4", "224.0.0.254") // see RFC 4727 if err != nil { t.Fatalf("net.ResolveIPAddr failed: %v", err) } p := ipv4.NewPacketConn(c) if err := p.JoinGroup(ifi, dst); err != nil { t.Fatalf("ipv4.PacketConn.JoinGroup on %v failed: %v", ifi, err) } if err := p.SetMulticastInterface(ifi); err != nil { t.Fatalf("ipv4.PacketConn.SetMulticastInterface failed: %v", err) } id := os.Getpid() & 0xffff pld := newICMPEchoRequest(id, 1, 128, []byte("HELLO-R-U-THERE")) runPayloadTransponder(t, p, pld, dst) }
func TestUDPSingleConnWithMultipleGroupListeners(t *testing.T) { if testing.Short() || !*testExternal { t.Logf("skipping test to avoid external network") return } for _, tt := range udpMultipleGroupListenerTests { // listen to a wildcard address with no reusable port c, err := net.ListenPacket("udp4", "0.0.0.0:0") if err != nil { t.Fatalf("net.ListenPacket failed: %v", err) } defer c.Close() p := ipv4.NewPacketConn(c) var mift []*net.Interface ift, err := net.Interfaces() if err != nil { t.Fatalf("net.Interfaces failed: %v", err) } for i, ifi := range ift { if _, ok := isGoodForMulticast(&ifi); !ok { continue } if err := p.JoinGroup(&ifi, tt.gaddr); err != nil { t.Fatalf("ipv4.PacketConn.JoinGroup %v on %v failed: %v", tt.gaddr, ifi, err) } mift = append(mift, &ift[i]) } for _, ifi := range mift { if err := p.LeaveGroup(ifi, tt.gaddr); err != nil { t.Fatalf("ipv4.PacketConn.LeaveGroup %v on %v failed: %v", tt.gaddr, ifi, err) } } } }
// Returns UDP Multicast packet connection to read incoming bytes from func GetStreamSource(url conf.Url) (net.PacketConn, error) { f, err := getSocketFile(url.Source) if err != nil { return nil, err } c, err := net.FilePacketConn(f) if err != nil { log.Printf("Failed to get packet file connection: %s", err) return nil, err } f.Close() host, _, err := net.SplitHostPort(url.Source) ipAddr := net.ParseIP(host).To4() if err != nil { log.Printf("Cannot resolve address %s", url.Source) return nil, err } iface, _ := net.InterfaceByName(url.Interface) if err := ipv4.NewPacketConn(c).JoinGroup(iface, &net.UDPAddr{IP: net.IPv4(ipAddr[0], ipAddr[1], ipAddr[2], ipAddr[3])}); err != nil { log.Printf("Failed to join mulitcast group: %s", err) return nil, err } return c, nil }
func ExampleMulticastUDPListener() { en0, err := net.InterfaceByName("en0") if err != nil { log.Fatal(err) } en1, err := net.InterfaceByIndex(911) if err != nil { log.Fatal(err) } group := net.IPv4(224, 0, 0, 250) c, err := net.ListenPacket("udp4", "0.0.0.0:1024") if err != nil { log.Fatal(err) } defer c.Close() p := ipv4.NewPacketConn(c) err = p.JoinGroup(en0, &net.UDPAddr{IP: group}) if err != nil { log.Fatal(err) } err = p.JoinGroup(en1, &net.UDPAddr{IP: group}) if err != nil { log.Fatal(err) } err = p.SetControlMessage(ipv4.FlagDst, true) if err != nil { log.Fatal(err) } b := make([]byte, 1500) for { n, cm, src, err := p.ReadFrom(b) if err != nil { log.Fatal(err) } if cm.Dst.IsMulticast() { if cm.Dst.Equal(group) { // joined group, do something } else { // unknown group, discard continue } } p.SetTOS(ipv4.DSCP_CS7) p.SetTTL(16) _, err = p.WriteTo(b[:n], nil, src) if err != nil { log.Fatal(err) } dst := &net.UDPAddr{IP: group, Port: 1024} for _, ifi := range []*net.Interface{en0, en1} { err := p.SetMulticastInterface(ifi) if err != nil { log.Fatal(err) } p.SetMulticastTTL(2) _, err = p.WriteTo(b[:n], nil, dst) if err != nil { log.Fatal(err) } } } err = p.LeaveGroup(en1, &net.UDPAddr{IP: group}) if err != nil { log.Fatal(err) } newgroup := net.IPv4(224, 0, 0, 249) err = p.JoinGroup(en1, &net.UDPAddr{IP: newgroup}) if err != nil { log.Fatal(err) } }
func TestPacketConnReadWriteUnicastICMP(t *testing.T) { switch runtime.GOOS { case "plan9", "windows": t.Skipf("not supported on %q", runtime.GOOS) } if os.Getuid() != 0 { t.Skip("must be root") } ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback) if ifi == nil { t.Skipf("not available on %q", runtime.GOOS) } c, err := net.ListenPacket("ip4:icmp", "0.0.0.0") if err != nil { t.Fatalf("net.ListenPacket failed: %v", err) } defer c.Close() dst, err := net.ResolveIPAddr("ip4", "127.0.0.1") if err != nil { t.Fatalf("ResolveIPAddr failed: %v", err) } p := ipv4.NewPacketConn(c) defer p.Close() cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface for i, toggle := range []bool{true, false, true} { wb, err := (&icmp.Message{ Type: ipv4.ICMPTypeEcho, Code: 0, Body: &icmp.Echo{ ID: os.Getpid() & 0xffff, Seq: i + 1, Data: []byte("HELLO-R-U-THERE"), }, }).Marshal(nil) if err != nil { t.Fatalf("icmp.Message.Marshal failed: %v", err) } if err := p.SetControlMessage(cf, toggle); err != nil { t.Fatalf("ipv4.PacketConn.SetControlMessage failed: %v", err) } p.SetTTL(i + 1) if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil { t.Fatalf("ipv4.PacketConn.SetWriteDeadline failed: %v", err) } if _, err := p.WriteTo(wb, nil, dst); err != nil { t.Fatalf("ipv4.PacketConn.WriteTo failed: %v", err) } b := make([]byte, 128) loop: if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil { t.Fatalf("ipv4.PacketConn.SetReadDeadline failed: %v", err) } if n, cm, _, err := p.ReadFrom(b); err != nil { t.Fatalf("ipv4.PacketConn.ReadFrom failed: %v", err) } else { t.Logf("rcvd cmsg: %v", cm) m, err := icmp.ParseMessage(iana.ProtocolICMP, b[:n]) if err != nil { t.Fatalf("icmp.ParseMessage failed: %v", err) } if runtime.GOOS == "linux" && m.Type == ipv4.ICMPTypeEcho { // On Linux we must handle own sent packets. goto loop } if m.Type != ipv4.ICMPTypeEchoReply || m.Code != 0 { t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0) } } } }
func (b *Beacon) start() (err error) { if b.iface == "" { b.iface = os.Getenv("BEACON_INTERFACE") } if b.iface == "" { b.iface = os.Getenv("ZSYS_INTERFACE") } var ifs []net.Interface if b.iface == "" { ifs, err = net.Interfaces() if err != nil { return err } } else { iface, err := net.InterfaceByName(b.iface) if err != nil { return err } ifs = append(ifs, *iface) } conn, err := net.ListenPacket("udp4", net.JoinHostPort("224.0.0.0", strconv.Itoa(b.port))) if err == nil { b.ipv4Conn = ipv4.NewPacketConn(conn) b.ipv4Conn.SetMulticastLoopback(true) b.ipv4Conn.SetControlMessage(ipv4.FlagSrc, true) } if !b.ipv4 { conn, err := net.ListenPacket("udp6", net.JoinHostPort(net.IPv6linklocalallnodes.String(), strconv.Itoa(b.port))) if err != nil { return err } b.ipv6Conn = ipv6.NewPacketConn(conn) b.ipv6Conn.SetMulticastLoopback(true) b.ipv6Conn.SetControlMessage(ipv6.FlagSrc, true) } broadcast := os.Getenv("BEACON_BROADCAST") != "" for _, iface := range ifs { if b.ipv4Conn != nil { b.inAddr = &net.UDPAddr{ IP: net.ParseIP(ipv4Group), } b.ipv4Conn.JoinGroup(&iface, b.inAddr) // Find IP of the interface // TODO(armen): Let user set the ipaddress which here can be verified to be valid addrs, err := iface.Addrs() if err != nil { return err } if len(addrs) <= 0 { return errors.New("no address to bind to") } ip, ipnet, err := net.ParseCIDR(addrs[0].String()) if err != nil { return err } b.addr = ip.String() switch { case broadcast: bcast := ipnet.IP for i := 0; i < len(ipnet.Mask); i++ { bcast[i] |= ^ipnet.Mask[i] } b.outAddr = &net.UDPAddr{IP: bcast, Port: b.port} case iface.Flags&net.FlagLoopback != 0: b.outAddr = &net.UDPAddr{IP: net.IPv4allsys, Port: b.port} default: b.outAddr = &net.UDPAddr{IP: net.ParseIP(ipv4Group), Port: b.port} } break } else if b.ipv6Conn != nil { b.inAddr = &net.UDPAddr{ IP: net.ParseIP(ipv6Group), } b.ipv6Conn.JoinGroup(&iface, b.inAddr) // Find IP of the interface // TODO(armen): Let user set the ipaddress which here can be verified to be valid addrs, err := iface.Addrs() if err != nil { return err } ip, ipnet, err := net.ParseCIDR(addrs[0].String()) if err != nil { return err } b.addr = ip.String() switch { case broadcast: bcast := ipnet.IP for i := 0; i < len(ipnet.Mask); i++ { bcast[i] |= ^ipnet.Mask[i] } b.outAddr = &net.UDPAddr{IP: bcast, Port: b.port} case iface.Flags&net.FlagLoopback != 0: b.outAddr = &net.UDPAddr{IP: net.IPv6interfacelocalallnodes, Port: b.port} default: b.outAddr = &net.UDPAddr{IP: net.ParseIP(ipv6Group), Port: b.port} } break } } if b.ipv4Conn == nil && b.ipv6Conn == nil { return errors.New("no interfaces to bind to") } go b.listen() go b.signal() return nil }
func TestPacketConnReadWriteMulticastICMP(t *testing.T) { switch runtime.GOOS { case "nacl", "plan9", "solaris", "windows": t.Skipf("not supported on %q", runtime.GOOS) } if os.Getuid() != 0 { t.Skip("must be root") } ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback) if ifi == nil { t.Skipf("not available on %q", runtime.GOOS) } c, err := net.ListenPacket("ip4:icmp", "0.0.0.0") if err != nil { t.Fatalf("net.ListenPacket failed: %v", err) } defer c.Close() dst, err := net.ResolveIPAddr("ip4", "224.0.0.254") // see RFC 4727 if err != nil { t.Fatalf("net.ResolveIPAddr failed: %v", err) } p := ipv4.NewPacketConn(c) defer p.Close() if err := p.JoinGroup(ifi, dst); err != nil { t.Fatalf("ipv4.PacketConn.JoinGroup on %v failed: %v", ifi, err) } if err := p.SetMulticastInterface(ifi); err != nil { t.Fatalf("ipv4.PacketConn.SetMulticastInterface failed: %v", err) } if _, err := p.MulticastInterface(); err != nil { t.Fatalf("ipv4.PacketConn.MulticastInterface failed: %v", err) } if err := p.SetMulticastLoopback(true); err != nil { t.Fatalf("ipv4.PacketConn.SetMulticastLoopback failed: %v", err) } if _, err := p.MulticastLoopback(); err != nil { t.Fatalf("ipv4.PacketConn.MulticastLoopback failed: %v", err) } cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface for i, toggle := range []bool{true, false, true} { wb, err := (&icmp.Message{ Type: ipv4.ICMPTypeEcho, Code: 0, Body: &icmp.Echo{ ID: os.Getpid() & 0xffff, Seq: i + 1, Data: []byte("HELLO-R-U-THERE"), }, }).Marshal(nil) if err != nil { t.Fatalf("icmp.Message.Marshal failed: %v", err) } if err := p.SetControlMessage(cf, toggle); err != nil { if protocolNotSupported(err) { t.Skipf("not supported on %q", runtime.GOOS) } t.Fatalf("ipv4.PacketConn.SetControlMessage failed: %v", err) } if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil { t.Fatalf("ipv4.PacketConn.SetDeadline failed: %v", err) } p.SetMulticastTTL(i + 1) if _, err := p.WriteTo(wb, nil, dst); err != nil { t.Fatalf("ipv4.PacketConn.WriteTo failed: %v", err) } b := make([]byte, 128) if n, cm, _, err := p.ReadFrom(b); err != nil { t.Fatalf("ipv4.PacketConn.ReadFrom failed: %v", err) } else { t.Logf("rcvd cmsg: %v", cm) m, err := icmp.ParseMessage(iana.ProtocolICMP, b[:n]) if err != nil { t.Fatalf("icmp.ParseMessage failed: %v", err) } switch { case m.Type == ipv4.ICMPTypeEchoReply && m.Code == 0: // net.inet.icmp.bmcastecho=1 case m.Type == ipv4.ICMPTypeEcho && m.Code == 0: // net.inet.icmp.bmcastecho=0 default: t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0) } } } }
func TestPacketConnReadWriteMulticastUDP(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.FlagMulticast|net.FlagLoopback) if ifi == nil { t.Skipf("not available on %q", runtime.GOOS) } c, err := net.ListenPacket("udp4", "224.0.0.0:0") // see RFC 4727 if err != nil { t.Fatalf("net.ListenPacket failed: %v", err) } defer c.Close() _, port, err := net.SplitHostPort(c.LocalAddr().String()) if err != nil { t.Fatalf("net.SplitHostPort failed: %v", err) } dst, err := net.ResolveUDPAddr("udp4", "224.0.0.254:"+port) // see RFC 4727 if err != nil { t.Fatalf("net.ResolveUDPAddr failed: %v", err) } p := ipv4.NewPacketConn(c) defer p.Close() if err := p.JoinGroup(ifi, dst); err != nil { t.Fatalf("ipv4.PacketConn.JoinGroup on %v failed: %v", ifi, err) } if err := p.SetMulticastInterface(ifi); err != nil { t.Fatalf("ipv4.PacketConn.SetMulticastInterface failed: %v", err) } if _, err := p.MulticastInterface(); err != nil { t.Fatalf("ipv4.PacketConn.MulticastInterface failed: %v", err) } if err := p.SetMulticastLoopback(true); err != nil { t.Fatalf("ipv4.PacketConn.SetMulticastLoopback failed: %v", err) } if _, err := p.MulticastLoopback(); err != nil { t.Fatalf("ipv4.PacketConn.MulticastLoopback failed: %v", err) } cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface for i, toggle := range []bool{true, false, true} { if err := p.SetControlMessage(cf, toggle); err != nil { if protocolNotSupported(err) { t.Skipf("not supported on %q", runtime.GOOS) } t.Fatalf("ipv4.PacketConn.SetControlMessage failed: %v", err) } if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil { t.Fatalf("ipv4.PacketConn.SetDeadline failed: %v", err) } p.SetMulticastTTL(i + 1) if _, err := p.WriteTo([]byte("HELLO-R-U-THERE"), nil, dst); err != nil { t.Fatalf("ipv4.PacketConn.WriteTo failed: %v", err) } b := make([]byte, 128) if _, cm, _, err := p.ReadFrom(b); err != nil { t.Fatalf("ipv4.PacketConn.ReadFrom failed: %v", err) } else { t.Logf("rcvd cmsg: %v", cm) } } }