github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/net/ipv4/unicast_test.go (about) 1 // Copyright 2012 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package ipv4_test 6 7 import ( 8 "bytes" 9 "net" 10 "os" 11 "runtime" 12 "testing" 13 "time" 14 15 "golang.org/x/net/icmp" 16 "golang.org/x/net/internal/iana" 17 "golang.org/x/net/internal/nettest" 18 "golang.org/x/net/ipv4" 19 ) 20 21 func TestPacketConnReadWriteUnicastUDP(t *testing.T) { 22 switch runtime.GOOS { 23 case "nacl", "plan9", "solaris", "windows": 24 t.Skipf("not supported on %s", runtime.GOOS) 25 } 26 ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback) 27 if ifi == nil { 28 t.Skipf("not available on %s", runtime.GOOS) 29 } 30 31 c, err := net.ListenPacket("udp4", "127.0.0.1:0") 32 if err != nil { 33 t.Fatal(err) 34 } 35 defer c.Close() 36 37 dst, err := net.ResolveUDPAddr("udp4", c.LocalAddr().String()) 38 if err != nil { 39 t.Fatal(err) 40 } 41 p := ipv4.NewPacketConn(c) 42 defer p.Close() 43 cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface 44 wb := []byte("HELLO-R-U-THERE") 45 46 for i, toggle := range []bool{true, false, true} { 47 if err := p.SetControlMessage(cf, toggle); err != nil { 48 if nettest.ProtocolNotSupported(err) { 49 t.Logf("not supported on %s", runtime.GOOS) 50 continue 51 } 52 t.Fatal(err) 53 } 54 p.SetTTL(i + 1) 55 if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil { 56 t.Fatal(err) 57 } 58 if n, err := p.WriteTo(wb, nil, dst); err != nil { 59 t.Fatal(err) 60 } else if n != len(wb) { 61 t.Fatalf("got %v; want %v", n, len(wb)) 62 } 63 rb := make([]byte, 128) 64 if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil { 65 t.Fatal(err) 66 } 67 if n, _, _, err := p.ReadFrom(rb); err != nil { 68 t.Fatal(err) 69 } else if !bytes.Equal(rb[:n], wb) { 70 t.Fatalf("got %v; want %v", rb[:n], wb) 71 } 72 } 73 } 74 75 func TestPacketConnReadWriteUnicastICMP(t *testing.T) { 76 switch runtime.GOOS { 77 case "nacl", "plan9", "solaris", "windows": 78 t.Skipf("not supported on %s", runtime.GOOS) 79 } 80 if m, ok := nettest.SupportsRawIPSocket(); !ok { 81 t.Skip(m) 82 } 83 ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback) 84 if ifi == nil { 85 t.Skipf("not available on %s", runtime.GOOS) 86 } 87 88 c, err := net.ListenPacket("ip4:icmp", "0.0.0.0") 89 if err != nil { 90 t.Fatal(err) 91 } 92 defer c.Close() 93 94 dst, err := net.ResolveIPAddr("ip4", "127.0.0.1") 95 if err != nil { 96 t.Fatal(err) 97 } 98 p := ipv4.NewPacketConn(c) 99 defer p.Close() 100 cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface 101 102 for i, toggle := range []bool{true, false, true} { 103 wb, err := (&icmp.Message{ 104 Type: ipv4.ICMPTypeEcho, Code: 0, 105 Body: &icmp.Echo{ 106 ID: os.Getpid() & 0xffff, Seq: i + 1, 107 Data: []byte("HELLO-R-U-THERE"), 108 }, 109 }).Marshal(nil) 110 if err != nil { 111 t.Fatal(err) 112 } 113 if err := p.SetControlMessage(cf, toggle); err != nil { 114 if nettest.ProtocolNotSupported(err) { 115 t.Logf("not supported on %s", runtime.GOOS) 116 continue 117 } 118 t.Fatal(err) 119 } 120 p.SetTTL(i + 1) 121 if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil { 122 t.Fatal(err) 123 } 124 if n, err := p.WriteTo(wb, nil, dst); err != nil { 125 t.Fatal(err) 126 } else if n != len(wb) { 127 t.Fatalf("got %v; want %v", n, len(wb)) 128 } 129 rb := make([]byte, 128) 130 loop: 131 if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil { 132 t.Fatal(err) 133 } 134 if n, _, _, err := p.ReadFrom(rb); err != nil { 135 switch runtime.GOOS { 136 case "darwin": // older darwin kernels have some limitation on receiving icmp packet through raw socket 137 t.Logf("not supported on %s", runtime.GOOS) 138 continue 139 } 140 t.Fatal(err) 141 } else { 142 m, err := icmp.ParseMessage(iana.ProtocolICMP, rb[:n]) 143 if err != nil { 144 t.Fatal(err) 145 } 146 if runtime.GOOS == "linux" && m.Type == ipv4.ICMPTypeEcho { 147 // On Linux we must handle own sent packets. 148 goto loop 149 } 150 if m.Type != ipv4.ICMPTypeEchoReply || m.Code != 0 { 151 t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0) 152 } 153 } 154 } 155 } 156 157 func TestRawConnReadWriteUnicastICMP(t *testing.T) { 158 switch runtime.GOOS { 159 case "nacl", "plan9", "solaris", "windows": 160 t.Skipf("not supported on %s", runtime.GOOS) 161 } 162 if m, ok := nettest.SupportsRawIPSocket(); !ok { 163 t.Skip(m) 164 } 165 ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback) 166 if ifi == nil { 167 t.Skipf("not available on %s", runtime.GOOS) 168 } 169 170 c, err := net.ListenPacket("ip4:icmp", "0.0.0.0") 171 if err != nil { 172 t.Fatal(err) 173 } 174 defer c.Close() 175 176 dst, err := net.ResolveIPAddr("ip4", "127.0.0.1") 177 if err != nil { 178 t.Fatal(err) 179 } 180 r, err := ipv4.NewRawConn(c) 181 if err != nil { 182 t.Fatal(err) 183 } 184 defer r.Close() 185 cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface 186 187 for i, toggle := range []bool{true, false, true} { 188 wb, err := (&icmp.Message{ 189 Type: ipv4.ICMPTypeEcho, Code: 0, 190 Body: &icmp.Echo{ 191 ID: os.Getpid() & 0xffff, Seq: i + 1, 192 Data: []byte("HELLO-R-U-THERE"), 193 }, 194 }).Marshal(nil) 195 if err != nil { 196 t.Fatal(err) 197 } 198 wh := &ipv4.Header{ 199 Version: ipv4.Version, 200 Len: ipv4.HeaderLen, 201 TOS: i + 1, 202 TotalLen: ipv4.HeaderLen + len(wb), 203 TTL: i + 1, 204 Protocol: 1, 205 Dst: dst.IP, 206 } 207 if err := r.SetControlMessage(cf, toggle); err != nil { 208 if nettest.ProtocolNotSupported(err) { 209 t.Logf("not supported on %s", runtime.GOOS) 210 continue 211 } 212 t.Fatal(err) 213 } 214 if err := r.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil { 215 t.Fatal(err) 216 } 217 if err := r.WriteTo(wh, wb, nil); err != nil { 218 t.Fatal(err) 219 } 220 rb := make([]byte, ipv4.HeaderLen+128) 221 loop: 222 if err := r.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil { 223 t.Fatal(err) 224 } 225 if _, b, _, err := r.ReadFrom(rb); err != nil { 226 switch runtime.GOOS { 227 case "darwin": // older darwin kernels have some limitation on receiving icmp packet through raw socket 228 t.Logf("not supported on %s", runtime.GOOS) 229 continue 230 } 231 t.Fatal(err) 232 } else { 233 m, err := icmp.ParseMessage(iana.ProtocolICMP, b) 234 if err != nil { 235 t.Fatal(err) 236 } 237 if runtime.GOOS == "linux" && m.Type == ipv4.ICMPTypeEcho { 238 // On Linux we must handle own sent packets. 239 goto loop 240 } 241 if m.Type != ipv4.ICMPTypeEchoReply || m.Code != 0 { 242 t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0) 243 } 244 } 245 } 246 }