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.
11 "golang.org/x/net/bpf"
14 var _ bpf.Instruction = unknown{}
18 func (unknown) Assemble() (bpf.RawInstruction, error) {
19 return bpf.RawInstruction{}, nil
22 func TestVMUnknownInstruction(t *testing.T) {
23 vm, done, err := testVM(t, []bpf.Instruction{
28 // Should terminate the program with an error immediately
33 t.Fatalf("unexpected error: %v", err)
37 _, err = vm.Run([]byte{
38 0xff, 0xff, 0xff, 0xff,
39 0xff, 0xff, 0xff, 0xff,
42 if errStr(err) != "unknown Instruction at index 1: bpf_test.unknown" {
43 t.Fatalf("unexpected error while running program: %v", err)
47 func TestVMNoReturnInstruction(t *testing.T) {
48 _, _, err := testVM(t, []bpf.Instruction{
54 if errStr(err) != "BPF program must end with RetA or RetConstant" {
55 t.Fatalf("unexpected error: %v", err)
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)
66 // ExampleNewVM demonstrates usage of a VM, using an Ethernet frame
67 // as input and checking its EtherType to determine if it should be accepted.
69 // Offset | Length | Comment
70 // -------------------------
71 // 00 | 06 | Ethernet destination MAC address
72 // 06 | 06 | Ethernet source MAC address
73 // 12 | 02 | Ethernet EtherType
81 // Set up a VM to filter traffic based on if its EtherType
82 // matches the ARP EtherType.
83 vm, err := bpf.NewVM([]bpf.Instruction{
84 // Load EtherType value from Ethernet header
89 // If EtherType is equal to the ARP EtherType, jump to allow
90 // packet to be accepted
96 // EtherType does not match the ARP EtherType
100 // EtherType matches the ARP EtherType, accept up to 1500
107 panic(fmt.Sprintf("failed to load BPF program: %v", err))
110 // Create an Ethernet frame with the ARP EtherType for testing
112 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
113 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
115 // Payload omitted for brevity
118 // Run our VM's BPF program using the Ethernet frame as input
119 out, err := vm.Run(frame)
121 panic(fmt.Sprintf("failed to accept Ethernet frame: %v", err))
124 // BPF VM can return a byte count greater than the number of input
125 // bytes, so trim the output to match the input byte length
126 if out > len(frame) {
130 fmt.Printf("out: %d bytes", out)
136 // errStr returns the string representation of an error, or
137 // "<nil>" if it is nil.
138 func errStr(err error) string {