*nix Documentation Project
·  Home
 +   man pages
·  Linux HOWTOs
·  FreeBSD Tips
·  *niX Forums

  man pages->Tru64 Unix man pages -> bpf (7)              
Title
Content
Arch
Section
 

bpf(7)

Contents


NAME    [Toc]    [Back]

       bpf - BSD Packet Filter Extensions

DESCRIPTION    [Toc]    [Back]

       The  BSD  Packet Filter (BPF) is similar to the Tru64 UNIX
       Packet Filter facility (see packetfilter(7)), but provides
       a  slightly  different  programming  interface.   The  BPF
       Extensions to the Tru64 UNIX packet filter provide  nearly
       complete source-level compatibility with BPF.

       The  reader  should  be  familiar with the packetfilter(7)
       reference page before reading this reference page.

       The most useful feature of  the  BPF  Extensions  is  that
       packet  filter  programs  may be written in the BPF filter
       language, which is more efficient and more  flexible  than
       the  original  packet  filter language.  The original language
 uses a stack-machine model,  deals  only  in  16-bit
       quantities,  has minimal control flow primitives.  It also
       does not support indirect loads, which are  necessary  for
       parsing  variable-length headers.  The BPF language uses a
       register-machine model, supports 1, 2, and  4  byte  data,
       has  a  rich  set of control flow primitives, and supports
       indirection.

RESTRICTIONS    [Toc]    [Back]

       If BPF headers are used, data link protocols with variable
       length headers are not properly supported.

IOCTLS    [Toc]    [Back]

       The BPF Extensions consist of a set of ioctl commands that
       may be applied to a packetfilter(7) file descriptor.   The
       command  codes  below are defined in <net/bpf.h>. All commands
   require   these   header   files:         #include
       <sys/types.h>        #include  <sys/time.h>       #include
       <sys/ioctl.h>      #include <net/bpf.h>

       Additionally, BIOCGETIF and BIOCSETIF require  <net/if.h>.

       For  the  following  commands,  the  third argument to the
       ioctl(2) system call should be a pointer to the type indicated.
   Returns  the  required buffer length for reads on
       bpf files. [Provided for compatibility only; on Tru64 UNIX
       this may be ignored.]  Sets the buffer length for reads on
       bpf files.  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. [Provided
       for compatibility only; on Tru64 UNIX this command has  no
       effect, and reads may specify any buffer size large enough
       to hold at least one packet.]  Returns  the  type  of  the
       data  link layer underlying the attached interface. EINVAL
       is returned if no interface has been specified. The device
       types  are  defined  in <net/bpf.h>.  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,  on  some
       operating  systems  a  listener  that opened its interface
       non-promiscuously may receive packets promiscuously.  This
       problem  can be remedied with an appropriate filter. [This
       problem does not occur  on  Tru64  UNIX  systems,  but  by
       assuming  that it might happen you will make your programs
       more portable.]

              The interface remains in promiscuous mode until all
              files  listening promiscuously are closed.  Flushes
              the buffer of  incoming  packets,  and  resets  the
              statistics   that   are   returned  by  BIOCGSTATS.
              Returns the name of  the  hardware  interface  that
              file  is  listening on. The name is returned in the
              if_name field of ifr. All other  fields  are  undefined.
   Sets the hardware interface associate with
              the file.  This command must  be  performed  before
              any packets can be read. The device is indicated by
              name using the if_name field of the  ifreq.   Additionally,
  performs  the actions of BIOCFLUSH.  Set
              or get the  read  timeout  parameter.  The  timeval
              specifies  the length of time to wait before timing
              out on a read request.  This parameter is  initialized
  to  zero  by  open(2), indicating no timeout.
              [See the description of EIOCSRTIMEOUT in packetfilter(7)   for   more  details  on  timeout  values.]
              Returns the following structure of  packet  statistics:
 struct bpf_stat {
                     u_int bs_recv;
                     u_int bs_drop; };

              The  fields  are: The number of packets received by
              the descriptor since opened or reset (including any
              buffered  since the last read call).  The number of
              packets which  were  accepted  by  the  filter  but
              dropped  by  the kernel because of buffer overflows
              (i.e., because  the  application's  reads  are  not
              keeping  up  with  the  packet traffic).  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.  The  default  for  a  new file is off. [On
              Tru64 UNIX systems, this  command  has  no  effect.
              ``Immediate mode'' is always in effect; a read will
              never block if there is a  received  packet  available.]
   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: struct bpf_program {
                     int bf_len;
                     struct bpf_insn *bf_insns; };

              The filter program is pointed to  by  the  bf_insns
              field   while   its  length  in  units  of  `struct
              bpf_insn' is given by the bf_len field.  Also,  the
              actions of BIOCFLUSH are performed.

              See  section  FILTER  MACHINE for an explanation of
              the filter language.

              In addition, the SIOCGIFADDR ioctl may  be  applied
              to packet filter file descriptors.








BPF HEADER    [Toc]    [Back]

       By  default, the Tru64 UNIX Packet Filter does not prepend
       a header to each packet, while the BSD Packet Filter does.
       To request that the BPF header be prepended to each packet
       returned by read(2), use the EIOCMBIS ioctl command to set
       the  ENBPFHDR mode bit (see packetfilter(7) for details on
       the use of EIOCMBIS). If the ENBPFHDR  and  ENTSTAMP  mode
       bits  are  simultaneously  set,  the ENBPFHDR takes precedence.
  If the ENBPFHDR mode bit is set, batch  mode  (see
       the description of ENBATCH in packetfilter(7)) is enabled,
       and the following structure is prepended  to  each  packet
       returned by read(2): struct bpf_hdr {
              struct timeval bh_tstamp;
              u_int bh_caplen;
              u_int bh_datalen;
              u_short bh_hdrlen; };

       The  fields,  whose  values are stored in host byte order,
       and are: The time at which the packet was processed by the
       packet  filter.  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. [On
       Tru64 UNIX systems, the truncation amount specified by the
       filter  is  ignored, and the one specified by EIOCTRUNCATE
       (see packetfilter(7)) is used.]  The length of the  packet
       off  the wire. This value is independent of the truncation
       amount specified by the filter.  The  length  of  the  BPF
       header,  which may not be equal to sizeof(struct bpf_hdr).

       The 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 bpf_hdr and the
       network layer 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).

       Additionally,  individual  packets are padded so that each
       BPF header 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).

       For example, if `p' points to the start of a packet (i.e.,
       the start of the prepended BPF  header),  this  expression
       will advance it to the next packet (BPF header): p = (char
       *)p + BPF_WORDALIGN(p->bh_hdrlen + p->bh_caplen)

       For the alignment mechanisms to work properly, the  buffer
       passed  to read(2) must itself be word aligned.  malloc(3)
       will always return an aligned buffer.







