📄 ipfw.c.svn-base
字号:
/*
* Copyright (c) 1996 Alex Nash, Paul Traina, Poul-Henning Kamp
* Copyright (c) 1994 Ugen J.S.Antsilevich
*
* Idea and grammar partially left from:
* Copyright (c) 1993 Daniel Boulet
*
* Redistribution and use in source forms, with and without modification,
* are permitted provided that this entire comment appears intact.
*
* Redistribution in binary form may occur without any restrictions.
* Obviously, it would be nice if you gave credit where credit is due
* but requiring it would be too onerous.
*
* This software is provided ``AS IS'' without any warranties of any kind.
*
* NEW command line interface for IP firewall facility
*
*/
#ifndef lint
static const char rcsid[] =
"$FreeBSD: src/sbin/ipfw/ipfw.c,v 1.80.2.26 2003/01/14 19:15:58 dillon Exp $";
#endif /* not lint */
#ifdef _WIN32
#include <windows.h>
#include <winsock.h>
#include <ctype.h>
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <time.h>
#include "stdint.h"
#include "win32.h"
#include "wrap.h"
#include "wipfw.h"
#undef SLIST_ENTRY
#undef TCP_NODELAY
#else /* !_WIN32 */
#include <sys/param.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/sysctl.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <grp.h>
#include <limits.h>
#include <netdb.h>
#include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <sysexits.h>
#endif /* !_WIN32 */
#ifdef _WIN32
# pragma pack(1)
#endif
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netinet/ip_fw.h>
#include <net/route.h> /* def. of struct route */
#include <netinet/ip_dummynet.h>
#include <netinet/tcp.h>
#ifndef _WIN32
#include <arpa/inet.h>
#endif
#ifdef _WIN32
# pragma pack()
#endif
int s, /* main RAW socket */
do_resolv, /* Would try to resolve all */
do_acct, /* Show packet/byte count */
do_time, /* Show time stamps */
do_quiet, /* Be quiet in add and flush */
do_force, /* Don't ask for confirmation */
#ifndef _WIN32 /* no pipe support yet */
do_pipe, /* this cmd refers to a pipe */
#endif
do_sort, /* field to sort results (0 = no) */
do_dynamic, /* display dynamic rules */
do_expired, /* display expired dynamic rules */
verbose;
struct icmpcode {
int code;
char *str;
};
static struct icmpcode icmpcodes[] = {
{ ICMP_UNREACH_NET, "net" },
{ ICMP_UNREACH_HOST, "host" },
{ ICMP_UNREACH_PROTOCOL, "protocol" },
{ ICMP_UNREACH_PORT, "port" },
{ ICMP_UNREACH_NEEDFRAG, "needfrag" },
{ ICMP_UNREACH_SRCFAIL, "srcfail" },
{ ICMP_UNREACH_NET_UNKNOWN, "net-unknown" },
{ ICMP_UNREACH_HOST_UNKNOWN, "host-unknown" },
{ ICMP_UNREACH_ISOLATED, "isolated" },
{ ICMP_UNREACH_NET_PROHIB, "net-prohib" },
{ ICMP_UNREACH_HOST_PROHIB, "host-prohib" },
{ ICMP_UNREACH_TOSNET, "tosnet" },
{ ICMP_UNREACH_TOSHOST, "toshost" },
{ ICMP_UNREACH_FILTER_PROHIB, "filter-prohib" },
{ ICMP_UNREACH_HOST_PRECEDENCE, "host-precedence" },
{ ICMP_UNREACH_PRECEDENCE_CUTOFF, "precedence-cutoff" },
{ 0, NULL }
};
static void show_usage(void);
static int
mask_bits(struct in_addr m_ad)
{
int h_fnd = 0, h_num = 0, i;
u_long mask;
mask = ntohl(m_ad.s_addr);
for (i = 0; i < sizeof(u_long)*CHAR_BIT; i++) {
if (mask & 1L) {
h_fnd = 1;
h_num++;
} else {
if (h_fnd)
return -1;
}
mask = mask >> 1;
}
return h_num;
}
static void
print_port(u_char prot, u_short port, const char comma)
{
struct servent *se = NULL;
struct protoent *pe;
if (comma == ':') {
printf("%c0x%04x", comma, port);
return;
}
if (do_resolv) {
pe = getprotobynumber(prot);
se = getservbyport(htons(port), pe ? pe->p_name : NULL);
}
if (se)
printf("%c%s", comma, se->s_name);
else
printf("%c%d", comma, port);
}
static void
print_iface(char *key, union ip_fw_if *un, int byname)
{
char ifnb[FW_IFNLEN+1];
if (byname) {
strncpy(ifnb, un->fu_via_if.name, FW_IFNLEN);
ifnb[FW_IFNLEN] = '\0';
if (un->fu_via_if.unit == -1)
printf(" %s %s*", key, ifnb);
else
printf(" %s %s%d", key, ifnb, un->fu_via_if.unit);
} else if (un->fu_via_ip.s_addr != 0) {
printf(" %s %s", key, inet_ntoa(un->fu_via_ip));
} else
printf(" %s any", key);
}
static void
print_reject_code(int code)
{
struct icmpcode *ic;
for (ic = icmpcodes; ic->str; ic++)
if (ic->code == code) {
printf("%s", ic->str);
return;
}
printf("%u", code);
}
/**
* _s_x holds a string-int pair for various lookups.
* s=NULL terminates the struct.
*/
struct _s_x { char *s; int x; };
static struct _s_x limit_masks[] = {
{"src-addr", DYN_SRC_ADDR},
{"src-port", DYN_SRC_PORT},
{"dst-addr", DYN_DST_ADDR},
{"dst-port", DYN_DST_PORT},
{NULL, 0} };
static void
show_ipfw(struct ip_fw *chain, int pcwidth, int bcwidth)
{
static int twidth = 0;
char comma;
u_long adrt;
struct hostent *he;
struct protoent *pe;
int i, mb;
int nsp = IP_FW_GETNSRCP(chain);
int ndp = IP_FW_GETNDSTP(chain);
if (do_resolv)
setservent(1/*stay open*/);
printf("%05u ", chain->fw_number);
if (do_acct)
#ifdef _WIN32
printf("%*I64u %*I64u ", pcwidth, chain->fw_pcnt, bcwidth, chain->fw_bcnt);
#else
printf("%*qu %*qu ", pcwidth, chain->fw_pcnt, bcwidth, chain->fw_bcnt);
#endif
if (do_time) {
char timestr[30];
if (twidth == 0) {
strcpy(timestr, ctime((time_t *)&twidth));
*strchr(timestr, '\n') = '\0';
twidth = strlen(timestr);
}
if (chain->timestamp) {
strcpy(timestr, ctime((time_t *)&chain->timestamp));
*strchr(timestr, '\n') = '\0';
printf("%s ", timestr);
} else {
printf("%*s ", twidth, " ");
}
}
if (chain->fw_flg == IP_FW_F_CHECK_S) {
printf("check-state\n");
goto done;
}
if (chain->fw_flg & IP_FW_F_RND_MATCH) {
double d = 1.0 * chain->dont_match_prob;
d = 1 - (d / 0x7fffffff);
printf("prob %f ", d);
}
switch (chain->fw_flg & IP_FW_F_COMMAND) {
case IP_FW_F_ACCEPT:
printf("allow");
break;
case IP_FW_F_DENY:
printf("deny");
break;
case IP_FW_F_COUNT:
printf("count");
break;
case IP_FW_F_DIVERT:
printf("divert %u", chain->fw_divert_port);
break;
case IP_FW_F_TEE:
printf("tee %u", chain->fw_divert_port);
break;
case IP_FW_F_SKIPTO:
printf("skipto %u", chain->fw_skipto_rule);
break;
case IP_FW_F_PIPE:
printf("pipe %u", chain->fw_skipto_rule);
break;
case IP_FW_F_QUEUE:
printf("queue %u", chain->fw_skipto_rule);
break;
case IP_FW_F_REJECT:
if (chain->fw_reject_code == IP_FW_REJECT_RST)
printf("reset");
else {
printf("unreach ");
print_reject_code(chain->fw_reject_code);
}
break;
case IP_FW_F_FWD:
printf("fwd %s", inet_ntoa(chain->fw_fwd_ip.sin_addr));
if(chain->fw_fwd_ip.sin_port)
printf(",%d", chain->fw_fwd_ip.sin_port);
break;
default:
errx(EX_OSERR, "impossible");
}
if (chain->fw_flg & IP_FW_F_PRN) {
printf(" log");
if (chain->fw_logamount)
printf(" logamount %d", chain->fw_logamount);
}
pe = getprotobynumber(chain->fw_prot);
if (pe)
printf(" %s", pe->p_name);
else
printf(" %u", chain->fw_prot);
printf(" from %s", chain->fw_flg & IP_FW_F_INVSRC ? "not " : "");
if (chain->fw_flg & IP_FW_F_SME) {
printf("me");
} else {
adrt = ntohl(chain->fw_smsk.s_addr);
if (adrt == ULONG_MAX && do_resolv) {
adrt = (chain->fw_src.s_addr);
he = gethostbyaddr((char *)&adrt,
sizeof(u_long), AF_INET);
if (he == NULL)
printf("%s", inet_ntoa(chain->fw_src));
else
printf("%s", he->h_name);
} else if (adrt != ULONG_MAX) {
mb = mask_bits(chain->fw_smsk);
if (mb == 0) {
printf("any");
} else if (mb > 0) {
printf("%s", inet_ntoa(chain->fw_src));
printf("/%d", mb);
} else {
printf("%s", inet_ntoa(chain->fw_src));
printf(":");
printf("%s", inet_ntoa(chain->fw_smsk));
}
} else {
printf("%s", inet_ntoa(chain->fw_src));
}
}
if (chain->fw_prot == IPPROTO_TCP || chain->fw_prot == IPPROTO_UDP) {
comma = ' ';
for (i = 0; i < nsp; i++) {
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 = ',';
}
}
printf(" to %s", chain->fw_flg & IP_FW_F_INVDST ? "not " : "");
if (chain->fw_flg & IP_FW_F_DME) {
printf("me");
} else {
adrt = ntohl(chain->fw_dmsk.s_addr);
if (adrt == ULONG_MAX && do_resolv) {
adrt = (chain->fw_dst.s_addr);
he = gethostbyaddr((char *)&adrt,
sizeof(u_long), AF_INET);
if (he == NULL)
printf("%s", inet_ntoa(chain->fw_dst));
else
printf("%s", he->h_name);
} else if (adrt != ULONG_MAX) {
mb = mask_bits(chain->fw_dmsk);
if (mb == 0) {
printf("any");
} else if (mb > 0) {
printf("%s", inet_ntoa(chain->fw_dst));
printf("/%d", mb);
} else {
printf("%s", inet_ntoa(chain->fw_dst));
printf(":");
printf("%s", inet_ntoa(chain->fw_dmsk));
}
} else {
printf("%s", inet_ntoa(chain->fw_dst));
}
}
if (chain->fw_prot == IPPROTO_TCP || chain->fw_prot == IPPROTO_UDP) {
comma = ' ';
for (i = 0; i < ndp; i++) {
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 = ',';
}
}
#ifndef _WIN32
if (chain->fw_flg & IP_FW_F_UID) {
struct passwd *pwd = getpwuid(chain->fw_uid);
if (pwd)
printf(" uid %s", pwd->pw_name);
else
printf(" uid %u", chain->fw_uid);
}
if (chain->fw_flg & IP_FW_F_GID) {
struct group *grp = getgrgid(chain->fw_gid);
if (grp)
printf(" gid %s", grp->gr_name);
else
printf(" gid %u", chain->fw_gid);
}
#endif /* !_WIN32 */
if (chain->fw_flg & IP_FW_F_KEEP_S) {
struct _s_x *p = limit_masks;
switch(chain->dyn_type) {
default:
printf(" *** unknown type ***");
break ;
case DYN_KEEP_STATE:
printf(" keep-state");
break;
case DYN_LIMIT:
printf(" limit");
for ( ; p->s != NULL ; p++)
if (chain->limit_mask & p->x)
printf(" %s", p->s);
printf(" %d", chain->conn_limit);
break ;
}
}
/* Direction */
if (chain->fw_flg & IP_FW_BRIDGED)
printf(" bridged");
if ((chain->fw_flg & IP_FW_F_IN) && !(chain->fw_flg & IP_FW_F_OUT))
printf(" in");
if (!(chain->fw_flg & IP_FW_F_IN) && (chain->fw_flg & IP_FW_F_OUT))
printf(" out");
/* Handle hack for "via" backwards compatibility */
if ((chain->fw_flg & IF_FW_F_VIAHACK) == IF_FW_F_VIAHACK) {
print_iface("via",
&chain->fw_in_if, chain->fw_flg & IP_FW_F_IIFNAME);
} else {
/* Receive interface specified */
if (chain->fw_flg & IP_FW_F_IIFACE)
print_iface("recv", &chain->fw_in_if,
chain->fw_flg & IP_FW_F_IIFNAME);
/* Transmit interface specified */
if (chain->fw_flg & IP_FW_F_OIFACE)
print_iface("xmit", &chain->fw_out_if,
chain->fw_flg & IP_FW_F_OIFNAME);
}
if (chain->fw_flg & IP_FW_F_FRAG)
printf(" frag");
if (chain->fw_ipopt || chain->fw_ipnopt) {
int _opt_printed = 0;
#define PRINTOPT(x) {if (_opt_printed) printf(",");\
printf(x); _opt_printed = 1;}
printf(" ipopt ");
if (chain->fw_ipopt & IP_FW_IPOPT_SSRR)
PRINTOPT("ssrr");
if (chain->fw_ipnopt & IP_FW_IPOPT_SSRR)
PRINTOPT("!ssrr");
if (chain->fw_ipopt & IP_FW_IPOPT_LSRR)
PRINTOPT("lsrr");
if (chain->fw_ipnopt & IP_FW_IPOPT_LSRR)
PRINTOPT("!lsrr");
if (chain->fw_ipopt & IP_FW_IPOPT_RR)
PRINTOPT("rr");
if (chain->fw_ipnopt & IP_FW_IPOPT_RR)
PRINTOPT("!rr");
if (chain->fw_ipopt & IP_FW_IPOPT_TS)
PRINTOPT("ts");
if (chain->fw_ipnopt & IP_FW_IPOPT_TS)
PRINTOPT("!ts");
}
if (chain->fw_ipflg & IP_FW_IF_TCPEST)
printf(" established");
else if (chain->fw_tcpf == IP_FW_TCPF_SYN &&
chain->fw_tcpnf == IP_FW_TCPF_ACK)
printf(" setup");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -