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

📄 ipfw.c.svn-base

📁 wipfw 是windows下的网络控制工具
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
	else if (chain->fw_tcpf || chain->fw_tcpnf) {
		int	_flg_printed = 0;
#define PRINTFLG(x)	{if (_flg_printed) printf(",");\
			printf(x); _flg_printed = 1;}

		printf(" tcpflags ");
		if (chain->fw_tcpf & IP_FW_TCPF_FIN)
			PRINTFLG("fin");
		if (chain->fw_tcpnf & IP_FW_TCPF_FIN)
			PRINTFLG("!fin");
		if (chain->fw_tcpf & IP_FW_TCPF_SYN)
			PRINTFLG("syn");
		if (chain->fw_tcpnf & IP_FW_TCPF_SYN)
			PRINTFLG("!syn");
		if (chain->fw_tcpf & IP_FW_TCPF_RST)
			PRINTFLG("rst");
		if (chain->fw_tcpnf & IP_FW_TCPF_RST)
			PRINTFLG("!rst");
		if (chain->fw_tcpf & IP_FW_TCPF_PSH)
			PRINTFLG("psh");
		if (chain->fw_tcpnf & IP_FW_TCPF_PSH)
			PRINTFLG("!psh");
		if (chain->fw_tcpf & IP_FW_TCPF_ACK)
			PRINTFLG("ack");
		if (chain->fw_tcpnf & IP_FW_TCPF_ACK)
			PRINTFLG("!ack");
		if (chain->fw_tcpf  & IP_FW_TCPF_URG)
			PRINTFLG("urg");
		if (chain->fw_tcpnf & IP_FW_TCPF_URG)
			PRINTFLG("!urg");
	}
	if (chain->fw_tcpopt || chain->fw_tcpnopt) {
		int	_opt_printed = 0;
#define PRINTTOPT(x)	{if (_opt_printed) printf(",");\
			printf(x); _opt_printed = 1;}

		printf(" tcpoptions ");
		if (chain->fw_tcpopt & IP_FW_TCPOPT_MSS)
			PRINTTOPT("mss");
		if (chain->fw_tcpnopt & IP_FW_TCPOPT_MSS)
			PRINTTOPT("!mss");
		if (chain->fw_tcpopt & IP_FW_TCPOPT_WINDOW)
			PRINTTOPT("window");
		if (chain->fw_tcpnopt & IP_FW_TCPOPT_WINDOW)
			PRINTTOPT("!window");
		if (chain->fw_tcpopt & IP_FW_TCPOPT_SACK)
			PRINTTOPT("sack");
		if (chain->fw_tcpnopt & IP_FW_TCPOPT_SACK)
			PRINTTOPT("!sack");
		if (chain->fw_tcpopt & IP_FW_TCPOPT_TS)
			PRINTTOPT("ts");
		if (chain->fw_tcpnopt & IP_FW_TCPOPT_TS)
			PRINTTOPT("!ts");
		if (chain->fw_tcpopt & IP_FW_TCPOPT_CC)
			PRINTTOPT("cc");
		if (chain->fw_tcpnopt & IP_FW_TCPOPT_CC)
			PRINTTOPT("!cc");
	}

	if (chain->fw_flg & IP_FW_F_ICMPBIT) {
		int type_index;
		int first = 1;

		printf(" icmptype");

		for (type_index = 0; type_index < IP_FW_ICMPTYPES_DIM * sizeof(unsigned) * 8; ++type_index)
			if (chain->fw_uar.fw_icmptypes[type_index / (sizeof(unsigned) * 8)] &
				(1U << (type_index % (sizeof(unsigned) * 8)))) {
				printf("%c%d", first == 1 ? ' ' : ',', type_index);
				first = 0;
			}
	}
	printf("\n");
done:
	if (do_resolv)
		endservent();
}

#ifndef _WIN32      /* no queues support yet! */

int
sort_q(const void *pa, const void *pb)
{
	int rev = (do_sort < 0);
	int field = rev ? -do_sort : do_sort;
	long long res = 0;
	const struct dn_flow_queue *a = pa;
	const struct dn_flow_queue *b = pb;

	switch (field) {
	case 1: /* pkts */
		res = a->len - b->len;
		break;
	case 2: /* bytes */
		res = a->len_bytes - b->len_bytes;
		break;

	case 3: /* tot pkts */
		res = a->tot_pkts - b->tot_pkts;
		break;

	case 4: /* tot bytes */
		res = a->tot_bytes - b->tot_bytes;
		break;
	}
	if (res < 0)
		res = -1;
	if (res > 0)
		res = 1;
	return (int)(rev ? res : -res);
}

