1
2
3
4
5 package bpf_test
6
7 import (
8 "fmt"
9 "testing"
10
11 "golang.org/x/net/bpf"
12 )
13
14 var _ bpf.Instruction = unknown{}
15
16 type unknown struct{}
17
18 func (unknown) Assemble() (bpf.RawInstruction, error) {
19 return bpf.RawInstruction{}, nil
20 }
21
22 func TestVMUnknownInstruction(t *testing.T) {
23 vm, done, err := testVM(t, []bpf.Instruction{
24 bpf.LoadConstant{
25 Dst: bpf.RegA,
26 Val: 100,
27 },
28
29 unknown{},
30 bpf.RetA{},
31 })
32 if err != nil {
33 t.Fatalf("unexpected error: %v", err)
34 }
35 defer done()
36
37 _, err = vm.Run([]byte{
38 0xff, 0xff, 0xff, 0xff,
39 0xff, 0xff, 0xff, 0xff,
40 0x00, 0x00,
41 })
42 if errStr(err) != "unknown Instruction at index 1: bpf_test.unknown" {
43 t.Fatalf("unexpected error while running program: %v", err)
44 }
45 }
46
47 func TestVMNoReturnInstruction(t *testing.T) {
48 _, _, err := testVM(t, []bpf.Instruction{
49 bpf.LoadConstant{
50 Dst: bpf.RegA,
51 Val: 1,
52 },
53 })
54 if errStr(err) != "BPF program must end with RetA or RetConstant" {
55 t.Fatalf("unexpected error: %v", err)
56 }
57 }
58
59 func TestVMNoInputInstructions(t *testing.T) {
60 _, _, err := testVM(t, []bpf.Instruction{})
61 if errStr(err) != "one or more Instructions must be specified" {
62 t.Fatalf("unexpected error: %v", err)
63 }
64 }
65
66
67
68 func ExampleNewVM() {
69
70
71
72
73
74 const (
75 etOff = 12
76 etLen = 2
77
78 etARP = 0x0806
79 )
80
81
82
83 vm, err := bpf.NewVM([]bpf.Instruction{
84
85 bpf.LoadAbsolute{
86 Off: etOff,
87 Size: etLen,
88 },
89
90
91 bpf.JumpIf{
92 Cond: bpf.JumpEqual,
93 Val: etARP,
94 SkipTrue: 1,
95 },
96
97 bpf.RetConstant{
98 Val: 0,
99 },
100
101
102 bpf.RetConstant{
103 Val: 1500,
104 },
105 })
106 if err != nil {
107 panic(fmt.Sprintf("failed to load BPF program: %v", err))
108 }
109
110
111 frame := []byte{
112 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
113 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
114 0x08, 0x06,
115
116 }
117
118
119 out, err := vm.Run(frame)
120 if err != nil {
121 panic(fmt.Sprintf("failed to accept Ethernet frame: %v", err))
122 }
123
124
125
126 if out > len(frame) {
127 out = len(frame)
128 }
129
130 fmt.Printf("out: %d bytes", out)
131
132
133
134 }
135
136
137
138 func errStr(err error) string {
139 if err == nil {
140 return "<nil>"
141 }
142
143 return err.Error()
144 }
145
View as plain text