📄 ipfw.c.svn-base
字号:
rule.fw_flg |= IP_FW_F_GID;
ac--; av++;
if (!ac)
errx(EX_USAGE, "``gid'' requires argument");
gid = strtoul(*av, &end, 0);
if (*end == '\0')
grp = getgrgid(gid);
else
grp = getgrnam(*av);
if (grp == NULL)
errx(EX_DATAERR, "gid \"%s\" is"
" nonexistent", *av);
rule.fw_gid = grp->gr_gid;
ac--; av++;
} else if (!strncmp(*av, "in", strlen(*av))) {
#else /* _WIN32 */
if (!strncmp(*av, "in", strlen(*av))) {
#endif /* _WIN32 */
rule.fw_flg |= IP_FW_F_IN;
av++; ac--;
} else if (!strncmp(*av,"limit",strlen(*av))) {
/* dyn. rule used to limit number of connections. */
rule.fw_flg |= IP_FW_F_KEEP_S;
rule.dyn_type = DYN_LIMIT ;
rule.limit_mask = 0 ;
av++; ac--;
for (; ac >1 ;) {
struct _s_x *p = limit_masks;
for ( ; p->s != NULL ; p++)
if (!strncmp(*av, p->s, strlen(*av))) {
rule.limit_mask |= p->x ;
av++; ac-- ;
break ;
}
if (p->s == NULL)
break ;
}
if (ac < 1)
errx(EX_USAGE,
"limit needs mask and # of connections");
rule.conn_limit = atoi(*av);
if (rule.conn_limit == 0)
errx(EX_USAGE, "limit: limit must be >0");
if (rule.limit_mask == 0)
errx(EX_USAGE, "missing limit mask");
av++; ac--;
} else if (!strncmp(*av, "keep-state", strlen(*av))) {
u_long type;
rule.fw_flg |= IP_FW_F_KEEP_S;
av++; ac--;
if (ac > 0 && (type = atoi(*av)) != 0) {
rule.dyn_type = type;
av++; ac--;
}
} else if (!strncmp(*av, "bridged", strlen(*av))) {
rule.fw_flg |= IP_FW_BRIDGED;
av++; ac--;
} else if (!strncmp(*av, "out", strlen(*av))) {
rule.fw_flg |= IP_FW_F_OUT;
av++; ac--;
} else if (ac && !strncmp(*av, "xmit", strlen(*av))) {
union ip_fw_if ifu;
int byname;
if (saw_via) {
badviacombo:
errx(EX_USAGE, "``via'' is incompatible"
" with ``xmit'' and ``recv''");
}
saw_xmrc = 1;
av++; ac--;
fill_iface("xmit", &ifu, &byname, ac, *av);
rule.fw_out_if = ifu;
rule.fw_flg |= IP_FW_F_OIFACE;
if (byname)
rule.fw_flg |= IP_FW_F_OIFNAME;
av++; ac--;
} else if (ac && !strncmp(*av, "recv", strlen(*av))) {
union ip_fw_if ifu;
int byname;
if (saw_via)
goto badviacombo;
saw_xmrc = 1;
av++; ac--;
fill_iface("recv", &ifu, &byname, ac, *av);
rule.fw_in_if = ifu;
rule.fw_flg |= IP_FW_F_IIFACE;
if (byname)
rule.fw_flg |= IP_FW_F_IIFNAME;
av++; ac--;
} else if (ac && !strncmp(*av, "via", strlen(*av))) {
union ip_fw_if ifu;
int byname = 0;
if (saw_xmrc)
goto badviacombo;
saw_via = 1;
av++; ac--;
fill_iface("via", &ifu, &byname, ac, *av);
rule.fw_out_if = rule.fw_in_if = ifu;
if (byname)
rule.fw_flg |=
(IP_FW_F_IIFNAME | IP_FW_F_OIFNAME);
av++; ac--;
} else if (!strncmp(*av, "fragment", strlen(*av))) {
rule.fw_flg |= IP_FW_F_FRAG;
av++; ac--;
} else if (!strncmp(*av, "ipoptions", strlen(*av))) {
av++; ac--;
if (!ac)
errx(EX_USAGE, "missing argument"
" for ``ipoptions''");
fill_ipopt(&rule.fw_ipopt, &rule.fw_ipnopt, av);
av++; ac--;
} else if (rule.fw_prot == IPPROTO_TCP) {
if (!strncmp(*av, "established", strlen(*av))) {
rule.fw_ipflg |= IP_FW_IF_TCPEST;
av++; ac--;
} else if (!strncmp(*av, "setup", strlen(*av))) {
rule.fw_tcpf |= IP_FW_TCPF_SYN;
rule.fw_tcpnf |= IP_FW_TCPF_ACK;
av++; ac--;
} else if (!strncmp(*av, "tcpflags", strlen(*av))
|| !strncmp(*av, "tcpflgs", strlen(*av))) {
av++; ac--;
if (!ac)
errx(EX_USAGE, "missing argument"
" for ``tcpflags''");
fill_tcpflag(&rule.fw_tcpf,
&rule.fw_tcpnf, av);
av++; ac--;
} else if (!strncmp(*av, "tcpoptions", strlen(*av))
|| !strncmp(*av, "tcpopts", strlen(*av))) {
av++; ac--;
if (!ac)
errx(EX_USAGE, "missing argument"
" for ``tcpoptions''");
fill_tcpopts(&rule.fw_tcpopt,
&rule.fw_tcpnopt, av);
av++; ac--;
} else {
errx(EX_USAGE, "unknown or out of order"
" argument ``%s''", *av);
}
} else if (rule.fw_prot == IPPROTO_ICMP) {
if (!strncmp(*av, "icmptypes", strlen(*av))) {
av++; ac--;
if (!ac)
errx(EX_USAGE, "missing argument"
" for ``icmptypes''");
fill_icmptypes(rule.fw_uar.fw_icmptypes,
av, &rule.fw_flg);
av++; ac--;
} else {
errx(EX_USAGE, "unknown or out of order"
" argument ``%s''", *av);
}
} else {
errx(EX_USAGE, "unknown argument ``%s''", *av);
}
}
/* No direction specified -> do both directions */
if (!(rule.fw_flg & (IP_FW_F_OUT|IP_FW_F_IN)))
rule.fw_flg |= (IP_FW_F_OUT|IP_FW_F_IN);
/* Sanity check interface check, but handle "via" case separately */
if (saw_via) {
if (rule.fw_flg & IP_FW_F_IN)
rule.fw_flg |= IP_FW_F_IIFACE;
if (rule.fw_flg & IP_FW_F_OUT)
rule.fw_flg |= IP_FW_F_OIFACE;
} else if ((rule.fw_flg & IP_FW_F_OIFACE)
&& (rule.fw_flg & IP_FW_F_IN)) {
errx(EX_DATAERR, "can't check xmit interface of incoming"
" packets");
}
/* frag may not be used in conjunction with ports or TCP flags */
if (rule.fw_flg & IP_FW_F_FRAG) {
if (rule.fw_tcpf || rule.fw_tcpnf)
errx(EX_DATAERR, "can't mix 'frag' and tcpflags");
if (rule.fw_nports)
errx(EX_DATAERR, "can't mix 'frag' and port"
" specifications");
}
if (rule.fw_flg & IP_FW_F_PRN) {
if (!rule.fw_logamount) {
size_t len = sizeof(int);
#ifndef _WIN32
if (sysctlbyname("net.inet.ip.fw.verbose_limit",
&rule.fw_logamount, &len, NULL, 0) == -1)
errx(1, "sysctlbyname(\"%s\")",
"net.inet.ip.fw.verbose_limit");
#endif /* !_WIN32 */
} else if (rule.fw_logamount == -1)
rule.fw_logamount = 0;
rule.fw_loghighest = rule.fw_logamount;
}
done:
i = sizeof(rule);
if (getsockopt(s, IPPROTO_IP, IP_FW_ADD, &rule, &i) == -1)
err(EX_UNAVAILABLE, "getsockopt(%s)", "IP_FW_ADD");
if (!do_quiet)
show_ipfw(&rule, 10, 10);
}
static void
zero (int ac, char *av[])
{
struct ip_fw rule;
int failed = EX_OK;
av++; ac--;
if (!ac) {
/* clear all entries */
if (setsockopt(s, IPPROTO_IP, IP_FW_ZERO, NULL, 0) < 0)
err(EX_UNAVAILABLE, "setsockopt(%s)", "IP_FW_ZERO");
if (!do_quiet)
printf("Accounting cleared.\n");
return;
}
memset(&rule, 0, sizeof rule);
while (ac) {
/* Rule number */
if (isdigit(**av)) {
rule.fw_number = atoi(*av); av++; ac--;
if (setsockopt(s, IPPROTO_IP,
IP_FW_ZERO, &rule, sizeof rule)) {
warn("rule %u: setsockopt(IP_FW_ZERO)",
rule.fw_number);
failed = EX_UNAVAILABLE;
} else if (!do_quiet)
printf("Entry %d cleared\n",
rule.fw_number);
} else {
errx(EX_USAGE, "invalid rule number ``%s''", *av);
}
}
if (failed != EX_OK)
exit(failed);
}
static void
resetlog (int ac, char *av[])
{
struct ip_fw rule;
int failed = EX_OK;
av++; ac--;
if (!ac) {
/* clear all entries */
if (setsockopt(s, IPPROTO_IP, IP_FW_RESETLOG, NULL, 0) < 0)
err(EX_UNAVAILABLE, "setsockopt(IP_FW_RESETLOG)");
if (!do_quiet)
printf("Logging counts reset.\n");
return;
}
memset(&rule, 0, sizeof rule);
while (ac) {
/* Rule number */
if (isdigit(**av)) {
rule.fw_number = atoi(*av); av++; ac--;
if (setsockopt(s, IPPROTO_IP,
IP_FW_RESETLOG, &rule, sizeof rule)) {
warn("rule %u: setsockopt(IP_FW_RESETLOG)",
rule.fw_number);
failed = EX_UNAVAILABLE;
} else if (!do_quiet)
printf("Entry %d logging count reset\n",
rule.fw_number);
} else {
errx(EX_DATAERR, "invalid rule number ``%s''", *av);
}
}
if (failed != EX_OK)
exit(failed);
}
static int
ipfw_main(int ac, char **av)
{
int ch;
if (ac == 1)
show_usage();
/* Initialize globals. */
#ifndef _WIN32
do_resolv = do_acct = do_time = do_quiet =
do_pipe = do_sort = verbose = 0;
#else
do_resolv = do_acct = do_time = do_quiet = do_sort = verbose = 0;
#endif
/* Set the force flag for non-interactive processes */
do_force = !isatty(STDIN_FILENO);
optind = optreset = 1;
while ((ch = getopt(ac, av, "s:adefNqtv")) != -1)
switch (ch) {
case 's': /* sort */
do_sort = atoi(optarg);
break;
case 'a':
do_acct = 1;
break;
case 'd':
do_dynamic = 1;
break;
case 'e':
do_expired = 1;
break;
case 'f':
do_force = 1;
break;
case 'N':
do_resolv = 1;
break;
case 'q':
do_quiet = 1;
break;
case 't':
do_time = 1;
break;
case 'v': /* verbose */
verbose++;
break;
default:
show_usage();
}
ac -= optind;
if (*(av += optind) == NULL)
errx(EX_USAGE, "bad arguments, for usage summary ``ipfw''");
#ifndef _WIN32
if (!strncmp(*av, "pipe", strlen(*av))) {
do_pipe = 1;
ac--;
av++;
} else if (!strncmp(*av, "queue", strlen(*av))) {
do_pipe = 2;
ac--;
av++;
}
#endif
if (!ac)
errx(EX_USAGE, "pipe requires arguments");
/* allow argument swapping */
if (ac > 1 && *av[0] >= '0' && *av[0] <= '9') {
char *p = av[0];
av[0] = av[1];
av[1] = p;
}
if (!strncmp(*av, "add", strlen(*av))) {
add(ac, av);
#ifndef _WIN32
} else if (do_pipe && !strncmp(*av, "config", strlen(*av))) {
config_pipe(ac, av);
#endif
} else if (!strncmp(*av, "delete", strlen(*av))) {
delete(ac, av);
} else if (!strncmp(*av, "flush", strlen(*av))) {
int do_flush = 0;
if (do_force || do_quiet)
do_flush = 1;
else {
int c;
/* Ask the user */
printf("Are you sure? [yn] ");
fflush(stdout);
do {
c = toupper(getc(stdin));
while (c != '\n' && getc(stdin) != '\n')
if (feof(stdin))
return (0);
} while (c != 'Y' && c != 'N');
printf("\n");
if (c == 'Y')
do_flush = 1;
}
if (do_flush) {
#ifndef _WIN32
if (setsockopt(s, IPPROTO_IP,
do_pipe ? IP_DUMMYNET_FLUSH : IP_FW_FLUSH,
NULL, 0) < 0)
err(EX_UNAVAILABLE, "setsockopt(IP_%s_FLUSH)",
do_pipe ? "DUMMYNET" : "FW");
if (!do_quiet)
printf("Flushed all %s.\n",
do_pipe ? "pipes" : "rules");
#else /* _WIN32 */
if (setsockopt(s, IPPROTO_IP, IP_FW_FLUSH, NULL, 0) < 0)
err(EX_UNAVAILABLE, "setsockopt(IP_FW_FLUSH)");
if (!do_quiet)
printf("Flushed all rules.\n");
#endif /* _WIN32 */
}
} else if (!strncmp(*av, "zero", strlen(*av))) {
zero(ac, av);
} else if (!strncmp(*av, "resetlog", strlen(*av))) {
resetlog(ac, av);
} else if (!strncmp(*av, "print", strlen(*av))) {
list(--ac, ++av);
#ifndef _WIN32
} else if (!strncmp(*av, "enable", strlen(*av))) {
sysctl_handler(ac, av, 1);
} else if (!strncmp(*av, "disable", strlen(*av))) {
sysctl_handler(ac, av, 0);
#else
} else if (!strncmp(*av, "sysctl", strlen(*av))) {
sysctl_handler(++ac, --av, do_quiet);
#endif /* !_WIN32 */
} else if (!strncmp(*av, "list", strlen(*av))) {
list(--ac, ++av);
} else if (!strncmp(*av, "show", strlen(*av))) {
do_acct++;
list(--ac, ++av);
} else {
errx(EX_USAGE, "bad arguments, for usage summary ``ipfw''");
}
return 0;
}
int
main(int ac, char *av[])
{
#define MAX_ARGS 32
#define WHITESP " \t\f\v\n\r"
char buf[BUFSIZ];
char *a, *p, *args[MAX_ARGS], *cmd = NULL;
char linename[10];
int i, c, lineno, qflag, pflag, status;
FILE *f = NULL;
pid_t preproc = 0;
#ifndef _WIN32
s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if (s < 0)
err(EX_UNAVAILABLE, "socket");
setbuf(stdout, 0);
/*
* Only interpret the last command line argument as a file to
* be preprocessed if it is specified as an absolute pathname.
*/
if (ac > 1 && av[ac - 1][0] == '/' && access(av[ac - 1], R_OK) == 0) {
#else
setbuf(stdout, 0);
if ((ac > 1 && av[ac - 1][0] == '\\' && access(av[ac - 1], R_OK) == 0) ||
(ac > 1 && strstr(av[ac - 1],":\\") && access(av[ac - 1], R_OK) == 0 )) {
#endif
qflag = pflag = i = 0;
lineno = 0;
while ((c = getopt(ac, av, "D:U:p:q")) != -1)
switch(c) {
case 'D':
if (!pflag)
errx(EX_USAGE, "-D requires -p");
if (i > MAX_ARGS - 2)
errx(EX_USAGE,
"too many -D or -U options");
args[i++] = "-D";
args[i++] = optarg;
break;
case 'U':
if (!pflag)
errx(EX_USAGE, "-U requires -p");
if (i > MAX_ARGS - 2)
errx(EX_USAGE,
"too many -D or -U options");
args[i++] = "-U";
args[i++] = optarg;
break;
case 'p':
pflag = 1;
cmd = optarg;
args[0] = cmd;
i = 1;
break;
case 'q':
qflag = 1;
break;
def
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -