func TestRawConnMulticastSocketOptions(t *testing.T) { switch runtime.GOOS { case "nacl", "plan9", "solaris": 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() r, err := ipv4.NewRawConn(c) if err != nil { t.Fatalf("ipv4.NewRawConn failed: %v", err) } testMulticastSocketOptions(t, r, ifi, &net.IPAddr{IP: net.IPv4(224, 0, 0, 250)}) /// see RFC 4727 }
func TestRawConnUnicastSocketOptions(t *testing.T) { switch runtime.GOOS { case "plan9": t.Skipf("not supported on %q", runtime.GOOS) } if os.Getuid() != 0 { t.Skip("must be root") } ifi := loopbackInterface() if ifi == nil { t.Skipf("not available on %q", runtime.GOOS) } c, err := net.ListenPacket("ip4:icmp", "127.0.0.1") if err != nil { t.Fatalf("net.ListenPacket failed: %v", err) } defer c.Close() r, err := ipv4.NewRawConn(c) if err != nil { t.Fatalf("ipv4.NewRawConn failed: %v", err) } testUnicastSocketOptions(t, r) }
func TestReadWriteUnicastIPDatagram(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) } r, err := ipv4.NewRawConn(c) if err != nil { t.Fatalf("ipv4.NewRawConn failed: %v", err) } id := os.Getpid() & 0xffff pld := newICMPEchoRequest(id, 1, 128, []byte("HELLO-R-U-THERE")) runDatagramTransponder(t, r, pld, nil, dst) }
func ExampleWriteIPOSPFHello() { var ifs []*net.Interface en0, err := net.InterfaceByName("en0") if err != nil { log.Fatal(err) } ifs = append(ifs, en0) en1, err := net.InterfaceByIndex(911) if err != nil { log.Fatal(err) } ifs = append(ifs, en1) c, err := net.ListenPacket("ip4:89", "0.0.0.0") if err != nil { log.Fatal(err) } defer c.Close() r, err := ipv4.NewRawConn(c) if err != nil { log.Fatal(err) } for _, ifi := range ifs { err := r.JoinGroup(ifi, &net.IPAddr{IP: AllSPFRouters}) if err != nil { log.Fatal(err) } err = r.JoinGroup(ifi, &net.IPAddr{IP: AllDRouters}) if err != nil { log.Fatal(err) } } hello := make([]byte, OSPFHelloHeaderLen) ospf := make([]byte, OSPFHeaderLen) ospf[0] = OSPF_VERSION ospf[1] = OSPF_TYPE_HELLO ospf = append(ospf, hello...) iph := &ipv4.Header{} iph.Version = ipv4.Version iph.Len = ipv4.HeaderLen iph.TOS = ipv4.DSCP_CS6 iph.TotalLen = ipv4.HeaderLen + len(ospf) iph.TTL = 1 iph.Protocol = 89 iph.Dst = AllSPFRouters for _, ifi := range ifs { err := r.SetMulticastInterface(ifi) if err != nil { return } err = r.WriteTo(iph, ospf, nil) if err != nil { return } } }
func TestReadWriteMulticastIPDatagram(t *testing.T) { if testing.Short() || !*testExternal { t.Skip("to avoid external network") } if os.Getuid() != 0 { t.Skip("must be root") } 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.Skip("an appropriate interface not found") } dst, err := net.ResolveIPAddr("ip4", "224.0.0.254") // see RFC 4727 if err != nil { t.Fatalf("ResolveIPAddr failed: %v", err) } r, err := ipv4.NewRawConn(c) if err != nil { t.Fatalf("ipv4.NewRawConn failed: %v", err) } if err := r.JoinGroup(ifi, dst); err != nil { t.Fatalf("ipv4.RawConn.JoinGroup on %v failed: %v", ifi, err) } if err := r.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: ipv4.ICMPTypeEcho, 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 := r.SetControlMessage(cf, toggle); err != nil { t.Fatalf("ipv4.RawConn.SetControlMessage failed: %v", err) } rb := writeThenReadDatagram(t, i, r, wb, nil, dst) m, err := parseICMPMessage(rb) if err != nil { t.Fatalf("parseICMPMessage failed: %v", err) } 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 (rdns *RawDNS) DnsQuery(wg *sync.WaitGroup, config *config.Config, cm *chanman.ChanMan) { defer wg.Done() //set the IP headers rdns.IPHeaders.Src = rdns.LocalAddress rdns.IPHeaders.Dst = rdns.RemoteAddress rdns.IPHeaders.Protocol = IPProtoUDP rdns.IPHeaders.Len = IPHeaderLen rdns.IPHeaders.Version = 4 rdns.IPHeaders.TTL = 128 //set the query query := NewQuery() query.SetRequest(config.Query, "A") queryb := query.Marshal() //set the UDP headers rdns.UDPHeader.SetLen(8 + uint16(len(queryb))) rdns.UDPHeader.GenRandomSrcPort() rdns.UDPHeader.SetChecksum(0) udpHead, _ := rdns.UDPHeader.Marshal() //set the control message rdns.CtrlMsg.TTL = 128 rdns.CtrlMsg.IfIndex = config.Interface.Index //ip on mac, ip4:udp for linux con, err := net.ListenPacket("ip4:udp", "0.0.0.0") if err != nil { log.Fatalln(err) } //new raw packet connection rawCon, err := ipv4.NewRawConn(con) if err != nil { log.Fatalln(err) } //set query //query := []byte{0x0d, 0x35, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x64, 0x61, 0x69, 0x73, 0x79, 0x06, 0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01} //set final payload //set packet length rdns.IPHeaders.TotalLen = 20 + len(queryb) + len(udpHead) rdns.Payload = make([]byte, 0) rdns.Payload = append(rdns.Payload, udpHead...) rdns.Payload = append(rdns.Payload, queryb...) rawCon.WriteTo(rdns.IPHeaders, rdns.Payload, rdns.CtrlMsg) cm.RunChan <- true }
func TestIPPerInterfaceSingleRawConnWithSingleGroupListener(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") } if os.Getuid() != 0 { t.Skip("must be root") } gaddr := net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727 type ml struct { c *ipv4.RawConn 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("ip4:253", ip.String()) // unicast address if err != nil { t.Fatalf("net.ListenPacket with %v failed: %v", ip, err) } defer c.Close() r, err := ipv4.NewRawConn(c) if err != nil { t.Fatalf("ipv4.NewRawConn failed: %v", err) } if err := r.JoinGroup(&ifi, &gaddr); err != nil { t.Fatalf("ipv4.RawConn.JoinGroup on %v failed: %v", ifi, err) } mlt = append(mlt, &ml{r, &ift[i]}) } for _, m := range mlt { if err := m.c.LeaveGroup(m.ifi, &gaddr); err != nil { t.Fatalf("ipv4.RawConn.LeaveGroup on %v failed: %v", m.ifi, err) } } }
func TestIPPerInterfaceSingleConnWithSingleGroupListener(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 } gaddr := &net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727 type ml struct { c *ipv4.RawConn 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("ip4:253", ip.String()) // see RFC 4727 if err != nil { t.Fatalf("net.ListenPacket with %v failed: %v", ip, err) } defer c.Close() r, err := ipv4.NewRawConn(c) if err != nil { t.Fatalf("ipv4.NewRawConn failed: %v", err) } if err := r.JoinGroup(&ifi, gaddr); err != nil { t.Fatalf("ipv4.RawConn.JoinGroup on %v failed: %v", ifi, err) } mlt = append(mlt, &ml{r, &ift[i]}) } for _, m := range mlt { if err := m.c.LeaveGroup(m.ifi, gaddr); err != nil { t.Fatalf("ipv4.RawConn.LeaveGroup on %v failed: %v", m.ifi, err) } } }
func TestReadWriteUnicastIPDatagram(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) } r, err := ipv4.NewRawConn(c) if err != nil { t.Fatalf("ipv4.NewRawConn 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 := r.SetControlMessage(cf, toggle); err != nil { t.Fatalf("ipv4.RawConn.SetControlMessage failed: %v", err) } rb := writeThenReadDatagram(t, i, r, wb, nil, 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 TestIPSingleRawConnWithSingleGroupListener(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") } if os.Getuid() != 0 { t.Skip("must be root") } c, err := net.ListenPacket("ip4:icmp", "0.0.0.0") // wildcard address if err != nil { t.Fatalf("net.ListenPacket failed: %v", err) } defer c.Close() r, err := ipv4.NewRawConn(c) if err != nil { t.Fatalf("ipv4.RawConn failed: %v", err) } gaddr := net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727 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 } if err := r.JoinGroup(&ifi, &gaddr); err != nil { t.Fatalf("ipv4.RawConn.JoinGroup on %v failed: %v", ifi, err) } mift = append(mift, &ift[i]) } for _, ifi := range mift { if err := r.LeaveGroup(ifi, &gaddr); err != nil { t.Fatalf("ipv4.RawConn.LeaveGroup on %v failed: %v", ifi, err) } } }
func TestIPSingleConnWithSingleGroupListener(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 } // listen to a wildcard address c, err := net.ListenPacket("ip4:icmp", "0.0.0.0") if err != nil { t.Fatalf("net.ListenPacket failed: %v", err) } defer c.Close() r, err := ipv4.NewRawConn(c) if err != nil { t.Fatalf("ipv4.RawConn failed: %v", err) } gaddr := &net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727 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 := r.JoinGroup(&ifi, gaddr); err != nil { t.Fatalf("ipv4.RawConn.JoinGroup on %v failed: %v", ifi, err) } mift = append(mift, &ift[i]) } for _, ifi := range mift { if err := r.LeaveGroup(ifi, gaddr); err != nil { t.Fatalf("ipv4.RawConn.LeaveGroup on %v failed: %v", ifi, err) } } }
func TestIPMulticastSockopt(t *testing.T) { if testing.Short() || !*testExternal { t.Skip("to avoid external network") } if os.Getuid() != 0 { t.Skip("must be root") } for _, tt := range multicastSockoptTests { c, err := net.ListenPacket("ip4:icmp", "0.0.0.0") if err != nil { t.Fatalf("net.ListenPacket failed: %v", err) } defer c.Close() r, _ := ipv4.NewRawConn(c) testMulticastSockopt(t, tt, r, &net.IPAddr{IP: tt.gaddr}) } }
func TestReadWriteMulticastIPDatagram(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("ResolveIPAddr failed: %v", err) } r, err := ipv4.NewRawConn(c) if err != nil { t.Fatalf("ipv4.NewRawConn failed: %v", err) } if err := r.JoinGroup(ifi, dst); err != nil { t.Fatalf("ipv4.RawConn.JoinGroup on %v failed: %v", ifi, err) } if err := r.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")) runDatagramTransponder(t, r, pld, nil, dst) }
func TestIPUnicastSockopt(t *testing.T) { if os.Getuid() != 0 { t.Skip("must be root") } for _, tt := range unicastSockoptTests { c, err := net.ListenPacket("ip4:icmp", "127.0.0.1") if err != nil { t.Errorf("net.ListenPacket failed: %v", err) return } defer c.Close() r, err := ipv4.NewRawConn(c) if err != nil { t.Errorf("ipv4.NewRawConn failed: %v", err) return } if err := testUnicastSockopt(t, tt, r); err != nil { break } } }
func TestRawConnReadWriteMulticastICMP(t *testing.T) { if testing.Short() { t.Skip("to avoid external network") } 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("ResolveIPAddr failed: %v", err) } r, err := ipv4.NewRawConn(c) if err != nil { t.Fatalf("ipv4.NewRawConn failed: %v", err) } defer r.Close() if err := r.JoinGroup(ifi, dst); err != nil { t.Fatalf("ipv4.RawConn.JoinGroup on %v failed: %v", ifi, err) } if err := r.SetMulticastInterface(ifi); err != nil { t.Fatalf("ipv4.RawConn.SetMulticastInterface failed: %v", err) } if _, err := r.MulticastInterface(); err != nil { t.Fatalf("ipv4.RawConn.MulticastInterface failed: %v", err) } if err := r.SetMulticastLoopback(true); err != nil { t.Fatalf("ipv4.RawConn.SetMulticastLoopback failed: %v", err) } if _, err := r.MulticastLoopback(); err != nil { t.Fatalf("ipv4.RawConn.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) } wh := &ipv4.Header{ Version: ipv4.Version, Len: ipv4.HeaderLen, TOS: i + 1, TotalLen: ipv4.HeaderLen + len(wb), Protocol: 1, Dst: dst.IP, } if err := r.SetControlMessage(cf, toggle); err != nil { if protocolNotSupported(err) { t.Skipf("not supported on %q", runtime.GOOS) } t.Fatalf("ipv4.RawConn.SetControlMessage failed: %v", err) } if err := r.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil { t.Fatalf("ipv4.RawConn.SetDeadline failed: %v", err) } r.SetMulticastTTL(i + 1) if err := r.WriteTo(wh, wb, nil); err != nil { t.Fatalf("ipv4.RawConn.WriteTo failed: %v", err) } rb := make([]byte, ipv4.HeaderLen+128) if rh, b, cm, err := r.ReadFrom(rb); err != nil { t.Fatalf("ipv4.RawConn.ReadFrom failed: %v", err) } else { t.Logf("rcvd cmsg: %v", cm) m, err := icmp.ParseMessage(iana.ProtocolICMP, b) if err != nil { t.Fatalf("icmp.ParseMessage failed: %v", err) } switch { case (rh.Dst.IsLoopback() || rh.Dst.IsLinkLocalUnicast() || rh.Dst.IsGlobalUnicast()) && m.Type == ipv4.ICMPTypeEchoReply && m.Code == 0: // net.inet.icmp.bmcastecho=1 case rh.Dst.IsMulticast() && 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 ExampleIPOSPFListener() { var ifs []*net.Interface en0, err := net.InterfaceByName("en0") if err != nil { log.Fatal(err) } ifs = append(ifs, en0) en1, err := net.InterfaceByIndex(911) if err != nil { log.Fatal(err) } ifs = append(ifs, en1) c, err := net.ListenPacket("ip4:89", "0.0.0.0") if err != nil { log.Fatal(err) } defer c.Close() r, err := ipv4.NewRawConn(c) if err != nil { log.Fatal(err) } for _, ifi := range ifs { err := r.JoinGroup(ifi, &net.IPAddr{IP: AllSPFRouters}) if err != nil { log.Fatal(err) } err = r.JoinGroup(ifi, &net.IPAddr{IP: AllDRouters}) if err != nil { log.Fatal(err) } } err = r.SetControlMessage(ipv4.FlagDst|ipv4.FlagInterface, true) if err != nil { log.Fatal(err) } r.SetTOS(ipv4.DSCP_CS6) parseOSPFHeader := func(b []byte) *OSPFHeader { if len(b) < OSPFHeaderLen { return nil } return &OSPFHeader{ Version: b[0], Type: b[1], Len: uint16(b[2])<<8 | uint16(b[3]), RouterID: uint32(b[4])<<24 | uint32(b[5])<<16 | uint32(b[6])<<8 | uint32(b[7]), AreaID: uint32(b[8])<<24 | uint32(b[9])<<16 | uint32(b[10])<<8 | uint32(b[11]), Checksum: uint16(b[12])<<8 | uint16(b[13]), } } b := make([]byte, 1500) for { iph, p, _, err := r.ReadFrom(b) if err != nil { log.Fatal(err) } if iph.Version != ipv4.Version { continue } if iph.Dst.IsMulticast() { if !iph.Dst.Equal(AllSPFRouters) && !iph.Dst.Equal(AllDRouters) { continue } } ospfh := parseOSPFHeader(p) if ospfh == nil { continue } if ospfh.Version != OSPF_VERSION { continue } switch ospfh.Type { case OSPF_TYPE_HELLO: case OSPF_TYPE_DB_DESCRIPTION: case OSPF_TYPE_LS_REQUEST: case OSPF_TYPE_LS_UPDATE: case OSPF_TYPE_LS_ACK: } } }
func TestRawConnReadWriteUnicastICMP(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) } r, err := ipv4.NewRawConn(c) if err != nil { t.Fatalf("ipv4.NewRawConn failed: %v", err) } defer r.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) } wh := &ipv4.Header{ Version: ipv4.Version, Len: ipv4.HeaderLen, TOS: i + 1, TotalLen: ipv4.HeaderLen + len(wb), TTL: i + 1, Protocol: 1, Dst: dst.IP, } if err := r.SetControlMessage(cf, toggle); err != nil { t.Fatalf("ipv4.RawConn.SetControlMessage failed: %v", err) } if err := r.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil { t.Fatalf("ipv4.RawConn.SetWriteDeadline failed: %v", err) } if err := r.WriteTo(wh, wb, nil); err != nil { t.Fatalf("ipv4.RawConn.WriteTo failed: %v", err) } rb := make([]byte, ipv4.HeaderLen+128) loop: if err := r.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil { t.Fatalf("ipv4.RawConn.SetReadDeadline failed: %v", err) } if _, b, cm, err := r.ReadFrom(rb); err != nil { t.Fatalf("ipv4.RawConn.ReadFrom failed: %v", err) } else { t.Logf("rcvd cmsg: %v", cm) m, err := icmp.ParseMessage(iana.ProtocolICMP, b) 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) } } } }