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

📄 ipfw.c.svn-base

📁 wipfw 是windows下的网络控制工具
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
#endif
);

	exit(EX_USAGE);
}

static int
lookup_host (char *host, struct in_addr *ipaddr)
{
	struct hostent *he;

	if (!inet_aton(host, ipaddr)) {
		if ((he = gethostbyname(host)) == NULL)
			return(-1);
		*ipaddr = *(struct in_addr *)he->h_addr_list[0];
	}
	return(0);
}

static void
fill_ip(struct in_addr *ipno, struct in_addr *mask, int *acp, char ***avp)
{
	int ac = *acp;
	char **av = *avp;
	char *p = 0, md = 0;

	if (ac && !strncmp(*av, "any", strlen(*av))) {
		ipno->s_addr = mask->s_addr = 0; av++; ac--;
	} else {
		p = strchr(*av, '/');
		if (!p)
			p = strchr(*av, ':');
		if (p) {
			md = *p;
			*p++ = '\0';
		}

		if (lookup_host(*av, ipno) != 0)
			errx(EX_NOHOST, "hostname ``%s'' unknown", *av);
		switch (md) {
			case ':':
				if (!inet_aton(p, mask))
					errx(EX_DATAERR, "bad netmask ``%s''", p);
				break;
			case '/':
				if (atoi(p) == 0) {
					mask->s_addr = 0;
				} else if (atoi(p) > 32) {
					errx(EX_DATAERR, "bad width ``%s''", p);
				} else {
					mask->s_addr =
					    htonl(~0 << (32 - atoi(p)));
				}
				break;
			default:
				mask->s_addr = htonl(~0);
				break;
		}
		ipno->s_addr &= mask->s_addr;
		av++;
		ac--;
	}
	*acp = ac;
	*avp = av;
}

static void
fill_reject_code(u_short *codep, char *str)
{
	struct icmpcode *ic;
	u_long val;
	char *s;

	if (str == '\0')
		errx(EX_DATAERR, "missing unreachable code");
	val = strtoul(str, &s, 0);
	if (s != str && *s == '\0' && val < 0x100) {
		*codep = val;
		return;
	}
	for (ic = icmpcodes; ic->str; ic++)
		if (!strcasecmp(str, ic->str)) {
			*codep = ic->code;
			return;
		}
	errx(EX_DATAERR, "unknown ICMP unreachable code ``%s''", str);
}

static void
add_port(u_short *cnt, u_short *ptr, u_short off, u_short port)
{
	if (off + *cnt >= IP_FW_MAX_PORTS)
		errx(EX_USAGE, "too many ports (max is %d)", IP_FW_MAX_PORTS);
	ptr[off+*cnt] = port;
	(*cnt)++;
}

static int
lookup_port(const char *arg, int proto, int test, int nodash)
{
	int		val;
	char		*earg, buf[32];
	struct servent	*s;
	char		*p, *q;

	snprintf(buf, sizeof(buf), "%s", arg);

	for (p = q = buf; *p; *q++ = *p++) {
		if (*p == '\\') {
			if (*(p+1))
				p++;
		} else {
			if (*p == ',' || (nodash && *p == '-'))
				break;
		}
	}
	*q = '\0';

	val = (int) strtoul(buf, &earg, 0);
	if (!*buf || *earg) {
		char *protocol = NULL;

		if (proto != 0) {
			struct protoent *pe = getprotobynumber(proto);

			if (pe)
				protocol = pe->p_name;
		}

		setservent(1);
		if ((s = getservbyname(buf, protocol))) {
			val = htons(s->s_port);
		} else {
			if (!test)
				errx(EX_DATAERR, "unknown port ``%s''", buf);
			val = -1;
		}
	} else {
		if (val < 0 || val > 0xffff) {
			if (!test)
				errx(EX_DATAERR,
				    "port ``%s'' out of range", buf);
			val = -1;
		}
	}
	return(val);
}

