⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipfw.c.svn-base

📁 wipfw 是windows下的网络控制工具
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
/*
 * 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 + -