mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 10:22:25 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			80 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			80 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2016 The Go Authors. All rights reserved.
 | |
| // Use of this source code is governed by a BSD-style
 | |
| // license that can be found in the LICENSE file.
 | |
| 
 | |
| /*
 | |
| Package bpf implements marshaling and unmarshaling of programs for the
 | |
| Berkeley Packet Filter virtual machine, and provides a Go implementation
 | |
| of the virtual machine.
 | |
| 
 | |
| BPF's main use is to specify a packet filter for network taps, so that
 | |
| the kernel doesn't have to expensively copy every packet it sees to
 | |
| userspace. However, it's been repurposed to other areas where running
 | |
| user code in-kernel is needed. For example, Linux's seccomp uses BPF
 | |
| to apply security policies to system calls. For simplicity, this
 | |
| documentation refers only to packets, but other uses of BPF have their
 | |
| own data payloads.
 | |
| 
 | |
| BPF programs run in a restricted virtual machine. It has almost no
 | |
| access to kernel functions, and while conditional branches are
 | |
| allowed, they can only jump forwards, to guarantee that there are no
 | |
| infinite loops.
 | |
| 
 | |
| # The virtual machine
 | |
| 
 | |
| The BPF VM is an accumulator machine. Its main register, called
 | |
| register A, is an implicit source and destination in all arithmetic
 | |
| and logic operations. The machine also has 16 scratch registers for
 | |
| temporary storage, and an indirection register (register X) for
 | |
| indirect memory access. All registers are 32 bits wide.
 | |
| 
 | |
| Each run of a BPF program is given one packet, which is placed in the
 | |
| VM's read-only "main memory". LoadAbsolute and LoadIndirect
 | |
| instructions can fetch up to 32 bits at a time into register A for
 | |
| examination.
 | |
| 
 | |
| The goal of a BPF program is to produce and return a verdict (uint32),
 | |
| which tells the kernel what to do with the packet. In the context of
 | |
| packet filtering, the returned value is the number of bytes of the
 | |
| packet to forward to userspace, or 0 to ignore the packet. Other
 | |
| contexts like seccomp define their own return values.
 | |
| 
 | |
| In order to simplify programs, attempts to read past the end of the
 | |
| packet terminate the program execution with a verdict of 0 (ignore
 | |
| packet). This means that the vast majority of BPF programs don't need
 | |
| to do any explicit bounds checking.
 | |
| 
 | |
| In addition to the bytes of the packet, some BPF programs have access
 | |
| to extensions, which are essentially calls to kernel utility
 | |
| functions. Currently, the only extensions supported by this package
 | |
| are the Linux packet filter extensions.
 | |
| 
 | |
| # Examples
 | |
| 
 | |
| This packet filter selects all ARP packets.
 | |
| 
 | |
| 	bpf.Assemble([]bpf.Instruction{
 | |
| 		// Load "EtherType" field from the ethernet header.
 | |
| 		bpf.LoadAbsolute{Off: 12, Size: 2},
 | |
| 		// Skip over the next instruction if EtherType is not ARP.
 | |
| 		bpf.JumpIf{Cond: bpf.JumpNotEqual, Val: 0x0806, SkipTrue: 1},
 | |
| 		// Verdict is "send up to 4k of the packet to userspace."
 | |
| 		bpf.RetConstant{Val: 4096},
 | |
| 		// Verdict is "ignore packet."
 | |
| 		bpf.RetConstant{Val: 0},
 | |
| 	})
 | |
| 
 | |
| This packet filter captures a random 1% sample of traffic.
 | |
| 
 | |
| 	bpf.Assemble([]bpf.Instruction{
 | |
| 		// Get a 32-bit random number from the Linux kernel.
 | |
| 		bpf.LoadExtension{Num: bpf.ExtRand},
 | |
| 		// 1% dice roll?
 | |
| 		bpf.JumpIf{Cond: bpf.JumpLessThan, Val: 2^32/100, SkipFalse: 1},
 | |
| 		// Capture.
 | |
| 		bpf.RetConstant{Val: 4096},
 | |
| 		// Ignore.
 | |
| 		bpf.RetConstant{Val: 0},
 | |
| 	})
 | |
| */
 | |
| package bpf // import "golang.org/x/net/bpf"
 |