/*
 * return: 0 normally, 1 if first pair is a range,
 * 2 if first pair is a port+mask
 */
static int
fill_port(u_short *cnt, u_short *ptr, u_short off, char *arg, int proto)
{
	char *s;
	int initial_range = 0;

	for (s = arg; *s && *s != ',' && *s != '-' && *s != ':'; s++) {
		if (*s == '\\' && *(s+1))
			s++;
	}
	if (*s == ':') {
		*s++ = '\0';
		if (strchr(arg, ','))
			errx(EX_USAGE, "port/mask must be first in list");
		add_port(cnt, ptr, off,
		    *arg ? lookup_port(arg, proto, 0, 0) : 0x0000);
		arg = s;
		s = strchr(arg, ',');
		if (s)
			*s++ = '\0';
		add_port(cnt, ptr, off,
		    *arg ? lookup_port(arg, proto, 0, 0) : 0xffff);
		arg = s;
		initial_range = 2;
	} else
	if (*s == '-') {
		*s++ = '\0';
		if (strchr(arg, ','))
			errx(EX_USAGE, "port range must be first in list");
		add_port(cnt, ptr, off,
		    *arg ? lookup_port(arg, proto, 0, 0) : 0x0000);
		arg = s;
		s = strchr(arg, ',');
		if (s)
			*s++ = '\0';
		add_port(cnt, ptr, off,
		    *arg ? lookup_port(arg, proto, 0, 0) : 0xffff);
		arg = s;
		initial_range = 1;
	}
	while (arg != NULL) {
		s = strchr(arg, ',');
		if (s)
			*s++ = '\0';
		add_port(cnt, ptr, off, lookup_port(arg, proto, 0, 0));
		arg = s;
	}
	return initial_range;
}

static void
fill_tcpflag(u_char *set, u_char *reset, char **vp)
{
	char *p = *vp, *q;
	u_char *d;

	while (p && *p) {
		struct tpcflags {
			char * name;
			u_char value;
		} flags[] = {
			{ "syn", IP_FW_TCPF_SYN },
			{ "fin", IP_FW_TCPF_FIN },
			{ "ack", IP_FW_TCPF_ACK },
			{ "psh", IP_FW_TCPF_PSH },
			{ "rst", IP_FW_TCPF_RST },
			{ "urg", IP_FW_TCPF_URG }
		};
		int i;

		if (*p == '!') {
			p++;
			d = reset;
		} else {
			d = set;
		}
		q = strchr(p, ',');
		if (q)
			*q++ = '\0';
		for (i = 0; i < sizeof(flags) / sizeof(flags[0]); ++i)
			if (!strncmp(p, flags[i].name, strlen(p))) {
				*d |= flags[i].value;
				break;
			}
		if (i == sizeof(flags) / sizeof(flags[0]))
			errx(EX_DATAERR, "invalid tcp flag ``%s''", p);
		p = q;
	}
}

static void
fill_tcpopts(u_char *set, u_char *reset, char **vp)
{
	char *p = *vp, *q;
	u_char *d;

	while (p && *p) {
		struct tpcopts {
			char * name;
			u_char value;
		} opts[] = {
			{ "mss", IP_FW_TCPOPT_MSS },
			{ "window", IP_FW_TCPOPT_WINDOW },
			{ "sack", IP_FW_TCPOPT_SACK },
			{ "ts", IP_FW_TCPOPT_TS },
			{ "cc", IP_FW_TCPOPT_CC },
		};
		int i;

		if (*p == '!') {
			p++;
			d = reset;
		} else {
			d = set;
		}
		q = strchr(p, ',');
		if (q)
			*q++ = '\0';
		for (i = 0; i < sizeof(opts) / sizeof(opts[0]); ++i)
			if (!strncmp(p, opts[i].name, strlen(p))) {
				*d |= opts[i].value;
				break;
			}
		if (i == sizeof(opts) / sizeof(opts[0]))
			errx(EX_DATAERR, "invalid tcp option ``%s''", p);
		p = q;
	}
}

