Changeset View
Changeset View
Standalone View
Standalone View
sbin/ipfw/main.c
Show All 30 Lines | |||||
#include <sysexits.h> | #include <sysexits.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include "ipfw2.h" | #include "ipfw2.h" | ||||
static void | static void | ||||
help(void) | help(void) | ||||
{ | { | ||||
if (is_ipfw()) { | |||||
fprintf(stderr, | 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" | ||||
"add [num] [set N] [prob x] RULE-BODY\n" | "add [num] [set N] [prob x] RULE-BODY\n" | ||||
"{pipe|queue} N config PIPE-BODY\n" | "{pipe|queue} N config PIPE-BODY\n" | ||||
"[pipe|queue] {zero|delete|show} [N{,N}]\n" | "[pipe|queue] {zero|delete|show} [N{,N}]\n" | ||||
"nat N config {ip IPADDR|if IFNAME|log|deny_in|same_ports|unreg_only|unreg_cgn|\n" | "nat N config {ip IPADDR|if IFNAME|log|deny_in|same_ports|unreg_only|unreg_cgn|\n" | ||||
" reset|reverse|proxy_only|redirect_addr linkspec|\n" | " reset|reverse|proxy_only|redirect_addr linkspec|\n" | ||||
Show All 23 Lines | |||||
" estab | frag | {gid|uid} N | icmptypes LIST | in | out | ipid LIST |\n" | " estab | frag | {gid|uid} N | icmptypes LIST | in | out | ipid LIST |\n" | ||||
" iplen LIST | ipoptions SPEC | ipprecedence | ipsec | iptos SPEC |\n" | " iplen LIST | ipoptions SPEC | ipprecedence | ipsec | iptos SPEC |\n" | ||||
" ipttl LIST | ipversion VER | keep-state | layer2 | limit ... |\n" | " ipttl LIST | ipversion VER | keep-state | layer2 | limit ... |\n" | ||||
" icmp6types LIST | ext6hdr LIST | flow-id N[,N] | fib FIB |\n" | " icmp6types LIST | ext6hdr LIST | flow-id N[,N] | fib FIB |\n" | ||||
" mac ... | mac-type LIST | proto LIST | {recv|xmit|via} {IF|IPADDR} |\n" | " mac ... | mac-type LIST | proto LIST | {recv|xmit|via} {IF|IPADDR} |\n" | ||||
" 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); | ||||
} | } | ||||
/* | /* | ||||
* Called with the arguments, including program name because getopt | * Called with the arguments, including program name because getopt | ||||
* wants it to be present. | * wants it to be present. | ||||
* Returns 0 if successful, 1 if empty command, errx() in case of errors. | * Returns 0 if successful, 1 if empty command, errx() in case of errors. | ||||
▲ Show 20 Lines • Show All 139 Lines • ▼ Show 20 Lines | #define WHITESP " \t\f\v\n\r" | ||||
av[0] = oldav[0]; | av[0] = oldav[0]; | ||||
av[ac] = NULL; | av[ac] = NULL; | ||||
/* Set the force flag for non-interactive processes */ | /* Set the force flag for non-interactive processes */ | ||||
if (!g_co.do_force) | if (!g_co.do_force) | ||||
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; | ||||
if (ac != 3) { | if (ac != 3) { | ||||
printf( "sysctl emulation usage:\n" | printf( "sysctl emulation usage:\n" | ||||
" ipfw sysctl name[=value]\n" | " ipfw sysctl name[=value]\n" | ||||
" ipfw sysctl -a\n"); | " ipfw sysctl -a\n"); | ||||
return 0; | return 0; | ||||
Show All 15 Lines | if (is_ipfw() && ac >= 2 && | ||||
return 0; | return 0; | ||||
} | } | ||||
#endif | #endif | ||||
/* Save arguments for final freeing of memory. */ | /* Save arguments for final freeing of memory. */ | ||||
save_av = av; | save_av = av; | ||||
optind = optreset = 1; /* restart getopt() */ | optind = optreset = 1; /* restart getopt() */ | ||||
if (is_ipfw()) { | |||||
while ((ch = getopt(ac, av, "abcdDefhinNp:qs:STtv")) != -1) | while ((ch = getopt(ac, av, "abcdDefhinNp:qs:STtv")) != -1) | ||||
switch (ch) { | switch (ch) { | ||||
case 'a': | case 'a': | ||||
do_acct = 1; | do_acct = 1; | ||||
break; | 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; | ||||
NEED1("bad arguments, for usage summary ``ipfw''"); | NEED1("bad arguments, for usage summary ``ipfw''"); | ||||
/* | /* | ||||
* An undocumented behaviour of ipfw1 was to allow rule numbers first, | * An undocumented behaviour of ipfw1 was to allow rule numbers first, | ||||
* e.g. "100 add allow ..." instead of "add 100 allow ...". | * e.g. "100 add allow ..." instead of "add 100 allow ...". | ||||
* In case, swap first and second argument to get the normal form. | * In case, swap first and second argument to get the normal form. | ||||
*/ | */ | ||||
if (ac > 1 && isdigit(*av[0])) { | if (ac > 1 && isdigit(*av[0])) { | ||||
char *p = av[0]; | char *p = av[0]; | ||||
av[0] = av[1]; | av[0] = av[1]; | ||||
av[1] = p; | av[1] = p; | ||||
} | } | ||||
/* | /* | ||||
* Optional: pipe, queue or nat. | * Optional: pipe, queue or nat. | ||||
*/ | */ | ||||
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; | ||||
else if (_substrcmp(*av, "queue") == 0) | else if (_substrcmp(*av, "queue") == 0) | ||||
g_co.do_pipe = 2; | g_co.do_pipe = 2; | ||||
else if (_substrcmp(*av, "flowset") == 0) | else if (_substrcmp(*av, "flowset") == 0) | ||||
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); | ||||
if (errstr) | if (errstr) | ||||
errx(EX_DATAERR, | errx(EX_DATAERR, | ||||
"invalid set number %s\n", av[1]); | "invalid set number %s\n", av[1]); | ||||
ac -= 2; av += 2; g_co.use_set++; | ac -= 2; av += 2; g_co.use_set++; | ||||
} | } | ||||
Show All 12 Lines | #endif | ||||
*/ | */ | ||||
if ((g_co.do_pipe || g_co.do_nat) && ac > 1 && isdigit(*av[0])) { | if ((g_co.do_pipe || g_co.do_nat) && ac > 1 && isdigit(*av[0])) { | ||||
char *p = av[0]; | char *p = av[0]; | ||||
av[0] = av[1]; | av[0] = av[1]; | ||||
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); | ||||
else if (g_co.do_pipe && _substrcmp(*av, "config") == 0) | else if (g_co.do_pipe && _substrcmp(*av, "config") == 0) | ||||
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; | ||||
} | } | ||||
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); | ||||
} | } | ||||
/* Free memory allocated in the argument parsing. */ | /* Free memory allocated in the argument parsing. */ | ||||
free(save_av); | free(save_av); | ||||
return 0; | return 0; | ||||
▲ Show 20 Lines • Show All 152 Lines • ▼ Show 20 Lines | #if defined(_WIN32) && defined(TCC) | ||||
if (ret != 0) { | if (ret != 0) { | ||||
/* Tell the user that we could not find a usable */ | /* Tell the user that we could not find a usable */ | ||||
/* Winsock DLL. */ | /* Winsock DLL. */ | ||||
printf("WSAStartup failed with error: %d\n", ret); | printf("WSAStartup failed with error: %d\n", ret); | ||||
return 1; | return 1; | ||||
} | } | ||||
} | } | ||||
#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 | ||||
err(EX_USAGE, "pathname: %s", av[ac - 1]); | err(EX_USAGE, "pathname: %s", av[ac - 1]); | ||||
} 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; | ||||
} | } |