// 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 }
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 BenchmarkReadWriteIPv4UDP(b *testing.B) { c, dst, err := benchmarkUDPListener() if err != nil { b.Fatalf("benchmarkUDPListener failed: %v", 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.Fatalf("ipv4.PacketConn.SetControlMessage failed: %v", 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) } }
func TestPacketConnUnicastSocketOptions(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.FlagLoopback) 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 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(iana.DiffServCS7) 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 "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.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 { 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(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 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) } } }