static void
fill_ipopt(u_char *set, u_char *reset, char **vp)
{
	char *p = *vp, *q;
	u_char *d;

	while (p && *p) {
		if (*p == '!') {
			p++;
			d = reset;
		} else {
			d = set;
		}
		q = strchr(p, ',');
		if (q)
			*q++ = '\0';
		if (!strncmp(p, "ssrr", strlen(p))) *d |= IP_FW_IPOPT_SSRR;
		if (!strncmp(p, "lsrr", strlen(p))) *d |= IP_FW_IPOPT_LSRR;
		if (!strncmp(p, "rr", strlen(p)))   *d |= IP_FW_IPOPT_RR;
		if (!strncmp(p, "ts", strlen(p)))   *d |= IP_FW_IPOPT_TS;
		p = q;
	}
}

static void
fill_icmptypes(unsigned *types, char **vp, u_int *fw_flg)
{
	unsigned long icmptype;
	char *c = *vp;

	while (*c) {
		if (*c == ',')
			++c;

		icmptype = strtoul(c, &c, 0);

		if (*c != ',' && *c != '\0')
			errx(EX_DATAERR, "invalid ICMP type");

		if (icmptype >= IP_FW_ICMPTYPES_DIM * sizeof(unsigned) * 8)
			errx(EX_DATAERR, "ICMP type out of range");

		types[icmptype / (sizeof(unsigned) * 8)] |=
			1 << (icmptype % (sizeof(unsigned) * 8));
		*fw_flg |= IP_FW_F_ICMPBIT;
	}
}

static void
delete(int ac, char *av[])
{
	struct ip_fw rule;
#ifndef _WIN32
	struct dn_pipe pipe;
#endif
	int i;
	int exitval = EX_OK;

	memset(&rule, 0, sizeof rule);
#ifndef _WIN32
	memset(&pipe, 0, sizeof pipe);
#endif

	av++; ac--;

	/* Rule number */
	while (ac && isdigit(**av)) {
		i = atoi(*av); av++; ac--;
#ifndef _WIN32
		if (do_pipe) {
			if (do_pipe == 1)
				pipe.pipe_nr = i;
			else
				pipe.fs.fs_nr = i;
			i = setsockopt(s, IPPROTO_IP, IP_DUMMYNET_DEL,
			    &pipe, sizeof pipe);
			if (i) {
				exitval = 1;
				warn("rule %u: setsockopt(IP_DUMMYNET_DEL)",
				    do_pipe == 1 ? pipe.pipe_nr :
				    pipe.fs.fs_nr);
			}
		} else {
#endif /* !_WIN32 */
			rule.fw_number = i;
			i = setsockopt(s, IPPROTO_IP, IP_FW_DEL, &rule,
			    sizeof rule);
			if (i) {
				exitval = EX_UNAVAILABLE;
				warn("rule %u: setsockopt(IP_FW_DEL)",
				    rule.fw_number);
			}
#ifndef _WIN32
		}
#endif
	}
	if (exitval != EX_OK)
		exit(exitval);
}

static void
verify_interface(union ip_fw_if *ifu)
{
	struct ifreq ifr;

	/*
	 *	If a unit was specified, check for that exact interface.
	 *	If a wildcard was specified, check for unit 0.
	 */
	snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d",
			 ifu->fu_via_if.name,
			 ifu->fu_via_if.unit == -1 ? 0 : ifu->fu_via_if.unit);

	if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0)
		warnx("warning: interface ``%s'' does not exist",
		    ifr.ifr_name);
}

