]> git.saurik.com Git - apple/network_cmds.git/blobdiff - ipfw.tproj/ipfw.8
network_cmds-356.9.tar.gz
[apple/network_cmds.git] / ipfw.tproj / ipfw.8
index c332dc02a1104b935f9d371df58ba89eb124006e..4136a3fe994bae78d0f63d38ac8b3ce07c0ca73a 100644 (file)
-.Dd July 2, 2003
+.\"
+.\" $FreeBSD: /repoman/r/ncvs/src/sbin/ipfw/ipfw.8,v 1.63.2.38 2003/07/28 07:15:13 luigi Exp $
+.\"
+.Dd August 13, 2002
 .Dt IPFW 8
 .Os Darwin
 .Sh NAME
 .Nm ipfw
 .Nd IP firewall and traffic shaper control program
+(DEPRECATED)
 .Sh SYNOPSIS
 .Nm
-.Op Fl q
-.Oo
-.Fl p Ar preproc
-.Oo Fl D
-.Ar macro Ns Op = Ns Ar value
-.Oc
-.Op Fl U Ar macro
-.Oc
-.Ar pathname
+.Op Fl cq
+.Cm add
+.Ar rule
+.Nm
+.Op Fl acdefnNStT
+.Brq Cm list | show
+.Op Ar rule | first-last ...
 .Nm
 .Op Fl f | q
 .Cm flush
 .Nm
 .Op Fl q
-.Es \&{ \&}
-.En Cm zero | resetlog | delete
+.Brq Cm delete | zero | resetlog
+.Op Cm set
 .Op Ar number ...
 .Nm
+.Cm enable
+.Brq Cm firewall | one_pass | debug | verbose | dyn_keepalive
+.Nm
+.Cm disable
+.Brq Cm firewall | one_pass | debug | verbose | dyn_keepalive
+.Pp
+.Nm
+.Cm set Oo Cm disable Ar number ... Oc Op Cm enable Ar number ...
+.Nm
+.Cm set move
+.Op Cm rule
+.Ar number Cm to Ar number
+.Nm
+.Cm set swap Ar number number
+.Nm
+.Cm set show
+.Pp
+.Nm
+.Brq Cm pipe | queue
+.Ar number
+.Cm config
+.Ar config-options
+.Nm
 .Op Fl s Op Ar field
-.Op Fl aftN
-.Es \&{ \&}
-.En Cm list | show
+.Brq Cm pipe | queue
+.Brq Cm delete | list | show
 .Op Ar number ...
+.Pp
 .Nm
-.Op Fl q
-.Cm add
-.Op Ar number
-.Ar rule-body
+.Op Fl cnNqS
+.Oo
+.Fl p Ar preproc
+.Oo
+.Ar preproc-flags
+.Oc
+.Oc
+.Ar pathname
 .Sh DESCRIPTION
+Note that use of this utility is
+.Cm DEPRECATED.
+Please use
+.Xr pfctl 8
+instead.
+.Pp
+The
 .Nm
-is the user interface for controlling the
-.Xr ipfirewall 4
-.
+utility is the user interface for controlling the
+.Xr ipfw 4
+firewall and the
+.Xr dummynet 4
+traffic shaper. 
 .Pp
-Each incoming or outgoing packet is passed through the
+An
 .Nm
-rules.
-If the host is acting as a gateway, packets forwarded by
-the gateway are processed by
+configuration, or
+.Em ruleset ,
+is made of a list of
+.Em rules
+numbered from 1 to 65535.
+Packets are passed to
 .Nm
-twice.
-When the host is acting as a bridge, packets forwarded by
-the bridge are processed by
+from a number of different places in the protocol stack
+(depending on the source and destination of the packet,
+it is possible that
 .Nm
-once.
+is invoked multiple times on the same packet).
+The packet passed to the firewall is compared
+against each of the rules in the firewall
+.Em ruleset .
+When a match is found, the action corresponding to the
+matching rule is performed.
 .Pp
-A firewall configuration is made of a list of numbered rules,
-which is scanned for each packet until a match is found and
-the relevant action is performed.
 Depending on the action and certain system settings, packets
-can be reinjected into the firewall at the rule after the
+can be reinjected into the firewall at some rule after the
 matching one for further processing.
-All rules apply to all interfaces, so it is responsibility
-of the system administrator to write the ruleset in such a
-way as to minimize the number of checks.
-.Pp
-A configuration always includes a
-.Em DEFAULT
-rule (numbered 65535) which cannot be modified by the programmer
-and always matches packets.
-The action associated with the default rule can be either
+.Pp
+An
+.Nm
+ruleset always includes a
+.Em default
+rule (numbered 65535) which cannot be modified or deleted,
+and matches all packets.
+The action associated with the
+.Em default
+rule can be either
 .Cm deny
 or
 .Cm allow
@@ -74,25 +118,28 @@ depending on how the kernel is configured.
 .Pp
 If the ruleset includes one or more rules with the
 .Cm keep-state
+or
+.Cm limit
 option, then
 .Nm
 assumes a
 .Em stateful
-behaviour, i.e. upon a match will create dynamic rules matching
+behaviour, i.e. upon a match it will create dynamic rules matching
 the exact parameters (addresses and ports) of the matching packet.
 .Pp
 These dynamic rules, which have a limited lifetime, are checked
 at the first occurrence of a
-.Cm check-state
-or
+.Cm check-state ,
 .Cm keep-state
+or
+.Cm limit
 rule, and are typically used to open the firewall on-demand to
 legitimate traffic only.
 See the
-.Sx RULE FORMAT
+.Sx STATEFUL FIREWALL
 and
 .Sx EXAMPLES
-sections below for more information on the stateful behaviour of
+Sections below for more information on the stateful behaviour of
 .Nm .
 .Pp
 All rules (including dynamic ones) have a few associated counters:
@@ -104,9 +151,9 @@ commands.
 .Pp
 Rules can be added with the
 .Cm add
-command; deleted individually with the
+command; deleted individually or in groups with the
 .Cm delete
-command, and globally with the
+command, and globally (except those in set 31) with the
 .Cm flush
 command; displayed, optionally with the content of the
 counters, using the
@@ -120,19 +167,46 @@ and
 .Cm resetlog
 commands.
 .Pp
+Also, each rule belongs to one of 32 different
+.Em sets
+, and there are
+.Nm
+commands to atomically manipulate sets, such as enable,
+disable, swap sets, move all rules in a set to another
+one, delete all rules in a set. These can be useful to
+install temporary configurations, or to test them.
+See Section
+.Sx SETS OF RULES
+for more information on
+.Em sets .
+.Pp
 The following options are available:
 .Bl -tag -width indent
 .It Fl a
 While listing, show counter values.
-See also the
+The
 .Cm show
-command.
+command just implies this option.
+.It Fl c
+When entering or showing rules, print them in compact form,
+i.e. without the optional "ip from any to any" string
+when this does not carry any additional information.
+.It Fl d
+While listing, show dynamic rules in addition to static ones.
+.It Fl e
+While listing, if the
+.Fl d
+option was specified, also show expired dynamic rules.
 .It Fl f
 Don't ask for confirmation for commands that can cause problems
 if misused,
 .No i.e. Cm flush .
-.Em Note ,
-if there is no tty associated with the process, this is implied.
+If there is no tty associated with the process, this is implied.
+.It Fl n
+Only check syntax of the command strings, without actually passing
+them to the kernel.
+.It Fl N
+Try to resolve addresses and service names in output.
 .It Fl q
 While
 .Cm add Ns ing ,
@@ -150,32 +224,39 @@ commands in a script
 .Ql sh\ /etc/rc.firewall ) ,
 or by processing a file of many
 .Nm
-rules,
-across a remote login session.
+rules across a remote login session.
 If a
 .Cm flush
 is performed in normal (verbose) mode (with the default kernel
 configuration), it prints a message.
-Because all rules are flushed, the message cannot be delivered
-to the login session.
-This causes the remote login session to be closed and the
-remainder of the ruleset is not processed.
-Access to the console is required to recover.
+Because all rules are flushed, the message might not be delivered
+to the login session, causing the remote login session to be closed
+and the remainder of the ruleset to not be processed.
+Access to the console would then be required to recover.
+.It Fl S
+While listing rules, show the
+.Em set
+each rule belongs to.
+If this flag is not specified, disabled rules will not be
+listed.
+.It Fl s Op Ar field
+While listing pipes, sort according to one of the four
+counters (total or current packets or bytes).
 .It Fl t
-While listing, show last match timestamp.
-.It Fl N
-Try to resolve addresses and service names in output.
+While listing, show last match timestamp (converted with ctime()).
+.It Fl T
+While listing, show last match timestamp (as seconds from the epoch).
+This form can be more convenient for postprocessing by scripts.
 .El
 .Pp
 To ease configuration, rules can be put into a file which is
 processed using
 .Nm
-as shown in the first synopsis line.
+as shown in the last synopsis line.
 An absolute
 .Ar pathname
 must be used.
-The file
-will be read line by line and applied as arguments to the
+The file will be read line by line and applied as arguments to the
 .Nm
 utility.
 .Pp
@@ -196,287 +277,556 @@ as its first character, the usual
 .Ev PATH
 name search is performed.
 Care should be taken with this in environments where not all
-filesystems are mounted (yet) by the time
+file systems are mounted (yet) by the time
 .Nm
 is being run (e.g. when they are mounted over NFS).
 Once
 .Fl p
-has been specified, optional
-.Fl D
-and
-.Fl U
-specifications can follow and will be passed on to the preprocessor.
+has been specified, any additional arguments as passed on to the preprocessor
+for interpretation.
 This allows for flexible configuration files (like conditionalizing
 them on the local hostname) and the use of macros to centralize
 frequently required arguments like IP addresses.
-.Sh RULE FORMAT
+.Pp
 The
 .Nm
