diff options
Diffstat (limited to 'static/netbsd/man4/bpf.4')
| -rw-r--r-- | static/netbsd/man4/bpf.4 | 890 |
1 files changed, 890 insertions, 0 deletions
diff --git a/static/netbsd/man4/bpf.4 b/static/netbsd/man4/bpf.4 new file mode 100644 index 00000000..3a629849 --- /dev/null +++ b/static/netbsd/man4/bpf.4 @@ -0,0 +1,890 @@ +.\" -*- nroff -*- +.\" +.\" $NetBSD: bpf.4,v 1.73 2023/02/11 18:03:25 uwe Exp $ +.\" +.\" Copyright (c) 1990, 1991, 1992, 1993, 1994 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that: (1) source code distributions +.\" retain the above copyright notice and this paragraph in its entirety, (2) +.\" distributions including binary code include the above copyright notice and +.\" this paragraph in its entirety in the documentation or other materials +.\" provided with the distribution, and (3) all advertising materials mentioning +.\" features or use of this software display the following acknowledgement: +.\" ``This product includes software developed by the University of California, +.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of +.\" the University nor the names of its contributors may be used to endorse +.\" or promote products derived from this software without specific prior +.\" written permission. +.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED +.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" This document is derived in part from the enet man page (enet.4) +.\" distributed with 4.3BSD Unix. +.\" +.Dd November 30, 2022 +.Dt BPF 4 +.Os +.Sh NAME +.Nm bpf +.Nd Berkeley Packet Filter raw network interface +.Sh SYNOPSIS +.Cd "pseudo-device bpfilter" +.Sh DESCRIPTION +The Berkeley Packet Filter +provides a raw interface to data link layers in a protocol +independent fashion. +All packets on the network, even those destined for other hosts, +are accessible through this mechanism. +.Pp +The packet filter appears as a character special device, +.Pa /dev/bpf . +After opening the device, the file descriptor must be bound to a +specific network interface with the +.Dv BIOCSETIF +ioctl. +A given interface can be shared by multiple listeners, and the filter +underlying each descriptor will see an identical packet stream. +.Pp +Associated with each open instance of a +.Nm +file is a user-settable packet filter. +Whenever a packet is received by an interface, +all file descriptors listening on that interface apply their filter. +Each descriptor that accepts the packet receives its own copy. +.Pp +Reads from these files return the next group of packets +that have matched the filter. +To improve performance, the buffer passed to read must be +the same size as the buffers used internally by +.Nm . +This size is returned by the +.Dv BIOCGBLEN +ioctl (see below), and can be set with +.Dv BIOCSBLEN . +Note that an individual packet larger than this size is necessarily +truncated. +.Pp +Since packet data is in network byte order, applications should use the +.Xr byteorder 3 +macros to extract multi-byte values. +.Pp +A packet can be sent out on the network by writing to a +.Nm +file descriptor. +The writes are unbuffered, meaning only one packet can be processed per write. +Currently, only writes to Ethernet-based (including Wi-Fi), SLIP and loopback +links are supported. +.Sh IOCTLS +The +.Xr ioctl 2 +command codes below are defined in +.In net/bpf.h . +All commands require these includes: +.Bd -literal -offset indent +#include <sys/types.h> +#include <sys/time.h> +#include <sys/ioctl.h> +#include <net/bpf.h> +.Ed +.Pp +Additionally, +.Dv BIOCGETIF +and +.Dv BIOCSETIF +require +.Pa <net/if.h> . +.Pp +The (third) argument to the +.Xr ioctl 2 +should be a pointer to the type indicated. +.Bl -tag -width Dv +.It Dv BIOCGBLEN Pq Vt u_int +Returns the required buffer length for reads on +.Nm +files. +.It Dv BIOCSBLEN Pq Vt u_int +Sets the buffer length for reads on +.Nm +files. +The buffer must be set before the file is attached to an interface with +.Dv BIOCSETIF . +If the requested buffer size cannot be accommodated, the closest +allowable size will be set and returned in the argument. +A read call will result in +.Er EINVAL +if it is passed a buffer that is not this size. +.It Dv BIOCGDLT Pq Vt u_int +Returns the type of the data link layer underlying the attached interface. +.Er EINVAL +is returned if no interface has been specified. +The device types, prefixed with +.Ql DLT_ , +are defined in +.In net/bpf.h . +.It Dv BIOCGDLTLIST Pq Vt struct bpf_dltlist +Returns an array of the available types of the data link layer +underlying the attached interface: +.Bd -literal -offset indent +struct bpf_dltlist { + u_int bfl_len; + u_int *bfl_list; +}; +.Ed +.Pp +The available types are returned in the array pointed to by the +.Fa bfl_list +field while their length in +.Vt u_int +is supplied to the +.Fa bfl_len +field. +.Er ENOMEM +is returned if there is not enough buffer space and +.Er EFAULT +is returned if a bad address is encountered. +The +.Fa bfl_len +field is modified on return to indicate the actual length in u_int +of the array returned. +If +.Fa bfl_list +is +.Dv NULL , +the +.Fa bfl_len +field is set to indicate the required length of an array in +.Vt u_int . +.It Dv BIOCSDLT Pq Vt u_int +Changes the type of the data link layer underlying the attached interface. +.Er EINVAL +is returned if no interface has been specified or the specified +type is not available for the interface. +.It Dv BIOCPROMISC +Forces the interface into promiscuous mode. +All packets, not just those destined for the local host, are processed. +Since more than one file can be listening on a given interface, +a listener that opened its interface non-promiscuously may receive +packets promiscuously. +This problem can be remedied with an appropriate filter. +.Pp +The interface remains in promiscuous mode until all files listening +promiscuously are closed. +.It Dv BIOCFLUSH +Flushes the buffer of incoming packets, +and resets the statistics that are returned by +.Dv BIOCGSTATS . +.It Dv BIOCGETIF Pq Vt struct ifreq +Returns the name of the hardware interface that the file is listening on. +The name is returned in the +.Fa ifr_name +field of +.Vt ifreq . +All other fields are undefined. +.It Dv BIOCSETIF Pq Vt struct ifreq +Sets the hardware interface associated with the file. +This command must be performed before any packets can be read. +The device is indicated by name using the +.Fa ifr_name +field of the +.Vt ifreq . +Additionally, performs the actions of +.Dv BIOCFLUSH . +.It Dv BIOCSRTIMEOUT , BIOCGRTIMEOUT Pq Vt struct timeval +Sets or gets the +.Dq Em read timeout +parameter. +The +.Vt timeval +specifies the length of time to wait before timing +out on a read request. +This parameter is initialized to zero by +.Xr open 2 , +indicating no timeout. +.It Dv BIOCGSTATS Pq Vt struct bpf_stat +Returns the following structure of packet statistics: +.Bd -literal -offset indent +struct bpf_stat { + uint64_t bs_recv; + uint64_t bs_drop; + uint64_t bs_capt; + uint64_t bs_padding[13]; +}; +.Ed +.Pp +The fields are: +.Bl -tag -width Fa -offset indent +.It Fa bs_recv +the number of packets received by the descriptor since opened or reset +.Pq including any buffered since the last read call ; +.It Fa bs_drop +the number of packets which were accepted by the filter but dropped by the +kernel because of buffer overflows +.Po +i.e., the application's reads aren't keeping up with the packet traffic +.Pc ; +and +.It Fa bs_capt +the number of packets accepted by the filter. +.El +.It Dv BIOCIMMEDIATE Pq Vt u_int +Enables or disables +.Dq Em immediate mode , +based on the truth value of the argument. +When immediate mode is enabled, reads return immediately upon packet +reception. +Otherwise, a read will block until either the kernel buffer +becomes full or a timeout occurs. +This is useful for programs like +.Xr rarpd 8 , +which must respond to messages in real time. +The default for a new file is off. +.It Dv BIOCLOCK Pq Dv NULL +Set the locked flag on the bpf descriptor. +This prevents the execution of ioctl commands which could change the +underlying operating parameters of the device. +.It Dv BIOCSETF Pq Vt struct bpf_program +Sets the filter program used by the kernel to discard uninteresting +packets. +An array of instructions and its length are passed in using the following structure: +.Bd -literal -offset indent +struct bpf_program { + u_int bf_len; + struct bpf_insn *bf_insns; +}; +.Ed +.Pp +The filter program is pointed to by the +.Fa bf_insns +field while its length in units of +.Vt struct bpf_insn +is given by the +.Fa bf_len +field. +Also, the actions of +.Dv BIOCFLUSH +are performed. +.Pp +See section +.Sx FILTER MACHINE +for an explanation of the filter language. +.It Dv BIOCSETWF Pq Vt struct bpf_program +Sets the write filter program used by the kernel to control what type +of packets can be written to the interface. +See the +.Dv BIOCSETF +command for more information on the bpf filter program. +.It Dv BIOCVERSION Pq Vt struct bpf_version +Returns the major and minor version numbers of the filter language currently +recognized by the kernel. +Before installing a filter, applications must check +that the current version is compatible with the running kernel. +Version numbers are compatible if the major numbers match and the +application minor is less than or equal to the kernel minor. +The kernel version number is returned in the following structure: +.Bd -literal -offset indent +struct bpf_version { + u_short bv_major; + u_short bv_minor; +}; +.Ed +.Pp +The current version numbers are given by +.Dv BPF_MAJOR_VERSION +and +.Dv BPF_MINOR_VERSION +from +.In net/bpf.h . +An incompatible filter +may result in undefined behavior +.Po +most likely, an error returned by +.Xr ioctl 2 +or haphazard packet matching +.Pc . +.It Dv BIOCSRSIG , BIOCGRSIG Pq Vt u_int +Sets or gets the receive signal. +This signal will be sent to the process or process group specified by +.Dv FIOSETOWN . +It defaults to +.Dv SIGIO . +.It Dv BIOCGHDRCMPLT , BIOCSHDRCMPLT Pq Vt u_int +Sets or gets the status of the +.Dq header complete +flag. +Set to zero if the link level source address should be filled in +automatically by the interface output routine. +Set to one if the link level source address will be written, +as provided, to the wire. +This flag is initialized to zero by default. +.It Dv BIOCGSEESENT , BIOCSSEESENT Pq Vt u_int +These commands are obsolete but left for compatibility. +Use +.Dv BIOCSDIRECTION +and +.Dv BIOCGDIRECTION +instead. +Set or get the flag determining whether locally generated packets on the +interface should be returned by BPF. +Set to zero to see only incoming packets on the interface. +Set to one to see packets originating locally and remotely on the interface. +This flag is initialized to one by default. +.It Dv BIOCSDIRECTION , BIOCGDIRECTION Pq Vt u_int +Set or get the setting determining whether incoming, outgoing, or all packets +on the interface should be returned by BPF. +Set to +.Dv BPF_D_IN +to see only incoming packets on the interface. +Set to +.Dv BPF_D_INOUT +to see packets originating locally and remotely on the interface. +Set to +.Dv BPF_D_OUT +to see only outgoing packets on the interface. +This setting is initialized to +.Dv BPF_D_INOUT +by default. +.It Dv BIOCFEEDBACK , BIOCSFEEDBACK , BIOCGFEEDBACK Pq Vt u_int +Set (or get) +.Dq packet feedback mode . +This allows injected packets to be fed back as input to the interface when +output via the interface is successful. +The first name is meant for +.Fx +compatibility, the two others follow the Get/Set convention. +.\"When +.\".Dv BPF_D_INOUT +.\"direction is set, injected +Injected +outgoing packets are not returned by BPF to avoid +duplication. +This flag is initialized to zero by default. +.El +.Sh STANDARD IOCTLS +.Nm +supports several standard +.Xr ioctl 2 Ap s +which allow the user to do async and/or non-blocking I/O to an open +.Nm bpf +file descriptor. +.Bl -tag -width Dv +.It Dv FIONREAD Pq Vt int +Returns the number of bytes that are immediately available for reading. +.It Dv FIONBIO Pq Vt int +Set or clear non-blocking I/O. +If arg is non-zero, then doing a +.Xr read 2 +when no data is available will return \-1 and +.Va errno +will be set to +.Er EAGAIN . +If arg is zero, non-blocking I/O is disabled. +Note: setting this +overrides the timeout set by +.Dv BIOCSRTIMEOUT . +.It Dv FIOASYNC Pq Vt int +Enable or disable async I/O. +When enabled (arg is non-zero), the process or process group specified by +.Dv FIOSETOWN +will start receiving +.Dv SIGIO Ap s +when packets arrive. +Note that you must do an +.Dv FIOSETOWN +in order for this to take effect, as +the system will not default this for you. +The signal may be changed via +.Dv BIOCSRSIG . +.It Dv FIOSETOWN , FIOGETOWN Pq Vt int +Set or get the process or process group (if negative) that should receive +.Dv SIGIO +when packets are available. +The signal may be changed using +.Dv BIOCSRSIG +(see above). +.El +.Sh BPF HEADER +The following structure is prepended to each packet returned by +.Xr read 2 : +.Bd -literal -offset indent +struct bpf_hdr { + struct bpf_timeval bh_tstamp; + uint32_t bh_caplen; + uint32_t bh_datalen; + uint16_t bh_hdrlen; +}; +.Ed +.Pp +The fields, whose values are stored in host order, are: +.Bl -tag -width Fa -offset indent +.It Fa bh_tstamp +The time at which the packet was processed by the packet filter. +This structure differs from the standard +.Vt struct timeval +in that both members are of type +.Vt long . +.It Fa bh_caplen +The length of the captured portion of the packet. +This is the minimum of +the truncation amount specified by the filter and the length of the packet. +.It Fa bh_datalen +The length of the packet off the wire. +This value is independent of the truncation amount specified by the filter. +.It Fa bh_hdrlen +The length of the BPF header, which may not be equal to +.Li sizeof(struct bpf_hdr) . +.El +.Pp +The +.Fa bh_hdrlen +field exists to account for +padding between the header and the link level protocol. +The purpose here is to guarantee proper alignment of the packet +data structures, which is required on alignment sensitive +architectures and improves performance on many other architectures. +The packet filter ensures that the +.Vt bpf_hdr +and the +.Em network layer +header will be word aligned. +Suitable precautions must be taken when accessing the link layer +protocol fields on alignment restricted machines. +.Po +This isn't a problem on an Ethernet, since +the type field is a short falling on an even offset, +and the addresses are probably accessed in a bytewise fashion +.Pc . +.Pp +Additionally, individual packets are padded so that each starts +on a word boundary. +This requires that an application +has some knowledge of how to get from packet to packet. +The macro +.Dv BPF_WORDALIGN +is defined in +.In net/bpf.h +to facilitate this process. +It rounds up its argument +to the nearest word aligned value +.Po +where a word is +.Dv BPF_ALIGNMENT +bytes wide +.Pc . +.Pp +For example, if +.Va p +points to the start of a packet, this expression +will advance it to the next packet: +.Pp +.Dl p = (char *)p + BPF_WORDALIGN(p->bh_hdrlen + p->bh_caplen) +.Pp +For the alignment mechanisms to work properly, the +buffer passed to +.Xr read 2 +must itself be word aligned. +.Xr malloc 3 +will always return an aligned buffer. +.Sh FILTER MACHINE +A filter program is an array of instructions, with all branches +.Em forwardly directed , +terminated by a +.Em return +instruction. +Each instruction performs some action on the pseudo-machine state, +which consists of an accumulator, index register, scratch memory store, +and implicit program counter. +.Pp +The following structure defines the instruction format: +.Bd -literal -offset indent +struct bpf_insn { + uint16_t code; + u_char jt; + u_char jf; + uint32_t k; +}; +.Ed +.Pp +The +.Fa k +field is used in different ways by different instructions, +and the +.Fa jt +and +.Fa jf +fields are used as offsets +by the branch instructions. +The opcodes are encoded in a semi-hierarchical fashion. +There are eight classes of instructions: +.Dv BPF_LD , +.Dv BPF_LDX , +.Dv BPF_ST , +.Dv BPF_STX , +.Dv BPF_ALU , +.Dv BPF_JMP , +.Dv BPF_RET , +and +.Dv BPF_MISC . +Various other mode and +operator bits are +.Em or Ap d +into the class to give the actual instructions. +The classes and modes are defined in +.In net/bpf.h . +.Pp +Below are the semantics for each defined BPF instruction. +We use the convention that +.Ar A +is the accumulator, +.Ar X +is the index register, +.Ar P +packet data, and +.Ar M +scratch memory store. +.Sm off +.Ar P Li \&[ Ar i Li \&: Ar n\^ Li \&] +.Sm on +gives the data at byte offset +.Ar i +in the packet, +interpreted as a word +.Ar ( n No = 4 ) , +unsigned halfword +.Ar ( n No = 2 ) , +or unsigned byte +.Ar ( n No = 1 ) . +.Sm off +.Ar M\^ Li \&[ Ar i\^ Li \&] +.Sm on +gives the +.Ar i Ap th +word in the scratch memory store, which is only +addressed in word units. +The memory store is indexed from 0 to +.Dv BPF_MEMWORDS Ns Li \&-1 . +.Fa k , +.Fa jt , +and +.Fa jf +are the corresponding fields in the +instruction definition. +.Ar len +refers to the length of the packet. +.Bl -tag -width indent +.It Sy BPF_LD +These instructions copy a value into the accumulator. +The type of the source operand is specified by an +.Dq addressing mode +and can be a constant +.Sy ( BPF_IMM ) , +packet data at a fixed offset +.Sy ( BPF_ABS ) , +packet data at a variable offset +.Sy ( BPF_IND ) , +the packet length +.Sy ( BPF_LEN ) , +or a word in the scratch memory store +.Sy ( BPF_MEM ) . +For +.Sy BPF_IND +and +.Sy BPF_ABS , +the data size must be specified as a word +.Sy ( BPF_W ) , +halfword +.Sy ( BPF_H ) , +or byte +.Sy ( BPF_B ) . +Arithmetic overflow when calculating a variable offset terminates +the filter program and the packet is ignored. +The semantics of all the recognized +.Sy BPF_LD +instructions follow. +.\" to make all instruction tables align nicely, use common max width +.ds max-insn .Sy BPF_LDX + BPF_W + BPF_WWW +.\" +.Bl -column "\*[max-insn]" -offset indent +.It Sy BPF_LD + BPF_W + BPF_ABS Ta A \[<-] P[k:4] +.It Sy BPF_LD + BPF_H + BPF_ABS Ta A \[<-] P[k:2] +.It Sy BPF_LD + BPF_B + BPF_ABS Ta A \[<-] P[k:1] +.It Sy BPF_LD + BPF_W + BPF_IND Ta A \[<-] P[X+k:4] +.It Sy BPF_LD + BPF_H + BPF_IND Ta A \[<-] P[X+k:2] +.It Sy BPF_LD + BPF_B + BPF_IND Ta A \[<-] P[X+k:1] +.It Sy BPF_LD + BPF_W + BPF_LEN Ta A \[<-] len +.It Sy BPF_LD + BPF_IMM Ta A \[<-] k +.It Sy BPF_LD + BPF_MEM Ta A \[<-] M[k] +.El +.It Sy BPF_LDX +These instructions load a value into the index register. +Note that the addressing modes are more restricted than those of +the accumulator loads, but they include +.Sy BPF_MSH , +a hack for efficiently loading the IP header length. +.Bl -column "\*[max-insn]" -offset indent +.It Sy BPF_LDX + BPF_W + BPF_IMM Ta X \[<-] k +.It Sy BPF_LDX + BPF_W + BPF_MEM Ta X \[<-] M[k] +.It Sy BPF_LDX + BPF_W + BPF_LEN Ta X \[<-] len +.It Sy BPF_LDX + BPF_B + BPF_MSH Ta X \[<-] 4*(P[k:1]&0xf) +.El +.It Sy BPF_ST +This instruction stores the accumulator into the scratch memory. +We do not need an addressing mode since there is only one possibility +for the destination. +.Bl -column "\*[max-insn]" -offset indent +.It Sy BPF_ST Ta M[k] \[<-] A +.El +.It Sy BPF_STX +This instruction stores the index register in the scratch memory store. +.Bl -column "\*[max-insn]" -offset indent +.It Sy BPF_STX Ta M[k] \[<-] X +.El +.It Sy BPF_ALU +The alu instructions perform operations between the accumulator and +index register or constant, and store the result back in the accumulator. +For binary operations, a source mode is required +.Sy ( BPF_K +or +.Sy BPF_X ) . +.Bl -column "\*[max-insn]" -offset indent +.It Sy BPF_ALU + BPF_ADD + BPF_K Ta A \[<-] A + k +.It Sy BPF_ALU + BPF_SUB + BPF_K Ta A \[<-] A \- k +.It Sy BPF_ALU + BPF_MUL + BPF_K Ta A \[<-] A * k +.It Sy BPF_ALU + BPF_DIV + BPF_K Ta A \[<-] A / k +.It Sy BPF_ALU + BPF_AND + BPF_K Ta A \[<-] A & k +.It Sy BPF_ALU + BPF_OR + BPF_K Ta A \[<-] A | k +.It Sy BPF_ALU + BPF_LSH + BPF_K Ta A \[<-] A \[<<] k +.It Sy BPF_ALU + BPF_RSH + BPF_K Ta A \[<-] A \[>>] k +.It Sy BPF_ALU + BPF_ADD + BPF_X Ta A \[<-] A + X +.It Sy BPF_ALU + BPF_SUB + BPF_X Ta A \[<-] A \- X +.It Sy BPF_ALU + BPF_MUL + BPF_X Ta A \[<-] A * X +.It Sy BPF_ALU + BPF_DIV + BPF_X Ta A \[<-] A / X +.It Sy BPF_ALU + BPF_AND + BPF_X Ta A \[<-] A & X +.It Sy BPF_ALU + BPF_OR + BPF_X Ta A \[<-] A | X +.It Sy BPF_ALU + BPF_LSH + BPF_X Ta A \[<-] A \[<<] X +.It Sy BPF_ALU + BPF_RSH + BPF_X Ta A \[<-] A \[>>] X +.It Sy BPF_ALU + BPF_NEG Ta A \[<-] \-A +.El +.It Sy BPF_JMP +The jump instructions alter flow of control. +Conditional jumps compare the accumulator against a constant +.Sy ( BPF_K ) +or the index register +.Sy ( BPF_X ) . +If the result is true (or non-zero), +the true branch is taken, otherwise the false branch is taken. +Jump offsets are encoded in 8 bits so the longest jump is 256 instructions. +However, the jump always +.Sy ( BPF_JA ) +opcode uses the 32 bit +.Fa k +field as the offset, allowing arbitrarily distant destinations. +All conditionals use unsigned comparison conventions. +.Bl -column "\*[max-insn]" -offset indent +.It Sy BPF_JMP + BPF_JA Ta pc += k +.It Sy BPF_JMP + BPF_JGT + BPF_K Ta "pc += (A > k) ? jt : jf" +.It Sy BPF_JMP + BPF_JGE + BPF_K Ta "pc += (A \*[Ge] k) ? jt : jf" +.It Sy BPF_JMP + BPF_JEQ + BPF_K Ta "pc += (A == k) ? jt : jf" +.It Sy BPF_JMP + BPF_JSET + BPF_K Ta "pc += (A & k) ? jt : jf" +.It Sy BPF_JMP + BPF_JGT + BPF_X Ta "pc += (A > X) ? jt : jf" +.It Sy BPF_JMP + BPF_JGE + BPF_X Ta "pc += (A \*[Ge] X) ? jt : jf" +.It Sy BPF_JMP + BPF_JEQ + BPF_X Ta "pc += (A == X) ? jt : jf" +.It Sy BPF_JMP + BPF_JSET + BPF_X Ta "pc += (A & X) ? jt : jf" +.El +.It Sy BPF_RET +The return instructions terminate the filter program and specify the amount +of packet to accept +.Pq i.e., they return the truncation amount . +A return value of zero indicates that the packet should be ignored. +The return value is either a constant +.Sy ( BPF_K ) +or the accumulator +.Sy ( BPF_A ) . +.Bl -column "\*[max-insn]" -offset indent +.It Sy BPF_RET + BPF_A Ta accept A bytes +.It Sy BPF_RET + BPF_K Ta accept k bytes +.El +.It Sy BPF_MISC +The miscellaneous category was created for anything that doesn't +fit into the above classes, and for any new instructions that might need to +be added. +Currently, these are the register transfer instructions +that copy the index register to the accumulator or vice versa. +.Bl -column "\*[max-insn]" -offset indent +.It Sy BPF_MISC + BPF_TAX Ta X \[<-] A +.It Sy BPF_MISC + BPF_TXA Ta A \[<-] X +.El +.Pp +Also, two instructions to call a +.Dq Em coprocessor +if initialized by the kernel component. +There is no coprocessor by default. +.Bl -column "\*[max-insn]" -offset indent +.It Sy BPF_MISC + BPF_COP Ta A \[<-] funcs[k](...) +.It Sy BPF_MISC + BPF_COPX Ta A \[<-] funcs[X](...) +.El +.Pp +If the coprocessor is not set or the function index is out of range, these +instructions will abort the program and return zero. +.El +.Pp +The BPF interface provides the following macros to facilitate +array initializers: +.Bd -unfilled -offset indent +.Fn BPF_STMT opcode operand +.Fn BPF_JUMP opcode operand true_offset false_offset +.Ed +.Sh SYSCTLS +The following sysctls are available when +.Nm +is enabled: +.Bl -tag -width ".Li net.bpf.maxbufsize" +.It Li net.bpf.maxbufsize +Sets the maximum buffer size available for +.Nm +peers. +.It Li net.bpf.stats +Shows +.Nm +statistics. +They can be retrieved with the +.Xr netstat 1 +utility. +.It Li net.bpf.peers +Shows the current +.Nm +peers. +This is only available to the super user and can also be retrieved with the +.Xr netstat 1 +utility. +.El +.Pp +On architectures with +.Xr bpfjit 4 +support, the additional sysctl is available: +.Bl -tag -width ".Li net.bpf.jit" +.It Li net.bpf.jit +Toggle +.Em just-in-time +compilation of new filter programs. +In order to enable just-in-time compilation, +the bpfjit kernel module must be loaded. +Changing a value of this sysctl doesn't affect +existing filter programs. +.El +.Sh FILES +.Pa /dev/bpf +.Sh EXAMPLES +The following filter is taken from the Reverse ARP Daemon. +It accepts only Reverse ARP requests. +.Bd -literal -offset indent +struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETHERTYPE_REVARP, 0, 3), + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, REVARP_REQUEST, 0, 1), + BPF_STMT(BPF_RET+BPF_K, sizeof(struct ether_arp) + + sizeof(struct ether_header)), + BPF_STMT(BPF_RET+BPF_K, 0), +}; +.Ed +.Pp +This filter accepts only IP packets between host 128.3.112.15 and +128.3.112.35. +.Bd -literal -offset indent +struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETHERTYPE_IP, 0, 8), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 4), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 1), + BPF_STMT(BPF_RET+BPF_K, (u_int)-1), + BPF_STMT(BPF_RET+BPF_K, 0), +}; +.Ed +.Pp +Finally, this filter returns only TCP finger packets. +We must parse the IP header to reach the TCP header. +The +.Sy BPF_JSET +instruction checks that the IP fragment offset is 0 so we are sure +that we have a TCP header. +.Bd -literal -offset indent +struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETHERTYPE_IP, 0, 10), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 23), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_TCP, 0, 8), + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 0x1fff, 6, 0), + BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 14), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 14), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 79, 2, 0), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 16), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 79, 0, 1), + BPF_STMT(BPF_RET+BPF_K, (u_int)-1), + BPF_STMT(BPF_RET+BPF_K, 0), +}; +.Ed +.Sh SEE ALSO +.Xr ioctl 2 , +.Xr read 2 , +.Xr select 2 , +.Xr signal 3 , +.Xr bpfjit 4 , +.Xr tcpdump 8 +.Rs +.%T "The BSD Packet Filter: A New Architecture for User-level Packet Capture" +.%A S. McCanne +.%A V. Jacobson +.%J Proceedings of the 1993 Winter USENIX +.%C Technical Conference, San Diego, CA +.Re +.Sh HISTORY +The Enet packet filter was created in 1980 by Mike Accetta and +Rick Rashid at Carnegie-Mellon University. +Jeffrey Mogul, at Stanford, ported the code to BSD and continued +its development from 1983 on. +Since then, it has evolved into the ULTRIX Packet Filter +at DEC, a STREAMS NIT module under SunOS 4.1, and BPF. +.Sh AUTHORS +.An -nosplit +.An Steven McCanne , +of Lawrence Berkeley Laboratory, implemented BPF in Summer 1990. +The design was in collaboration with +.An Van Jacobson , +also of Lawrence Berkeley Laboratory. +.Sh BUGS +The read buffer must be of a fixed size +.Po +returned by the +.Dv BIOCGBLEN +ioctl +.Pc . +.Pp +A file that does not request promiscuous mode may receive promiscuously +received packets as a side effect of another file requesting this +mode on the same hardware interface. +This could be fixed in the kernel with additional processing overhead. +However, we favor the model where +all files must assume that the interface is promiscuous, and if +so desired, must use a filter to reject foreign packets. +.\" .Pp +.\" Under SunOS, if a BPF application reads more than 2^31 bytes of +.\" data, read will fail in +.\" .Er EINVAL . +.\" You can either fix the bug in SunOS, +.\" or lseek to 0 when read fails for this reason. +.Pp +.Dq Em Immediate mode +and the +.Dq Em read timeout +are misguided features. +This functionality can be emulated with non-blocking mode and +.Xr select 2 . |