static void
fill_iface(char *which, union ip_fw_if *ifu, int *byname, int ac, char *arg)
{
	if (!ac)
	    errx(EX_USAGE, "missing argument for ``%s''", which);

	/* Parse the interface or address */
	if (!strcmp(arg, "any")) {
		ifu->fu_via_ip.s_addr = 0;
		*byname = 0;
	} else if (!isdigit(*arg)) {
		char *q;

		*byname = 1;
		strncpy(ifu->fu_via_if.name, arg,
		    sizeof(ifu->fu_via_if.name));
		ifu->fu_via_if.name[sizeof(ifu->fu_via_if.name) - 1] = '\0';
		for (q = ifu->fu_via_if.name;
		    *q && !isdigit(*q) && *q != '*'; q++)
			continue;
		ifu->fu_via_if.unit = (*q == '*') ? -1 : atoi(q);
		*q = '\0';
		verify_interface(ifu);
	} else if (!inet_aton(arg, &ifu->fu_via_ip)) {
		errx(EX_DATAERR, "bad ip address ``%s''", arg);
	} else
		*byname = 0;
}

#ifndef _WIN32
static void
config_pipe(int ac, char **av)
{
	struct dn_pipe pipe;
	int i;
	char *end;

	memset(&pipe, 0, sizeof pipe);

	av++; ac--;
	/* Pipe number */
	if (ac && isdigit(**av)) {
		i = atoi(*av); av++; ac--;
		if (do_pipe == 1)
			pipe.pipe_nr = i;
		else
			pipe.fs.fs_nr = i;
	}
	while (ac > 1) {
		if (!strncmp(*av, "plr", strlen(*av))) {

			double d = strtod(av[1], NULL);
			if (d > 1)
				d = 1;
			else if (d < 0)
				d = 0;
			pipe.fs.plr = (int)(d*0x7fffffff);
			av += 2;
			ac -= 2;
		} else if (!strncmp(*av, "queue", strlen(*av))) {
			end = NULL;
			pipe.fs.qsize = strtoul(av[1], &end, 0);
			if (*end == 'K' || *end == 'k') {
				pipe.fs.flags_fs |= DN_QSIZE_IS_BYTES;
				pipe.fs.qsize *= 1024;
			} else if (*end == 'B' || !strncmp(end, "by", 2)) {
				pipe.fs.flags_fs |= DN_QSIZE_IS_BYTES;
			}
			av += 2;
			ac -= 2;
		} else if (!strncmp(*av, "buckets", strlen(*av))) {
			pipe.fs.rq_size = strtoul(av[1], NULL, 0);
			av += 2;
			ac -= 2;
		} else if (!strncmp(*av, "mask", strlen(*av))) {
			/* per-flow queue, mask is dst_ip, dst_port,
			 * src_ip, src_port, proto measured in bits
			 */
			u_int32_t a;
			void *par = NULL;

			pipe.fs.flow_mask.dst_ip = 0;
			pipe.fs.flow_mask.src_ip = 0;
			pipe.fs.flow_mask.dst_port = 0;
			pipe.fs.flow_mask.src_port = 0;
			pipe.fs.flow_mask.proto = 0;
			end = NULL;
			av++; ac--;
			if (ac >= 1 && !strncmp(*av, "all", strlen(*av))) {
				/* special case -- all bits are significant */
				pipe.fs.flow_mask.dst_ip = ~0;
				pipe.fs.flow_mask.src_ip = ~0;
				pipe.fs.flow_mask.dst_port = ~0;
				pipe.fs.flow_mask.src_port = ~0;
				pipe.fs.flow_mask.proto = ~0;
				pipe.fs.flags_fs |= DN_HAVE_FLOW_MASK;
				av++;
				ac--;
				continue;
			}
			while (ac >= 1) {
				int len = strlen(*av);

				if (!strncmp(*av, "dst-ip", len))
					par = &pipe.fs.flow_mask.dst_ip;
				else if (!strncmp(*av, "src-ip", len))
					par = &pipe.fs.flow_mask.src_ip;
				else if (!strncmp(*av, "dst-port", len))
					par = &pipe.fs.flow_mask.dst_port;
				else if (!strncmp(*av, "src-port", len))

⌨️ 快捷键说明

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