-rule format is the following:
-.Bd -ragged
+.Cm pipe
+and
+.Cm queue
+commands are used to configure the traffic shaper, as shown in the
+.Sx TRAFFIC SHAPER (DUMMYNET) CONFIGURATION
+Section below.
+.Pp
+If the world and the kernel get out of sync the
+.Nm
+ABI may break, preventing you from being able to add any rules.  This can
+adversely effect the booting process.  You can use
+.Nm
+.Cm disable
+.Cm firewall
+to temporarily disable the firewall to regain access to the network,
+allowing you to fix the problem.
+.Sh PACKET FLOW
+A packet is checked against the active ruleset in multiple places
+in the protocol stack, under control of several sysctl variables.
+These places and variables are shown below, and it is important to
+have this picture in mind in order to design a correct ruleset.
+.Bd -literal -offset indent
+      ^            to upper layers   V
+      |                       |
+      +----------->-----------+
+      ^                       V
+ [ip_input]              [ip_output]   net.inet.ip.fw.enable=1
+      |                       |
+      ^                       V
+[ether_demux]    [ether_output_frame]  net.link.ether.ipfw=1
+      |                       |
+      +-->--[bdg_forward]-->--+        net.link.ether.bridge_ipfw=1
+      ^                       V
+      |      to devices       |
+.Ed
+.Pp
+As can be noted from the above picture, the number of
+times the same packet goes through the firewall can
+vary between 0 and 4 depending on packet source and
+destination, and system configuration.
+.Pp
+Note that as packets flow through the stack, headers can be
+stripped or added to it, and so they may or may not be available
+for inspection.
+E.g., incoming packets will include the MAC header when
+.Nm
+is invoked from
+.Cm ether_demux() ,
+but the same packets will have the MAC header stripped off when
+.Nm
+is invoked from
+.Cm ip_input() .
+.Pp
+Also note that each packet is always checked against the complete ruleset,
+irrespective of the place where the check occurs, or the source of the packet.
+If a rule contains some match patterns or actions which are not valid
+for the place of invocation (e.g. trying to match a MAC header within
+.Cm ip_input()
+), the match pattern will not match, but a
+.Cm not
+operator in front of such patterns
+.Em will
+cause the pattern to
+.Em always
+match on those packets.
+It is thus the responsibility of
+the programmer, if necessary, to write a suitable ruleset to
+differentiate among the possible places.
+.Cm skipto
+rules can be useful here, as an example:
+.Bd -literal -offset indent
+# packets from ether_demux or bdg_forward
+ipfw add 10 skipto 1000 all from any to any layer2 in
+# packets from ip_input
+ipfw add 10 skipto 2000 all from any to any not layer2 in
+# packets from ip_output
+ipfw add 10 skipto 3000 all from any to any not layer2 out
+# packets from ether_output_frame
+ipfw add 10 skipto 4000 all from any to any layer2 out
+.Ed
+.Pp
+(yes, at the moment there is no way to differentiate between
+ether_demux and bdg_forward).
+.Sh SYNTAX
+In general, each keyword or argument must be provided as
+a separate command line argument, with no leading or trailing
+spaces. Keywords are case-sensitive, whereas arguments may
+or may not be case-sensitive depending on their nature
+(e.g. uid's are, hostnames are not).
+.Pp
+In
+.Nm ipfw2
+you can introduce spaces after commas ',' to make
+the line more readable. You can also put the entire
+command (including flags) into a single argument.
+E.g. the following forms are equivalent:
+.Bd -literal -offset indent
+ipfw -q add deny src-ip 10.0.0.0/24,127.0.0.1/8
+ipfw -q add deny src-ip 10.0.0.0/24, 127.0.0.1/8
+ipfw "-q add deny src-ip 10.0.0.0/24, 127.0.0.1/8"
+.Ed
+.Sh RULE FORMAT
+The format of
+.Nm
+rules is the following:
+.Bd -ragged -offset indent
+.Op Ar rule_number
+.Op Cm set Ar set_number
 .Op Cm prob Ar match_probability
-.Ar action
+.br
+.Ar "   " action
 .Op Cm log Op Cm logamount Ar number
-.Ar proto
-.Cm from Ar src
-.Cm to Ar dst
-.Op Ar interface-spec
-.Op Ar options
+.Ar body
 .Ed
 .Pp
-Each packet can be filtered based on the following information that is
-associated with it:
+where the body of the rule specifies which information is used
+for filtering packets, among the following:
 .Pp
-.Bl -tag -width "Source and destination IP address" -offset indent -compact
-.It Transmit and receive interface
-(by name or address)
+.Bl -tag -width "Source and dest. addresses and ports" -offset XXX -compact
+.It Layer-2 header fields
+When available
+.It IPv4 Protocol
+TCP, UDP, ICMP, etc.
+.It Source and dest. addresses and ports
 .It Direction
-(incoming or outgoing)
-.It Source and destination IP address
-(possibly masked)
-.It Protocol
-(TCP, UDP, ICMP, etc.)
-.It Source and destination port
-(lists, ranges or masks)
-.It TCP flags
-.It IP fragment flag
+See Section
+.Sx PACKET FLOW
+.It Transmit and receive interface
+By name or address
+.It Misc. IP header fields
+Version, type of service, datagram length, identification,
+fragment flag (non-zero IP offset),
+Time To Live
 .It IP options
+.It Misc. TCP header fields
+TCP flags (SYN, FIN, ACK, RST, etc.),
+sequence number, acknowledgment number,
+window
+.It TCP options
 .It ICMP types
-.It User ID of the socket associated with the packet
+for ICMP packets
+.It User/group ID
+When the packet can be associated with a local socket.
 .El
 .Pp
-Note that it may be dangerous to filter on the source IP
-address or source TCP/UDP port because either or both could
-easily be spoofed.
+Note that some of the above information, e.g. source MAC or IP addresses and
+TCP/UDP ports, could easily be spoofed, so filtering on those fields
+alone might not guarantee the desired results.
 .Bl -tag -width indent
+.It Ar rule_number
+Each rule is associated with a
+.Ar rule_number
+in the range 1..65535, with the latter reserved for the
+.Em default
+rule.
+Rules are checked sequentially by rule number.
+Multiple rules can have the same number, in which case they are
+checked (and listed) according to the order in which they have
+been added.
+If a rule is entered without specifying a number, the kernel will
+assign one in such a way that the rule becomes the last one
+before the
+.Em default
+rule.
+Automatic rule numbers are assigned by incrementing the last
+non-default rule number by the value of the sysctl variable
+.Ar net.inet.ip.fw.autoinc_step
+which defaults to 100.
+If this is not possible (e.g. because we would go beyond the
+maximum allowed rule number), the number of the last
+non-default value is used instead.
+.It Cm set Ar set_number
+Each rule is associated with a
+.Ar set_number
+in the range 0..31.
+Sets can be individually disabled and enabled, so this parameter
+is of fundamental importance for atomic ruleset manipulation.
+It can be also used to simplify deletion of groups of rules.
+If a rule is entered without specifying a set number,
+set 0 will be used.
+.br
+Set 31 is special in that it cannot be disabled,
+and rules in set 31 are not deleted by the
+.Nm ipfw flush
+command (but you can delete them with the
+.Nm ipfw delete set 31
+command).
+Set 31 is also used for the
+.Em default
+rule.
 .It Cm prob Ar match_probability
 A match is only declared with the specified probability
 (floating point number between 0 and 1).
 This can be useful for a number of applications such as
-random packet drop.
-.It Ar action :
+random packet drop or
+(in conjunction with
+.Xr dummynet 4 )
+to simulate the effect of multiple paths leading to out-of-order
+packet delivery.
+.Pp
+Note: this condition is checked before any other condition, including
+ones such as keep-state or check-state which might have side effects.
+.It Cm log Op Cm logamount Ar number
+When a packet matches a rule with the
+.Cm log
+keyword, a message will be
+logged to
+.Xr syslogd 8
+with a
+.Dv LOG_SECURITY
+facility.
+The logging only occurs if the sysctl variable
+.Em net.inet.ip.fw.verbose
+is set to 1
+(which is the default when the kernel is compiled with
+.Dv IPFIREWALL_VERBOSE
+) and the number of packets logged so far for that
+particular rule does not exceed the
+.Cm logamount
+parameter.
+If no
+.Cm logamount
+is specified, the limit is taken from the sysctl variable
+.Em net.inet.ip.fw.verbose_limit .
+In both cases, a value of 0 removes the logging limit.
+.Pp
+Once the limit is reached, logging can be re-enabled by
+clearing the logging counter or the packet counter for that entry, see the
+.Cm resetlog
+command.
+.Pp
+Note: logging is done after all other packet matching conditions
+have been successfully verified, and before performing the final
+action (accept, deny, etc.) on the packet.
+.El
+.Ss RULE ACTIONS
+A rule can be associated with one of the following actions, which
+will be executed when the packet matches the body of the rule.
 .Bl -tag -width indent
-.It Cm allow
+.It Cm allow | accept | pass | permit
 Allow packets that match rule.
 The search terminates.
-Aliases are
-.Cm pass ,
-.Cm permit
-and
-.Cm accept .
-.It Cm deny
-Discard packets that match this rule.
-The search terminates.
-.Cm drop
-is an alias for
-.Cm deny .
-.It Cm reject
-(Deprecated).
-Discard packets that match this rule, and try to send an ICMP
-host unreachable notice.
-The search terminates.
-.It Cm unreach Ar code
-Discard packets that match this rule, and try to send an ICMP
-unreachable notice with code
-.Ar code ,
-where
-.Ar code
-is a number from 0 to 255, or one of these aliases:
-.Cm net , host , protocol , port ,
-.Cm needfrag , srcfail , net-unknown , host-unknown ,
-.Cm isolated , net-prohib , host-prohib , tosnet ,
-.Cm toshost , filter-prohib , host-precedence
-or
-.Cm precedence-cutoff .
-The search terminates.
-.It Cm reset
-TCP packets only.
-Discard packets that match this rule, and try to send a TCP
-reset (RST) notice.
-The search terminates.
-.It Cm count
-Update counters for all packets that match rule.
-The search continues with the next rule.
 .It Cm check-state
 Checks the packet against the dynamic ruleset.
-If a match is found then the search terminates, otherwise
-we move to the next rule.
+If a match is found, execute the action associated with
+the rule which generated this dynamic rule, otherwise
+move to the next rule.
+.br
+.Cm Check-state
+rules do not have a body.
 If no
 .Cm check-state
 rule is found, the dynamic ruleset is checked at the first
 .Cm keep-state
+or
+.Cm limit
 rule.
+.It Cm count
+Update counters for all packets that match rule.
+The search continues with the next rule.
+.It Cm deny | drop
+Discard packets that match this rule.
+The search terminates.
 .It Cm divert Ar port
 Divert packets that match this rule to the
 .Xr divert 4
 socket bound to port
 .Ar port .
 The search terminates.
-.It Cm tee Ar port
-Send a copy of packets matching this rule to the
-.Xr divert 4
-socket bound to port
-.Ar port .
-The search terminates and the original packet is accepted
-(but see section
-.Sx BUGS
-below).
-.It Cm fwd Ar ipaddr Ns Xo
-.Op , Ns Ar port
-.Xc
+.It Cm fwd | forward Ar ipaddr Ns Op , Ns Ar port
 Change the next-hop on matching packets to
 .Ar ipaddr ,
-which can be an IP address in dotted quad or a host name.
+which can be an IP address in dotted quad format or a host name.
+The search terminates if this rule matches.
+.Pp
 If
 .Ar ipaddr
-is not a directly-reachable address, the route as found in
-the local routing table for that IP is used instead.
+is a local address, then matching packets will be forwarded to
+.Ar port
+(or the port number in the packet if one is not specified in the rule)
+on the local machine.
+.br
 If
 .Ar ipaddr
-is a local address, then on a packet entering the system
-from a remote host it will be diverted to
-.Ar port
-on the local machine, keeping the local address of the socket
-set to the original IP address the packet was destined for.
-This is intended for use with transparent proxy servers.
-If the IP is not a local address then the port number
-(if specified) is ignored and the rule only applies to packets
-leaving the system.
-This will also map addresses to local ports when packets are
-generated locally.
-The search terminates if this rule matches.
-If the port number is not given then the port number in the
-packet is used, so that a packet for an external machine port
-Y would be forwarded to local port Y.
-The kernel must have been compiled with the
-.Dv IPFIREWALL_FORWARD
-option.
+is not a local address, then the port number
+(if specified) is ignored, and the packet will be
+forwarded to the remote address, using the route as found in
+the local routing table for that IP.
+.br
+A
+.Ar fwd
+rule will not match layer-2 packets (those received
+on ether_input, ether_output, or bridged).
+.br
+The
+.Cm fwd
+action does not change the contents of the packet at all.
+In particular, the destination address remains unmodified, so
+packets forwarded to another system will usually be rejected by that system
+unless there is a matching rule on that system to capture them.
+For packets forwarded locally,
+the local address of the socket will be
+set to the original destination address of the packet.
+This makes the
+.Xr netstat 1
+entry look rather weird but is intended for
+use with transparent proxy servers.
+.It Cm pipe Ar pipe_nr
+Pass packet to a
+.Xr dummynet 4
+.Dq pipe
+(for bandwidth limitation, delay, etc.).
+See the
+.Sx TRAFFIC SHAPER (DUMMYNET) CONFIGURATION
+Section for further information.
+The search terminates; however, on exit from the pipe and if
+the
+.Xr sysctl 8
+variable
+.Em net.inet.ip.fw.one_pass
+is not set, the packet is passed again to the firewall code
+starting from the next rule.
+.It Cm queue Ar queue_nr
+Pass packet to a
+.Xr dummynet 4
+.Dq queue
+(for bandwidth limitation using WF2Q+).
+.It Cm reject
+(Deprecated).
+Synonym for
+.Cm unreach host .
+.It Cm reset
+Discard packets that match this rule, and if the
+packet is a TCP packet, try to send a TCP reset (RST) notice.
+The search terminates.
 .It Cm skipto Ar number
 Skip all subsequent rules numbered less than
 .Ar number .
 The search continues with the first rule numbered
 .Ar number
 or higher.
+.It Cm tee Ar port
+Send a copy of packets matching this rule to the
+.Xr divert 4
+socket bound to port
+.Ar port .
+The search terminates and the original packet is accepted
+(but see Section
+.Sx BUGS
+below).
+.It Cm unreach Ar code
+Discard packets that match this rule, and try to send an ICMP
+unreachable notice with code
+.Ar code ,
+where
+.Ar code
+is a number from 0 to 255, or one of these aliases:
+.Cm net , host , protocol , port ,
+.Cm needfrag , srcfail , net-unknown , host-unknown ,
+.Cm isolated , net-prohib , host-prohib , tosnet ,
+.Cm toshost , filter-prohib , host-precedence
+or
+.Cm precedence-cutoff .
+The search terminates.
 .El
-.It Cm log Op Cm logamount Ar number
-If the kernel was compiled with
-.Dv IPFIREWALL_VERBOSE ,
-then when a packet matches a rule with the
-.Cm log
-keyword a message will be
-logged to
-.Xr syslogd 8
-with a
-.Dv LOG_AUTHPRIV
-facility.
-.Em Note :
-by default, they are appended to the
-.Pa /var/log/system.log
-file (see
-.Xr syslog.conf 5 ) .
-If the kernel was compiled with the
-.Dv IPFIREWALL_VERBOSE_LIMIT
-option, then by default logging will cease after the number
-of packets specified by the option are received for that
-particular chain entry, and
-.Em net.inet.ip.fw.verbose_limit
-will be set to that number.
-However, if
-.Cm logamount Ar number
-is used, that
-.Ar number
-will be the logging limit rather than
-.Em net.inet.ip.fw.verbose_limit ,
-where the value
-.Dq 0
-removes the logging limit.
-Logging may then be re-enabled by clearing the logging counter
-or the packet counter for that entry.
-.Pp
-Console logging and the log limit are adjustable dynamically
-through the
-.Xr sysctl 8
-interface in the MIB base of
-.Em net.inet.ip.fw .
-.It Ar proto
-An IP protocol specified by number or name (for a complete
-list see
+.Ss RULE BODY
+The body of a rule contains zero or more patterns (such as
+specific source and destination addresses or ports,
+protocol options, incoming or outgoing interfaces, etc.)
+that the packet must match in order to be recognised.
+In general, the patterns are connected by (implicit)
+.Cm and
+operators -- i.e. all must match in order for the
+rule to match.
+Individual patterns can be prefixed by the
+.Cm not
+operator to reverse the result of the match, as in
+.Pp
+.Dl "ipfw add 100 allow ip from not 1.2.3.4 to any"
+.Pp
+Additionally, sets of alternative match patterns (
+.Em or-blocks
+) can be constructed by putting the patterns in
+lists enclosed between parentheses ( ) or braces { }, and
+using the
+.Cm or
+operator as follows:
+.Pp
+.Dl "ipfw add 100 allow ip from { x or not y or z } to any"
+.Pp
+Only one level of parentheses is allowed.
+Beware that most shells have special meanings for parentheses
+or braces, so it is advisable to put a backslash \\ in front of them
+to prevent such interpretations.
+.Pp
+The body of a rule must in general include a source and destination
+address specifier.
+The keyword
+.Ar any
+can be used in various places to specify that the content of
+a required field is irrelevant.
+.Pp
+The rule body has the following format:
+.Bd -ragged -offset indent
+.Op Ar proto Cm from Ar src Cm to Ar dst
+.Op Ar options
+.Ed
+.Pp
+The first part (proto from src to dst) is for backward
+compatibility with
+.Nm ipfw1 .
+In
+.Nm ipfw2
+any match pattern (including MAC headers, IPv4 protocols,
+addresses and ports) can be specified in the
+.Ar options
+section.
+.Pp
+Rule fields have the following meaning:
+.Bl -tag -width indent
+.It Ar proto : protocol | Cm { Ar protocol Cm or ... }
+.It Ar protocol : Oo Cm not Oc Ar protocol-name | protocol-number
+An IPv4 protocol specified by number or name
+(for a complete list see
 .Pa /etc/protocols ) .
 The
 .Cm ip
 or
 .Cm all
 keywords mean any protocol will match.
-.It Ar src No and Ar dst :
-.Cm any | me | Op Cm not
-.Aq Ar address Ns / Ns Ar mask
-.Op Ar ports
-.Pp
-Specifying
-.Cm any
-makes the rule match any IP number.
-.Pp
-Specifying
-.Cm me
-makes the rule match any IP number configured on an interface in the system.
-This is a computationally semi-expensive check which should be used with care.
 .Pp
 The
-.Aq Ar address Ns / Ns Ar mask
-may be specified as:
-.Bl -tag -width "ipno/bits"
-.It Ar ipno
-An IP number of the form 1.2.3.4.
-Only this exact IP number will match the rule.
-.It Ar ipno Ns / Ns Ar bits
-An IP number with a mask width of the form 1.2.3.4/24.
-In this case all IP numbers from 1.2.3.0 to 1.2.3.255 will match.
-.It Ar ipno Ns : Ns Ar mask
-An IP number with a mask of the form 1.2.3.4:255.255.240.0.
-In this case all IP numbers from 1.2.0.0 to 1.2.15.255 will match.
-.El
+.Cm { Ar protocol Cm or ... }
+format (an
+.Em or-block )
+is provided for convenience only but its use is deprecated.
+.It Ar src No and Ar dst : Bro Cm addr | Cm { Ar addr Cm or ... } Brc Op Oo Cm not Oc Ar ports
+An address (or a list, see below)
+optionally followed by
+.Ar ports
+specifiers.
 .Pp
-The sense of the match can be inverted by preceding an address with the
+The second format (
+.Em or-block
+with multiple addresses) is provided for convenience only and
+its use is discouraged.
+.It Ar addr : Oo Cm not Oc Brq Cm any | me | Ar addr-list | Ar addr-set
+.It Cm any
+matches any IP address.
+.It Cm me
+matches any IP address configured on an interface in the system.
+The address list is evaluated at the time the packet is
+analysed.
+.It Ar addr-list : ip-addr Ns Op Ns , Ns Ar addr-list
+.It Ar ip-addr :
+A host or subnet address specified in one of the following ways:
+.Bl -tag -width indent
+.It Ar numeric-ip | hostname
+Matches a single IPv4 address, specified as dotted-quad or a hostname.
+Hostnames are resolved at the time the rule is added to the firewall list.
+.It Ar addr Ns / Ns Ar masklen
+Matches all addresses with base
+.Ar addr
+(specified as a dotted quad or a hostname)
+and mask width of
+.Cm masklen
+bits.
+As an example, 1.2.3.4/25 will match
+all IP numbers from 1.2.3.0 to 1.2.3.127 .
+.It Ar addr Ns : Ns Ar mask
+Matches all addresses with base
+.Ar addr
+(specified as a dotted quad or a hostname)
+and the mask of
+.Ar mask ,
+specified as a dotted quad.
+As an example, 1.2.3.4/255.0.255.0 will match
+1.*.3.*.
+We suggest to use this form only for non-contiguous
+masks, and resort to the
+.Ar addr Ns / Ns Ar masklen
+format for contiguous masks, which is more compact and less
+error-prone.
+.El
+.It Ar addr-set : addr Ns Oo Ns / Ns Ar masklen Oc Ns Cm { Ns Ar list Ns Cm }
+.It Ar list : Bro Ar num | num-num Brc Ns Op Ns , Ns Ar list
+Matches all addresses with base address
+.Ar addr
+(specified as a dotted quad or a hostname)
+and whose last byte is in the list between braces { } .
+Note that there must be no spaces between braces and
+numbers (spaces after commas are allowed).
+Elements of the list can be specified as single entries
+or ranges.
+The
+.Ar masklen
+field is used to limit the size of the set of addresses,
+and can have any value between 24 and 32. If not specified,
+it will be assumed as 24.
+.br
+This format is particularly useful to handle sparse address sets
+within a single rule. Because the matching occurs using a
+bitmask, it takes constant time and dramatically reduces
+the complexity of rulesets.
+.br
+As an example, an address specified as 1.2.3.4/24{128,35-55,89}
+will match the following IP addresses:
+.br
+1.2.3.128, 1.2.3.35 to 1.2.3.55, 1.2.3.89 .
+.It Ar ports : Bro Ar port | port Ns \&- Ns Ar port Ns Brc Ns Op , Ns Ar ports
+For protocols which support port numbers (such as TCP and UDP), optional
+.Cm ports
+may be specified as one or more ports or port ranges, separated
+by commas but no spaces, and an optional
 .Cm not
-modifier, causing all other addresses to be matched instead.
-This does not affect the selection of port numbers.
-.Pp
-With the TCP and UDP protocols, optional
-.Em ports
-may be specified as:
-.Bd -ragged -offset indent
-.Sm off
-.Eo \&{
-.Ar port |
-.Ar port No \&- Ar port |
-.Ar port : mask
-.Ec \&} Op , Ar port Op , Ar ...
-.Sm on
-.Ed
-.Pp
+operator.
 The
 .Ql \&-
 notation specifies a range of ports (including boundaries).
 .Pp
-The
-.Ql \&:
-notation specifies a port and a mask, a match is declared if
-the port number in the packet matches the one in the rule,
-limited to the bits which are set in the mask.
-.Pp
 Service names (from
 .Pa /etc/services )
 may be used instead of numeric port values.
-A range may only be specified as the first value, and the
-length of the port list is limited to
-.Dv IP_FW_MAX_PORTS
-ports (as defined in
-.Pa /usr/src/sys/netinet/ip_fw.h ) .
+The length of the port list is limited to 30 ports or ranges,
+though one can specify larger ranges by using an
+.Em or-block
+in the
+.Cm options
+section of the rule.
+.Pp
 A backslash
 .Pq Ql \e
 can be used to escape the dash
 .Pq Ql -
-character in a service name:
+character in a service name (from a shell, the backslash must be
+typed twice to avoid the shell itself interpreting it as an escape
+character).
 .Pp
 .Dl "ipfw add count tcp from any ftp\e\e-data-ftp to any"
 .Pp
@@ -486,107 +836,115 @@ specifications.
 See the
 .Cm frag
 option for details on matching fragmented packets.
-.It Ar interface-spec
-Some combinations of the following specifiers are allowed:
-.Bl -tag -width "via ipno"
-.It Cm in
-Only match incoming packets.
-.It Cm out
-Only match outgoing packets.
-.It Cm via Ar ifX
-Packet must be going through interface
-.Ar ifX .
-.It Cm via Ar if Ns Cm *
-Packet must be going through interface
-.Ar ifX ,
-where
-.Ar X
-is any unit number.
-.It Cm via any
-Packet must be going through
-.Em some
-interface.
-.It Cm via Ar ipno
-Packet must be going through the interface having IP address
-.Ar ipno .
 .El
+.Ss RULE OPTIONS (MATCH PATTERNS)
+Additional match patterns can be used within
+rules. Zero or more of these so-called
+.Em options
+can be present in a rule, optionally prefixed by the
+.Cm not
+operand, and possibly grouped into
+.Em or-blocks .
 .Pp
-The
-.Cm via
-keyword causes the interface to always be checked.
-If
-.Cm recv
-or
-.Cm xmit
-is used instead of
-.Cm via ,
-then the only receive or transmit interface (respectively)
-is checked.
-By specifying both, it is possible to match packets based on
-both receive and transmit interface, e.g.:
-.Pp
-.Dl "ipfw add 100 deny ip from any to any out recv ed0 xmit ed1"
-.Pp
-The
-.Cm recv
-interface can be tested on either incoming or outgoing packets,
-while the
-.Cm xmit
-interface can only be tested on outgoing packets.
-So
-.Cm out
-is required (and
-.Cm in
-is invalid) whenever
-.Cm xmit
-is used.
-Specifying
-.Cm via
-together with
-.Cm xmit
-or
-.Cm recv
-is invalid.
-.Pp
-A packet may not have a receive or transmit interface: packets
-originating from the local host have no receive interface,
-while packets destined for the local host have no transmit
-interface.
-.It Ar options :
+The following match patterns can be used (listed in alphabetical order):
 .Bl -tag -width indent
-.It Cm keep-state Op Ar method
-Upon a match, the firewall will create a dynamic rule, whose
-default behaviour is to matching bidirectional traffic between
-source and destination IP/port using the same protocol.
-The rule has a limited lifetime (controlled by a set of
-.Xr sysctl 8
-variables), and the lifetime is refreshed every time a matching
-packet is found.
-.Pp
-The actual behaviour can be modified by specifying a different
-.Ar method ,
-although at the moment only the default one is specified.
+.It Cm // this is a comment.
+Inserts the specified text as a comment in the rule.
+Everything following // is considered as a comment and stored in the rule.
+You can have comment-only rules, which are listed as having a
+.Cm count
+action followed by the comment.
 .It Cm bridged
 Matches only bridged packets.
-This can be useful for multicast or broadcast traffic, which
-would otherwise pass through the firewall twice: once during
-bridging, and a second time when the packet is delivered to
-the local stack.
+.It Cm dst-ip Ar ip-address
+Matches IP packets whose destination IP is one of the address(es)
+specified as argument.
+.It Cm dst-port Ar ports
+Matches IP packets whose destination port is one of the port(s)
+specified as argument.
+.It Cm established
+Matches TCP packets that have the RST or ACK bits set.
 .It Cm frag
-Match if the packet is a fragment and this is not the first
-fragment of the datagram.
-.Cm frag
-may not be used in conjunction with either
-.Cm tcpflags
-or TCP/UDP port specifications.
-.It Cm ipoptions Ar spec
-Match if the IP header contains the comma separated list of
-options specified in
-.Ar spec .
-The supported IP options are:
+Matches packets that are fragments and not the first
+fragment of an IP datagram. Note that these packets will not have
+the next protocol header (e.g. TCP, UDP) so options that look into
+these headers cannot match.
+.It Cm gid Ar group
+Matches all TCP or UDP packets sent by or received for a
+.Ar group .
+A
+.Ar group
+may be specified by name or number.
+.It Cm icmptypes Ar types
+Matches ICMP packets whose ICMP type is in the list
+.Ar types .
+The list may be specified as any combination of
+individual types (numeric) separated by commas.
+.Em Ranges are not allowed.
+The supported ICMP types are:
 .Pp
-.Cm ssrr
-(strict source route),
+echo reply
+.Pq Cm 0 ,
+destination unreachable
+.Pq Cm 3 ,
+source quench
+.Pq Cm 4 ,
+redirect
+.Pq Cm 5 ,
+echo request
+.Pq Cm 8 ,
+router advertisement
+.Pq Cm 9 ,
+router solicitation
+.Pq Cm 10 ,
+time-to-live exceeded
+.Pq Cm 11 ,
+IP header bad
+.Pq Cm 12 ,
+timestamp request
+.Pq Cm 13 ,
+timestamp reply
+.Pq Cm 14 ,
+information request
+.Pq Cm 15 ,
+information reply
+.Pq Cm 16 ,
+address mask request
+.Pq Cm 17
+and address mask reply
+.Pq Cm 18 .
+.It Cm in | out
+Matches incoming or outgoing packets, respectively.
+.Cm in
+and
+.Cm out
+are mutually exclusive (in fact,
+.Cm out
+is implemented as
+.Cm not in Ns No ).
+.It Cm ipid Ar id-list
+Matches IP packets whose
+.Cm ip_id
+field has value included in
+.Ar id-list ,
+which is either a single value or a list of values or ranges
+specified in the same way as
+.Ar ports .
+.It Cm iplen Ar len-list
+Matches IP packets whose total length, including header and data, is
+in the set
+.Ar len-list ,
+which is either a single value or a list of values or ranges 
+specified in the same way as
+.Ar ports .
+.It Cm ipoptions Ar spec
+Matches packets whose IP header contains the comma separated list of
+options specified in
+.Ar spec .
+The supported IP options are:
+.Pp
+.Cm ssrr
+(strict source route),
 .Cm lsrr
 (loose source route),
 .Cm rr
@@ -596,31 +954,160 @@ The supported IP options are:
 The absence of a particular option may be denoted
 with a
 .Ql \&! .
-.It Cm tcpoptions Ar spec
-Match if the TCP header contains the comma separated list of
-options specified in
+.It Cm ipprecedence Ar precedence
+Matches IP packets whose precedence field is equal to
+.Ar precedence .
+.It Cm ipsec
+Matches packets that have IPSEC history associated with them
+(i.e. the packet comes encapsulated in IPSEC, the kernel
+has IPSEC support and IPSEC_FILTERGIF option, and can correctly
+decapsulate it).
+.Pp
+Note that specifying
+.Cm ipsec
+is different from specifying
+.Cm proto Ar ipsec
+as the latter will only look at the specific IP protocol field,
+irrespective of IPSEC kernel support and the validity of the IPSEC data.
+.It Cm iptos Ar spec
+Matches IP packets whose
+.Cm tos
+field contains the comma separated list of
+service types specified in
 .Ar spec .
-The supported TCP options are:
+The supported IP types of service are:
 .Pp
-.Cm mss
-(maximum segment size),
-.Cm window
-(tcp window advertisement),
-.Cm sack
-(selective ack),
-.Cm ts
-(rfc1323 timestamp) and
-.Cm cc
-(rfc1644 t/tcp connection count).
-The absence of a particular option may be denoted
+.Cm lowdelay
+.Pq Dv IPTOS_LOWDELAY ,
+.Cm throughput
+.Pq Dv IPTOS_THROUGHPUT ,
+.Cm reliability
+.Pq Dv IPTOS_RELIABILITY ,
+.Cm mincost
+.Pq Dv IPTOS_MINCOST ,
+.Cm congestion
+.Pq Dv IPTOS_CE .
+The absence of a particular type may be denoted
 with a
 .Ql \&! .
-.It Cm established
-TCP packets only.
-Match packets that have the RST or ACK bits set.
+.It Cm ipttl Ar ttl-list
+Matches IP packets whose time to live is included in
+.Ar ttl-list ,
+which is either a single value or a list of values or ranges
+specified in the same way as
+.Ar ports .
+.It Cm ipversion Ar ver
+Matches IP packets whose IP version field is
+.Ar ver .
+.It Cm keep-state
+Upon a match, the firewall will create a dynamic rule, whose
+default behaviour is to match bidirectional traffic between
+source and destination IP/port using the same protocol.
+The rule has a limited lifetime (controlled by a set of
+.Xr sysctl 8
+variables), and the lifetime is refreshed every time a matching
+packet is found.
+.It Cm layer2
+Matches only layer2 packets, i.e. those passed to
+.Nm
+from ether_demux() and ether_output_frame().
+.It Cm limit Bro Cm src-addr | src-port | dst-addr | dst-port Brc Ar N
+The firewall will only allow
+.Ar N
+connections with the same
+set of parameters as specified in the rule.
+One or more
+of source and destination addresses and ports can be
+specified.
+.It Cm { MAC | mac } Ar dst-mac src-mac
+Match packets with a given
+.Ar dst-mac
+and
+.Ar src-mac
+addresses, specified as the
+.Cm any
+keyword (matching any MAC address), or six groups of hex digits
+separated by colons,
+and optionally followed by a mask indicating how many bits are
+significant, as in
+.Pp
+.Dl "MAC 10:20:30:40:50:60/33 any"
+.Pp
+Note that the order of MAC addresses (destination first,
+source second) is
+the same as on the wire, but the opposite of the one used for
+IP addresses.
+.It Cm mac-type Ar mac-type
+Matches packets whose Ethernet Type field
+corresponds to one of those specified as argument.
+.Ar mac-type
+is specified in the same way as
+.Cm port numbers
+(i.e. one or more comma-separated single values or ranges).
+You can use symbolic names for known values such as
+.Em vlan , ipv4, ipv6 .
+Values can be entered as decimal or hexadecimal (if prefixed by 0x),
+and they are always printed as hexadecimal (unless the
+.Cm -N
+option is used, in which case symbolic resolution will be attempted).
+.It Cm proto Ar protocol
+Matches packets with the corresponding IPv4 protocol.
+.It Cm recv | xmit | via Brq Ar ifX | Ar if Ns Cm * | Ar ipno | Ar any
+Matches packets received, transmitted or going through,
+respectively, the interface specified by exact name
+.Ns No ( Ar ifX Ns No ),
+by device name
+.Ns No ( Ar if Ns Ar * Ns No ),
+by IP address, or through some interface.
+.Pp
+The
+.Cm via
+keyword causes the interface to always be checked.
+If
+.Cm recv
+or
+.Cm xmit
+is used instead of
+.Cm via ,
+then only the receive or transmit interface (respectively)
+is checked.
+By specifying both, it is possible to match packets based on
+both receive and transmit interface, e.g.:
+.Pp
+.Dl "ipfw add deny ip from any to any out recv ed0 xmit ed1"
+.Pp
+The
+.Cm recv
+interface can be tested on either incoming or outgoing packets,
+while the
+.Cm xmit
+interface can only be tested on outgoing packets.
+So
+.Cm out
+is required (and
+.Cm in
+is invalid) whenever
+.Cm xmit
+is used.
+.Pp
+A packet may not have a receive or transmit interface: packets
+originating from the local host have no receive interface,
+while packets destined for the local host have no transmit
+interface.
 .It Cm setup
+Matches TCP packets that have the SYN bit set but no ACK bit.
+This is the short form of
+.Dq Li tcpflags\ syn,!ack .
+.It Cm src-ip Ar ip-address
+Matches IP packets whose source IP is one of the address(es)
+specified as argument.
+.It Cm src-port Ar ports
+Matches IP packets whose source port is one of the port(s)
+specified as argument.
+.It Cm tcpack Ar ack
 TCP packets only.
-Match packets that have the SYN bit set but no ACK bit.
+Match if the TCP header acknowledgment number field is set to
+.Ar ack .
 .It Cm tcpflags Ar spec
 TCP packets only.
 Match if the TCP header contains the comma separated list of
@@ -645,50 +1132,397 @@ a non-zero offset.
 See the
 .Cm frag
 option for details on matching fragmented packets.
-.It Cm icmptypes Ar types
-ICMP packets only.
-Match if the ICMP type is in the list
-.Ar types .
-The list may be specified as any combination of ranges or
-individual types separated by commas.
-The supported ICMP types are:
+.It Cm tcpseq Ar seq
+TCP packets only.
+Match if the TCP header sequence number field is set to
+.Ar seq .
+.It Cm tcpwin Ar win
+TCP packets only.
+Match if the TCP header window field is set to
+.Ar win .
+.It Cm tcpoptions Ar spec
+TCP packets only.
+Match if the TCP header contains the comma separated list of
+options specified in
+.Ar spec .
+The supported TCP options are:
 .Pp
-echo reply
-.Pq Cm 0 ,
-destination unreachable
-.Pq Cm 3 ,
-source quench
-.Pq Cm 4 ,
-redirect
-.Pq Cm 5 ,
-echo request
-.Pq Cm 8 ,
-router advertisement
-.Pq Cm 9 ,
-router solicitation
-.Pq Cm 10 ,
-time-to-live exceeded
-.Pq Cm 11 ,
-IP header bad
-.Pq Cm 12 ,
-timestamp request
-.Pq Cm 13 ,
-timestamp reply
-.Pq Cm 14 ,
-information request
-.Pq Cm 15 ,
-information reply
-.Pq Cm 16 ,
-address mask request
-.Pq Cm 17
-and address mask reply
-.Pq Cm 18 .
+.Cm mss
+(maximum segment size),
+.Cm window
+(tcp window advertisement),
+.Cm sack
+(selective ack),
+.Cm ts
+(rfc1323 timestamp) and
+.Cm cc
+(rfc1644 t/tcp connection count).
+The absence of a particular option may be denoted
+with a
+.Ql \&! .
 .It Cm uid Ar user
 Match all TCP or UDP packets sent by or received for a
 .Ar user .
 A
 .Ar user
 may be matched by name or identification number.
+.It Cm verrevpath
+For incoming packets,
+a routing table lookup is done on the packet's source address.
+If the interface on which the packet entered the system matches the
+outgoing interface for the route,
+the packet matches.
+If the interfaces do not match up,
+the packet does not match.
+All outgoing packets or packets with no incoming interface match.
+.Pp
+The name and functionality of the option is intentionally similar to
+the Cisco IOS command:
+.Pp
+.Dl ip verify unicast reverse-path
+.Pp
+This option can be used to make anti-spoofing rules.
+.El
+.Sh SETS OF RULES
+Each rule belongs to one of 32 different
+.Em sets
+, numbered 0 to 31.
+Set 31 is reserved for the default rule.
+.Pp
+By default, rules are put in set 0, unless you use the
+.Cm set N
+attribute when entering a new rule.
+Sets can be individually and atomically enabled or disabled,
+so this mechanism permits an easy way to store multiple configurations
+of the firewall and quickly (and atomically) switch between them.
+The command to enable/disable sets is
+.Bd -ragged -offset indent
+.Nm
+.Cm set Oo Cm disable Ar number ... Oc Op Cm enable Ar number ...
+.Ed
+.Pp
+where multiple
+.Cm enable
+or
+.Cm disable
+sections can be specified.
+Command execution is atomic on all the sets specified in the command.
+By default, all sets are enabled.
+.Pp
+When you disable a set, its rules behave as if they do not exist
+in the firewall configuration, with only one exception:
+.Bd -ragged -offset indent
+dynamic rules created from a rule before it had been disabled
+will still be active until they expire. In order to delete
+dynamic rules you have to explicitly delete the parent rule
+which generated them.
+.Ed
+.Pp
+The set number of rules can be changed with the command
+.Bd -ragged -offset indent
+.Nm
+.Cm set move
+.Brq Cm rule Ar rule-number | old-set
+.Cm to Ar new-set
+.Ed
+.Pp
+Also, you can atomically swap two rulesets with the command
+.Bd -ragged -offset indent
+.Nm
+.Cm set swap Ar first-set second-set
+.Ed
+.Pp
+See the
+.Sx EXAMPLES
+Section on some possible uses of sets of rules.
+.Sh STATEFUL FIREWALL
+Stateful operation is a way for the firewall to dynamically
+create rules for specific flows when packets that
+match a given pattern are detected. Support for stateful
+operation comes through the
+.Cm check-state , keep-state
+and
+.Cm limit
+options of
+.Nm rules.
+.Pp
+Dynamic rules are created when a packet matches a
+.Cm keep-state
+or
+.Cm limit
+rule, causing the creation of a
+.Em dynamic
+rule which will match all and only packets with
+a given
+.Em protocol
+between a
+.Em src-ip/src-port dst-ip/dst-port
+pair of addresses (
+.Em src
+and
+.Em dst
+are used here only to denote the initial match addresses, but they
+are completely equivalent afterwards).
+Dynamic rules will be checked at the first
+.Cm check-state, keep-state
+or
+.Cm limit
+occurrence, and the action performed upon a match will be the same
+as in the parent rule.
+.Pp
+Note that no additional attributes other than protocol and IP addresses
+and ports are checked on dynamic rules.
+.Pp
+The typical use of dynamic rules is to keep a closed firewall configuration,
+but let the first TCP SYN packet from the inside network install a
+dynamic rule for the flow so that packets belonging to that session
+will be allowed through the firewall:
+.Pp
+.Dl "ipfw add check-state"
+.Dl "ipfw add allow tcp from my-subnet to any setup keep-state"
+.Dl "ipfw add deny tcp from any to any"
+.Pp
+A similar approach can be used for UDP, where an UDP packet coming
+from the inside will install a dynamic rule to let the response through
+the firewall:
+.Pp
+.Dl "ipfw add check-state"
+.Dl "ipfw add allow udp from my-subnet to any keep-state"
+.Dl "ipfw add deny udp from any to any"
+.Pp
+Dynamic rules expire after some time, which depends on the status
+of the flow and the setting of some
+.Cm sysctl
+variables.
+See Section
+.Sx SYSCTL VARIABLES
+for more details.
+For TCP sessions, dynamic rules can be instructed to periodically
+send keepalive packets to refresh the state of the rule when it is
+about to expire.
+.Pp
+See Section
+.Sx EXAMPLES
+for more examples on how to use dynamic rules.
+.Sh TRAFFIC SHAPER (DUMMYNET) CONFIGURATION
+.Nm
+is also the user interface for the
+.Xr dummynet 4
+traffic shaper.
+.Pp
+.Nm dummynet
+operates by first using the firewall to classify packets and divide them into
+.Em flows ,
+using any match pattern that can be used in
+.Nm
+rules.
+Depending on local policies, a flow can contain packets for a single
+TCP connection, or from/to a given host, or entire subnet, or a
+protocol type, etc.
+.Pp
+Packets belonging to the same flow are then passed to either of two
+different objects, which implement the traffic regulation:
+.Bl -hang -offset XXXX
+.It Em pipe
+A pipe emulates a link with given bandwidth, propagation delay,
+queue size and packet loss rate.
+Packets are queued in front of the pipe as they come out from the classifier,
+and then transferred to the pipe according to the pipe's parameters.
+.Pp
+.It Em queue
+A queue
+is an abstraction used to implement the WF2Q+
+(Worst-case Fair Weighted Fair Queueing) policy, which is
+an efficient variant of the WFQ policy.
+.br
+The queue associates a
+.Em weight
+and a reference pipe to each flow, and then all backlogged (i.e.,
+with packets queued) flows linked to the same pipe share the pipe's
+bandwidth proportionally to their weights.
+Note that weights are not priorities; a flow with a lower weight
+is still guaranteed to get its fraction of the bandwidth even if a
+flow with a higher weight is permanently backlogged.
+.Pp
+.El
+In practice,
+.Em pipes
+can be used to set hard limits to the bandwidth that a flow can use, whereas
+.Em queues
+can be used to determine how different flow share the available bandwidth.
+.Pp
+The
+.Em pipe
+and
+.Em queue
+configuration commands are the following:
+.Bd -ragged -offset indent
+.Cm pipe Ar number Cm config Ar pipe-configuration
+.Pp
+.Cm queue Ar number Cm config Ar queue-configuration
+.Ed
+.Pp
+The following parameters can be configured for a pipe:
+.Pp
+.Bl -tag -width indent -compact
+.It Cm bw Ar bandwidth | device
+Bandwidth, measured in
+.Sm off
+.Op Cm K | M
+.Brq Cm bit/s | Byte/s .
+.Sm on
+.Pp
+A value of 0 (default) means unlimited bandwidth.
+The unit must immediately follow the number, as in
+.Pp
+.Dl "ipfw pipe 1 config bw 300Kbit/s"
+.Pp
+If a device name is specified instead of a numeric value, as in
+.Pp
+.Dl "ipfw pipe 1 config bw tun0"
+.Pp
+then the transmit clock is supplied by the specified device.
+At the moment only the
+.Xr tun 4
+device supports this
+functionality, for use in conjunction with
+.Xr ppp 8 .
+.Pp
+.It Cm delay Ar ms-delay
+Propagation delay, measured in milliseconds.
+The value is rounded to the next multiple of the clock tick
+(typically 10ms, but it is a good practice to run kernels
+with
+.Dq "options HZ=1000"
+to reduce
+the granularity to 1ms or less).
+Default value is 0, meaning no delay.
+.El
+.Pp
+The following parameters can be configured for a queue:
+.Pp
+.Bl -tag -width indent -compact
+.It Cm pipe Ar pipe_nr
+Connects a queue to the specified pipe.
+Multiple queues (with the same or different weights) can be connected to
+the same pipe, which specifies the aggregate rate for the set of queues.
+.Pp
+.It Cm weight Ar weight
+Specifies the weight to be used for flows matching this queue.
+The weight must be in the range 1..100, and defaults to 1.
+.El
+.Pp
+Finally, the following parameters can be configured for both
+pipes and queues:
+.Pp
+.Bl -tag -width XXXX -compact
+.Pp
+.It Cm buckets Ar hash-table-size
+Specifies the size of the hash table used for storing the
+various queues.
+Default value is 64 controlled by the
+.Xr sysctl 8
+variable
+.Em net.inet.ip.dummynet.hash_size ,
+allowed range is 16 to 65536.
+.Pp
+.It Cm mask Ar mask-specifier
+Packets sent to a given pipe or queue by an
+.Nm
+rule can be further classified into multiple flows, each of which is then
+sent to a different
+.Em dynamic
+pipe or queue.
+A flow identifier is constructed by masking the IP addresses,
+ports and protocol types as specified with the
+.Cm mask
+options in the configuration of the pipe or queue.
+For each different flow identifier, a new pipe or queue is created
+with the same parameters as the original object, and matching packets
+are sent to it.
+.Pp
+Thus, when
+.Em dynamic pipes
+are used, each flow will get the same bandwidth as defined by the pipe,
+whereas when
+.Em dynamic queues
+are used, each flow will share the parent's pipe bandwidth evenly
+with other flows generated by the same queue (note that other queues
+with different weights might be connected to the same pipe).
+.br
+Available mask specifiers are a combination of one or more of the following:
+.Pp
+.Cm dst-ip Ar mask ,
+.Cm src-ip Ar mask ,
+.Cm dst-port Ar mask ,
+.Cm src-port Ar mask ,
+.Cm proto Ar mask
+or
+.Cm all ,
+.Pp
+where the latter means all bits in all fields are significant.
+.Pp
+.It Cm noerror
+When a packet is dropped by a dummynet queue or pipe, the error
+is normally reported to the caller routine in the kernel, in the
+same way as it happens when a device queue fills up. Setting this
+option reports the packet as successfully delivered, which can be
+needed for some experimental setups where you want to simulate
+loss or congestion at a remote router.
+.Pp
+.It Cm plr Ar packet-loss-rate
+Packet loss rate.
+Argument
+.Ar packet-loss-rate
+is a floating-point number between 0 and 1, with 0 meaning no
+loss, 1 meaning 100% loss.
+The loss rate is internally represented on 31 bits.
+.Pp
+.It Cm queue Brq Ar slots | size Ns Cm Kbytes
+Queue size, in
+.Ar slots
+or
+.Cm KBytes .
+Default value is 50 slots, which
+is the typical queue size for Ethernet devices.
+Note that for slow speed links you should keep the queue
+size short or your traffic might be affected by a significant
+queueing delay.
+E.g., 50 max-sized ethernet packets (1500 bytes) mean 600Kbit
+or 20s of queue on a 30Kbit/s pipe.
+Even worse effect can result if you get packets from an
+interface with a much larger MTU, e.g. the loopback interface
+with its 16KB packets.
+.Pp
+.It Cm red | gred Ar w_q Ns / Ns Ar min_th Ns / Ns Ar max_th Ns / Ns Ar max_p
+Make use of the RED (Random Early Detection) queue management algorithm.
+.Ar w_q
+and
+.Ar max_p
+are floating
+point numbers between 0 and 1 (0 not included), while
+.Ar min_th
+and
+.Ar max_th
+are integer numbers specifying thresholds for queue management
+(thresholds are computed in bytes if the queue has been defined
+in bytes, in slots otherwise).
+The
+.Xr dummynet 4
+also supports the gentle RED variant (gred).
+Three
+.Xr sysctl 8
+variables can be used to control the RED behaviour:
+.Bl -tag -width indent
+.It Em net.inet.ip.dummynet.red_lookup_depth
+specifies the accuracy in computing the average queue
+when the link is idle (defaults to 256, must be greater than zero)
+.It Em net.inet.ip.dummynet.red_avg_pkt_size
+specifies the expected average packet size (defaults to 512, must be
+greater than zero)
+.It Em net.inet.ip.dummynet.red_max_pkt_size
+specifies the expected maximum packet size, only used when queue
+thresholds are in bytes (defaults to 1500, must be greater than zero).
 .El
 .El
 .Sh CHECKLIST
@@ -705,16 +1539,28 @@ Most connections need packets going in both directions.
 Remember to test very carefully.
 It is a good idea to be near the console when doing this.
 If you cannot be near the console,
-use an auto-recovery script.
+use an auto-recovery script such as the one in
+.Pa /usr/share/examples/ipfw/change_rules.sh .
 .It
 Don't forget the loopback interface.
 .El
 .Sh FINE POINTS
 .Bl -bullet
 .It
-There is one kind of packet that the firewall will always
-discard, that is a TCP packet's fragment with a fragment offset of
-one.
+There are circumstances where fragmented datagrams are unconditionally
+dropped.
+TCP packets are dropped if they do not contain at least 20 bytes of
+TCP header, UDP packets are dropped if they do not contain a full 8
+byte UDP header, and ICMP packets are dropped if they do not contain
+4 bytes of ICMP header, enough to specify the ICMP type, code, and
+checksum.
+These packets are simply logged as
+.Dq pullup failed
+since there may not be enough good data in the packet to produce a
+meaningful log entry.
+.It
+Another type of packet is unconditionally dropped, a TCP packet with a
+fragment offset of one.
 This is a valid packet, but it only has one use, to try
 to circumvent firewalls.
 When logging is enabled, these packets are
@@ -723,10 +1569,7 @@ reported as being dropped by rule -1.
 The
 .Nm
 filter list may not be modified if the system security level
-is set to 3 or higher
-(see
-.Xr init 8
-for information on system security levels).
+is set to 3 or higher.
 .El
 .Sh PACKET DIVERSION
 A
@@ -739,49 +1582,231 @@ dropped.
 .Sh SYSCTL VARIABLES
 A set of
 .Xr sysctl 8
-variables controls the behaviour of the firewall.
-These are shown below together with their default value and
-meaning:
+variables controls the behaviour of the firewall and
+associated modules (
+.Nm dummynet, bridge
+).
+These are shown below together with their default value
+(but always check with the
+.Xr sysctl 8
+command what value is actually in use) and meaning:
 .Bl -tag -width indent
+.It Em net.inet.ip.dummynet.expire : No 1
+Lazily delete dynamic pipes/queue once they have no pending traffic.
+You can disable this by setting the variable to 0, in which case
+the pipes/queues will only be deleted when the threshold is reached.
+.It Em net.inet.ip.dummynet.hash_size : No 64
+Default size of the hash table used for dynamic pipes/queues.
+This value is used when no
+.Cm buckets
+option is specified when configuring a pipe/queue.
+.It Em net.inet.ip.dummynet.max_chain_len : No 16
+Target value for the maximum number of pipes/queues in a hash bucket.
+The product
+.Cm max_chain_len*hash_size
+is used to determine the threshold over which empty pipes/queues
+will be expired even when
+.Cm net.inet.ip.dummynet.expire=0 .
+.It Em net.inet.ip.dummynet.red_lookup_depth : No 256
+.It Em net.inet.ip.dummynet.red_avg_pkt_size : No 512
+.It Em net.inet.ip.dummynet.red_max_pkt_size : No 1500
+Parameters used in the computations of the drop probability
+for the RED algorithm.
+.It Em net.inet.ip.fw.autoinc_step : No 100
+Delta between rule numbers when auto-generating them.
+The value must be in the range 1..1000.
+This variable is only present in
+.Nm ipfw2 ,
+the delta is hardwired to 100 in
+.Nm ipfw1 .
+.It Em net.inet.ip.fw.curr_dyn_buckets : Em net.inet.ip.fw.dyn_buckets
+The current number of buckets in the hash table for dynamic rules
+(readonly).
 .It Em net.inet.ip.fw.debug : No 1
 Controls debugging messages produced by
 .Nm .
-.It Em net.inet.ip.fw.verbose : No 1
-Enables verbose messages.
-.It Em net.inet.ip.fw.enable : No 1
-Enables the firewall.
-Setting this variable to 0 lets you run your machine without
-firewall even if compiled in.
-.It Em net.inet.ip.fw.verbose_limit : No 0
-Limits the number of messages produced by a verbose firewall.
 .It Em net.inet.ip.fw.dyn_buckets : No 256
-.It Em net.inet.ip.fw.curr_dyn_buckets : No 256
-The configured and current size of the hash table used to
-hold dynamic rules.
-This must be a power of 2.
-The table can only be resized when empty, so in order to
-resize it on the fly you will probably have to
+The number of buckets in the hash table for dynamic rules.
+Must be a power of 2, up to 65536.
+It only takes effect when all dynamic rules have expired, so you
+are advised to use a
 .Cm flush
-and reload the ruleset.
+command to make sure that the hash table is resized.
 .It Em net.inet.ip.fw.dyn_count : No 3
 Current number of dynamic rules
 (read-only).
-.It Em net.inet.ip.fw.dyn_max : No 1000
+.It Em net.inet.ip.fw.dyn_keepalive : No 1
+Enables generation of keepalive packets for
+.Cm keep-state
+rules on TCP sessions. A keepalive is generated to both
+sides of the connection every 5 seconds for the last 20
+seconds of the lifetime of the rule.
+.It Em net.inet.ip.fw.dyn_max : No 8192
 Maximum number of dynamic rules.
 When you hit this limit, no more dynamic rules can be
 installed until old ones expire.
 .It Em net.inet.ip.fw.dyn_ack_lifetime : No 300
 .It Em net.inet.ip.fw.dyn_syn_lifetime : No 20
-.It Em net.inet.ip.fw.dyn_fin_lifetime : No 20
-.It Em net.inet.ip.fw.dyn_rst_lifetime : No 5
+.It Em net.inet.ip.fw.dyn_fin_lifetime : No 1
+.It Em net.inet.ip.fw.dyn_rst_lifetime : No 1
+.It Em net.inet.ip.fw.dyn_udp_lifetime : No 5
 .It Em net.inet.ip.fw.dyn_short_lifetime : No 30
 These variables control the lifetime, in seconds, of dynamic
 rules.
 Upon the initial SYN exchange the lifetime is kept short,
 then increased after both SYN have been seen, then decreased
-again during the final FIN exchange or when a RST
+again during the final FIN exchange or when a RST is received.
+Both
+.Em dyn_fin_lifetime
+and
+.Em dyn_rst_lifetime
+must be strictly lower than 5 seconds, the period of
+repetition of keepalives. The firewall enforces that.
+.It Em net.inet.ip.fw.enable : No 1
+Enables the firewall.
+Setting this variable to 0 lets you run your machine without
+firewall even if compiled in.
+.It Em net.inet.ip.fw.one_pass : No 1
+When set, the packet exiting from the
+.Xr dummynet 4
+pipe is not passed though the firewall again.
+Otherwise, after a pipe action, the packet is
+reinjected into the firewall at the next rule.
+.It Em net.inet.ip.fw.verbose : No 1
+Enables verbose messages.
+.It Em net.inet.ip.fw.verbose_limit : No 0
+Limits the number of messages produced by a verbose firewall.
+.It Em net.link.ether.ipfw : No 0
+Controls whether layer-2 packets are passed to
+.Nm .
+Default is no.
+.It Em net.link.ether.bridge_ipfw : No 0
+Controls whether bridged packets are passed to
+.Nm .
+Default is no.
+.El
+.Pp
+.Sh IPFW2 ENHANCEMENTS
+This Section lists the features that have been introduced in
+.Nm ipfw2
+which were not present in
+.Nm ipfw1 .
+We list them in order of the potential impact that they can
+have in writing your rulesets.
+You might want to consider using these features in order to
+write your rulesets in a more efficient way.
+.Bl -tag -width indent
+.It Syntax and flags
+.Nm ipfw1
+does not support the -n flag (only test syntax),
+nor it allows spaces after commas or supports all
+rule fields in a single argument.
+.It Handling of non-IPv4 packets
+.Nm ipfw1
+will silently accept all non-IPv4 packets (which
+.Nm ipfw1
+will only see when
+.Em net.link.ether.bridge_ipfw=1 Ns
+).
+.Nm ipfw2
+will filter all packets (including non-IPv4 ones) according to the ruleset.
+To achieve the same behaviour as
+.Nm ipfw1
+you can use the following as the very first rule in your ruleset:
+.Pp
+.Dl "ipfw add 1 allow layer2 not mac-type ip"
+.Pp
+The
+.Cm layer2
+option might seem redundant, but it is necessary -- packets
+passed to the firewall from layer3 will not have a MAC header,
+so the
+.Cm mac-type ip
+pattern will always fail on them, and the
+.Cm not
+operator will make this rule into a pass-all.
+.It Addresses
+.Nm ipfw1
+does not supports address sets or lists of addresses.
+.Pp
+.It Port specifications
+.Nm ipfw1
+only allows one port range when specifying TCP and UDP ports, and
+is limited to 10 entries instead of the 15 allowed by
+.Nm ipfw2 .
+Also, in
+.Nm ipfw1
+you can only specify ports when the rule is requesting
+.Cm tcp
+or
+.Cm udp
+packets. With
+.Nm ipfw2
+you can put port specifications in rules matching all packets,
+and the match will be attempted only on those packets carrying
+protocols which include port identifiers.
+.Pp
+Finally,
+.Nm ipfw1
+allowed the first port entry to be specified as
+.Ar port:mask
+where
+.Ar mask
+can be an arbitrary 16-bit mask.
+This syntax is of questionable usefulness and it is not
+supported anymore in
+.Nm ipfw2 .
+.It Or-blocks
+.Nm ipfw1
+does not support Or-blocks.
+.It keepalives
+.Nm ipfw1
+does not generate keepalives for stateful sessions.
+As a consequence, it might cause idle sessions to drop because
+the lifetime of the dynamic rules expires.
+.It Sets of rules
+.Nm ipfw1
+does not implement sets of rules.
+.It MAC header filtering and Layer-2 firewalling.
+.Nm ipfw1
+does not implement filtering on MAC header fields, nor is it
+invoked on packets from
+.Cm ether_demux()
+and
+.Cm ether_output_frame().
+The sysctl variable
+.Em net.link.ether.ipfw
+has no effect there.
+.It Options
+In
+.Nm ipfw1 ,
+the following options only accept a single value as an argument:
+.Pp
+.Cm ipid, iplen, ipttl
+.Pp
+The following options are not implemented by
+.Nm ipfw1 :
+.Pp
+.Cm dst-ip, dst-port, layer2, mac, mac-type, src-ip, src-port.
+.Pp
+Additionally, the RELENG_4 version of
+.Nm ipfw1
+does not implement the following options:
+.Pp
+.Cm ipid, iplen, ipprecedence, iptos, ipttl,
+.Cm ipversion, tcpack, tcpseq, tcpwin .
+.It Dummynet options
+The following option for
+.Nm dummynet
+pipes/queues is not supported:
+.Cm noerror .
 .El
 .Sh EXAMPLES
+There are far too many possible uses of
+.Nm
+so this Section will only give a small set of examples.
+.Pp
+.Ss BASIC PACKET FILTERING
 This command adds an entry which denies all tcp packets from
 .Em cracker.evil.org
 to the telnet port of
@@ -790,12 +1815,12 @@ from being forwarded by the host:
 .Pp
 .Dl "ipfw add deny tcp from cracker.evil.org to wolf.tambov.su telnet"
 .Pp
-This one disallows any connection from the entire crackers
+This one disallows any connection from the entire cracker's
 network to my host:
 .Pp
 .Dl "ipfw add deny ip from 123.45.67.0/24 to my.host.org"
 .Pp
-A fast and efficient way to limit access (not using dynamic rules)
+A first and efficient way to limit access (not using dynamic rules)
 is the use of the following rules:
 .Pp
 .Dl "ipfw add allow tcp from any to any established"
@@ -813,6 +1838,36 @@ All other SYN packets will be rejected by the final
 .Cm deny
 rule.
 .Pp
+If you administer one or more subnets, you can take advantage of the
+.Nm ipfw2
+syntax to specify address sets and or-blocks and write extremely
+compact rulesets which selectively enable services to blocks
+of clients, as below:
+.Pp
+.Dl "goodguys=\*q{ 10.1.2.0/24{20,35,66,18} or 10.2.3.0/28{6,3,11} }\*q"
+.Dl "badguys=\*q10.1.2.0/24{8,38,60}\*q"
+.Dl ""
+.Dl "ipfw add allow ip from ${goodguys} to any"
+.Dl "ipfw add deny ip from ${badguys} to any"
+.Dl "... normal policies ..."
+.Pp
+The
+.Nm ipfw1
+syntax would require a separate rule for each IP in the above
+example.
+.Pp
+The
+.Cm verrevpath
+option could be used to do automated anti-spoofing by adding the
+following to the top of a ruleset:
+.Pp
+.Dl "ipfw add deny ip from any to any not verrevpath in"
+.Pp
+This rule drops all incoming packets that appear to be coming to the
+sytem on the wrong interface. For example, a packet with a source
+address belonging to a host on a protected internal network would be
+dropped if it tried to enter the system from an external interface.
+.Ss DYNAMIC RULES
 In order to protect a site from flood attacks involving fake
 TCP packets, it is safer to use dynamic rules:
 .Pp
@@ -830,10 +1885,21 @@ or
 rule.
 A
 .Cm check-state
-rule should be usually placed near the beginning of the
+rule should usually be placed near the beginning of the
 ruleset to minimize the amount of work scanning the ruleset.
 Your mileage may vary.
 .Pp
+To limit the number of connections a user can open
+you can use the following type of rules:
+.Pp
+.Dl "ipfw add allow tcp from my-net/24 to any setup limit src-addr 10"
+.Dl "ipfw add allow tcp from any to me setup limit src-addr 4"
+.Pp
+The former (assuming it runs on a gateway) will allow each host
+on a /24 network to open at most 10 TCP connections.
+The latter can be placed on a server to make sure that a single
+client does not use more than 4 simultaneous connections.
+.Pp
 .Em BEWARE :
 stateful rules can be subject to denial-of-service attacks
 by a SYN-flood which opens a huge number of dynamic rules.
@@ -852,48 +1918,177 @@ or in short form without timestamps:
 .Pp
 .Dl ipfw -a list
 .Pp
+which is equivalent to:
+.Pp
+.Dl ipfw show
+.Pp
 Next rule diverts all incoming packets from 192.168.2.0/24
 to divert port 5000:
 .Pp
 .Dl ipfw divert 5000 ip from 192.168.2.0/24 to any in
 .Pp
+.Ss TRAFFIC SHAPING
+The following rules show some of the applications of
+.Nm
+and
+.Xr dummynet 4
+for simulations and the like.
+.Pp
+This rule drops random incoming packets with a probability
+of 5%:
+.Pp
+.Dl "ipfw add prob 0.05 deny ip from any to any in"
+.Pp
+A similar effect can be achieved making use of dummynet pipes:
+.Pp
+.Dl "ipfw add pipe 10 ip from any to any"
+.Dl "ipfw pipe 10 config plr 0.05"
+.Pp
+We can use pipes to artificially limit bandwidth, e.g. on a
+machine acting as a router, if we want to limit traffic from
+local clients on 192.168.2.0/24 we do:
+.Pp
+.Dl "ipfw add pipe 1 ip from 192.168.2.0/24 to any out"
+.Dl "ipfw pipe 1 config bw 300Kbit/s queue 50KBytes"
+.Pp
+note that we use the
+.Cm out
+modifier so that the rule is not used twice.
+Remember in fact that
+.Nm
+rules are checked both on incoming and outgoing packets.
+.Pp
+Should we want to simulate a bidirectional link with bandwidth
+limitations, the correct way is the following:
+.Pp
+.Dl "ipfw add pipe 1 ip from any to any out"
+.Dl "ipfw add pipe 2 ip from any to any in"
+.Dl "ipfw pipe 1 config bw 64Kbit/s queue 10Kbytes"
+.Dl "ipfw pipe 2 config bw 64Kbit/s queue 10Kbytes"
+.Pp
+The above can be very useful, e.g. if you want to see how
+your fancy Web page will look for a residential user who
+is connected only through a slow link.
+You should not use only one pipe for both directions, unless
+you want to simulate a half-duplex medium (e.g. AppleTalk,
+Ethernet, IRDA).
+It is not necessary that both pipes have the same configuration,
+so we can also simulate asymmetric links.
+.Pp
+Should we want to verify network performance with the RED queue
+management algorithm:
+.Pp
+.Dl "ipfw add pipe 1 ip from any to any"
+.Dl "ipfw pipe 1 config bw 500Kbit/s queue 100 red 0.002/30/80/0.1"
+.Pp
+Another typical application of the traffic shaper is to
+introduce some delay in the communication.
+This can significantly affect applications which do a lot of Remote
+Procedure Calls, and where the round-trip-time of the
+connection often becomes a limiting factor much more than
+bandwidth:
+.Pp
+.Dl "ipfw add pipe 1 ip from any to any out"
+.Dl "ipfw add pipe 2 ip from any to any in"
+.Dl "ipfw pipe 1 config delay 250ms bw 1Mbit/s"
+.Dl "ipfw pipe 2 config delay 250ms bw 1Mbit/s"
+.Pp
+Per-flow queueing can be useful for a variety of purposes.
+A very simple one is counting traffic:
+.Pp
+.Dl "ipfw add pipe 1 tcp from any to any"
+.Dl "ipfw add pipe 1 udp from any to any"
+.Dl "ipfw add pipe 1 ip from any to any"
+.Dl "ipfw pipe 1 config mask all"
+.Pp
+The above set of rules will create queues (and collect
+statistics) for all traffic.
+Because the pipes have no limitations, the only effect is
+collecting statistics.
+Note that we need 3 rules, not just the last one, because
+when
+.Nm
+tries to match IP packets it will not consider ports, so we
+would not see connections on separate ports as different
+ones.
+.Pp
+A more sophisticated example is limiting the outbound traffic
+on a net with per-host limits, rather than per-network limits:
+.Pp
+.Dl "ipfw add pipe 1 ip from 192.168.2.0/24 to any out"
+.Dl "ipfw add pipe 2 ip from any to 192.168.2.0/24 in"
+.Dl "ipfw pipe 1 config mask src-ip 0x000000ff bw 200Kbit/s queue 20Kbytes"
+.Dl "ipfw pipe 2 config mask dst-ip 0x000000ff bw 200Kbit/s queue 20Kbytes"
+.Ss SETS OF RULES
+To add a set of rules atomically, e.g. set 18:
+.Pp
+.Dl "ipfw set disable 18"
+.Dl "ipfw add NN set 18 ...         # repeat as needed"
+.Dl "ipfw set enable 18"
+.Pp
+To delete a set of rules atomically the command is simply:
+.Pp
+.Dl "ipfw delete set 18"
+.Pp
+To test a ruleset and disable it and regain control if something goes wrong:
+.Pp
+.Dl "ipfw set disable 18"
+.Dl "ipfw add NN set 18 ...         # repeat as needed"
+.Dl "ipfw set enable 18; echo done; sleep 30 && ipfw set disable 18"
+.Pp
+Here if everything goes well, you press control-C before the "sleep"
+terminates, and your ruleset will be left active. Otherwise, e.g. if
+you cannot access your box, the ruleset will be disabled after
+the sleep terminates thus restoring the previous situation.
 .Sh SEE ALSO
 .Xr cpp 1 ,
 .Xr m4 1 ,
 .Xr divert 4 ,
+.Xr dummynet 4 ,
 .Xr ip 4 ,
 .Xr ipfirewall 4 ,
 .Xr protocols 5 ,
 .Xr services 5 ,
-.Xr init 8 ,
 .Xr reboot 8 ,
 .Xr sysctl 8 ,
 .Xr syslogd 8
 .Sh BUGS
-The syntax has grown over the years and it is not very clean.
-.Pp
-.Em WARNING!!WARNING!!WARNING!!WARNING!!WARNING!!WARNING!!WARNING!!
+The syntax has grown over the years and sometimes it might be confusing.
+Unfortunately, backward compatibility prevents cleaning up mistakes
+made in the definition of the syntax.
 .Pp
-This program can put your computer in rather unusable state.
-When using it for the first time, work on the console of the
-computer, and do
-.Em NOT
-do anything you don't understand.
+.Em !!! WARNING !!!
 .Pp
-When manipulating/adding chain entries, service and protocol names
-are not accepted.
+Misconfiguring the firewall can put your computer in an unusable state,
+possibly shutting down network services and requiring console access to
+regain control of it.
 .Pp
 Incoming packet fragments diverted by
 .Cm divert
 or
 .Cm tee
 are reassembled before delivery to the socket.
+The action used on those packet is the one from the
+rule which matches the first fragment of the packet.
 .Pp
 Packets that match a
 .Cm tee
 rule should not be immediately accepted, but should continue
 going through the rule list.
 This may be fixed in a later version.
+.Pp
+Packets diverted to userland, and then reinserted by a userland process
+may lose various packet attributes.
+The packet source interface name
+will be preserved if it is shorter than 8 bytes and the userland process
+saves and reuses the sockaddr_in
+(as does
+.Xr natd 8 ) ;
+otherwise, it may be lost.
+If a packet is reinserted in this manner, later rules may be incorrectly
+applied, making the order of
+.Cm divert
+rules in the rule sequence very important.
 .Sh AUTHORS
 .An Ugen J. S. Antsilevich ,
 .An Poul-Henning Kamp ,
@@ -905,10 +2100,19 @@ This may be fixed in a later version.
 API based upon code written by
 .An Daniel Boulet
 for BSDI.
+.Pp
+Work on
+.Xr dummynet 4
+traffic shaper supported by Akamba Corp.
 .Sh HISTORY
 The
 .Nm
 utility first appeared in
 .Fx 2.0 .
+.Xr dummynet 4
+was introduced in
+.Fx 2.2.8 .
 Stateful extensions were introduced in
 .Fx 4.0 .
+.Nm ipfw2
+was introduced in Summer 2002.