ipfw: Introduce dnctl
Introduce a link to the ipfw command, dnctl, for dummynet configuration. dnctl only handles dummynet configuration, and is part of the effort to support dummynet in pf. /sbin/ipfw continues to accept pipe, queue and sched commands, but these can now also be issued via the new dnctl command. Reviewed by: donner MFC after: 2 weeks Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D30465
This commit is contained in:
parent
aab1d593b2
commit
0b95680e07
@ -4,6 +4,10 @@
|
|||||||
|
|
||||||
PACKAGE=ipfw
|
PACKAGE=ipfw
|
||||||
PROG= ipfw
|
PROG= ipfw
|
||||||
|
|
||||||
|
LINKS= ${BINDIR}/ipfw ${BINDIR}/dnctl
|
||||||
|
MLINKS= ipfw.8 dnctl.8
|
||||||
|
|
||||||
SRCS= ipfw2.c dummynet.c ipv6.c main.c nat.c tables.c
|
SRCS= ipfw2.c dummynet.c ipv6.c main.c nat.c tables.c
|
||||||
SRCS+= nat64clat.c nat64lsn.c nat64stl.c nptv6.c
|
SRCS+= nat64clat.c nat64lsn.c nat64stl.c nptv6.c
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd June 4, 2021
|
.Dd June 14, 2021
|
||||||
.Dt IPFW 8
|
.Dt IPFW 8
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
.Nm ipfw
|
.Nm ipfw , dnctl
|
||||||
.Nd User interface for firewall, traffic shaper, packet scheduler,
|
.Nd User interface for firewall, traffic shaper, packet scheduler,
|
||||||
in-kernel NAT.
|
in-kernel NAT.
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
@ -88,12 +88,12 @@ in-kernel NAT.
|
|||||||
.Brq Ar name | all
|
.Brq Ar name | all
|
||||||
.Cm flush
|
.Cm flush
|
||||||
.Ss DUMMYNET CONFIGURATION (TRAFFIC SHAPER AND PACKET SCHEDULER)
|
.Ss DUMMYNET CONFIGURATION (TRAFFIC SHAPER AND PACKET SCHEDULER)
|
||||||
.Nm
|
.Nm dnctl
|
||||||
.Brq Cm pipe | queue | sched
|
.Brq Cm pipe | queue | sched
|
||||||
.Ar number
|
.Ar number
|
||||||
.Cm config
|
.Cm config
|
||||||
.Ar config-options
|
.Ar config-options
|
||||||
.Nm
|
.Nm dnctl
|
||||||
.Op Fl s Op Ar field
|
.Op Fl s Op Ar field
|
||||||
.Brq Cm pipe | queue | sched
|
.Brq Cm pipe | queue | sched
|
||||||
.Brq Cm delete | list | show
|
.Brq Cm delete | list | show
|
||||||
@ -440,7 +440,7 @@ them on the local hostname) and the use of macros to centralize
|
|||||||
frequently required arguments like IP addresses.
|
frequently required arguments like IP addresses.
|
||||||
.Ss TRAFFIC SHAPER CONFIGURATION
|
.Ss TRAFFIC SHAPER CONFIGURATION
|
||||||
The
|
The
|
||||||
.Nm
|
.Nm dnctl
|
||||||
.Cm pipe , queue
|
.Cm pipe , queue
|
||||||
and
|
and
|
||||||
.Cm sched
|
.Cm sched
|
||||||
@ -2650,11 +2650,11 @@ Bandwidth, measured in
|
|||||||
A value of 0 (default) means unlimited bandwidth.
|
A value of 0 (default) means unlimited bandwidth.
|
||||||
The unit must immediately follow the number, as in
|
The unit must immediately follow the number, as in
|
||||||
.Pp
|
.Pp
|
||||||
.Dl "ipfw pipe 1 config bw 300Kbit/s"
|
.Dl "dnctl pipe 1 config bw 300Kbit/s"
|
||||||
.Pp
|
.Pp
|
||||||
If a device name is specified instead of a numeric value, as in
|
If a device name is specified instead of a numeric value, as in
|
||||||
.Pp
|
.Pp
|
||||||
.Dl "ipfw pipe 1 config bw tun0"
|
.Dl "dnctl pipe 1 config bw tun0"
|
||||||
.Pp
|
.Pp
|
||||||
then the transmit clock is supplied by the specified device.
|
then the transmit clock is supplied by the specified device.
|
||||||
At the moment only the
|
At the moment only the
|
||||||
@ -2731,7 +2731,7 @@ The file format is the following, with whitespace acting as
|
|||||||
a separator and '#' indicating the beginning a comment:
|
a separator and '#' indicating the beginning a comment:
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
.It Cm name Ar identifier
|
.It Cm name Ar identifier
|
||||||
optional name (listed by "ipfw pipe show")
|
optional name (listed by "dnctl pipe show")
|
||||||
to identify the delay distribution;
|
to identify the delay distribution;
|
||||||
.It Cm bw Ar value
|
.It Cm bw Ar value
|
||||||
the bandwidth used for the pipe.
|
the bandwidth used for the pipe.
|
||||||
@ -4356,15 +4356,15 @@ A similar effect can be achieved making use of
|
|||||||
.Nm dummynet
|
.Nm dummynet
|
||||||
pipes:
|
pipes:
|
||||||
.Pp
|
.Pp
|
||||||
.Dl "ipfw add pipe 10 ip from any to any"
|
.Dl "dnctl add pipe 10 ip from any to any"
|
||||||
.Dl "ipfw pipe 10 config plr 0.05"
|
.Dl "dnctl pipe 10 config plr 0.05"
|
||||||
.Pp
|
.Pp
|
||||||
We can use pipes to artificially limit bandwidth, e.g.\& on a
|
We can use pipes to artificially limit bandwidth, e.g.\& on a
|
||||||
machine acting as a router, if we want to limit traffic from
|
machine acting as a router, if we want to limit traffic from
|
||||||
local clients on 192.168.2.0/24 we do:
|
local clients on 192.168.2.0/24 we do:
|
||||||
.Pp
|
.Pp
|
||||||
.Dl "ipfw add pipe 1 ip from 192.168.2.0/24 to any out"
|
.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"
|
.Dl "dnctl pipe 1 config bw 300Kbit/s queue 50KBytes"
|
||||||
.Pp
|
.Pp
|
||||||
note that we use the
|
note that we use the
|
||||||
.Cm out
|
.Cm out
|
||||||
@ -4378,8 +4378,8 @@ limitations, the correct way is the following:
|
|||||||
.Pp
|
.Pp
|
||||||
.Dl "ipfw add pipe 1 ip from any to any out"
|
.Dl "ipfw add pipe 1 ip from any to any out"
|
||||||
.Dl "ipfw add pipe 2 ip from any to any in"
|
.Dl "ipfw add pipe 2 ip from any to any in"
|
||||||
.Dl "ipfw pipe 1 config bw 64Kbit/s queue 10Kbytes"
|
.Dl "dnctl pipe 1 config bw 64Kbit/s queue 10Kbytes"
|
||||||
.Dl "ipfw pipe 2 config bw 64Kbit/s queue 10Kbytes"
|
.Dl "dnctl pipe 2 config bw 64Kbit/s queue 10Kbytes"
|
||||||
.Pp
|
.Pp
|
||||||
The above can be very useful, e.g.\& if you want to see how
|
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
|
your fancy Web page will look for a residential user who
|
||||||
@ -4394,7 +4394,7 @@ Should we want to verify network performance with the RED queue
|
|||||||
management algorithm:
|
management algorithm:
|
||||||
.Pp
|
.Pp
|
||||||
.Dl "ipfw add pipe 1 ip from any to any"
|
.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"
|
.Dl "dnctl pipe 1 config bw 500Kbit/s queue 100 red 0.002/30/80/0.1"
|
||||||
.Pp
|
.Pp
|
||||||
Another typical application of the traffic shaper is to
|
Another typical application of the traffic shaper is to
|
||||||
introduce some delay in the communication.
|
introduce some delay in the communication.
|
||||||
@ -4405,8 +4405,8 @@ bandwidth:
|
|||||||
.Pp
|
.Pp
|
||||||
.Dl "ipfw add pipe 1 ip from any to any out"
|
.Dl "ipfw add pipe 1 ip from any to any out"
|
||||||
.Dl "ipfw add pipe 2 ip from any to any in"
|
.Dl "ipfw add pipe 2 ip from any to any in"
|
||||||
.Dl "ipfw pipe 1 config delay 250ms bw 1Mbit/s"
|
.Dl "dnctl pipe 1 config delay 250ms bw 1Mbit/s"
|
||||||
.Dl "ipfw pipe 2 config delay 250ms bw 1Mbit/s"
|
.Dl "dnctl pipe 2 config delay 250ms bw 1Mbit/s"
|
||||||
.Pp
|
.Pp
|
||||||
Per-flow queueing can be useful for a variety of purposes.
|
Per-flow queueing can be useful for a variety of purposes.
|
||||||
A very simple one is counting traffic:
|
A very simple one is counting traffic:
|
||||||
@ -4414,7 +4414,7 @@ A very simple one is counting traffic:
|
|||||||
.Dl "ipfw add pipe 1 tcp from any to any"
|
.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 udp from any to any"
|
||||||
.Dl "ipfw add pipe 1 ip from any to any"
|
.Dl "ipfw add pipe 1 ip from any to any"
|
||||||
.Dl "ipfw pipe 1 config mask all"
|
.Dl "dnctl pipe 1 config mask all"
|
||||||
.Pp
|
.Pp
|
||||||
The above set of rules will create queues (and collect
|
The above set of rules will create queues (and collect
|
||||||
statistics) for all traffic.
|
statistics) for all traffic.
|
||||||
@ -4432,8 +4432,8 @@ on a net with per-host limits, rather than per-network limits:
|
|||||||
.Pp
|
.Pp
|
||||||
.Dl "ipfw add pipe 1 ip from 192.168.2.0/24 to any out"
|
.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 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 "dnctl 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"
|
.Dl "dnctl pipe 2 config mask dst-ip 0x000000ff bw 200Kbit/s queue 20Kbytes"
|
||||||
.Ss LOOKUP TABLES
|
.Ss LOOKUP TABLES
|
||||||
In the following example, we need to create several traffic bandwidth
|
In the following example, we need to create several traffic bandwidth
|
||||||
classes and we need different hosts/networks to fall into different classes.
|
classes and we need different hosts/networks to fall into different classes.
|
||||||
@ -4443,8 +4443,8 @@ For each subnet/host we set the argument equal to the number of the pipe
|
|||||||
that it should use.
|
that it should use.
|
||||||
Then we classify traffic using a single rule:
|
Then we classify traffic using a single rule:
|
||||||
.Pp
|
.Pp
|
||||||
.Dl "ipfw pipe 1 config bw 1000Kbyte/s"
|
.Dl "dnctl pipe 1 config bw 1000Kbyte/s"
|
||||||
.Dl "ipfw pipe 4 config bw 4000Kbyte/s"
|
.Dl "dnctl pipe 4 config bw 4000Kbyte/s"
|
||||||
.Dl "..."
|
.Dl "..."
|
||||||
.Dl "ipfw table T1 create type addr"
|
.Dl "ipfw table T1 create type addr"
|
||||||
.Dl "ipfw table T1 add 192.168.2.0/24 1"
|
.Dl "ipfw table T1 add 192.168.2.0/24 1"
|
||||||
@ -4626,7 +4626,7 @@ with
|
|||||||
AQM using default configuration for traffic from 192.168.0.0/24 and 1Mbits/s
|
AQM using default configuration for traffic from 192.168.0.0/24 and 1Mbits/s
|
||||||
rate limit, we do:
|
rate limit, we do:
|
||||||
.Pp
|
.Pp
|
||||||
.Dl "ipfw pipe 1 config bw 1mbits/s codel"
|
.Dl "dnctl pipe 1 config bw 1mbits/s codel"
|
||||||
.Dl "ipfw add 100 pipe 1 ip from 192.168.0.0/24 to any"
|
.Dl "ipfw add 100 pipe 1 ip from 192.168.0.0/24 to any"
|
||||||
.Pp
|
.Pp
|
||||||
To configure a
|
To configure a
|
||||||
@ -4636,8 +4636,8 @@ with
|
|||||||
AQM using different configurations parameters for traffic from
|
AQM using different configurations parameters for traffic from
|
||||||
192.168.0.0/24 and 1Mbits/s rate limit, we do:
|
192.168.0.0/24 and 1Mbits/s rate limit, we do:
|
||||||
.Pp
|
.Pp
|
||||||
.Dl "ipfw pipe 1 config bw 1mbits/s"
|
.Dl "dnctl pipe 1 config bw 1mbits/s"
|
||||||
.Dl "ipfw queue 1 config pipe 1 codel target 8ms interval 160ms ecn"
|
.Dl "dnctl queue 1 config pipe 1 codel target 8ms interval 160ms ecn"
|
||||||
.Dl "ipfw add 100 queue 1 ip from 192.168.0.0/24 to any"
|
.Dl "ipfw add 100 queue 1 ip from 192.168.0.0/24 to any"
|
||||||
.Pp
|
.Pp
|
||||||
To configure a
|
To configure a
|
||||||
@ -4647,7 +4647,7 @@ with
|
|||||||
AQM using default configuration for traffic from 192.168.0.0/24 and 1Mbits/s
|
AQM using default configuration for traffic from 192.168.0.0/24 and 1Mbits/s
|
||||||
rate limit, we do:
|
rate limit, we do:
|
||||||
.Pp
|
.Pp
|
||||||
.Dl "ipfw pipe 1 config bw 1mbits/s pie"
|
.Dl "dnctl pipe 1 config bw 1mbits/s pie"
|
||||||
.Dl "ipfw add 100 pipe 1 ip from 192.168.0.0/24 to any"
|
.Dl "ipfw add 100 pipe 1 ip from 192.168.0.0/24 to any"
|
||||||
.Pp
|
.Pp
|
||||||
To configure a
|
To configure a
|
||||||
@ -4657,8 +4657,8 @@ with
|
|||||||
AQM using different configuration parameters for traffic from
|
AQM using different configuration parameters for traffic from
|
||||||
192.168.0.0/24 and 1Mbits/s rate limit, we do:
|
192.168.0.0/24 and 1Mbits/s rate limit, we do:
|
||||||
.Pp
|
.Pp
|
||||||
.Dl "ipfw pipe 1 config bw 1mbits/s"
|
.Dl "dnctl pipe 1 config bw 1mbits/s"
|
||||||
.Dl "ipfw queue 1 config pipe 1 pie target 20ms tupdate 30ms ecn"
|
.Dl "dnctl queue 1 config pipe 1 pie target 20ms tupdate 30ms ecn"
|
||||||
.Dl "ipfw add 100 queue 1 ip from 192.168.0.0/24 to any"
|
.Dl "ipfw add 100 queue 1 ip from 192.168.0.0/24 to any"
|
||||||
.Pp
|
.Pp
|
||||||
.Cm fq_codel
|
.Cm fq_codel
|
||||||
@ -4673,9 +4673,9 @@ To configure
|
|||||||
scheduler using different configurations parameters for traffic from
|
scheduler using different configurations parameters for traffic from
|
||||||
192.168.0.0/24 and 1Mbits/s rate limit, we do:
|
192.168.0.0/24 and 1Mbits/s rate limit, we do:
|
||||||
.Pp
|
.Pp
|
||||||
.Dl "ipfw pipe 1 config bw 1mbits/s"
|
.Dl "dnctl pipe 1 config bw 1mbits/s"
|
||||||
.Dl "ipfw sched 1 config pipe 1 type fq_codel"
|
.Dl "dnctl sched 1 config pipe 1 type fq_codel"
|
||||||
.Dl "ipfw queue 1 config sched 1"
|
.Dl "dnctl queue 1 config sched 1"
|
||||||
.Dl "ipfw add 100 queue 1 ip from 192.168.0.0/24 to any"
|
.Dl "ipfw add 100 queue 1 ip from 192.168.0.0/24 to any"
|
||||||
.Pp
|
.Pp
|
||||||
To change
|
To change
|
||||||
@ -4686,7 +4686,7 @@ such as disable ECN and change the
|
|||||||
.Ar target
|
.Ar target
|
||||||
to 10ms, we do:
|
to 10ms, we do:
|
||||||
.Pp
|
.Pp
|
||||||
.Dl "ipfw sched 1 config pipe 1 type fq_codel target 10ms noecn"
|
.Dl "dnctl sched 1 config pipe 1 type fq_codel target 10ms noecn"
|
||||||
.Pp
|
.Pp
|
||||||
Similar to
|
Similar to
|
||||||
.Cm fq_codel ,
|
.Cm fq_codel ,
|
||||||
@ -4695,9 +4695,9 @@ to configure
|
|||||||
scheduler using different configurations parameters for traffic from
|
scheduler using different configurations parameters for traffic from
|
||||||
192.168.0.0/24 and 1Mbits/s rate limit, we do:
|
192.168.0.0/24 and 1Mbits/s rate limit, we do:
|
||||||
.Pp
|
.Pp
|
||||||
.Dl "ipfw pipe 1 config bw 1mbits/s"
|
.Dl "dnctl pipe 1 config bw 1mbits/s"
|
||||||
.Dl "ipfw sched 1 config pipe 1 type fq_pie"
|
.Dl "dnctl sched 1 config pipe 1 type fq_pie"
|
||||||
.Dl "ipfw queue 1 config sched 1"
|
.Dl "dnctl queue 1 config sched 1"
|
||||||
.Dl "ipfw add 100 queue 1 ip from 192.168.0.0/24 to any"
|
.Dl "ipfw add 100 queue 1 ip from 192.168.0.0/24 to any"
|
||||||
.Pp
|
.Pp
|
||||||
The configurations of
|
The configurations of
|
||||||
|
@ -411,6 +411,12 @@ static void object_sort_ctlv(ipfw_obj_ctlv *ctlv);
|
|||||||
static char *object_search_ctlv(ipfw_obj_ctlv *ctlv, uint16_t idx,
|
static char *object_search_ctlv(ipfw_obj_ctlv *ctlv, uint16_t idx,
|
||||||
uint16_t type);
|
uint16_t type);
|
||||||
|
|
||||||
|
int
|
||||||
|
is_ipfw(void)
|
||||||
|
{
|
||||||
|
return (g_co.prog == cmdline_prog_ipfw);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Simple string buffer API.
|
* Simple string buffer API.
|
||||||
* Used to simplify buffer passing between function and for
|
* Used to simplify buffer passing between function and for
|
||||||
|
@ -20,6 +20,11 @@
|
|||||||
* $FreeBSD$
|
* $FreeBSD$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
enum cmdline_prog {
|
||||||
|
cmdline_prog_ipfw,
|
||||||
|
cmdline_prog_dnctl
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Options that can be set on the command line.
|
* Options that can be set on the command line.
|
||||||
* When reading commands from a file, a subset of the options can also
|
* When reading commands from a file, a subset of the options can also
|
||||||
@ -54,8 +59,11 @@ struct cmdline_opts {
|
|||||||
uint32_t use_set; /* work with specified set number */
|
uint32_t use_set; /* work with specified set number */
|
||||||
/* 0 means all sets, otherwise apply to set use_set - 1 */
|
/* 0 means all sets, otherwise apply to set use_set - 1 */
|
||||||
|
|
||||||
|
enum cmdline_prog prog; /* Are we ipfw or dnctl? */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int is_ipfw(void);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
TIMESTAMP_NONE = 0,
|
TIMESTAMP_NONE = 0,
|
||||||
TIMESTAMP_STRING,
|
TIMESTAMP_STRING,
|
||||||
|
219
sbin/ipfw/main.c
219
sbin/ipfw/main.c
@ -36,7 +36,8 @@
|
|||||||
static void
|
static void
|
||||||
help(void)
|
help(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
if (is_ipfw()) {
|
||||||
|
fprintf(stderr,
|
||||||
"ipfw syntax summary (but please do read the ipfw(8) manpage):\n\n"
|
"ipfw syntax summary (but please do read the ipfw(8) manpage):\n\n"
|
||||||
"\tipfw [-abcdefhnNqStTv] <command>\n\n"
|
"\tipfw [-abcdefhnNqStTv] <command>\n\n"
|
||||||
"where <command> is one of the following:\n\n"
|
"where <command> is one of the following:\n\n"
|
||||||
@ -76,6 +77,16 @@ help(void)
|
|||||||
" setup | {tcpack|tcpseq|tcpwin} NN | tcpflags SPEC | tcpoptions SPEC |\n"
|
" setup | {tcpack|tcpseq|tcpwin} NN | tcpflags SPEC | tcpoptions SPEC |\n"
|
||||||
" tcpdatalen LIST | verrevpath | versrcreach | antispoof\n"
|
" tcpdatalen LIST | verrevpath | versrcreach | antispoof\n"
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,
|
||||||
|
"dnctl syntax summary (but please do read the dnctl(8) manpage):\n\n"
|
||||||
|
"\tdnctl [-hnsv] <command>\n\n"
|
||||||
|
"where <command> is one of the following:\n\n"
|
||||||
|
"[pipe|queue|sched] N config PIPE-BODY\n"
|
||||||
|
"[pipe|queue|sched] {delete|list|show} [N{,N}]\n"
|
||||||
|
"\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
@ -231,7 +242,8 @@ ipfw_main(int oldac, char **oldav)
|
|||||||
g_co.do_force = !isatty(STDIN_FILENO);
|
g_co.do_force = !isatty(STDIN_FILENO);
|
||||||
|
|
||||||
#ifdef EMULATE_SYSCTL /* sysctl emulation */
|
#ifdef EMULATE_SYSCTL /* sysctl emulation */
|
||||||
if ( ac >= 2 && !strcmp(av[1], "sysctl")) {
|
if (is_ipfw() && ac >= 2 &&
|
||||||
|
!strcmp(av[1], "sysctl")) {
|
||||||
char *s;
|
char *s;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -263,87 +275,115 @@ ipfw_main(int oldac, char **oldav)
|
|||||||
save_av = av;
|
save_av = av;
|
||||||
|
|
||||||
optind = optreset = 1; /* restart getopt() */
|
optind = optreset = 1; /* restart getopt() */
|
||||||
while ((ch = getopt(ac, av, "abcdDefhinNp:qs:STtv")) != -1)
|
if (is_ipfw()) {
|
||||||
switch (ch) {
|
while ((ch = getopt(ac, av, "abcdDefhinNp:qs:STtv")) != -1)
|
||||||
case 'a':
|
switch (ch) {
|
||||||
do_acct = 1;
|
case 'a':
|
||||||
break;
|
do_acct = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'b':
|
case 'b':
|
||||||
g_co.comment_only = 1;
|
g_co.comment_only = 1;
|
||||||
g_co.do_compact = 1;
|
g_co.do_compact = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'c':
|
case 'c':
|
||||||
g_co.do_compact = 1;
|
g_co.do_compact = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
g_co.do_dynamic = 1;
|
g_co.do_dynamic = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'D':
|
case 'D':
|
||||||
g_co.do_dynamic = 2;
|
g_co.do_dynamic = 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'e':
|
case 'e':
|
||||||
/* nop for compatibility */
|
/* nop for compatibility */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
g_co.do_force = 1;
|
g_co.do_force = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'h': /* help */
|
case 'h': /* help */
|
||||||
free(save_av);
|
free(save_av);
|
||||||
help();
|
help();
|
||||||
break; /* NOTREACHED */
|
break; /* NOTREACHED */
|
||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
g_co.do_value_as_ip = 1;
|
g_co.do_value_as_ip = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'n':
|
case 'n':
|
||||||
g_co.test_only = 1;
|
g_co.test_only = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'N':
|
case 'N':
|
||||||
g_co.do_resolv = 1;
|
g_co.do_resolv = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'p':
|
case 'p':
|
||||||
errx(EX_USAGE, "An absolute pathname must be used "
|
errx(EX_USAGE, "An absolute pathname must be used "
|
||||||
"with -p option.");
|
"with -p option.");
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
|
|
||||||
case 'q':
|
case 'q':
|
||||||
g_co.do_quiet = 1;
|
g_co.do_quiet = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 's': /* sort */
|
case 's': /* sort */
|
||||||
g_co.do_sort = atoi(optarg);
|
g_co.do_sort = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'S':
|
case 'S':
|
||||||
g_co.show_sets = 1;
|
g_co.show_sets = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 't':
|
case 't':
|
||||||
g_co.do_time = TIMESTAMP_STRING;
|
g_co.do_time = TIMESTAMP_STRING;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'T':
|
case 'T':
|
||||||
g_co.do_time = TIMESTAMP_NUMERIC;
|
g_co.do_time = TIMESTAMP_NUMERIC;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'v': /* verbose */
|
case 'v': /* verbose */
|
||||||
g_co.verbose = 1;
|
g_co.verbose = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
free(save_av);
|
free(save_av);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
while ((ch = getopt(ac, av, "hns:v")) != -1)
|
||||||
|
switch (ch) {
|
||||||
|
|
||||||
|
case 'h': /* help */
|
||||||
|
free(save_av);
|
||||||
|
help();
|
||||||
|
break; /* NOTREACHED */
|
||||||
|
|
||||||
|
case 'n':
|
||||||
|
g_co.test_only = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's': /* sort */
|
||||||
|
g_co.do_sort = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'v': /* verbose */
|
||||||
|
g_co.verbose = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
free(save_av);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
ac -= optind;
|
ac -= optind;
|
||||||
av += optind;
|
av += optind;
|
||||||
@ -367,7 +407,7 @@ ipfw_main(int oldac, char **oldav)
|
|||||||
g_co.do_nat = 0;
|
g_co.do_nat = 0;
|
||||||
g_co.do_pipe = 0;
|
g_co.do_pipe = 0;
|
||||||
g_co.use_set = 0;
|
g_co.use_set = 0;
|
||||||
if (!strncmp(*av, "nat", strlen(*av)))
|
if (is_ipfw() && !strncmp(*av, "nat", strlen(*av)))
|
||||||
g_co.do_nat = 1;
|
g_co.do_nat = 1;
|
||||||
else if (!strncmp(*av, "pipe", strlen(*av)))
|
else if (!strncmp(*av, "pipe", strlen(*av)))
|
||||||
g_co.do_pipe = 1;
|
g_co.do_pipe = 1;
|
||||||
@ -377,7 +417,7 @@ ipfw_main(int oldac, char **oldav)
|
|||||||
g_co.do_pipe = 2;
|
g_co.do_pipe = 2;
|
||||||
else if (_substrcmp(*av, "sched") == 0)
|
else if (_substrcmp(*av, "sched") == 0)
|
||||||
g_co.do_pipe = 3;
|
g_co.do_pipe = 3;
|
||||||
else if (!strncmp(*av, "set", strlen(*av))) {
|
else if (is_ipfw() && !strncmp(*av, "set", strlen(*av))) {
|
||||||
if (ac > 1 && isdigit(av[1][0])) {
|
if (ac > 1 && isdigit(av[1][0])) {
|
||||||
g_co.use_set = strtonum(av[1], 0, resvd_set_number,
|
g_co.use_set = strtonum(av[1], 0, resvd_set_number,
|
||||||
&errstr);
|
&errstr);
|
||||||
@ -406,8 +446,12 @@ ipfw_main(int oldac, char **oldav)
|
|||||||
av[1] = p;
|
av[1] = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! is_ipfw() && g_co.do_pipe == 0) {
|
||||||
|
help();
|
||||||
|
}
|
||||||
|
|
||||||
if (g_co.use_set == 0) {
|
if (g_co.use_set == 0) {
|
||||||
if (_substrcmp(*av, "add") == 0)
|
if (is_ipfw() && _substrcmp(*av, "add") == 0)
|
||||||
ipfw_add(av);
|
ipfw_add(av);
|
||||||
else if (g_co.do_nat && _substrcmp(*av, "show") == 0)
|
else if (g_co.do_nat && _substrcmp(*av, "show") == 0)
|
||||||
ipfw_show_nat(ac, av);
|
ipfw_show_nat(ac, av);
|
||||||
@ -415,13 +459,13 @@ ipfw_main(int oldac, char **oldav)
|
|||||||
ipfw_config_pipe(ac, av);
|
ipfw_config_pipe(ac, av);
|
||||||
else if (g_co.do_nat && _substrcmp(*av, "config") == 0)
|
else if (g_co.do_nat && _substrcmp(*av, "config") == 0)
|
||||||
ipfw_config_nat(ac, av);
|
ipfw_config_nat(ac, av);
|
||||||
else if (_substrcmp(*av, "set") == 0)
|
else if (is_ipfw() && _substrcmp(*av, "set") == 0)
|
||||||
ipfw_sets_handler(av);
|
ipfw_sets_handler(av);
|
||||||
else if (_substrcmp(*av, "table") == 0)
|
else if (is_ipfw() && _substrcmp(*av, "table") == 0)
|
||||||
ipfw_table_handler(ac, av);
|
ipfw_table_handler(ac, av);
|
||||||
else if (_substrcmp(*av, "enable") == 0)
|
else if (is_ipfw() && _substrcmp(*av, "enable") == 0)
|
||||||
ipfw_sysctl_handler(av, 1);
|
ipfw_sysctl_handler(av, 1);
|
||||||
else if (_substrcmp(*av, "disable") == 0)
|
else if (is_ipfw() && _substrcmp(*av, "disable") == 0)
|
||||||
ipfw_sysctl_handler(av, 0);
|
ipfw_sysctl_handler(av, 0);
|
||||||
else
|
else
|
||||||
try_next = 1;
|
try_next = 1;
|
||||||
@ -430,28 +474,28 @@ ipfw_main(int oldac, char **oldav)
|
|||||||
if (g_co.use_set || try_next) {
|
if (g_co.use_set || try_next) {
|
||||||
if (_substrcmp(*av, "delete") == 0)
|
if (_substrcmp(*av, "delete") == 0)
|
||||||
ipfw_delete(av);
|
ipfw_delete(av);
|
||||||
else if (!strncmp(*av, "nat64clat", strlen(*av)))
|
else if (is_ipfw() && !strncmp(*av, "nat64clat", strlen(*av)))
|
||||||
ipfw_nat64clat_handler(ac, av);
|
ipfw_nat64clat_handler(ac, av);
|
||||||
else if (!strncmp(*av, "nat64stl", strlen(*av)))
|
else if (is_ipfw() && !strncmp(*av, "nat64stl", strlen(*av)))
|
||||||
ipfw_nat64stl_handler(ac, av);
|
ipfw_nat64stl_handler(ac, av);
|
||||||
else if (!strncmp(*av, "nat64lsn", strlen(*av)))
|
else if (is_ipfw() && !strncmp(*av, "nat64lsn", strlen(*av)))
|
||||||
ipfw_nat64lsn_handler(ac, av);
|
ipfw_nat64lsn_handler(ac, av);
|
||||||
else if (!strncmp(*av, "nptv6", strlen(*av)))
|
else if (is_ipfw() && !strncmp(*av, "nptv6", strlen(*av)))
|
||||||
ipfw_nptv6_handler(ac, av);
|
ipfw_nptv6_handler(ac, av);
|
||||||
else if (_substrcmp(*av, "flush") == 0)
|
else if (_substrcmp(*av, "flush") == 0)
|
||||||
ipfw_flush(g_co.do_force);
|
ipfw_flush(g_co.do_force);
|
||||||
else if (_substrcmp(*av, "zero") == 0)
|
else if (is_ipfw() && _substrcmp(*av, "zero") == 0)
|
||||||
ipfw_zero(ac, av, 0 /* IP_FW_ZERO */);
|
ipfw_zero(ac, av, 0 /* IP_FW_ZERO */);
|
||||||
else if (_substrcmp(*av, "resetlog") == 0)
|
else if (is_ipfw() && _substrcmp(*av, "resetlog") == 0)
|
||||||
ipfw_zero(ac, av, 1 /* IP_FW_RESETLOG */);
|
ipfw_zero(ac, av, 1 /* IP_FW_RESETLOG */);
|
||||||
else if (_substrcmp(*av, "print") == 0 ||
|
else if (_substrcmp(*av, "print") == 0 ||
|
||||||
_substrcmp(*av, "list") == 0)
|
_substrcmp(*av, "list") == 0)
|
||||||
ipfw_list(ac, av, do_acct);
|
ipfw_list(ac, av, do_acct);
|
||||||
else if (_substrcmp(*av, "show") == 0)
|
else if (_substrcmp(*av, "show") == 0)
|
||||||
ipfw_list(ac, av, 1 /* show counters */);
|
ipfw_list(ac, av, 1 /* show counters */);
|
||||||
else if (_substrcmp(*av, "table") == 0)
|
else if (is_ipfw() && _substrcmp(*av, "table") == 0)
|
||||||
ipfw_table_handler(ac, av);
|
ipfw_table_handler(ac, av);
|
||||||
else if (_substrcmp(*av, "internal") == 0)
|
else if (is_ipfw() && _substrcmp(*av, "internal") == 0)
|
||||||
ipfw_internal_handler(ac, av);
|
ipfw_internal_handler(ac, av);
|
||||||
else
|
else
|
||||||
errx(EX_USAGE, "bad command `%s'", *av);
|
errx(EX_USAGE, "bad command `%s'", *av);
|
||||||
@ -620,12 +664,22 @@ main(int ac, char *av[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (strcmp(av[0], "dnctl") == 0)
|
||||||
|
g_co.prog = cmdline_prog_dnctl;
|
||||||
|
else
|
||||||
|
g_co.prog = cmdline_prog_ipfw;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the last argument is an absolute pathname, interpret it
|
* If the last argument is an absolute pathname, interpret it
|
||||||
* as a file to be preprocessed.
|
* as a file to be preprocessed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (ac > 1 && av[ac - 1][0] == '/') {
|
if (ac > 1 && av[ac - 1][0] == '/') {
|
||||||
|
if (! is_ipfw())
|
||||||
|
errx(EX_USAGE, "usage: dnctl [options]\n"
|
||||||
|
"do \"dnctl -h\" for details");
|
||||||
|
|
||||||
if (access(av[ac - 1], R_OK) == 0)
|
if (access(av[ac - 1], R_OK) == 0)
|
||||||
ipfw_readfile(ac, av);
|
ipfw_readfile(ac, av);
|
||||||
else
|
else
|
||||||
@ -633,8 +687,9 @@ main(int ac, char *av[])
|
|||||||
} else {
|
} else {
|
||||||
if (ipfw_main(ac, av)) {
|
if (ipfw_main(ac, av)) {
|
||||||
errx(EX_USAGE,
|
errx(EX_USAGE,
|
||||||
"usage: ipfw [options]\n"
|
"usage: %s [options]\n"
|
||||||
"do \"ipfw -h\" or \"man ipfw\" for details");
|
"do \"%s -h\" or \"man %s\" for details", av[0],
|
||||||
|
av[0], av[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return EX_OK;
|
return EX_OK;
|
||||||
|
Loading…
Reference in New Issue
Block a user