mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 07:32:26 -05:00 
			
		
		
		
	
		
			
	
	
		
			81 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			81 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" |