github.com/spotify/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/pkg/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 for _, tt := range resolveIPAddrTests { 72 addr, err := ResolveIPAddr(tt.net, tt.litAddrOrName) 73 if err != tt.err { 74 t.Fatalf("ResolveIPAddr(%v, %v) failed: %v", tt.net, tt.litAddrOrName, err) 75 } else if !reflect.DeepEqual(addr, tt.addr) { 76 t.Fatalf("got %#v; expected %#v", addr, tt.addr) 77 } 78 } 79 } 80 81 var icmpEchoTests = []struct { 82 net string 83 laddr string 84 raddr string 85 }{ 86 {"ip4:icmp", "0.0.0.0", "127.0.0.1"}, 87 {"ip6:ipv6-icmp", "::", "::1"}, 88 } 89 90 func TestConnICMPEcho(t *testing.T) { 91 if skip, skipmsg := skipRawSocketTest(t); skip { 92 t.Skip(skipmsg) 93 } 94 95 for i, tt := range icmpEchoTests { 96 net, _, err := parseNetwork(tt.net) 97 if err != nil { 98 t.Fatalf("parseNetwork failed: %v", err) 99 } 100 if net == "ip6" && !supportsIPv6 { 101 continue 102 } 103 104 c, err := Dial(tt.net, tt.raddr) 105 if err != nil { 106 t.Fatalf("Dial failed: %v", err) 107 } 108 c.SetDeadline(time.Now().Add(100 * time.Millisecond)) 109 defer c.Close() 110 111 typ := icmpv4EchoRequest 112 if net == "ip6" { 113 typ = icmpv6EchoRequest 114 } 115 xid, xseq := os.Getpid()&0xffff, i+1 116 wb, err := (&icmpMessage{ 117 Type: typ, Code: 0, 118 Body: &icmpEcho{ 119 ID: xid, Seq: xseq, 120 Data: bytes.Repeat([]byte("Go Go Gadget Ping!!!"), 3), 121 }, 122 }).Marshal() 123 if err != nil { 124 t.Fatalf("icmpMessage.Marshal failed: %v", err) 125 } 126 if _, err := c.Write(wb); err != nil { 127 t.Fatalf("Conn.Write failed: %v", err) 128 } 129 var m *icmpMessage 130 rb := make([]byte, 20+len(wb)) 131 for { 132 if _, err := c.Read(rb); err != nil { 133 t.Fatalf("Conn.Read failed: %v", err) 134 } 135 if net == "ip4" { 136 rb = ipv4Payload(rb) 137 } 138 if m, err = parseICMPMessage(rb); err != nil { 139 t.Fatalf("parseICMPMessage failed: %v", err) 140 } 141 switch m.Type { 142 case icmpv4EchoRequest, icmpv6EchoRequest: 143 continue 144 } 145 break 146 } 147 switch p := m.Body.(type) { 148 case *icmpEcho: 149 if p.ID != xid || p.Seq != xseq { 150 t.Fatalf("got id=%v, seqnum=%v; expected id=%v, seqnum=%v", p.ID, p.Seq, xid, xseq) 151 } 152 default: 153 t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, typ, 0) 154 } 155 } 156 } 157 158 func TestPacketConnICMPEcho(t *testing.T) { 159 if skip, skipmsg := skipRawSocketTest(t); skip { 160 t.Skip(skipmsg) 161 } 162 163 for i, tt := range icmpEchoTests { 164 net, _, err := parseNetwork(tt.net) 165 if err != nil { 166 t.Fatalf("parseNetwork failed: %v", err) 167 } 168 if net == "ip6" && !supportsIPv6 { 169 continue 170 } 171 172 c, err := ListenPacket(tt.net, tt.laddr) 173 if err != nil { 174 t.Fatalf("ListenPacket failed: %v", err) 175 } 176 c.SetDeadline(time.Now().Add(100 * time.Millisecond)) 177 defer c.Close() 178 179 ra, err := ResolveIPAddr(tt.net, tt.raddr) 180 if err != nil { 181 t.Fatalf("ResolveIPAddr failed: %v", err) 182 } 183 typ := icmpv4EchoRequest 184 if net == "ip6" { 185 typ = icmpv6EchoRequest 186 } 187 xid, xseq := os.Getpid()&0xffff, i+1 188 wb, err := (&icmpMessage{ 189 Type: typ, Code: 0, 190 Body: &icmpEcho{ 191 ID: xid, Seq: xseq, 192 Data: bytes.Repeat([]byte("Go Go Gadget Ping!!!"), 3), 193 }, 194 }).Marshal() 195 if err != nil { 196 t.Fatalf("icmpMessage.Marshal failed: %v", err) 197 } 198 if _, err := c.WriteTo(wb, ra); err != nil { 199 t.Fatalf("PacketConn.WriteTo failed: %v", err) 200 } 201 var m *icmpMessage 202 rb := make([]byte, 20+len(wb)) 203 for { 204 if _, _, err := c.ReadFrom(rb); err != nil { 205 t.Fatalf("PacketConn.ReadFrom failed: %v", err) 206 } 207 // See BUG section. 208 //if net == "ip4" { 209 // rb = ipv4Payload(rb) 210 //} 211 if m, err = parseICMPMessage(rb); err != nil { 212 t.Fatalf("parseICMPMessage failed: %v", err) 213 } 214 switch m.Type { 215 case icmpv4EchoRequest, icmpv6EchoRequest: 216 continue 217 } 218 break 219 } 220 switch p := m.Body.(type) { 221 case *icmpEcho: 222 if p.ID != xid || p.Seq != xseq { 223 t.Fatalf("got id=%v, seqnum=%v; expected id=%v, seqnum=%v", p.ID, p.Seq, xid, xseq) 224 } 225 default: 226 t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, typ, 0) 227 } 228 } 229 } 230 231 func ipv4Payload(b []byte) []byte { 232 if len(b) < 20 { 233 return b 234 } 235 hdrlen := int(b[0]&0x0f) << 2 236 return b[hdrlen:] 237 } 238 239 var ipConnLocalNameTests = []struct { 240 net string 241 laddr *IPAddr 242 }{ 243 {"ip4:icmp", &IPAddr{IP: IPv4(127, 0, 0, 1)}}, 244 {"ip4:icmp", &IPAddr{}}, 245 {"ip4:icmp", nil}, 246 } 247 248 func TestIPConnLocalName(t *testing.T) { 249 switch runtime.GOOS { 250 case "plan9", "windows": 251 t.Skipf("skipping test on %q", runtime.GOOS) 252 default: 253 if os.Getuid() != 0 { 254 t.Skip("skipping test; must be root") 255 } 256 } 257 258 for _, tt := range ipConnLocalNameTests { 259 c, err := ListenIP(tt.net, tt.laddr) 260 if err != nil { 261 t.Fatalf("ListenIP failed: %v", err) 262 } 263 defer c.Close() 264 if la := c.LocalAddr(); la == nil { 265 t.Fatal("IPConn.LocalAddr failed") 266 } 267 } 268 } 269 270 func TestIPConnRemoteName(t *testing.T) { 271 switch runtime.GOOS { 272 case "plan9", "windows": 273 t.Skipf("skipping test on %q", runtime.GOOS) 274 default: 275 if os.Getuid() != 0 { 276 t.Skip("skipping test; must be root") 277 } 278 } 279 280 raddr := &IPAddr{IP: IPv4(127, 0, 0, 10).To4()} 281 c, err := DialIP("ip:tcp", &IPAddr{IP: IPv4(127, 0, 0, 1)}, raddr) 282 if err != nil { 283 t.Fatalf("DialIP failed: %v", err) 284 } 285 defer c.Close() 286 if !reflect.DeepEqual(raddr, c.RemoteAddr()) { 287 t.Fatalf("got %#v, expected %#v", c.RemoteAddr(), raddr) 288 } 289 }