FILTER MACHINE    [Toc]    [Back]

       A filter program is an array  of  instructions,  with  all
       branches   forwardly  directed,  terminated  by  a  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.

       The  following  structure  defines the instruction format:
       struct bpf_insn {
              u_short code;
              u_char  jt;
              u_char  jf;
              int k; };

       The k  field  is  used  in  different  ways  by  different
       instructions, and the jt and 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 with the class  bits  to  give  the
       actual instructions.  The classes and modes are defined in
       <net/bpf.h>.

       Below is given the semantics for each defined BPF 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.  k,  jt,  and  jf  are  the  corresponding
       fields  in  the instruction definition.  ``len'' refers to
       the length of the packet.  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
       (BPF_IMM), packet data at a fixed offset (BPF_ABS), packet
       data at a variable offset  (BPF_IND),  the  packet  length
       (BPF_LEN),   or   a  word  in  the  scratch  memory  store
       (BPF_MEM). For BPF_IND and BPF_ABS, the data size must  be
       specified  as  a  word  (BPF_W), halfword (BPF_H), or byte
       (BPF_B).  The  semantics  of  all  the  recognized  BPF_LD
       instructions  followings:  A  <-  P[k:4]  A <- P[k:2] A <-
       P[k:1] A <- P[X+k:4] A <- P[X+k:2] A <- P[X+k:1] A <-  len
       A  <- k A <- M[k] 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 BPF_MSH, a hack for  efficiently  loading  the  IP
       header  length.   X  <-  k  X  <-  M[k]  X  <-  len  X  <-
       4*(P[k:1]&0xf) 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.
       M[k]  <-  A  This instruction stores the index register in
       the scratch memory store.  M[k] <- X 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
       (BPF_K or BPF_X).  A <- A + k A <- A - k A <- A * k A <- A
       / k A <- A & k A <- A | k A <- A << k A <- A >> k A <- A +
       X A <- A - X A <- A * X A <- A / X A <- A & X A <- A | X A
       <-  A << X A <- A >> X A <- -A The jump instructions alter
       flow of control.  Conditional jumps compare the  accumulator
  against  a  constant  (BPF_K)  or  the index register
       (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 (BPF_JA) opcode
       uses the 32 bit k field as the offset, allowing  arbitrarily
  distant  destinations.  All conditionals use unsigned
       comparison conventions.  pc += k pc += (A > k) ? jt  :  jf
       pc += (A >= k) ? jt : jf pc += (A == k) ? jt : jf pc += (A
       & k) ? jt : jf pc += (A > X) ? jt : jf pc += (A >= X) ? jt
       :  jf pc += (A == X) ? jt : jf pc += (A & X) ? jt : jf 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 (BPF_K) or the  accumulator  (BPF_A).   accept  A
       bytes  accept  k  bytes [On Tru64 UNIX systems, the entire
       packet is accepted if and only if the return value is nonzero;
  the truncation amount is controlled using EIOCTRUNCATE.]
  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.  X <- A A
       <- X

       The BPF interface provides the following macros to facilitate
   array   initializers:   BPF_STMT(opcode,   operand)
       BPF_JUMP(opcode, operand, true_offset, false_offset)

INCOMPATIBILITIES    [Toc]    [Back]

       The BSD Packet Filter Extensions for the Tru64 UNIX Packet
       Filter are intended to  provide  nearly  complete  sourcelevel
  compatibility with the BSD Packet Filter (BPF), but
       in some details this is not  possible.  To  summarize  the
       significant  differences: In BPF, pseudo-devices are named
       /dev/bpf0, /dev/bpf1, and so on.  Applications  open  them
       directly.  On Tru64 UNIX systems, pseudo-devices are named
       /dev/pf/pfilt0, /dev/pf/pfilt1, and so on.   In  BPF,  the
       BPF  header  is always prepended to packets. On Tru64 UNIX
       this behavior must be specifically  requested  by  setting
       the ENBPFHDR mode bit.  In BPF, the number of packet bytes
       returned by the kernel is specified by  the  return  value
       from  the  BPF  filter  program.   This can thus vary from
       packet to packet (since a BPF filter program may have more
       than  one  return  statement).   On  Tru64  UNIX  the size
       returned by a BPF filter program is ignored, and the  number
  of  returned  packet bytes is set using EIOCTRUNCATE.
       This means that it cannot vary from packet to packet.   By
       default, Tru64 UNIX returns the entire packet, which means
       that programs not using EIOCTRUNCATE will probably operate
       correctly,  but  perhaps  not efficiently.  In BPF, packet
       filter applications see packets to or from their own host.
       On  Tru64 UNIX packet filter applications do not see packets
 to or from their own host, unless the  ENCOPYALL  mode
       bit  is set.  In BPF, the number of queued packets is limited
 to what will fit in one page (after truncation).   On
       Tru64  UNIX  the  limit  on  the  number of queued packets
       defaults to 2. This limit may be increased using EIOCSETW.
       Not doing so may result in many lost packets.






EXAMPLES    [Toc]    [Back]

       The following filter is taken from the Reverse ARP Daemon.
       It accepts only Reverse  ARP  requests.   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), };

       This   filter   accepts   only  IP  packets  between  host
       128.3.112.15 and 128.3.112.35.  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_H+BPF_ABS, 26),
              BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
              BPF_STMT(BPF_LD+BPF_H+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_H+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), };

       Finally, this filter returns only TCP finger packets.   We
       must  parse  the  IP  header to reach the TCP header.  The
       BPF_JSET instruction checks that the IP fragment offset is
       0  so  we  are  sure  that  we  have a TCP header.  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), };

SEE ALSO    [Toc]    [Back]

      
      
       Commands: pfconfig(8) pfstat(1)

       Files: packetfilter(7)



                                                           bpf(7)
[ Back ]
 Similar pages
Name OS Title
ipfstat FreeBSD reports on packet filter statistics and filter list
pf OpenBSD packet filter
pfil_remove_hook NetBSD packet filter interface
pfil_remove_hook FreeBSD packet filter interface
pfil_add_hook FreeBSD packet filter interface
pfil_hook_get FreeBSD packet filter interface
pfil FreeBSD packet filter interface
bpf FreeBSD Berkeley Packet Filter
bpf OpenBSD Berkeley Packet Filter
iptables Linux IP packet filter administration
Copyright © 2004-2005 DeniX Solutions SRL
newsletter delivery service