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