static void
list_queues(struct dn_flow_set *fs, struct dn_flow_queue *q)
{
	int l;

	printf("    mask: 0x%02x 0x%08x/0x%04x -> 0x%08x/0x%04x\n",
	    fs->flow_mask.proto,
	    fs->flow_mask.src_ip, fs->flow_mask.src_port,
	    fs->flow_mask.dst_ip, fs->flow_mask.dst_port);
	if (fs->rq_elements == 0)
		return;

	printf("BKT Prot ___Source IP/port____ "
	    "____Dest. IP/port____ Tot_pkt/bytes Pkt/Byte Drp\n");
	if (do_sort != 0)
		heapsort(q, fs->rq_elements, sizeof *q, sort_q);
	for (l = 0; l < fs->rq_elements; l++) {
		struct in_addr ina;
		struct protoent *pe;

		ina.s_addr = htonl(q[l].id.src_ip);
		printf("%3d ", q[l].hash_slot);
		pe = getprotobynumber(q[l].id.proto);
		if (pe)
			printf("%-4s ", pe->p_name);
		else
			printf("%4u ", q[l].id.proto);
		printf("%15s/%-5d ",
		    inet_ntoa(ina), q[l].id.src_port);
		ina.s_addr = htonl(q[l].id.dst_ip);
		printf("%15s/%-5d ",
		    inet_ntoa(ina), q[l].id.dst_port);
		printf("%4qu %8qu %2u %4u %3u\n",
		    q[l].tot_pkts, q[l].tot_bytes,
		    q[l].len, q[l].len_bytes, q[l].drops);
		if (verbose)
			printf("   S %20qd  F %20qd\n",
			    q[l].S, q[l].F);
	}
}

static void
print_flowset_parms(struct dn_flow_set *fs, char *prefix)
{
	int l;
	char qs[30];
	char plr[30];
	char red[90];	/* Display RED parameters */

	l = fs->qsize;
	if (fs->flags_fs & DN_QSIZE_IS_BYTES) {
		if (l >= 8192)
			sprintf(qs, "%d KB", l / 1024);
		else
			sprintf(qs, "%d B", l);
	} else
		sprintf(qs, "%3d sl.", l);
	if (fs->plr)
		sprintf(plr, "plr %f", 1.0 * fs->plr / (double)(0x7fffffff));
	else
		plr[0] = '\0';
	if (fs->flags_fs & DN_IS_RED)	/* RED parameters */
		sprintf(red,
		    "\n\t  %cRED w_q %f min_th %d max_th %d max_p %f",
		    (fs->flags_fs & DN_IS_GENTLE_RED) ? 'G' : ' ',
		    1.0 * fs->w_q / (double)(1 << SCALE_RED),
		    SCALE_VAL(fs->min_th),
		    SCALE_VAL(fs->max_th),
		    1.0 * fs->max_p / (double)(1 << SCALE_RED));
	else
		sprintf(red, "droptail");

	printf("%s %s%s %d queues (%d buckets) %s\n",
	    prefix, qs, plr, fs->rq_elements, fs->rq_size, red);
}

static void
sysctl_handler(int ac, char *av[], int which)
{
	ac--;
	av++;

	if (*av == NULL) {
		warnx("missing keyword to enable/disable\n");
	} else if (strncmp(*av, "firewall", strlen(*av)) == 0) {
		sysctlbyname("net.inet.ip.fw.enable", NULL, 0,
		    &which, sizeof(which));
	} else if (strncmp(*av, "one_pass", strlen(*av)) == 0) {
		sysctlbyname("net.inet.ip.fw.one_pass", NULL, 0,
		    &which, sizeof(which));
	} else if (strncmp(*av, "debug", strlen(*av)) == 0) {
		sysctlbyname("net.inet.ip.fw.debug", NULL, 0,
		    &which, sizeof(which));
	} else if (strncmp(*av, "verbose", strlen(*av)) == 0) {
		sysctlbyname("net.inet.ip.fw.verbose", NULL, 0,
		    &which, sizeof(which));
	} else {
		warnx("unrecognize enable/disable keyword: %s\n", *av);
	}
}

#endif  /* !_WIN32 */

