github.com/roboticscm/goman@v0.0.0-20210203095141-87c07b4a0a55/src/net/ipraw_test.go (about) 1 // Copyright 2009 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 net 6 7 import ( 8 "bytes" 9 "fmt" 10 "os" 11 "reflect" 12 "runtime" 13 "testing" 14 "time" 15 ) 16 17 type resolveIPAddrTest struct { 18 net string 19 litAddrOrName string 20 addr *IPAddr 21 err error 22 } 23 24 var resolveIPAddrTests = []resolveIPAddrTest{ 25 {"ip", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil}, 26 {"ip4", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil}, 27 {"ip4:icmp", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil}, 28 29 {"ip", "::1", &IPAddr{IP: ParseIP("::1")}, nil}, 30 {"ip6", "::1", &IPAddr{IP: ParseIP("::1")}, nil}, 31 {"ip6:ipv6-icmp", "::1", &IPAddr{IP: ParseIP("::1")}, nil}, 32 {"ip6:IPv6-ICMP", "::1", &IPAddr{IP: ParseIP("::1")}, nil}, 33 34 {"ip", "::1%en0", &IPAddr{IP: ParseIP("::1"), Zone: "en0"}, nil}, 35 {"ip6", "::1%911", &IPAddr{IP: ParseIP("::1"), Zone: "911"}, nil}, 36 37 {"", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil}, // Go 1.0 behavior 38 {"", "::1", &IPAddr{IP: ParseIP("::1")}, nil}, // Go 1.0 behavior 39 40 {"l2tp", "127.0.0.1", nil, UnknownNetworkError("l2tp")}, 41 {"l2tp:gre", "127.0.0.1", nil, UnknownNetworkError("l2tp:gre")}, 42 {"tcp", "1.2.3.4:123", nil, UnknownNetworkError("tcp")}, 43 } 44 45 func init() { 46 if ifi := loopbackInterface(); ifi != nil { 47 index := fmt.Sprintf("%v", ifi.Index) 48 resolveIPAddrTests = append(resolveIPAddrTests, []resolveIPAddrTest{ 49 {"ip6", "fe80::1%" + ifi.Name, &IPAddr{IP: ParseIP("fe80::1"), Zone: zoneToString(ifi.Index)}, nil}, 50 {"ip6", "fe80::1%" + index, &IPAddr{IP: ParseIP("fe80::1"), Zone: index}, nil}, 51 }...) 52 } 53 if ips, err := LookupIP("localhost"); err == nil && len(ips) > 1 && supportsIPv4 && supportsIPv6 { 54 resolveIPAddrTests = append(resolveIPAddrTests, []resolveIPAddrTest{ 55 {"ip", "localhost", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil}, 56 {"ip4", "localhost", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil}, 57 {"ip6", "localhost", &IPAddr{IP: IPv6loopback}, nil}, 58 }...) 59 } 60 } 61 62 func skipRawSocketTest(t *testing.T) (skip bool, skipmsg string) { 63 skip, skipmsg, err := skipRawSocketTests() 64 if err != nil { 65 t.Fatal(err) 66 } 67 return skip, skipmsg 68 } 69 70 func TestResolveIPAddr(t *testing.T) { 71 switch runtime.GOOS { 72 case "nacl": 73 t.Skipf("skipping test on %q", runtime.GOOS) 74 } 75 76 for _, tt := range resolveIPAddrTests { 77 addr, err := ResolveIPAddr(tt.net, tt.litAddrOrName) 78 if err != tt.err { 79 t.Fatalf("ResolveIPAddr(%v, %v) failed: %v", tt.net, tt.litAddrOrName, err) 80 } else if !reflect.DeepEqual(addr, tt.addr) { 81 t.Fatalf("got %#v; expected %#v", addr, tt.addr) 82 } 83 } 84 } 85 86 var icmpEchoTests = []struct { 87 net string 88 laddr string 89 raddr string 90 }{ 91 {"ip4:icmp", "0.0.0.0", "127.0.0.1"}, 92 {"ip6:ipv6-icmp", "::", "::1"}, 93 } 94 95 func TestConnICMPEcho(t *testing.T) { 96 if skip, skipmsg := skipRawSocketTest(t); skip { 97 t.Skip(skipmsg) 98 } 99 100 for i, tt := range icmpEchoTests { 101 net, _, err := parseNetwork(tt.net) 102 if err != nil { 103 t.Fatalf("parseNetwork failed: %v", err) 104 } 105 if net == "ip6" && !supportsIPv6 { 106 continue 107 } 108 109 c, err := Dial(tt.net, tt.raddr) 110 if err != nil { 111 t.Fatalf("Dial failed: %v", err) 112 } 113 c.SetDeadline(time.Now().Add(100 * time.Millisecond)) 114 defer c.Close() 115 116 typ := icmpv4EchoRequest 117 if net == "ip6" { 118 typ = icmpv6EchoRequest 119 } 120 xid, xseq := os.Getpid()&0xffff, i+1 121 wb, err := (&icmpMessage{ 122 Type: typ, Code: 0, 123 Body: &icmpEcho{ 124 ID: xid, Seq: xseq, 125 Data: bytes.Repeat([]byte("Go Go Gadget Ping!!!"), 3), 126 }, 127 }).Marshal() 128 if err != nil { 129 t.Fatalf("icmpMessage.Marshal failed: %v", err) 130 } 131 if _, err := c.Write(wb); err != nil { 132 t.Fatalf("Conn.Write failed: %v", err) 133 } 134 var m *icmpMessage 135 rb := make([]byte, 20+len(wb)) 136 for { 137 if _, err := c.Read(rb); err != nil { 138 t.Fatalf("Conn.Read failed: %v", err) 139 } 140 if net == "ip4" { 141 rb = ipv4Payload(rb) 142 } 143 if m, err = parseICMPMessage(rb); err != nil { 144 t.Fatalf("parseICMPMessage failed: %v", err) 145 } 146 switch m.Type { 147 case icmpv4EchoRequest, icmpv6EchoRequest: 148 continue 149 } 150 break 151 } 152 switch p := m.Body.(type) { 153 case *icmpEcho: 154 if p.ID != xid || p.Seq != xseq { 155 t.Fatalf("got id=%v, seqnum=%v; expected id=%v, seqnum=%v", p.ID, p.Seq, xid, xseq) 156 } 157 default: 158 t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, typ, 0) 159 } 160 } 161 } 162 163 func TestPacketConnICMPEcho(t *testing.T) { 164 if skip, skipmsg := skipRawSocketTest(t); skip { 165 t.Skip(skipmsg) 166 } 167 168 for i, tt := range icmpEchoTests { 169 net, _, err := parseNetwork(tt.net) 170 if err != nil { 171 t.Fatalf("parseNetwork failed: %v", err) 172 } 173 if net == "ip6" && !supportsIPv6 { 174 continue 175 } 176 177 c, err := ListenPacket(tt.net, tt.laddr) 178 if err != nil { 179 t.Fatalf("ListenPacket failed: %v", err) 180 } 181 c.SetDeadline(time.Now().Add(100 * time.Millisecond)) 182 defer c.Close() 183 184 ra, err := ResolveIPAddr(tt.net, tt.raddr) 185 if err != nil { 186 t.Fatalf("ResolveIPAddr failed: %v", err) 187 } 188 typ := icmpv4EchoRequest 189 if net == "ip6" { 190 typ = icmpv6EchoRequest 191 } 192 xid, xseq := os.Getpid()&0xffff, i+1 193 wb, err := (&icmpMessage{ 194 Type: typ, Code: 0, 195 Body: &icmpEcho{ 196 ID: xid, Seq: xseq, 197 Data: bytes.Repeat([]byte("Go Go Gadget Ping!!!"), 3), 198 }, 199 }).Marshal() 200 if err != nil { 201 t.Fatalf("icmpMessage.Marshal failed: %v", err) 202 } 203 if _, err := c.WriteTo(wb, ra); err != nil { 204 t.Fatalf("PacketConn.WriteTo failed: %v", err) 205 } 206 var m *icmpMessage 207 rb := make([]byte, 20+len(wb)) 208 for { 209 if _, _, err := c.ReadFrom(rb); err != nil { 210 t.Fatalf("PacketConn.ReadFrom failed: %v", err) 211 } 212 // See BUG section. 213 //if net == "ip4" { 214 // rb = ipv4Payload(rb) 215 //} 216 if m, err = parseICMPMessage(rb); err != nil { 217 t.Fatalf("parseICMPMessage failed: %v", err) 218 } 219 switch m.Type { 220 case icmpv4EchoRequest, icmpv6EchoRequest: 221 continue 222 } 223 break 224 } 225 switch p := m.Body.(type) { 226 case *icmpEcho: 227 if p.ID != xid || p.Seq != xseq { 228 t.Fatalf("got id=%v, seqnum=%v; expected id=%v, seqnum=%v", p.ID, p.Seq, xid, xseq) 229 } 230 default: 231 t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, typ, 0) 232 } 233 } 234 } 235 236 func ipv4Payload(b []byte) []byte { 237 if len(b) < 20 { 238 return b 239 } 240 hdrlen := int(b[0]&0x0f) << 2 241 return b[hdrlen:] 242 } 243 244 var ipConnLocalNameTests = []struct { 245 net string 246 laddr *IPAddr 247 }{ 248 {"ip4:icmp", &IPAddr{IP: IPv4(127, 0, 0, 1)}}, 249 {"ip4:icmp", &IPAddr{}}, 250 {"ip4:icmp", nil}, 251 } 252 253 func TestIPConnLocalName(t *testing.T) { 254 switch runtime.GOOS { 255 case "nacl", "plan9", "windows": 256 t.Skipf("skipping test on %q", runtime.GOOS) 257 default: 258 if os.Getuid() != 0 { 259 t.Skip("skipping test; must be root") 260 } 261 } 262 263 for _, tt := range ipConnLocalNameTests { 264 c, err := ListenIP(tt.net, tt.laddr) 265 if err != nil { 266 t.Fatalf("ListenIP failed: %v", err) 267 } 268 defer c.Close() 269 if la := c.LocalAddr(); la == nil { 270 t.Fatal("IPConn.LocalAddr failed") 271 } 272 } 273 } 274 275 func TestIPConnRemoteName(t *testing.T) { 276 switch runtime.GOOS { 277 case "plan9", "windows": 278 t.Skipf("skipping test on %q", runtime.GOOS) 279 default: 280 if os.Getuid() != 0 { 281 t.Skip("skipping test; must be root") 282 } 283 } 284 285 raddr := &IPAddr{IP: IPv4(127, 0, 0, 1).To4()} 286 c, err := DialIP("ip:tcp", &IPAddr{IP: IPv4(127, 0, 0, 1)}, raddr) 287 if err != nil { 288 t.Fatalf("DialIP failed: %v", err) 289 } 290 defer c.Close() 291 if !reflect.DeepEqual(raddr, c.RemoteAddr()) { 292 t.Fatalf("got %#v, expected %#v", c.RemoteAddr(), raddr) 293 } 294 }