Support per-flow queueing in dummynet.

Implement masks on UDP/TCP ports.
Large rewrite of the manpage.

Work supported by Akamba Corp.
This commit is contained in:
Luigi Rizzo 2000-01-08 11:19:19 +00:00
parent 37713edc2d
commit 8c020cb775
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=55595
2 changed files with 532 additions and 297 deletions

View File

@ -6,7 +6,7 @@
.Os FreeBSD
.Sh NAME
.Nm ipfw
.Nd controlling utility for IP firewall
.Nd controlling utility for IP firewall and traffic shaper
.Sh SYNOPSIS
.Nm ipfw
.Op Fl q
@ -27,26 +27,11 @@ flush
.Oo
.Fl q
.Oc
zero
{zero|resetlog|delete}
.Op Ar number ...
.Nm ipfw
.Oo
.Fl q
.Oc
resetlog
.Op Ar number ...
.Nm ipfw
delete
.Ar number ...
.Nm ipfw
.Op Fl aftN
list
.Op Ar number ...
.Nm ipfw
.Oo
.Fl ftN
.Oc
show
{list|show}
.Op Ar number ...
.Nm ipfw
.Oo
@ -54,225 +39,72 @@ show
.Oc
add
.Op Ar number
.Op prob match_probability
.Ar action
.Op log Op Ar logamount Ar number
.Ar proto
from
.Ar src
to
.Ar dst
.Op via Ar name | ipno
.Op Ar options
.Ar rule-body
.Nm ipfw
pipe
.Ar number
config
.Ar pipe-config-options
.Nm ipfw
pipe {delete|list|show}
.Op Ar number ...
.Sh DESCRIPTION
If used as shown in the first synopsis line, the
.Ar file
will be read line by line and applied as arguments to the
.Nm
command.
is the user interface for controlling the IPFW firewall and
.Nm dummynet
traffic shaper in FreeBSD.
.Pp
Optionally, a preprocessor can be specified using
.Fl p Ar preproc
where
.Ar file
is to be piped through. Useful preprocessors include
.Xr cpp 1
and
.Xr m4 1 .
If
.Ar preproc
doesn't start with a slash 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
Each incoming or outgoing packet is passed through the
.Nm
is being run (e. g. since 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.
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.
rules. In case a host is acting as a gateway, packets
forwarded by the gateway are processed by
.Nm
twice. In case a host is acting as a bridge, packets
forwarded by the bridge are processed by
.Nm
once.
.Pp
Each packet that has been received or is about to be sent goes through
the
.Nm
rules. In the case of a host acting as a gateway, packets that are
forwarded by the host are processed by
.Nm
twice
.Po
once when entering, and once when leaving
.Pc .
Each packet can be filtered based on the following information that is
associated with it:
A firewall configuration is made of a list of numbered rules, which are
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 matching one for further
processing. All rules apply to all interfaces, so it is
responsibility of the sysadmin to write the ruleset in such
a way to minimize the number of checks.
.Pp
.Bl -tag -offset indent -compact -width xxxx
.It Receive Interface Pq Ar recv
Interface over which the packet was received
.It Transmit Interface Pq Ar xmit
Interface over which the packet would be transmitted
.It Incoming Pq Ar in
Packet was just received
.It Outgoing Pq Ar out
Packet would be transmitted
.It Source IP Address
Sender's IP Address
.It Destination IP Address
Target's IP Address
.It Protocol
IP protocol, including but not limited to IP
.Pq Ar ip ,
UDP
.Pq Ar udp ,
TCP
.Pq Ar tcp ,
A configuration always includes a
.Ar 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
.Ar deny
or
ICMP
.Pq Ar icmp
.It Source Port
Sender's UDP or TCP port
.It Destination Port
Target's UDP or TCP port
.It Connection Setup Flag Pq Ar setup
This packet is a request to setup a TCP connection
.It Connection Established Flag Pq Ar established
This packet is part of an established TCP connection
.It All TCP Flags Pq Ar tcpflags
One or more of the TCP flags: close connection
.Pq Ar fin ,
open connection
.Pq Ar syn ,
reset connection
.Pq Ar rst ,
push
.Pq Ar psh ,
acknowledgment
.Pq Ar ack ,
and
urgent
.Pq Ar urg
.It Fragment Flag Pq Ar frag
This packet is a fragment of an IP packet
.It IP Options Pq Ar ipoptions
One or more of the IP options: strict source route
.Pq Ar ssrr ,
loose source route
.Pq Ar lsrr ,
record route
.Pq Ar rr ,
and timestamp
.Pq Ar ts
.It ICMP Types Pq Ar icmptypes
One or more of the ICMP types: echo reply
.Pq Ar 0 ,
destination unreachable
.Pq Ar 3 ,
source quench
.Pq Ar 4 ,
redirect
.Pq Ar 5 ,
echo request
.Pq Ar 8 ,
router advertisement
.Pq Ar 9 ,
router solicitation
.Pq Ar 10 ,
time-to-live exceeded
.Pq Ar 11 ,
IP header bad
.Pq Ar 12 ,
timestamp request
.Pq Ar 13 ,
timestamp reply
.Pq Ar 14 ,
information request
.Pq Ar 15 ,
information reply
.Pq Ar 16 ,
address mask request
.Pq Ar 17 ,
and address mask reply
.Pq Ar 18
.El
.Ar allow
depending on how the kernel is configured.
.Pp
Note that may be dangerous to filter on the source IP address or
source TCP/UDP port because either or both could easily be spoofed.
.Pp
The
All rules have a few associated counters: a packet count and
a byte count, a log count, and a timestamp indicating the time
of the last match. Counters can be visualized or reset with
.Nm
code works by going through the rule-list for each packet
until a match is found.
All rules have two associated counters, a packet count and
a byte count.
These counters are updated when a packet matches the rule.
commands.
.Pp
If a rule has the optional
.Dq prob match_probability
specifier, where the match_probability is a floating point number
between 0 and 1, a match is only declared with the specified
probability. This can be useful for a number of applications
such as 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
The rules are ordered by a
.Dq line-number
from 1 to 65534 that is used
to order and delete rules. Rules are tried in increasing order, and the
first rule that matches a packet applies.
Multiple rules may share the same number and apply in
the order in which they were added.
.Pp
If a rule is added without a number, it is numbered 100 higher than the highest
defined rule number, unless the highest defined rule number is 65435 or
greater, in which case new rules are given that same number.
.Pp
The delete operation deletes the first rule with number
.Ar number ,
if any.
.Pp
The list command prints out the current rule set.
.Pp
The show command is equivalent to
.Sq ipfw -a list .
.Pp
The zero operation zeroes the counters associated with rule number
.Ar number .
.Pp
The resetlog operation resets the logging counters associated with
rule number
.Ar number .
.Pp
The flush operation removes all rules.
.Pp
Any command beginning with a
.Sq # ,
or being all blank, is ignored.
.Pp
One rule is always present:
.Bd -literal -offset center
65535 deny all from any to any
.Ed
.Pp
This rule is the default policy, i.e., don't allow anything at all.
Your job in setting up rules is to modify this policy to match your
needs.
.Pp
However, if the kernel option
.Dq IPFIREWALL_DEFAULT_TO_ACCEPT
is active, the rule is instead:
.Bd -literal -offset center
65535 allow all from any to any
.Ed
.Pp
This variation lets everything pass through. This option should only be
activated in particular circumstances, such as if you use the firewall
system as an on-demand denial-of-service filter that is normally wide open.
Rules can be added with the
.Ar add
command; deleted individually with the
.Ar delete
command, and globally with the
.Ar flush
command; visualized, optionally with the content of
the counters, using the
.Ar show
and
.Ar list
commands. Finally, counters can be reset with the
.Ar zero
and
.Ar resetlog
commands.
.Pp
The following options are available:
.Bl -tag -width indent
@ -310,6 +142,92 @@ While listing, show last match timestamp.
Try to resolve addresses and service names in output.
.El
.Pp
To ease configuration, rules can be put into a file which is processed
using
.Nm
as shown in the first synopsis line. The
.Ar file
will be read line by line and applied as arguments to the
.Nm
command.
.Pp
Optionally, a preprocessor can be specified using
.Fl p Ar preproc
where
.Ar file
is to be piped through. Useful preprocessors include
.Xr cpp 1
and
.Xr m4 1 .
If
.Ar preproc
doesn't start with a slash 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
.Nm
is being run (e. g. since 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.
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.
.Pp
The
.Nm
.Ar pipe
commands are used to configure the traffic shaper, as shown in
the ``TRAFFIC SHAPER CONFIGURATION'' section below.
.Pp
.Sh RULE FORMAT
The
.Nm
rule format is the following
.Pp
.Op prob Ar match_probability
.Ar action
.Op log Op Ar logamount Ar number
.Ar proto
from
.Ar src
to
.Ar dst
.Op interface-spec
.Op Ar options
.Pp
Each packet can be filtered based on the following information that is
associated with it:
.Pp
.Bl -tag -offset indent -compact -width xxxx
.It Transmit and Receive Interface (by name or address)
.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
.It IP Options
.It ICMP Types
.It User/Group ID of the socket associated with the packet
.El
.Pp
Note that may be dangerous to filter on the source IP address or
source TCP/UDP port because either or both could easily be spoofed.
.Pp
.Ar prob match_probability
.Bd -ragged -offset flag
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 or (in conjunction with
.Xr dummynet 4
) to simulate the effect of multiple paths leading to out-of-order
packet delivery.
.Ed
.Pp
.Ar action :
.Bl -hang -offset flag -width 1234567890123456
.It Ar allow
@ -415,27 +333,16 @@ Skip all subsequent rules numbered less than
The search continues with the first rule numbered
.Ar number
or higher.
.It Ar uid 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 Ar gid group
Match all TCP or UDP packets sent by or received for a
.Ar group .
A
.Ar group
may be matched by name or identification number.
.El
.Pp
.Ar log Op Ar logamount Ar number
.Bd -ragged -offset flag
If the kernel was compiled with
.Dv IPFIREWALL_VERBOSE ,
then when a packet matches a rule with the
.Ar log
keyword or a clear/resetlog is performed, a message will be logged to
.Xr syslogd 8 ,
or, if that fails, to the console. If the kernel was compiled with the
keyword a message will be printed on the console.
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
@ -445,47 +352,39 @@ is used, that
.Ar number
will be the default logging limit rather than
.Dv IPFIREWALL_VERBOSE_LIMIT .
When this limit is reached, the limit and rule number will be logged.
Logging may then be re-enabled by clearing the logging counter
or the packet counter for that entry.
.Pp
The
.Xr syslogd 8
logging and the default log limit are adjustable dynamically through the
Console logging and the log limit are adjustable dynamically
through the
.Xr sysctl 8
interface in the MIB base of
.Dv net.inet.ip.fw .
.Ed
.Pp
.Ar proto :
.Bl -hang -offset flag -width 1234567890123456
.It Ar ip
All packets match. The alias
.Ar all
has the same effect.
.It Ar tcp
Only TCP packets match.
.It Ar udp
Only UDP packets match.
.It Ar icmp
Only ICMP packets match.
.It Ar <number|name>
Only packets for the specified protocol matches (see
.Bd -ragged -offset flag
An IP protocol specified by number or name (see
.Pa /etc/protocols
for a complete list).
.El
The
.Ar ip
or
.Ar all
keywords mean any protocol will match.
.Ed
.Pp
.Ar src
and
.Ar dst :
.Bl -hang -offset flag
.It Ar <address/mask>
.Op Ar ports
.El
.Bd -ragged -offset flag
.Ar <address/mask> Op Ar ports
.Pp
The
.Em <address/mask>
may be specified as:
.Bl -hang -offset flag -width 1234567890123456
.Pp
.Bl -hang -offset 0n -width 1234567890123456
.It Ar ipno
An ipnumber of the form 1.2.3.4.
Only this exact ip number match the rule.
@ -493,7 +392,7 @@ Only this exact ip number match the rule.
An ipnumber 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:mask
An ipnumber with a mask width of the form 1.2.3.4:255.255.240.0.
An ipnumber 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
.Pp
@ -507,9 +406,19 @@ With the TCP and UDP protocols, optional
may be specified as:
.Pp
.Bl -hang -offset flag
.It Ns {port|port-port} Ns Op ,port Ns Op ,...
.It Ns {port|port-port|port:mask} Ns Op ,port Ns Op ,...
.El
.Pp
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.
@ -533,18 +442,16 @@ specifications. See the
.Ar frag
option for details on matching fragmented packets.
.Pp
Rules can apply to packets when they are incoming, or outgoing, or both.
The
.Ar in
keyword indicates the rule should only match incoming packets.
The
.Ar out
keyword indicates the rule should only match outgoing packets.
.Ed
.Ar interface-spec :
.Pp
To match packets going through a certain interface, specify
the interface using
.Ar via :
.Bl -hang -offset flag -width 1234567890123456
.Bd -ragged -offset flag
Some combinations of the following specifiers are allowed:
.Bl -hang -offset 0n -width 1234567890123456
.It Ar in
Only match incoming packets.
.It Ar out
Only match outgoing packets.
.It Ar via ifX
Packet must be going through interface
.Ar ifX.
@ -595,10 +502,10 @@ or
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
from the local host have no receive interface, while packets destined for
the local host have no transmit interface.
.Ed
.Pp
Additional
.Ar options :
.Bl -hang -offset flag -width 1234567890123456
.It frag
@ -608,15 +515,12 @@ of the datagram.
may not be used in conjunction with either
.Ar tcpflags
or TCP/UDP port specifications.
.It in
Match if this packet was on the way in.
.It out
Match if this packet was on the way out.
.It ipoptions Ar spec
Match if the IP header contains the comma separated list of
options specified in
.Ar spec .
The supported IP options are:
.Pp
.Ar ssrr
(strict source route),
.Ar lsrr
@ -639,6 +543,7 @@ Match if the TCP header contains the comma separated list of
flags specified in
.Ar spec .
The supported TCP flags are:
.Pp
.Ar fin ,
.Ar syn ,
.Ar rst ,
@ -660,6 +565,116 @@ 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:
.Pp
echo reply
.Pq Ar 0 ,
destination unreachable
.Pq Ar 3 ,
source quench
.Pq Ar 4 ,
redirect
.Pq Ar 5 ,
echo request
.Pq Ar 8 ,
router advertisement
.Pq Ar 9 ,
router solicitation
.Pq Ar 10 ,
time-to-live exceeded
.Pq Ar 11 ,
IP header bad
.Pq Ar 12 ,
timestamp request
.Pq Ar 13 ,timestamp reply
.Pq Ar 14 ,
information request
.Pq Ar 15 ,
information reply
.Pq Ar 16 ,
address mask request
.Pq Ar 17 ,
and address mask reply
.Pq Ar 18
.It Ar uid 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 Ar gid group
Match all TCP or UDP packets sent by or received for a
.Ar group .
A
.Ar group
may be matched by name or identification number.
.El
.Sh TRAFFIC SHAPER CONFIGURATION
Ipfw is also the user interface for the
.Xr dummynet 4
traffic shaper.
The shaper operates by passing packets to objects called
.Ar pipes ,
which emulates a link with given bandwidth, propagation delay,
queue size and packet loss rate.
The
.Nm
pipe configuration format is the following
.Pp
.Ar pipe number config
.Op bw Ar bandwidth
.Op queue Ar {slots|size}
.Op delay Ar delay-ms
.Op plr Ar loss-probability
.Op mask Ar {all | {dst-ip|src-ip|dst-port|src-port|proto} bitmask}
.Op buckets Ar hash-table-size
.Pp
The following parameters can be configured for a pipe:
.Bl -hang -offset flag -width 1234567890
.It bw Ar bandwidth
Bandwidth, measured in
.Ar [K|M]{bit/s|Byte/s} .
A value of 0 (default) means unlimited bandwidth.
The unit must follow immediately the number, as in
.Dl "ipfw pipe 1 config bw 300Kbit/s queue 50KBytes"
.It 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
good practice to run kernels with "options HZ=1000" to reduce
the granularity to 1ms or less). Default value is 0, meaning
no delay.
.It queue Ar {slots|size}
queue size, in slots or 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.
.It plr packet-loss-rate
packet loss rate. NN is a floating-point number, with 0 meaning
no loss, 1 means 100% loss. The loss rate is internally represented
on 31 bits.
.It mask Ar mask-specifier
dummynet allows you to generate per-flow queues
using a single pipe specification. A flow identifier is constructed
by masking the IP addresses, ports and protocol types as specified
in the pipe configuration. Packets with the same ID after masking fall
into the same queue. Available mask specifiers are a combination
of the following:
.Ar dst-ip mask , src-ip mask ,
.Ar dst-port mask , src-port mask ,
.Ar proto mask
or
.Ar all
where the latter means all bits in all fields are significant.
.It buckets Ar NN
Specifies the size of the hash table used for storing the various queues.
Default value is 64 controlled by the sysctl variable
.Ar net.inet.ip.dummynet.hash_size ,
allowed range is 16 to 1024.
.El
.Sh CHECKLIST
Here are some important points to consider when designing your
@ -705,7 +720,7 @@ for information on system security levels
.Pc .
.Sh PACKET DIVERSION
A divert socket bound to the specified port will receive all packets diverted
or tee'd to that port; see
to that port; see
.Xr divert 4 .
If no socket is bound to the destination port, or if the kernel
wasn't compiled with divert socket support, the packets are dropped.
@ -737,11 +752,86 @@ or in short form without timestamps:
This rule diverts all incoming packets from 192.168.2.0/24 to divert port 5000:
.Pp
.Dl ipfw divert 5000 all from 192.168.2.0/24 to any in
.Pp
The following rules show some of the applications of ipfw and
dummynet for simulations and the like.
.Pp
This rule drops random 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
.Ql out
specifier so that the rule is not used twice. Remember in fact
that ipfw rules are checked both on incoming and outgoing packets.
.Pp
Should we like 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 which 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
Another typical application of the traffic shaper is to introduce some
delay in the communication. This can affect a lot 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 ipfw 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"
.Sh SEE ALSO
.Xr cpp 1 ,
.Xr m4 1 ,
.Xr divert 4 ,
.Xr dummynet 4 ,
.Xr bridge 4 ,
.Xr ip 4 ,
.Xr ipfirewall 4 ,
.Xr protocols 5 ,
@ -753,6 +843,8 @@ This rule diverts all incoming packets from 192.168.2.0/24 to divert port 5000:
.Xr syslogd 8 .
.Sh BUGS
.Pp
The syntax has grown over the years and it is not very clean.
.Pp
.Em WARNING!!WARNING!!WARNING!!WARNING!!WARNING!!WARNING!!WARNING!!
.Pp
This program can put your computer in rather unusable state. When
@ -778,11 +870,18 @@ going through the rule list. This may be fixed in a later version.
.An Ugen J. S. Antsilevich ,
.An Poul-Henning Kamp ,
.An Alex Nash ,
.An Archie Cobbs .
.An Archie Cobbs ,
.An Luigi Rizzo .
.Pp
API based upon code written by
.An Daniel Boulet
Daniel Boulet
for BSDI.
.Pp
Work on dummynet traffic shaper supported by Akamba Corp.
.Sh HISTORY
.Nm Ipfw
first appeared in
.Fx 2.0 .
.Nm dummynet
was introduced in
.Fx 2.2.8

View File

@ -127,6 +127,10 @@ print_port(prot, port, comma)
const char *protocol;
int printed = 0;
if (!strcmp(comma,":")) {
printf("%s0x%04x", comma, port);
return ;
}
if (do_resolv) {
pe = getprotobynumber(prot);
if (pe)
@ -300,6 +304,8 @@ show_ipfw(struct ip_fw *chain, int pcwidth, int bcwidth)
print_port(chain->fw_prot, chain->fw_uar.fw_pts[i], comma);
if (i==0 && (chain->fw_flg & IP_FW_F_SRNG))
comma = "-";
else if (i==0 && (chain->fw_flg & IP_FW_F_SMSK))
comma = ":";
else
comma = ",";
}
@ -340,6 +346,8 @@ show_ipfw(struct ip_fw *chain, int pcwidth, int bcwidth)
print_port(chain->fw_prot, chain->fw_uar.fw_pts[nsp+i], comma);
if (i==0 && (chain->fw_flg & IP_FW_F_DRNG))
comma = "-";
else if (i==0 && (chain->fw_flg & IP_FW_F_DMSK))
comma = ":";
else
comma = ",";
}
@ -456,13 +464,13 @@ list(ac, av)
int pcwidth = 0;
int bcwidth = 0;
int n, num = 0;
int nbytes;
/* get rules or pipes from kernel, resizing array as necessary */
{
const int unit = do_pipe ? sizeof(*pipes) : sizeof(*rules);
const int ocmd = do_pipe ? IP_DUMMYNET_GET : IP_FW_GET;
int nalloc = 0;
int nbytes;
while (num >= nalloc) {
nalloc = nalloc * 2 + 200;
@ -479,19 +487,25 @@ list(ac, av)
/* display requested pipes */
if (do_pipe) {
u_long rulenum;
void *next_pipe ;
struct dn_pipe *p = (struct dn_pipe *) data;
pipes = (struct dn_pipe *) data;
if (ac > 0)
rulenum = strtoul(*av++, NULL, 10);
else
rulenum = 0 ;
for (n = 0; n < num; n++) {
struct dn_pipe *const p = &pipes[n];
for ( ; nbytes > 0 ; p = (struct dn_pipe *)next_pipe ) {
double b = p->bandwidth ;
char buf[30] ;
char qs[30] ;
char plr[30] ;
int l ;
struct dn_flow_queue *q ;
l = sizeof(*p) + p->rq_elements * sizeof(struct dn_flow_queue) ;
next_pipe = (void *)p + l ;
q = (struct dn_flow_queue *)(p+1) ;
nbytes -= l ;
if (rulenum != 0 && rulenum != p->pipe_nr)
continue;
@ -516,9 +530,33 @@ list(ac, av)
else
plr[0]='\0';
printf("%05d: %s %4d ms %s %s -- %d pkts (%d B) %d drops\n",
printf("%05d: %s %4d ms %s%s %d queues (%d buckets)\n",
p->pipe_nr, buf, p->delay, qs, plr,
p->r_len, p->r_len_bytes, p->r_drops);
p->rq_elements, p->rq_size);
printf(" mask: 0x%02x 0x%08x/0x%04x -> 0x%08x/0x%04x\n",
p->flow_mask.proto,
p->flow_mask.src_ip, p->flow_mask.src_port,
p->flow_mask.dst_ip, p->flow_mask.src_port);
for (l = 0 ; l < p->rq_elements ; l++) {
struct in_addr ina ;
struct protoent *pe ;
ina.s_addr = htonl(q[l].id.src_ip) ;
printf(" (%d) ", q[l].hash_slot);
pe = getprotobynumber(q[l].id.proto);
if (pe)
printf(" %s", pe->p_name);
else
printf(" %u", q[l].id.proto);
printf(" %s/%d -> ",
inet_ntoa(ina), q[l].id.src_port);
ina.s_addr = htonl(q[l].id.dst_ip) ;
printf("%s/%d\n",
inet_ntoa(ina), q[l].id.dst_port);
printf("\t%u pkts %u bytes, tot %qu pkts %qu bytes %u drops\n",
q[l].len, q[l].len_bytes,
q[l].tot_pkts, q[l].tot_bytes, q[l].drops);
}
}
free(data);
return;
@ -634,6 +672,8 @@ show_usage(const char *fmt, ...)
" delay <milliseconds>\n"
" queue <size>{packets|Bytes|KBytes}\n"
" plr <fraction>\n"
" mask {all| [dst-ip|src-ip|dst-port|src-port|proto] <number>}\n"
" buckets <number>}\n"
);
exit(EX_USAGE);
@ -777,6 +817,10 @@ lookup_port(const char *arg, int test, int nodash)
return(val);
}
/*
* return: 0 normally, 1 if first pair is a range,
* 2 if first pair is a port+mask
*/
static int
fill_port(cnt, ptr, off, arg)
u_short *cnt, *ptr, off;
@ -785,10 +829,23 @@ fill_port(cnt, ptr, off, arg)
char *s;
int initial_range = 0;
for (s = arg; *s && *s != ',' && *s != '-'; s++) {
for (s = arg; *s && *s != ',' && *s != '-' && *s != ':'; s++) {
if (*s == '\\' && *(s+1))
s++;
}
if (*s == ':') {
*s++ = '\0';
if (strchr(arg, ','))
errx(EX_USAGE, "port/mask must be first in list");
add_port(cnt, ptr, off, *arg ? lookup_port(arg, 0, 0) : 0x0000);
arg = s;
s = strchr(arg,',');
if (s)
*s++ = '\0';
add_port(cnt, ptr, off, *arg ? lookup_port(arg, 0, 0) : 0xffff);
arg = s;
initial_range = 2;
} else
if (*s == '-') {
*s++ = '\0';
if (strchr(arg, ','))
@ -1038,6 +1095,77 @@ config_pipe(int ac, char **av)
pipe.queue_size = 0 ;
}
av+=2; ac-=2;
} else if (!strncmp(*av,"buckets",strlen(*av)) ) {
pipe.rq_size = strtoul(av[1], NULL, 0);
av+=2; ac-=2;
} else if (!strncmp(*av,"mask",strlen(*av)) ) {
/* per-flow queue, mask is dst_ip, dst_port,
* src_ip, src_port, proto measured in bits
*/
u_int32_t a ;
u_int32_t *par = NULL ;
pipe.flow_mask.dst_ip = 0 ;
pipe.flow_mask.src_ip = 0 ;
pipe.flow_mask.dst_port = 0 ;
pipe.flow_mask.src_port = 0 ;
pipe.flow_mask.proto = 0 ;
end = NULL ;
av++ ; ac-- ;
if (ac >= 1 && !strncmp(*av,"all", strlen(*av)) ) {
/* special case -- all bits are significant */
pipe.flow_mask.dst_ip = ~0 ;
pipe.flow_mask.src_ip = ~0 ;
pipe.flow_mask.dst_port = ~0 ;
pipe.flow_mask.src_port = ~0 ;
pipe.flow_mask.proto = ~0 ;
pipe.flags |= DN_HAVE_FLOW_MASK ;
av++ ; ac-- ;
} else {
for (;;) {
if (ac < 1)
break ;
if (!strncmp(*av,"dst-ip", strlen(*av)))
par = &(pipe.flow_mask.dst_ip) ;
else if (!strncmp(*av,"src-ip", strlen(*av)))
par = &(pipe.flow_mask.src_ip) ;
else if (!strncmp(*av,"dst-port", strlen(*av)))
(u_int16_t *)par = &(pipe.flow_mask.dst_port) ;
else if (!strncmp(*av,"src-port", strlen(*av)))
(u_int16_t *)par = &(pipe.flow_mask.src_port) ;
else if (!strncmp(*av,"proto", strlen(*av)))
(u_int8_t *)par = &(pipe.flow_mask.proto) ;
else
break ;
if (ac < 2)
show_usage("mask: %s value missing", *av);
if (*av[1] == '/') {
a = strtoul(av[1]+1, &end, 0);
if (a == 32) /* special case... */
a = ~0 ;
else
a = (1 << a) - 1 ;
fprintf(stderr, " mask is 0x%08x\n", a);
} else
a = strtoul(av[1], &end, 0);
if ( (u_int16_t *)par == &(pipe.flow_mask.src_port) ||
(u_int16_t *)par == &(pipe.flow_mask.dst_port) ) {
if (a >= (1<<16) )
show_usage("mask: %s must be 16 bit, not 0x%08x",
*av, a);
*((u_int16_t *)par) = (u_int16_t) a;
} else if ( (u_int8_t *)par == &(pipe.flow_mask.proto) ) {
if (a >= (1<<8) )
show_usage("mask: %s must be 8 bit, not 0x%08x",
*av, a);
*((u_int8_t *)par) = (u_int8_t) a;
} else
*par = a;
if (a != 0)
pipe.flags |= DN_HAVE_FLOW_MASK ;
av += 2 ; ac -= 2 ;
} /* end for */
}
} else
show_usage("unrecognised option ``%s''", *av);
}
@ -1230,9 +1358,13 @@ add(ac,av)
if (ac && (isdigit(**av) || lookup_port(*av, 1, 1) >= 0)) {
u_short nports = 0;
int retval ;
if (fill_port(&nports, rule.fw_uar.fw_pts, 0, *av))
retval = fill_port(&nports, rule.fw_uar.fw_pts, 0, *av) ;
if (retval == 1)
rule.fw_flg |= IP_FW_F_SRNG;
else if (retval == 2)
rule.fw_flg |= IP_FW_F_SMSK;
IP_FW_SETNSRCP(&rule, nports);
av++; ac--;
}
@ -1253,10 +1385,14 @@ add(ac,av)
if (ac && (isdigit(**av) || lookup_port(*av, 1, 1) >= 0)) {
u_short nports = 0;
int retval ;
if (fill_port(&nports,
rule.fw_uar.fw_pts, IP_FW_GETNSRCP(&rule), *av))
retval = fill_port(&nports,
rule.fw_uar.fw_pts, IP_FW_GETNSRCP(&rule), *av) ;
if (retval == 1)
rule.fw_flg |= IP_FW_F_DRNG;
else if (retval == 2)
rule.fw_flg |= IP_FW_F_DMSK;
IP_FW_SETNDSTP(&rule, nports);
av++; ac--;
}