static void
list(int ac, char *av[])
{
	struct ip_fw *rules;
	struct dn_pipe *pipes;
	void *data = NULL;
	int pcwidth = 0;
	int bcwidth = 0;
	int n, num = 0;
	int nbytes;

#ifndef _WIN32
	/* get rules or pipes from kernel, resizing array as necessary */
	{
		const int unit = do_pipe ? sizeof(*pipes) : sizeof(*rules);
		const int ocmd = do_pipe ? IP_DUMMYNET_GET : IP_FW_GET;
		int nalloc = unit;
		nbytes = nalloc;

		while (nbytes >= nalloc) {
			nalloc = nalloc * 2 + 200;
			nbytes = nalloc;
			if ((data = realloc(data, nbytes)) == NULL)
				err(EX_OSERR, "realloc");
			if (getsockopt(s, IPPROTO_IP, ocmd, data, &nbytes) < 0)
				err(EX_OSERR, "getsockopt(IP_%s_GET)",
				    do_pipe ? "DUMMYNET" : "FW");
		}
	}
#else   /* !_WIN32         the same code but without pipe support */
	{
		const int unit = sizeof(*rules);
		const int ocmd = IP_FW_GET;
		int nalloc = unit;
		nbytes = nalloc;

		while (nbytes >= nalloc) {
			nalloc = nalloc * 2 + 200;
			nbytes = nalloc;
			if ((data = realloc(data, nbytes)) == NULL)
				err(EX_OSERR, "realloc");
			if (getsockopt(s, IPPROTO_IP, ocmd, data, &nbytes) < 0)
				err(EX_OSERR, "getsockopt(IP_%s_GET)",
				    "FW");
		}
	}
#endif  /* _WIN32 */

#ifndef _WIN32
	/* display requested pipes */
	if (do_pipe) {
		u_long rulenum;
		void *next = data;
		struct dn_pipe *p = (struct dn_pipe *) data;
		struct dn_flow_set *fs;
		struct dn_flow_queue *q;
		int l;

		if (ac > 0)
			rulenum = strtoul(*av++, NULL, 10);
		else
			rulenum = 0;
		for (; nbytes >= sizeof *p; p = (struct dn_pipe *)next) {
			double b = p->bandwidth;
			char buf[30];
			char prefix[80];

			if (p->next != (struct dn_pipe *)DN_IS_PIPE)
				break;
			l = sizeof(*p) + p->fs.rq_elements * sizeof(*q);
			next = (void *)p + l;
			nbytes -= l;
			q = (struct dn_flow_queue *)(p+1);

			if (rulenum != 0 && rulenum != p->pipe_nr)
				continue;
			if (p->if_name[0] != '\0')
				sprintf(buf, "%s", p->if_name);
			else if (b == 0)
				sprintf(buf, "unlimited");
			else if (b >= 1000000)
				sprintf(buf, "%7.3f Mbit/s", b/1000000);
			else if (b >= 1000)
				sprintf(buf, "%7.3f Kbit/s", b/1000);
			else
				sprintf(buf, "%7.3f bit/s ", b);

			sprintf(prefix, "%05d: %s %4d ms ",
			    p->pipe_nr, buf, p->delay);
			print_flowset_parms(&(p->fs), prefix);
			if (verbose)
				printf("   V %20qd\n", p->V >> MY_M);
			list_queues(&(p->fs), q);
		}
		fs = (struct dn_flow_set *) next;
		for (; nbytes >= sizeof *fs; fs = (struct dn_flow_set *)next) {
			char prefix[80];

			if (fs->next != (struct dn_flow_set *)DN_IS_QUEUE)
				break;
			l = sizeof(*fs) + fs->rq_elements * sizeof(*q);
			next = (void *)fs + l;
			nbytes -= l;
			q = (struct dn_flow_queue *)(fs+1);
			sprintf(prefix, "q%05d: weight %d pipe %d ",
			    fs->fs_nr, fs->weight, fs->parent_nr);
			print_flowset_parms(fs, prefix);
			list_queues(fs, q);
		}
		free(data);
		return;
	}
#endif  /* !_WIN32 */

	rules = (struct ip_fw *)data;
	/* determine num more accurately */
	num = 0;
	while (rules[num].fw_number < 65535)
		num++;
	num++; /* counting starts from 0 ... */
	/* if showing stats, figure out column widths ahead of time */
	if (do_acct) {
		for (n = 0; n < num; n++) {
			struct ip_fw *const r = &rules[n];
			char temp[32];
			int width;

			/* packet counter */
#ifndef _WIN32
			width = sprintf(temp, "%qu", r->fw_pcnt);
#else
			width = sprintf(temp, "%I64u", r->fw_pcnt);
#endif
			if (width > pcwidth)
				pcwidth = width;

			/* byte counter */
#ifndef _WIN32
			width = sprintf(temp, "%qu", r->fw_bcnt);
#else
			width = sprintf(temp, "%I64u", r->fw_bcnt);
#endif
			if (width > bcwidth)
				bcwidth = width;
		}
	}
	if (ac == 0) {
		/* display all rules */
		for (n = 0; n < num; n++) {
			struct ip_fw *const r = &rules[n];

			show_ipfw(r, pcwidth, bcwidth);
		}
	} else {
		/* display specific rules requested on command line */
		int exitval = EX_OK;

		while (ac--) {
			u_long rnum;
			char *endptr;
			int seen;

			/* convert command line rule # */
			rnum = strtoul(*av++, &endptr, 10);
			if (*endptr) {
				exitval = EX_USAGE;
				warnx("invalid rule number: %s", *(av - 1));
				continue;
			}
			do_dynamic = 0;
			for (seen = n = 0; n < num; n++) {
				struct ip_fw *const r = &rules[n];

				if (r->fw_number > rnum)
					break;
				if (r->fw_number == rnum) {
					show_ipfw(r, pcwidth, bcwidth);
					seen = 1;
				}
			}
			if (!seen) {
				/* give precedence to other error(s) */
				if (exitval == EX_OK)
					exitval = EX_UNAVAILABLE;
				warnx("rule %lu does not exist", rnum);
			}
		}
		if (exitval != EX_OK)
			exit(exitval);
	}
	/*
	 * show dynamic rules
	*/
	if (do_dynamic && num * sizeof (rules[0]) != nbytes) {
		struct ipfw_dyn_rule *d =
		    (struct ipfw_dyn_rule *)&rules[num];
		struct in_addr a;
		struct protoent *pe;

            printf("## Dynamic rules:\n");
            for (;; d++) {
		if (d->expire == 0 && !do_expired) {
			if (d->next == NULL)
				break;
			continue;
		}

#ifndef _WIN32
                printf("%05d %qu %qu (T %d, slot %d)",
#else
                printf("%05d %I64u %I64u (T %d, slot %d)",
#endif
                    (u_short)(d->rule),
                    d->pcnt, d->bcnt,
                    d->expire,
                    d->bucket);
		switch (d->dyn_type) {
		case DYN_LIMIT_PARENT:
			printf(" PARENT %d", d->count);
			break;
		case DYN_LIMIT:
			printf(" LIMIT");
			break;
		case DYN_KEEP_STATE: /* bidir, no mask */
			printf(" <->");
			break;
		}

		pe = getprotobynumber(d->id.proto);
		if (pe)
			printf(" %s,", pe->p_name);
		else
			printf(" %u,", d->id.proto);
                a.s_addr = htonl(d->id.src_ip);
                printf(" %s %d", inet_ntoa(a), d->id.src_port);
                a.s_addr = htonl(d->id.dst_ip);
                printf("<-> %s %d", inet_ntoa(a), d->id.dst_port);
                printf("\n");
                if (d->next == NULL)
                    break;
            }
        }

	free(data);
}

static void
show_usage(void)
{
	fprintf(stderr, "usage: ipfw [options]\n"
"    [pipe] flush\n"
"    add [number] rule\n"
"    [pipe] delete number ...\n"
"    [pipe] list [number ...]\n"
"    [pipe] show [number ...]\n"
"    zero [number ...]\n"
"    resetlog [number ...]\n"
#ifndef _WIN32
"    pipe number config [pipeconfig]\n"
#endif
"  rule: [prob <match_probability>] action proto src dst extras...\n"
"    action:\n"
"      {allow|permit|accept|pass|deny|drop|reject|unreach code|\n"
"	reset|count|skipto num|divert port|tee port|fwd ip|\n"
"	pipe num} [log [logamount count]]\n"
"    proto: {ip|tcp|udp|icmp|<number>}\n"
"    src: from [not] {me|any|ip[{/bits|:mask}]} [{port[-port]}, [port], ...]\n"
"    dst: to [not] {me|any|ip[{/bits|:mask}]} [{port[-port]}, [port], ...]\n"
"  extras:\n"
#ifndef _WIN32
"    uid {user id}\n"
"    gid {group id}\n"
#endif
"    fragment	  (may not be used with ports or tcpflags)\n"
"    in\n"
"    out\n"
"    {xmit|recv|via} {iface|ip|any}\n"
"    {established|setup}\n"
"    tcpflags [!]{syn|fin|rst|ack|psh|urg}, ...\n"
"    ipoptions [!]{ssrr|lsrr|rr|ts}, ...\n"
"    tcpoptions [!]{mss|window|sack|ts|cc}, ...\n"
"    icmptypes {type[, type]}...\n"
"    keep-state [method]\n"
#ifndef _WIN32
"  pipeconfig:\n"
"    {bw|bandwidth} <number>{bit/s|Kbit/s|Mbit/s|Bytes/s|KBytes/s|MBytes/s}\n"
"    {bw|bandwidth} interface_name\n"
"    delay <milliseconds>\n"
"    queue <size>{packets|Bytes|KBytes}\n"
"    plr <fraction>\n"
"    mask {all| [dst-ip|src-ip|dst-port|src-port|proto] <number>}\n"
"    buckets <number>}\n"
"    {red|gred} <fraction>/<number>/<number>/<fraction>\n"
"    droptail\n"

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -