Rebase.
[official-gcc.git] / libgo / go / net / ipraw_test.go
blob0632dafc65e642cfef1ab535386f224fb0600080
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.
5 package net
7 import (
8 "bytes"
9 "fmt"
10 "os"
11 "reflect"
12 "runtime"
13 "testing"
14 "time"
17 type resolveIPAddrTest struct {
18 net string
19 litAddrOrName string
20 addr *IPAddr
21 err error
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},
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},
34 {"ip", "::1%en0", &IPAddr{IP: ParseIP("::1"), Zone: "en0"}, nil},
35 {"ip6", "::1%911", &IPAddr{IP: ParseIP("::1"), Zone: "911"}, nil},
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
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")},
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 }...)
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 }...)
62 func skipRawSocketTest(t *testing.T) (skip bool, skipmsg string) {
63 skip, skipmsg, err := skipRawSocketTests()
64 if err != nil {
65 t.Fatal(err)
67 return skip, skipmsg
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)
81 var icmpEchoTests = []struct {
82 net string
83 laddr string
84 raddr string
86 {"ip4:icmp", "0.0.0.0", "127.0.0.1"},
87 {"ip6:ipv6-icmp", "::", "::1"},
90 func TestConnICMPEcho(t *testing.T) {
91 if skip, skipmsg := skipRawSocketTest(t); skip {
92 t.Skip(skipmsg)
95 for i, tt := range icmpEchoTests {
96 net, _, err := parseNetwork(tt.net)
97 if err != nil {
98 t.Fatalf("parseNetwork failed: %v", err)
100 if net == "ip6" && !supportsIPv6 {
101 continue
104 c, err := Dial(tt.net, tt.raddr)
105 if err != nil {
106 t.Fatalf("Dial failed: %v", err)
108 c.SetDeadline(time.Now().Add(100 * time.Millisecond))
109 defer c.Close()
111 typ := icmpv4EchoRequest
112 if net == "ip6" {
113 typ = icmpv6EchoRequest
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),
122 }).Marshal()
123 if err != nil {
124 t.Fatalf("icmpMessage.Marshal failed: %v", err)
126 if _, err := c.Write(wb); err != nil {
127 t.Fatalf("Conn.Write failed: %v", err)
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)
135 if net == "ip4" {
136 rb = ipv4Payload(rb)
138 if m, err = parseICMPMessage(rb); err != nil {
139 t.Fatalf("parseICMPMessage failed: %v", err)
141 switch m.Type {
142 case icmpv4EchoRequest, icmpv6EchoRequest:
143 continue
145 break
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)
152 default:
153 t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, typ, 0)
158 func TestPacketConnICMPEcho(t *testing.T) {
159 if skip, skipmsg := skipRawSocketTest(t); skip {
160 t.Skip(skipmsg)
163 for i, tt := range icmpEchoTests {
164 net, _, err := parseNetwork(tt.net)
165 if err != nil {
166 t.Fatalf("parseNetwork failed: %v", err)
168 if net == "ip6" && !supportsIPv6 {
169 continue
172 c, err := ListenPacket(tt.net, tt.laddr)
173 if err != nil {
174 t.Fatalf("ListenPacket failed: %v", err)
176 c.SetDeadline(time.Now().Add(100 * time.Millisecond))
177 defer c.Close()
179 ra, err := ResolveIPAddr(tt.net, tt.raddr)
180 if err != nil {
181 t.Fatalf("ResolveIPAddr failed: %v", err)
183 typ := icmpv4EchoRequest
184 if net == "ip6" {
185 typ = icmpv6EchoRequest
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),
194 }).Marshal()
195 if err != nil {
196 t.Fatalf("icmpMessage.Marshal failed: %v", err)
198 if _, err := c.WriteTo(wb, ra); err != nil {
199 t.Fatalf("PacketConn.WriteTo failed: %v", err)
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)
207 // See BUG section.
208 //if net == "ip4" {
209 // rb = ipv4Payload(rb)
211 if m, err = parseICMPMessage(rb); err != nil {
212 t.Fatalf("parseICMPMessage failed: %v", err)
214 switch m.Type {
215 case icmpv4EchoRequest, icmpv6EchoRequest:
216 continue
218 break
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)
225 default:
226 t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, typ, 0)
231 func ipv4Payload(b []byte) []byte {
232 if len(b) < 20 {
233 return b
235 hdrlen := int(b[0]&0x0f) << 2
236 return b[hdrlen:]
239 var ipConnLocalNameTests = []struct {
240 net string
241 laddr *IPAddr
243 {"ip4:icmp", &IPAddr{IP: IPv4(127, 0, 0, 1)}},
244 {"ip4:icmp", &IPAddr{}},
245 {"ip4:icmp", nil},
248 func TestIPConnLocalName(t *testing.T) {
249 switch runtime.GOOS {
250 case "nacl", "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")
258 for _, tt := range ipConnLocalNameTests {
259 c, err := ListenIP(tt.net, tt.laddr)
260 if err != nil {
261 t.Fatalf("ListenIP failed: %v", err)
263 defer c.Close()
264 if la := c.LocalAddr(); la == nil {
265 t.Fatal("IPConn.LocalAddr failed")
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")
280 raddr := &IPAddr{IP: IPv4(127, 0, 0, 1).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)
285 defer c.Close()
286 if !reflect.DeepEqual(raddr, c.RemoteAddr()) {
287 t.Fatalf("got %#v, expected %#v", c.RemoteAddr(), raddr)