ipf -- packet filtering kernel interface


#include <netinet/ip_compat.h>
#include <netinet/ip_fil.h>


IP Filter is a TCP/IP packet filter, suitable for use in a firewall environment. It employs:

Network Address Translation (NAT)
Output packets going through the NAT will have their source IP address changed, if a mapping rule and space in the table exists, prior to being forwarded. Input packets going through the NAT will have their destination IP address changed, if it can be found in the table, to the original value.

IP Accounting
Input and output rules can be separately setup, recording the number of bytes that pass through. Each time a rule match occurs, the byte count of the packet is added to the rule (which act the same as the filtering, allowing for fall-through).

IP Filtering
Input and output rules can be separately setup, determining whether or not a packet will be allowed through the filter, into the kernel's TCP/IP routines or out onto the network.

IP Authentication
Packets which are authenticated are only passed through the filtering loops once to prevent double-filtering and double-accounting.

NOTE: IP filter is different from bpf(ADMP), the IP packet filtering module used to implement the packetfilter(SFF) file that stores packet filter specifications for PPP and SLIP network interfaces. bpf(ADMP) was formerly called ipf(ADMP).


To add and delete rules to the filter list, three 'basic' ioctls are provided for use. The ioctls are called as:
   ioctl(fd, SIOCADDFR, struct frentry *)
   ioctl(fd, SIOCDELFR, struct frentry *)
   ioctl(fd, SIOCIPFFL, int *)

However, the full complement is as follows:

   ioctl(fd, SIOCADAFR, struct frentry *) (same as SUICADDFR)
   ioctl(fd, SIOCRMAFR, struct frentry *) (same as SUICDELFR)
   ioctl(fd, SIOCADIFR, struct frentry *)
   ioctl(fd, SIOCRMIFR, struct frentry *)
   ioctl(fd, SIOCINAFR, struct frentry *)
   ioctl(fd, SIOCINIFR, struct frentry *)
   ioctl(fd, SIOCIPFFL, int *)

The variations, SIOCADAFR and SIOCADIFR, allow operation on the two lists, active and inactive, respectively. All of these ioctls are implemented as being routing ioctls and thus the same rules for the various routing ioctls and the file descriptor are employed, mainly being that the fd must be that of the device associated with the module (that is, /dev/ipl).

The three groups of ioctls above perform adding rules to the end of the list (SIOCAD*), deletion of rules from any place in the list (SIOCRM*) and insertion of a rule into the list (SIOCIN*). The rule place into which it is inserted is stored in the fr_hits field, below.

   typedef struct  frentry {
   	struct  frentry *fr_next;
   	u_short fr_group;       /* group to which this rule belongs */
   	u_short fr_head;        /* group # which this rule starts */
   	struct  frentry *fr_grp;
   	int     fr_ref;         /* reference count - for grouping */
   	struct  ifnet   *fr_ifa;
   	 * These are only incremented when a packet  matches this rule
   	 * and it is the last match
   	U_QUAD_T  fr_hits;
   	U_QUAD_T  fr_bytes;
   	 * Fields after this may not change whilst in the kernel.
   	struct  fr_ip   fr_ip;
   	struct  fr_ip   fr_mip;

u_char fr_tcpfm; /* tcp flags mask */ u_char fr_tcpf; /* tcp flags */

u_short fr_icmpm; /* data for ICMP packets (mask) */ u_short fr_icmp;

u_char fr_scmp; /* data for port comparisons */ u_char fr_dcmp; u_short fr_dport; u_short fr_sport; u_short fr_stop; /* top port for <> and >< */ u_short fr_dtop; /* top port for <> and >< */ u_long fr_flags; /* per-rule flags && options (see below) */ int fr_skip; /* # of rules to skip */ int (*fr_func)(); /* call this function */ char fr_icode; /* return ICMP code */ char fr_ifname[IFNAMSIZ]; struct frdest fr_tif; /* "to" interface */ struct frdest fr_dif; /* duplicate packet interfaces */ } frentry_t;

When adding a new rule, all unused fields (in the filter rule) should be initialised to be zero. To insert a rule, at a particular position in the filter list, the number of the rule which it is to be inserted before must be put in the fr_hits field (the first rule is number 0).

Flags which are recognised in fr_pass:

    FR_BLOCK        0x000001   /* do not allow packet to pass */
    FR_PASS         0x000002   /* allow packet to pass */
    FR_OUTQUE       0x000004   /* outgoing packets */
    FR_INQUE        0x000008   /* ingoing packets */
    FR_LOG          0x000010   /* Log */
    FR_LOGP         0x000011   /* Log-pass */
    FR_LOGB         0x000012   /* Log-fail */
    FR_LOGBODY      0x000020   /* log the body of packets too */
    FR_LOGFIRST     0x000040   /* log only the first packet to match */
    FR_RETRST       0x000080   /* return a TCP RST packet if blocked */
    FR__RETICMP     0x000100   /* return an ICMP packet if blocked */
    FR_NOMATCH      0x000200   /* no match occured */
    FR_ACCOUNT      0x000400   /* count packet bytes */
    FR_KEEPFRAG     0x000800   /* keep fragment information */
    FR_KEEPSTATE    0x001000   /* keep `connection' state information */
    FR_INACTIVE     0x002000
    FR_QUICK        0x004000   /* match & stop processing list */
    FR_FASTROUTE    0x008000   /* bypass normal routing */
    FR_CALLNOW      0x010000   /* call another function (fr_func) if matches */
    FR_DUP          0x020000   /* duplicate the packet */
    FR_LOGORBLOCK   0x040000   /* block the packet if it can't be logged */
    FR_NOTSRCIP     0x080000   /* not the src IP# */
    FR_NOTDSTIP     0x100000   /* not the dst IP# */
    FR_AUTH         0x200000   /* use authentication */
    FR_PREAUTH      0x400000   /* require preauthentication */

Values for fr_scomp and fr_dcomp (source and destination port value comparisons):

   FR_NONE         0
   FR_EQUAL        1
   FR_NEQUAL       2
   FR_LESST        3
   FR_GREATERT     4
   FR_LESSTE       5
   FR_OUTRANGE     7
   FR_INRANGE      8

The third ioctl, SIOCIPFFL, flushes either the input filter list, the output filter list or both and it returns the number of filters removed from the list(s). The values which it will take and recognise are FR_INQUE and FR_OUTQUE (see above).

General Logging Flags

There are two flags which can be set to log packets independantly of the rules used. These allow for packets which are either passed or blocked to be logged. To set (and clear)/get these flags, two ioctls are provided:

Takes an unsigned integer as the parameter. The flags are then set to those provided (clearing/setting all in one).
   FF_LOGPASS	0x10000000
   FF_LOGBLOCK	0x20000000
   FF_LOGNOMATCH	0x40000000
   FF_BLOCKNONIP	0x80000000    /* Solaris 2.x only */

Takes a pointer to an unsigned integer as the parameter. A copy of the flags currently in used is copied to user space.

Filter statistics

Statistics on the various operations performed by this package on packets is kept inside the kernel. These statistics apply to packets traversing through the kernel. To retrieve this structure, use this ioctl:
   ioctl(fd, SIOCGETFS, struct friostat *)

struct friostat { struct filterstats f_st[2]; struct frentry *f_fin[2]; struct frentry *f_fout[2]; struct frentry *f_acctin[2]; struct frentry *f_acctout[2]; struct frentry *f_auth; int f_active; };

struct filterstats { u_long fr_pass; /* packets allowed */ u_long fr_block; /* packets denied */ u_long fr_nom; /* packets which don't match any rule */ u_long fr_ppkl; /* packets allowed and logged */ u_long fr_bpkl; /* packets denied and logged */ u_long fr_npkl; /* packets unmatched and logged */ u_long fr_pkl; /* packets logged */ u_long fr_skip; /* packets to be logged but buffer full */ u_long fr_ret; /* packets for which a return is sent */ u_long fr_acct; /* packets for which counting was performed */ u_long fr_bnfr; /* bad attempts to allocate fragment state */ u_long fr_nfr; /* new fragment state kept */ u_long fr_cfr; /* add new fragment state but complete pkt */ u_long fr_bads; /* bad attempts to allocate packet state */ u_long fr_ads; /* new packet state kept */ u_long fr_chit; /* cached hit */ u_long fr_pull[2]; /* good and bad pullup attempts */ #if SOLARIS u_long fr_bad; /* bad IP packets to the filter */ u_long fr_notip; /* packets passed through no on ip queue */ u_long fr_drop; /* packets dropped - no info for them! */ #endif };



See also

ipl(ADMP), ipnat(ADMP), ipf(SFF), ipf(ADMN), ipfstat(TC)

Standards conformance

ipf is not part of any currently supported standard. It is an extension of AT&T UNIX System V provided by The Santa Cruz Operation, Inc. It includes software developed by the University of California, Berkeley and its contributors.
© 2003 Caldera International, Inc. All rights reserved.
SCO OpenServer Release 5.0.7 -- 11 February 2003