github.com/nicocha30/gvisor-ligolo@v0.0.0-20230726075806-989fa2c0a413/pkg/bpf/bpf.go (about)

     1  // Copyright 2018 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Package bpf provides tools for working with Berkeley Packet Filter (BPF)
    16  // programs. More information on BPF can be found at
    17  // https://www.freebsd.org/cgi/man.cgi?bpf(4)
    18  package bpf
    19  
    20  import "github.com/nicocha30/gvisor-ligolo/pkg/abi/linux"
    21  
    22  const (
    23  	// MaxInstructions is the maximum number of instructions in a BPF program,
    24  	// and is equal to Linux's BPF_MAXINSNS.
    25  	MaxInstructions = 4096
    26  
    27  	// ScratchMemRegisters is the number of M registers in a BPF virtual machine,
    28  	// and is equal to Linux's BPF_MEMWORDS.
    29  	ScratchMemRegisters = 16
    30  )
    31  
    32  // Parts of a linux.BPFInstruction.OpCode. Compare to the Linux kernel's
    33  // include/uapi/linux/filter.h.
    34  //
    35  // In the comments below:
    36  //
    37  //   - A, X, and M[] are BPF virtual machine registers.
    38  //
    39  //   - K refers to the instruction field linux.BPFInstruction.K.
    40  //
    41  //   - Bits are counted from the LSB position.
    42  const (
    43  	// Instruction class, stored in bits 0-2.
    44  	Ld                   = 0x00 // load into A
    45  	Ldx                  = 0x01 // load into X
    46  	St                   = 0x02 // store from A
    47  	Stx                  = 0x03 // store from X
    48  	Alu                  = 0x04 // arithmetic
    49  	Jmp                  = 0x05 // jump
    50  	Ret                  = 0x06 // return
    51  	Misc                 = 0x07
    52  	instructionClassMask = 0x07
    53  
    54  	// Size of a load, stored in bits 3-4.
    55  	W            = 0x00 // 32 bits
    56  	H            = 0x08 // 16 bits
    57  	B            = 0x10 // 8 bits
    58  	loadSizeMask = 0x18
    59  
    60  	// Source operand for a load, stored in bits 5-7.
    61  	// Address mode numbers in the comments come from Linux's
    62  	// Documentation/networking/filter.txt.
    63  	Imm          = 0x00 // immediate value K (mode 4)
    64  	Abs          = 0x20 // data in input at byte offset K (mode 1)
    65  	Ind          = 0x40 // data in input at byte offset X+K (mode 2)
    66  	Mem          = 0x60 // M[K] (mode 3)
    67  	Len          = 0x80 // length of the input in bytes ("BPF extension len")
    68  	Msh          = 0xa0 // 4 * lower nibble of input at byte offset K (mode 5)
    69  	loadModeMask = 0xe0
    70  
    71  	// Source operands for arithmetic, jump, and return instructions.
    72  	// Arithmetic and jump instructions can use K or X as source operands.
    73  	// Return instructions can use K or A as source operands.
    74  	K             = 0x00 // still mode 4
    75  	X             = 0x08 // mode 0
    76  	A             = 0x10 // mode 9
    77  	srcAluJmpMask = 0x08
    78  	srcRetMask    = 0x18
    79  
    80  	// Arithmetic instructions, stored in bits 4-7.
    81  	Add     = 0x00
    82  	Sub     = 0x10 // A - src
    83  	Mul     = 0x20
    84  	Div     = 0x30 // A / src
    85  	Or      = 0x40
    86  	And     = 0x50
    87  	Lsh     = 0x60 // A << src
    88  	Rsh     = 0x70 // A >> src
    89  	Neg     = 0x80 // -A (src ignored)
    90  	Mod     = 0x90 // A % src
    91  	Xor     = 0xa0
    92  	aluMask = 0xf0
    93  
    94  	// Jump instructions, stored in bits 4-7.
    95  	Ja      = 0x00 // unconditional (uses K for jump offset)
    96  	Jeq     = 0x10 // if A == src
    97  	Jgt     = 0x20 // if A > src
    98  	Jge     = 0x30 // if A >= src
    99  	Jset    = 0x40 // if (A & src) != 0
   100  	jmpMask = 0xf0
   101  
   102  	// Miscellaneous instructions, stored in bits 3-7.
   103  	Tax      = 0x00 // A = X
   104  	Txa      = 0x80 // X = A
   105  	miscMask = 0xf8
   106  
   107  	// Masks for bits that should be zero.
   108  	unusedBitsMask      = 0xff00 // all valid instructions use only bits 0-7
   109  	storeUnusedBitsMask = 0xf8   // stores only use instruction class
   110  	retUnusedBitsMask   = 0xe0   // returns only use instruction class and source operand
   111  )
   112  
   113  // Stmt returns a linux.BPFInstruction representing a BPF non-jump instruction.
   114  func Stmt(code uint16, k uint32) linux.BPFInstruction {
   115  	return linux.BPFInstruction{
   116  		OpCode: code,
   117  		K:      k,
   118  	}
   119  }
   120  
   121  // Jump returns a linux.BPFInstruction representing a BPF jump instruction.
   122  func Jump(code uint16, k uint32, jt, jf uint8) linux.BPFInstruction {
   123  	return linux.BPFInstruction{
   124  		OpCode:      code,
   125  		JumpIfTrue:  jt,
   126  		JumpIfFalse: jf,
   127  		K:           k,
   128  	}
   129  }