diff options
author | Aaron Campbell <aaron@cvs.openbsd.org> | 2001-03-26 05:36:07 +0000 |
---|---|---|
committer | Aaron Campbell <aaron@cvs.openbsd.org> | 2001-03-26 05:36:07 +0000 |
commit | 6100898e10cf720454d853e413620587eab6c364 (patch) | |
tree | d7c9b2794b089615fc0f7209017fbcefd6d36cad /share/man/man4/bpf.4 | |
parent | b9d026d90379e2721e8facbf1c214264be7bd44b (diff) |
mdoc'ifying manpages is a really easy way to kill loads of time on the plane.
Diffstat (limited to 'share/man/man4/bpf.4')
-rw-r--r-- | share/man/man4/bpf.4 | 1264 |
1 files changed, 726 insertions, 538 deletions
diff --git a/share/man/man4/bpf.4 b/share/man/man4/bpf.4 index 0ee78d2378e..3f21709f634 100644 --- a/share/man/man4/bpf.4 +++ b/share/man/man4/bpf.4 @@ -1,7 +1,5 @@ -.\" -*- nroff -*- -.\" -.\" $OpenBSD: bpf.4,v 1.6 2001/01/29 02:11:08 niklas Exp $ -.\" $NetBSD: bpf.4,v 1.7 1995/09/27 18:31:50 thorpej Exp $ +.\" $OpenBSD: bpf.4,v 1.7 2001/03/26 05:36:06 aaron Exp $ +.\" $NetBSD: bpf.4,v 1.7 1995/09/27 18:31:50 thorpej Exp $ .\" .\" Copyright (c) 1990 The Regents of the University of California. .\" All rights reserved. @@ -25,629 +23,806 @@ .\" This document is derived in part from the enet man page (enet.4) .\" distributed with 4.3BSD Unix. .\" -.TH BPF 4 "23 May 1991" -.SH NAME -bpf \- Berkeley Packet Filter -.SH SYNOPSIS -.B "pseudo-device bpfilter 16" -.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 +.Dd May 23, 1991 +.Dt BPF 4 +.Os +.Sh NAME +.Nm bpf +.Nd Berkeley Packet Filter +.Sh SYNOPSIS +.Cd pseudo-device bpfilter 8 +.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, -.I /dev/bpf0, /dev/bpf1, +.Pa /dev/bpf0 , +.Pa /dev/bpf1 , etc. -After opening the device, the file descriptor must be bound to a -specific network interface with the BIOSETIF ioctl. -A given interface can be shared be multiple listeners, and the filter +After opening the device, the file descriptor must be bound to a specific +network interface with the +.Dv BIOSETIF +ioctl. +A given interface can be shared between multiple listeners and the filter underlying each descriptor will see an identical packet stream. -The total number of open -files is limited to the value given in the kernel configuration; the -example given in the SYNOPSIS above sets the limit to 16. -.PP +The total number of open files is limited to the value given in the kernel +configuration; the example given in the +.Sx SYNOPSIS +above sets the limit to 8. +.Pp A separate device file is required for each minor device. If a file is in use, the open will fail and -.I errno -will be set to EBUSY. -.PP +.Va errno +will be set to +.Er EBUSY . +.Pp Associated with each open instance of a -.I bpf -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. +.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 -.I bpf. -This size is returned by the BIOCGBLEN ioctl (see below), and under -BSD, can be set with BIOCSBLEN. -Note that an individual packet larger than this size is necessarily -truncated. -.PP +.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 bpf . +This size is returned by the +.Dv BIOCGBLEN +ioctl (see below), and under BSD, can be set with +.Dv BIOCSBLEN . +Note that an individual packet larger than this size is necessarily truncated. +.Pp The packet filter will support any link level protocol that has fixed length -headers. Currently, only Ethernet, SLIP and PPP drivers have been -modified to interact with -.I bpf. -.PP +headers. +Currently, only Ethernet, SLIP, and PPP drivers have been modified to +interact with +.Nm bpf . +.Pp Since packet data is in network byte order, applications should use the -.I byteorder(3n) +.Xr byteorder 3 macros to extract multi-byte values. -.PP +.Pp A packet can be sent out on the network by writing to a -.I bpf -file descriptor. The writes are unbuffered, meaning only one -packet can be processed per write. +.Nm +file descriptor. +The writes are unbuffered, meaning only one packet can be processed per write. Currently, only writes to Ethernets and SLIP links are supported. -.SH IOCTLS -The -.I ioctl -command codes below are defined in <net/bpf.h>. All commands require -these includes: -.ft B -.nf - - #include <sys/types.h> - #include <sys/time.h> - #include <sys/ioctl.h> - #include <net/bpf.h> - -.fi -.ft R -Additionally, BIOCGETIF and BIOCSETIF require \fB<net/if.h>\fR. - +.Ss Ioctls +The ioctl command codes below are defined in +.Aq Pa net/bpf.h . +All commands require these includes: +.Pp +.Bd -offset indent +.Cd #include <sys/types.h> +.Cd #include <sys/time.h> +.Cd #include <sys/ioctl.h> +.Cd #include <net/bpf.h> +.Ed +.Pp +Additionally, +.Dv BIOCGETIF +and +.Dv BIOCSETIF +require +.Aq Pa net/if.h . +.Pp The (third) argument to the -.I ioctl -should be a pointer to the type indicated. -.TP 10 -.B BIOCGBLEN (u_int) +.Xr ioctl 2 +call should be a pointer to the type indicated. +.Bl -tag -width Ds +.It Dv BIOCGBLEN Pf ( Li int Ns No ) Returns the required buffer length for reads on -.I bpf +.Nm files. -.TP 10 -.B BIOCSBLEN (u_int) +.It Dv BIOCSBLEN Pf ( Li u_int Ns No ) Sets the buffer length for reads on -.I bpf -files. The buffer must be set before the file is attached to an interface -with 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 EIO if it is passed a buffer that is not this size. -.TP 10 -.B BIOCGDLT (u_int) +.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 accomodated, the closest allowable +size will be set and returned in the argument. +A read call will reseult in +.Er EIO +if it is passed a buffer that is not this size. +.It Dv BIOCGDLT Pf ( Li u_int Ns No ) Returns the type of the data link layer underlying the attached interface. -EINVAL is returned if no interface has been specified. -The device types, prefixed with ``DLT_'', are defined in <net/bpf.h>. -.TP 10 -.B BIOCPROMISC +.Er EINVAL +is returned if no interface has been specified. +The device types, prefixed with +.Dq DLT_ , +are defined in +.Aq Pa net/bpf.h . +.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. -.IP +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. -.TP 10 -.B BIOCFLUSH -Flushes the buffer of incoming packets, -and resets the statistics that are returned by BIOCGSTATS. -.TP 10 -.B BIOCGETIF (struct ifreq) +.It Dv BIOCFLUSH +Flushes the buffer of incoming packets and resets the statistics that are +returned by +.Dv BIOCGSTATS . +.It Dv BIOCGETIF Pf ( Li "struct ifreq" Ns No ) Returns the name of the hardware interface that the file is listening on. -The name is returned in the ifr_name field of -.I ifr. +The name is returned in the +.Fa ifr_name +field of the +.Li struct ifreq . All other fields are undefined. -.TP 10 -.B BIOCSETIF (struct ifreq) -Sets the hardware interface associated with the file. This -command must be performed before any packets can be read. +.It Dv BIOCSETIF Pf ( Li "struct ifreq" Ns No ) +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 -.I ifr_name +.Fa ifr_name field of the -.I ifreq. -Additionally, performs the actions of BIOCFLUSH. -.TP 10 -.B BIOCSRTIMEOUT, BIOCGRTIMEOUT (struct timeval) +.Li struct ifreq . +Additionally, performs the actions of +.Dv BIOCFLUSH . +.It Xo Dv BIOCSRTIMEOUT , Dv BIOCGRTIMEOUT ( +.Li struct timeval Ns No ) +.Xc Set or get the read timeout parameter. The -.I timeval -specifies the length of time to wait before timing -out on a read request. +.Ar timeval +specifies the length of time to wait before timing out on a read request. This parameter is initialized to zero by -.IR open(2), +.Xr open 2 , indicating no timeout. -.TP 10 -.B BIOCGSTATS (struct bpf_stat) +.It Dv BIOCGSTATS Pf ( Li "struct bpf_stat" Ns No ) Returns the following structure of packet statistics: -.ft B -.nf - +.Pp +.Bd -literal -offset indent struct bpf_stat { u_int bs_recv; u_int bs_drop; }; -.fi -.ft R -.IP +.Ed +.Pp The fields are: -.RS -.TP 15 -.I bs_recv -the number of packets received by the descriptor since opened or reset -(including any buffered since the last read call); -and -.TP -.I bs_drop -the number of packets which were accepted by the filter but dropped by the -kernel because of buffer overflows -(i.e., the application's reads aren't keeping up with the packet traffic). -.RE -.TP 10 -.B BIOCIMMEDIATE (u_int) -Enable or disable ``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. +.Pp +.Bl -tag -width bs_recv +.It Fa bs_recv +Number of packets received by the descriptor since opened or reset (including +any buffered since the last read call). +.It Fa bs_drop +Number of packets which were accepted by the filter but dropped by the kernel +because of buffer overflows (i.e., the application's reads aren't keeping up +with the packet traffic). +.El +.It Dv BIOCIMMEDIATE Pf ( Li u_int Ns No ) +Enable or disable +.Dq 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 -.I rarpd(8c), +.Xr rarpd 8 , which must respond to messages in real time. The default for a new file is off. -.TP 10 -.B BIOCSETF (struct bpf_program) -Sets the filter program used by the kernel to discard uninteresting -packets. An array of instructions and its length is passed in using -the following structure: -.ft B -.nf - +.It Dv BIOCSETF Pf ( Li "struct bpf_program" Ns No ) +Sets the filter program used by the kernel to discard uninteresting packets. +An array of instructions and its length is passed in using the following +structure: +.Pp +.Bd -literal -offset indent struct bpf_program { int bf_len; struct bpf_insn *bf_insns; }; -.fi -.ft R -.IP +.Ed +.Pp The filter program is pointed to by the -.I bf_insns -field while its length in units of `struct bpf_insn' is given by the -.I bf_len +.Fa bf_insns +field while its length in units of +.Li struct bpf_insn +is given by the +.Fa bf_len field. -Also, the actions of BIOCFLUSH are performed. -.IP -See section \fBFILTER MACHINE\fP for an explanation of the filter language. -.TP 10 -.B BIOCVERSION (struct bpf_version) +Also, the actions of +.Dv BIOCFLUSH +are performed. +.Pp +See section +.Sx FILTER MACHINE +for an explanation of the filter language. +.It Dv BIOCVERSION Pf ( Li "struct bpf_version" Ns No ) 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: -.ft B -.nf - +recognized by the kernel. +Before installating 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: +.Pp +.Bd -literal -offset indent struct bpf_version { u_short bv_major; u_short bv_minor; }; -.fi -.ft R -.IP +.Ed +.Pp The current version numbers are given by -.B BPF_MAJOR_VERSION +.Dv BPF_MAJOR_VERSION and -.B BPF_MINOR_VERSION -from <net/bpf.h>. -An incompatible filter -may result in undefined behavior (most likely, an error returned by -.I ioctl() -or haphazard packet matching). -.TP 10 -.B BIOCSRSIG BIOCGRSIG (u_int signal) -Set or get the receive signal. This signal will be sent to the process or process group -specified by FIOSETOWN. It defaults to SIGIO. -.SH STANDARD IOCTLS -.I bpf -now supports several standard -.I ioctls -which allow the user to do async and/or non-blocking I/O to an open -.I bpf +.Dv BPF_MINOR_VERSION +from +.Aq Pa net/bpf.h . +An incompatible filter may result in undefined behavior (most likely, an +error returned by +.Xr ioctl 2 +or haphazard packet mactching). +.It Xo Dv BIOCSRSIG , Dv BIOCGRSIG ( +.Li u_int Ns No ) +.Xc +Set or get the receive signal. +This signal will be sent to the process or process group specified by +.Dv FIOSETOWN . +It defaults to +.Dv SIGIO . +.El +.Ss Standard ioctls +.Nm +now supports several standard ioctls which allow the user to do asynchronous +and/or non-blocking I/O to an open +.Nm file descriptor. -.TP 10 -.B FIONREAD (int) +.Bl -tag -width Ds +.It Dv FIONREAD Pf ( Li int Ns No ) Returns the number of bytes that are immediately available for reading. -.TP 10 -.B SIOCGIFADDR (struct ifreq) +.It Dv SIOCGIFADDR Pf ( Li "struct ifreq" Ns No ) Returns the address associated with the interface. -.TP 10 -.B FIONBIO (int) -Set or clear non-blocking I/O. If arg is non-zero, then doing a -.I read -when no data is available will return -1 and -.I errno -will be set to EWOULDBLOCK. -If arg is zero, non-blocking I/O is disabled. Note: setting this -overrides the timeout set by BIOCSRTIMEOUT. -.TP 10 -.B FIOASYNC (int) -Enable or disable async I/O. When enabled (arg is non-zero), the process or -process group specified by FIOSETOWN will start receiving SIGIO's when packets -arrive. Note that you must do an FIOSETOWN in order for this to take effect, as -the system will not default this for you. -The signal may be changed via BIOCSRSIG. -.TP 10 -.B FIOSETOWN FIOGETOWN (int) -Set or get the process or process group (if negative) that should receive SIGIO -when packets are available. The signal may be changed using BIOCSRSIG (see above). -.SH BPF HEADER +.It Dv FIONBIO Pf ( Li int Ns No ) +Set or clear non-blocking I/O. +If the argument is non-zero, then doing a read when no data is available will +return \-1 and +.Va errno +will be set to +.Er EWOULDBLOCK . +If the argument is zero, non-blocking I/O is disabled. +Note: setting this overrides the timeout set by +.Dv BIOCSRTIMEOUT . +.It Dv FIOASYNC Pf ( Li int Ns No ) +Enable or disable asynchronous I/O. +When enabled (argument is non-zero), the process or process group specified +by +.Dv FIOSETOWN +will start receiving +.Dv SIGIO +signals when packets arrive. +Note that you must perform an +.Dv FIOSETOWN +command in order for this to take effect, as the system will not do it by +default. +The signal may be changed via +.Dv BIOCSRSIG . +.It Xo Dv FIOSETOWN , Dv FIOGETOWN ( +.Li int Ns No ) +.Xc +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 +.Ss BPF header The following structure is prepended to each packet returned by -.I read(2): -.in 15 -.ft B -.nf - +.Xr read 2 : +.Pp +.Bd -literal -offset indent struct bpf_hdr { struct timeval bh_tstamp; u_long bh_caplen; u_long bh_datalen; u_short bh_hdrlen; }; -.fi -.ft R -.in -15 -.PP -The fields, whose values are stored in host order, and are: -.TP 15 -.I bh_tstamp -The time at which the packet was processed by the packet filter. -.TP -.I 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. -.TP -.I bh_datalen -The length of the packet off the wire. +.Ed +.Pp +The fields, stored in host order, are as follows: +.Bl -tag -width Ds +.It Fa bh_tstamp +Time at which the packet was processed by the packet filter. +.It Fa bh_caplen +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 +Length of the packet off the wire. This value is independent of the truncation amount specified by the filter. -.TP -.I bh_hdrlen -The length of the BPF header, which may not be equal to -.I sizeof(struct bpf_hdr). -.RE -.PP +.It Fa bh_hdrlen +Length of the BPF header, which may not be equal to +.Li sizeof(struct bpf_hdr) . +.El +.Pp The -.I 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 insures that the -.I bpf_hdr -and the \fInetwork layer\fR header will be word aligned. Suitable precautions -must be taken when accessing the link layer protocol fields on alignment -restricted machines. (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). -.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 BPF_WORDALIGN is defined in <net/bpf.h> to facilitate -this process. It rounds up its argument -to the nearest word aligned value (where a word is BPF_ALIGNMENT bytes wide). -.PP -For example, if `p' points to the start of a packet, this expression -will advance it to the next packet: -.sp -.RS -.ce 1 -.nf -p = (char *)p + BPF_WORDALIGN(p->bh_hdrlen + p->bh_caplen) -.fi -.RE -.PP -For the alignment mechanisms to work properly, the -buffer passed to -.I read(2) +.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 +.Fa bpf_hdr +and the network layer header will be word aligned. +Suitable precuations must be taken when accessing the link layer protocol +fields on alignment restricted machines. +(This isn't a problem on an Ethernet, since the type field is a +.Li short +falling on an even offset, and the addresses are probably accessed in a +bytewise fashion). +.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 +.Aq Pa net/bpf.h +to facilitate this process. +It rounds up its argument to the nearest word aligned value (where a word is +.Dv BPF_ALIGNMENT +bytes wide). +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. -.I malloc(3) +.Xr malloc 3 will always return an aligned buffer. -.ft R -.SH FILTER MACHINE -A filter program is an array of instructions, with all branches forwardly -directed, terminated by a \fBreturn\fP 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. - +.Ss Filter machine +A filter program is an array of instructions with all branches forwardly +directed, terminated by a +.Dq 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: -.RS -.ft B -.nf - +.Pp +.Bd -literal -offset indent struct bpf_insn { - u_short code; - u_char jt; - u_char jf; + u_short code; + u_char jt; + u_char jf; long k; }; -.fi -.ft R -.RE - -The \fIk\fP field is used in different ways by different instructions, -and the \fIjt\fP and \fIjf\fP fields are used as offsets -by the branch instructions. +.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: BPF_LD, BPF_LDX, BPF_ST, BPF_STX, -BPF_ALU, BPF_JMP, BPF_RET, and BPF_MISC. Various other mode and -operator bits are or'd into the class to give the actual instructions. -The classes and modes are defined in <net/bpf.h>. - -Below are the semantics for each defined BPF instruction. +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 logically OR'd into the class to +given the actual instructions. +The classes and modes are defined in +.Aq Pa net/bpf.h . +Below are the semantics for each defined +.Nm +instruction. We use the convention that A is the accumulator, X is the index register, P[] packet data, and M[] scratch memory store. -P[i:n] gives the data at byte offset ``i'' in the packet, -interpreted as a word (n=4), -unsigned halfword (n=2), or unsigned byte (n=1). -M[i] gives the i'th word in the scratch memory store, which is only -addressed in word units. The memory store is indexed from 0 to BPF_MEMWORDS-1. -\fIk\fP, \fIjt\fP, and \fIjf\fP are the corresponding fields in the -instruction definition. ``len'' refers to the length of the packet. - -.TP 10 -.B BPF_LD -These instructions copy a value into the accumulator. The type of the -source operand is specified by an ``addressing mode'' and can be -a constant (\fBBPF_IMM\fP), packet data at a fixed offset (\fBBPF_ABS\fP), -packet data at a variable offset (\fBBPF_IND\fP), the packet length -(\fBBPF_LEN\fP), -or a word in the scratch memory store (\fBBPF_MEM\fP). -For \fBBPF_IND\fP and \fBBPF_ABS\fP, the data size must be specified as a word -(\fBBPF_W\fP), halfword (\fBBPF_H\fP), or byte (\fBBPF_B\fP). -The semantics of all the recognized BPF_LD instructions follow. - -.RS -.TP 30 -.B BPF_LD+BPF_W+BPF_ABS +P[i:n] gives the data at byte offset +.Dq i +in the packet, interpreted as a word (n=4), unsigned halfword (n=2), or +unsigned byte (n=1). +M[i] gives the i'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 No \-1 . +.Fa k , +.Fa jt , +and +.Fa jf +are the corresponding fields in the instruction definition. +.Dq len +refers to the length of the packet. +.Pp +.Bl -tag -width Ds +.It Dv 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 +.Pf ( Dv BPF_IMM ) , +packet data at a fixed offset +.Pf ( Dv BPF_ABS ) , +packet data at a variable offset +.Pf ( Dv BPF_IND ) , +the packet length +.Pf ( Dv BPF_LEN ) , +or a word in the scratch memory store +.Pf ( Dv BPF_MEM ) . +For +.Dv BPF_IND +and +.Dv BPF_ABS , +the data size must be specified as a word +.Pf ( Dv BPF_W ) , +halfword +.Pf ( Dv BPF_H ) , +or byte +.Pf ( Dv BPF_B ) . +The semantics of all recognized +.Dv BPF_LD +instructions follow. +.Pp +.Bl -tag -width 32n -compact +.Sm off +.It Xo Dv BPF_LD No + Dv BPF_W No + +.Dv BPF_ABS +.Xc +.Sm on A <- P[k:4] -.TP -.B BPF_LD+BPF_H+BPF_ABS +.Sm off +.It Xo Dv BPF_LD No + Dv BPF_H No + +.Dv BPF_ABS +.Xc +.Sm on A <- P[k:2] -.TP -.B BPF_LD+BPF_B+BPF_ABS +.Sm off +.It Xo Dv BPF_LD No + Dv BPF_B No + +.Dv BPF_ABS +.Xc +.Sm on A <- P[k:1] -.TP -.B BPF_LD+BPF_W+BPF_IND +.Sm off +.It Xo Dv BPF_LD No + Dv BPF_W No + +.Dv BPF_IND +.Xc +.Sm on A <- P[X+k:4] -.TP -.B BPF_LD+BPF_H+BPF_IND +.Sm off +.It Xo Dv BPF_LD No + Dv BPF_H No + +.Dv BPF_IND +.Xc +.Sm on A <- P[X+k:2] -.TP -.B BPF_LD+BPF_B+BPF_IND +.Sm off +.It Xo Dv BPF_LD No + Dv BPF_B No + +.Dv BPF_IND +.Xc +.Sm on A <- P[X+k:1] -.TP -.B BPF_LD+BPF_W+BPF_LEN +.Sm off +.It Xo Dv BPF_LD No + Dv BPF_W No + +.Dv BPF_LEN +.Xc +.Sm on A <- len -.TP -.B BPF_LD+BPF_IMM +.Sm off +.It Dv BPF_LD No + Dv BPF_IMM +.Sm on A <- k -.TP -.B BPF_LD+BPF_MEM +.It Dv BPF_LD No + Dv BPF_MEM +.Sm on A <- M[k] -.RE - -.TP 10 -.B 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 -.B BPF_MSH, +.El +.It Dv BPF_LDX +These instructions load a value into the index register. +Note that the addressign modes are more restricted than those of the +accumulator loads, but they include +.Dv BPF_MSH , a hack for efficiently loading the IP header length. -.RS -.TP 30 -.B BPF_LDX+BPF_W+BPF_IMM +.Pp +.Bl -tag -width 32n -compact +.Sm off +.It Xo Dv BPF_LDX No + Dv BPF_W No + +.Dv BPF_IMM +.Xc +.Sm on X <- k -.TP -.B BPF_LDX+BPF_W+BPF_MEM +.Sm off +.It Xo Dv BPF_LDX No + Dv BPF_W No + +.Dv BPF_MEM +.Xc +.Sm on X <- M[k] -.TP -.B BPF_LDX+BPF_W+BPF_LEN +.Sm off +.It Xo Dv BPF_LDX No + Dv BPF_W No + +.Dv BPF_LEN +.Xc +.Sm on X <- len -.TP -.B BPF_LDX+BPF_B+BPF_MSH +.Sm off +.It Xo Dv BPF_LDX No + Dv BPF_B No + +.Dv BPF_MSH +.Xc +.Sm on X <- 4*(P[k:1]&0xf) -.RE - -.TP 10 -.B BPF_ST +.El +.It Dv 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. -.RS -.TP 30 -.B BPF_ST +We do not need an addressing mode since there is only one possibility for +the destination. +.Pp +.Bl -tag -width 32n -compact +.It Dv BPF_ST M[k] <- A -.RE - -.TP 10 -.B BPF_STX +.El +.It Dv BPF_STX This instruction stores the index register in the scratch memory store. -.RS -.TP 30 -.B BPF_STX +.Pp +.Bl -tag -width 32n -compact +.It Dv BPF_STX M[k] <- X -.RE - -.TP 10 -.B 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 (\fBBPF_K\fP or -\fBBPF_X\fP). -.RS -.TP 30 -.B BPF_ALU+BPF_ADD+BPF_K +.El +.It Dv 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 +.Pf ( Dv BPF_K +or +.Dv BPF_X ) . +.Pp +.Bl -tag -width 32n -compact +.Sm off +.It Xo Dv BPF_ALU No + BPF_ADD No + +.Dv BPF_K +.Xc +.Sm on A <- A + k -.TP -.B BPF_ALU+BPF_SUB+BPF_K +.Sm off +.It Xo Dv BPF_ALU No + BPF_SUB No + +.Dv BPF_K +.Xc +.Sm on A <- A - k -.TP -.B BPF_ALU+BPF_MUL+BPF_K +.Sm off +.It Xo Dv BPF_ALU No + BPF_MUL No + +.Dv BPF_K +.Xc +.Sm on A <- A * k -.TP -.B BPF_ALU+BPF_DIV+BPF_K +.Sm off +.It Xo Dv BPF_ALU No + BPF_DIV No + +.Dv BPF_K +.Xc +.Sm on A <- A / k -.TP -.B BPF_ALU+BPF_AND+BPF_K +.Sm off +.It Xo Dv BPF_ALU No + BPF_AND No + +.Dv BPF_K +.Xc +.Sm on A <- A & k -.TP -.B BPF_ALU+BPF_OR+BPF_K +.Sm off +.It Xo Dv BPF_ALU No + BPF_OR No + +.Dv BPF_K +.Xc +.Sm on A <- A | k -.TP -.B BPF_ALU+BPF_LSH+BPF_K +.Sm off +.It Xo Dv BPF_ALU No + BPF_LSH No + +.Dv BPF_K +.Xc +.Sm on A <- A << k -.TP -.B BPF_ALU+BPF_RSH+BPF_K +.Sm off +.It Xo Dv BPF_ALU No + BPF_RSH No + +.Dv BPF_K +.Xc +.Sm on A <- A >> k -.TP -.B BPF_ALU+BPF_ADD+BPF_X +.Sm off +.It Xo Dv BPF_ALU No + BPF_ADD No + +.Dv BPF_X +.Xc +.Sm on A <- A + X -.TP -.B BPF_ALU+BPF_SUB+BPF_X +.Sm off +.It Xo Dv BPF_ALU No + BPF_SUB No + +.Dv BPF_X +.Xc +.Sm on A <- A - X -.TP -.B BPF_ALU+BPF_MUL+BPF_X +.Sm off +.It Xo Dv BPF_ALU No + BPF_MUL No + +.Dv BPF_X +.Xc +.Sm on A <- A * X -.TP -.B BPF_ALU+BPF_DIV+BPF_X +.Sm off +.It Xo Dv BPF_ALU No + BPF_DIV No + +.Dv BPF_X +.Xc +.Sm on A <- A / X -.TP -.B BPF_ALU+BPF_AND+BPF_X +.Sm off +.It Xo Dv BPF_ALU No + BPF_AND No + +.Dv BPF_X +.Xc +.Sm on A <- A & X -.TP -.B BPF_ALU+BPF_OR+BPF_X +.Sm off +.It Xo Dv BPF_ALU No + BPF_OR No + +.Dv BPF_X +.Xc +.Sm on A <- A | X -.TP -.B BPF_ALU+BPF_LSH+BPF_X +.Sm off +.It Xo Dv BPF_ALU No + BPF_LSH No + +.Dv BPF_X +.Xc +.Sm on A <- A << X -.TP -.B BPF_ALU+BPF_RSH+BPF_X +.Sm off +.It Xo Dv BPF_ALU No + BPF_RSH No + +.Dv BPF_X +.Xc +.Sm on A <- A >> X -.TP -.B BPF_ALU+BPF_NEG +.Sm off +.It Dv BPF_ALU No + BPF_NEG +.Sm on A <- -A -.RE - -.TP 10 -.B BPF_JMP -The jump instructions alter flow of control. Conditional jumps -compare the accumulator against a constant (\fBBPF_K\fP) or -the index register (\fBBPF_X\fP). If the result is true (or non-zero), -the true branch is taken, otherwise the false branch is taken. +.El +.It Dv BPF_JMP +The jump instructions alter flow of control. +Conditional jumps compare the accumulator against a constant +.Pf ( Dv BPF_K ) +or the index register +.Pf ( Dv 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 (\fBBPF_JA\fP) opcode uses the 32 bit \fIk\fP +However, the jump always +.Pf ( Dv BPF_JA ) +opcode uses the 32-bit +.Fa k field as the offset, allowing arbitrarily distant destinations. All conditionals use unsigned comparison conventions. -.RS -.TP 30 -.B BPF_JMP+BPF_JA +.Pp +.Bl -tag -width 32n -compact +.Sm off +.It Dv BPF_JMP No + BPF_JA pc += k -.TP -.B BPF_JMP+BPF_JGT+BPF_K +.Sm on +.Sm off +.It Xo Dv BPF_JMP No + BPF_JGT No + +.Dv BPF_K +.Xc +.Sm on pc += (A > k) ? jt : jf -.TP -.B BPF_JMP+BPF_JGE+BPF_K +.Sm off +.It Xo Dv BPF_JMP No + BPF_JGE No + +.Dv BPF_K +.Xc +.Sm on pc += (A >= k) ? jt : jf -.TP -.B BPF_JMP+BPF_JEQ+BPF_K +.Sm off +.It Xo Dv BPF_JMP No + BPF_JEQ No + +.Dv BPF_K +.Xc +.Sm on pc += (A == k) ? jt : jf -.TP -.B BPF_JMP+BPF_JSET+BPF_K +.Sm off +.It Xo Dv BPF_JMP No + BPF_JSET No + +.Dv BPF_K +.Xc +.Sm on pc += (A & k) ? jt : jf -.TP -.B BPF_JMP+BPF_JGT+BPF_X +.Sm off +.It Xo Dv BPF_JMP No + BPF_JGT No + +.Dv BPF_X +.Xc +.Sm on pc += (A > X) ? jt : jf -.TP -.B BPF_JMP+BPF_JGE+BPF_X +.Sm off +.It Xo Dv BPF_JMP No + BPF_JGE No + +.Dv BPF_X +.Xc +.Sm on pc += (A >= X) ? jt : jf -.TP -.B BPF_JMP+BPF_JEQ+BPF_X +.Sm off +.It Xo Dv BPF_JMP No + BPF_JEQ No + +.Dv BPF_X +.Xc +.Sm on pc += (A == X) ? jt : jf -.TP -.B BPF_JMP+BPF_JSET+BPF_X +.Sm off +.It Xo Dv BPF_JMP No + BPF_JSET No + +.Dv BPF_X +.Xc +.Sm on pc += (A & X) ? jt : jf -.RE -.TP 10 -.B BPF_RET +.El +.It Dv BPF_RET The return instructions terminate the filter program and specify the amount -of packet to accept (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 (\fBBPF_K\fP) or the accumulator -(\fBBPF_A\fP). -.RS -.TP 30 -.B BPF_RET+BPF_A -accept A bytes -.TP -.B BPF_RET+BPF_K -accept k bytes -.RE -.TP 10 -.B 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. -.RS -.TP 30 -.B BPF_MISC+BPF_TAX +of packet to accept (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 constnat +.Pf ( Dv BPF_K ) +of the accumulator +.Pf ( Dv BPF_A ) . +.Pp +.Bl -tag -width 32n -compact +.It Dv BPF_RET No + Dv BPF_A +Accept A bytes. +.It Dv BPF_RET No + Dv BPF_K +Accept k bytes. +.El +.It Dv 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. +.Pp +.Bl -tag -width 32n -compact +.Sm off +.It Dv BPF_MISC No + Dv BPF_TAX +.Sm on X <- A -.TP -.B BPF_MISC+BPF_TXA +.Sm off +.It Dv BPF_MISC No + Dv BPF_TXA +.Sm on A <- X -.RE -.PP -The BPF interface provides the following macros to facilitate -array initializers: -.RS -\fBBPF_STMT\fI(opcode, operand)\fR -.br -and -.br -\fBBPF_JUMP\fI(opcode, operand, true_offset, false_offset)\fR -.RE -.PP -.SH EXAMPLES -The following filter is taken from the Reverse ARP Daemon. It accepts -only Reverse ARP requests. -.RS -.nf - +.El +.El +.Pp +The +.Nm +interface provides the following macros to facilitate array initializers: +.Pp +.Bd -offset indent +.Dv BPF_STMT Ns No ( Ns Ar opcode , +.Ar operand Ns No ) +.Pp +.Dv BPF_JUMP Ns No ( Ns Ar opcode , +.Ar operand , +.Ar true_offset , +.Ar false_offset Ns No ) +.Ed +.Sh EXAMPLES +The following filter is taken from the Reverse ARP daemon. +It accepts only Reverse ARP requests. +.Pp +.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)), + sizeof(struct ether_header)), BPF_STMT(BPF_RET+BPF_K, 0), }; -.fi -.RE -.PP +.Ed +.Pp This filter accepts only IP packets between host 128.3.112.15 and 128.3.112.35. -.RS -.nf - +.Pp +.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), @@ -661,16 +836,16 @@ struct bpf_insn insns[] = { BPF_STMT(BPF_RET+BPF_K, (u_int)-1), BPF_STMT(BPF_RET+BPF_K, 0), }; -.fi -.RE -.PP -Finally, this filter returns only TCP finger packets. We must parse -the IP header to reach the TCP header. The \fBBPF_JSET\fP instruction -checks that the IP fragment offset is 0 so we are sure -that we have a TCP header. -.RS -.nf - +.Ed +.Pp +Finally, this filter returns only TCP finger packets. +We must parse the IP header to reach the TCP header. +The +.Dv BPF_JSET +instruction checks that the IP fragment offset is 0 so we are sure that we +have a TCP header. +.Pp +.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), @@ -686,38 +861,51 @@ struct bpf_insn insns[] = { BPF_STMT(BPF_RET+BPF_K, (u_int)-1), BPF_STMT(BPF_RET+BPF_K, 0), }; -.fi -.RE -.SH SEE ALSO -tcpdump(8), signal(3), ioctl(2), read(2), select(2) -.LP -McCanne, S., Jacobson V., -.RI ` "An efficient, extensible, and portable network monitor" ' -.SH FILES -/dev/bpf0, /dev/bpf1, ... -.SH BUGS -The read buffer must be of a fixed size (returned by the BIOCGBLEN ioctl). -.PP +.Ed +.Sh SEE ALSO +.Xr ioctl 2 , +.Xr read 2 , +.Xr select 2 , +.Xr signal 3 , +.Xr tcpdump 8 +.Rs +.%A McCanne, S., Jacobson V. +.%J "An efficient, extensible, and portable network monitor" +.Re +.Sh FILES +.Bl -tag -width /dev/bpf[0-9] -compact +.It Pa /dev/bpf[0-9] +BPF devices +.El +.Sh AUTHORS +Steve McCanne of Lawrence Berkeley Laboratary implemented BPF in Summer 1990. +Much of the design is due to Van Jacobson. +.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 BUGS +The read buffer must be of a fixed size (returned by the +.Dv BIOCGBLEN +ioctl). +.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 utilize a filter to reject foreign packets. -.PP +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 overead. +However, we favor the model where all files must assume that the interface +is promiscuous, and if so desired, must utilize a filter to reject foreign +packets. +.Pp Data link protocols with variable length headers are not currently supported. -.PP -Under SunOS, if a BPF application reads more than 2^31 bytes of -data, read will fail in EINVAL. You can either fix the bug in SunOS, -or lseek to 0 when read fails for this reason. -.SH HISTORY -.PP -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 -.PP -Steven McCanne, of Lawrence Berkeley Laboratory, implemented BPF in -Summer 1990. Much of the design is due to Van Jacobson. +.Pp +Under SunOS, if a +.Nm +application reads more than 2^31 bytes of data, read will fail with +.Er EINVAL . +You can either fix the bug in SunOS, or lseek to 0 when read fails for this +reason. + |