OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / net / ipv6 / bpf_test.go
1 // Copyright 2016 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 ipv6_test
6
7 import (
8         "net"
9         "runtime"
10         "testing"
11         "time"
12
13         "golang.org/x/net/bpf"
14         "golang.org/x/net/ipv6"
15 )
16
17 func TestBPF(t *testing.T) {
18         if runtime.GOOS != "linux" {
19                 t.Skipf("not supported on %s", runtime.GOOS)
20         }
21         if !supportsIPv6 {
22                 t.Skip("ipv6 is not supported")
23         }
24
25         l, err := net.ListenPacket("udp6", "[::1]:0")
26         if err != nil {
27                 t.Fatal(err)
28         }
29         defer l.Close()
30
31         p := ipv6.NewPacketConn(l)
32
33         // This filter accepts UDP packets whose first payload byte is
34         // even.
35         prog, err := bpf.Assemble([]bpf.Instruction{
36                 // Load the first byte of the payload (skipping UDP header).
37                 bpf.LoadAbsolute{Off: 8, Size: 1},
38                 // Select LSB of the byte.
39                 bpf.ALUOpConstant{Op: bpf.ALUOpAnd, Val: 1},
40                 // Byte is even?
41                 bpf.JumpIf{Cond: bpf.JumpEqual, Val: 0, SkipFalse: 1},
42                 // Accept.
43                 bpf.RetConstant{Val: 4096},
44                 // Ignore.
45                 bpf.RetConstant{Val: 0},
46         })
47         if err != nil {
48                 t.Fatalf("compiling BPF: %s", err)
49         }
50
51         if err = p.SetBPF(prog); err != nil {
52                 t.Fatalf("attaching filter to Conn: %s", err)
53         }
54
55         s, err := net.Dial("udp6", l.LocalAddr().String())
56         if err != nil {
57                 t.Fatal(err)
58         }
59         defer s.Close()
60         go func() {
61                 for i := byte(0); i < 10; i++ {
62                         s.Write([]byte{i})
63                 }
64         }()
65
66         l.SetDeadline(time.Now().Add(2 * time.Second))
67         seen := make([]bool, 5)
68         for {
69                 var b [512]byte
70                 n, _, err := l.ReadFrom(b[:])
71                 if err != nil {
72                         t.Fatalf("reading from listener: %s", err)
73                 }
74                 if n != 1 {
75                         t.Fatalf("unexpected packet length, want 1, got %d", n)
76                 }
77                 if b[0] >= 10 {
78                         t.Fatalf("unexpected byte, want 0-9, got %d", b[0])
79                 }
80                 if b[0]%2 != 0 {
81                         t.Fatalf("got odd byte %d, wanted only even bytes", b[0])
82                 }
83                 seen[b[0]/2] = true
84
85                 seenAll := true
86                 for _, v := range seen {
87                         if !v {
88                                 seenAll = false
89                                 break
90                         }
91                 }
92                 if seenAll {
93                         break
94                 }
95         }
96 }