Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 26 Jan 2009 18:46:37 +0000 (UTC)
From:      Luigi Rizzo <luigi@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r187738 - user/luigi/ipfw/sbin/ipfw
Message-ID:  <200901261846.n0QIkbF6059447@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: luigi
Date: Mon Jan 26 18:46:37 2009
New Revision: 187738
URL: http://svn.freebsd.org/changeset/base/187738

Log:
  remove code residing in other files

Modified:
  user/luigi/ipfw/sbin/ipfw/ipfw2.c

Modified: user/luigi/ipfw/sbin/ipfw/ipfw2.c
==============================================================================
--- user/luigi/ipfw/sbin/ipfw/ipfw2.c	Mon Jan 26 18:40:39 2009	(r187737)
+++ user/luigi/ipfw/sbin/ipfw/ipfw2.c	Mon Jan 26 18:46:37 2009	(r187738)
@@ -373,36 +373,6 @@ _substrcmp2(const char *str1, const char
 	return 0;
 }
 
-#if 0
-/*
- * prints one port, symbolic or numeric
- */
-static void
-print_port(int proto, uint16_t port)
-{
-
-	if (proto == IPPROTO_ETHERTYPE) {
-		char const *s;
-
-		if (do_resolv && (s = match_value(ether_types, port)) )
-			printf("%s", s);
-		else
-			printf("0x%04x", port);
-	} else {
-		struct servent *se = NULL;
-		if (do_resolv) {
-			struct protoent *pe = getprotobynumber(proto);
-
-			se = getservbyport(htons(port), pe ? pe->p_name : NULL);
-		}
-		if (se)
-			printf("%s", se->s_name);
-		else
-			printf("%d", port);
-	}
-}
-#endif
-
 struct _s_x _port_name[] = {
 	{"dst-port",	O_IP_DSTPORT},
 	{"src-port",	O_IP_SRCPORT},
@@ -415,256 +385,6 @@ struct _s_x _port_name[] = {
 	{NULL,		0}
 };
 
-#if 0
-/*
- * Print the values in a list 16-bit items of the types above.
- * XXX todo: add support for mask.
- */
-static void
-print_newports(ipfw_insn_u16 *cmd, int proto, int opcode)
-{
-	uint16_t *p = cmd->ports;
-	int i;
-	char const *sep;
-
-	if (opcode != 0) {
-		sep = match_value(_port_name, opcode);
-		if (sep == NULL)
-			sep = "???";
-		printf (" %s", sep);
-	}
-	sep = " ";
-	for (i = F_LEN((ipfw_insn *)cmd) - 1; i > 0; i--, p += 2) {
-		printf(sep);
-		print_port(proto, p[0]);
-		if (p[0] != p[1]) {
-			printf("-");
-			print_port(proto, p[1]);
-		}
-		sep = ",";
-	}
-}
-
-/*
- * Like strtol, but also translates service names into port numbers
- * for some protocols.
- * In particular:
- *	proto == -1 disables the protocol check;
- *	proto == IPPROTO_ETHERTYPE looks up an internal table
- *	proto == <some value in /etc/protocols> matches the values there.
- * Returns *end == s in case the parameter is not found.
- */
-static int
-strtoport(char *s, char **end, int base, int proto)
-{
-	char *p, *buf;
-	char *s1;
-	int i;
-
-	*end = s;		/* default - not found */
-	if (*s == '\0')
-		return 0;	/* not found */
-
-	if (isdigit(*s))
-		return strtol(s, end, base);
-
-	/*
-	 * find separator. '\\' escapes the next char.
-	 */
-	for (s1 = s; *s1 && (isalnum(*s1) || *s1 == '\\') ; s1++)
-		if (*s1 == '\\' && s1[1] != '\0')
-			s1++;
-
-	buf = safe_calloc(s1 - s + 1, 1);
-
-	/*
-	 * copy into a buffer skipping backslashes
-	 */
-	for (p = s, i = 0; p != s1 ; p++)
-		if (*p != '\\')
-			buf[i++] = *p;
-	buf[i++] = '\0';
-
-	if (proto == IPPROTO_ETHERTYPE) {
-		i = match_token(ether_types, buf);
-		free(buf);
-		if (i != -1) {	/* found */
-			*end = s1;
-			return i;
-		}
-	} else {
-		struct protoent *pe = NULL;
-		struct servent *se;
-
-		if (proto != 0)
-			pe = getprotobynumber(proto);
-		setservent(1);
-		se = getservbyname(buf, pe ? pe->p_name : NULL);
-		free(buf);
-		if (se != NULL) {
-			*end = s1;
-			return ntohs(se->s_port);
-		}
-	}
-	return 0;	/* not found */
-}
-#endif
-
-/*
- * Map between current altq queue id numbers and names.
- */
-#if 0
-static int altq_fetched = 0;
-#endif
-static TAILQ_HEAD(, pf_altq) altq_entries = 
-	TAILQ_HEAD_INITIALIZER(altq_entries);
-
-static void
-altq_set_enabled(int enabled)
-{
-	int pffd;
-
-	pffd = open("/dev/pf", O_RDWR);
-	if (pffd == -1)
-		err(EX_UNAVAILABLE,
-		    "altq support opening pf(4) control device");
-	if (enabled) {
-		if (ioctl(pffd, DIOCSTARTALTQ) != 0 && errno != EEXIST)
-			err(EX_UNAVAILABLE, "enabling altq");
-	} else {
-		if (ioctl(pffd, DIOCSTOPALTQ) != 0 && errno != ENOENT)
-			err(EX_UNAVAILABLE, "disabling altq");
-	}
-	close(pffd);
-}
-
-#if 0
-static void
-altq_fetch(void)
-{
-	struct pfioc_altq pfioc;
-	struct pf_altq *altq;
-	int pffd;
-	unsigned int mnr;
-
-	if (altq_fetched)
-		return;
-	altq_fetched = 1;
-	pffd = open("/dev/pf", O_RDONLY);
-	if (pffd == -1) {
-		warn("altq support opening pf(4) control device");
-		return;
-	}
-	bzero(&pfioc, sizeof(pfioc));
-	if (ioctl(pffd, DIOCGETALTQS, &pfioc) != 0) {
-		warn("altq support getting queue list");
-		close(pffd);
-		return;
-	}
-	mnr = pfioc.nr;
-	for (pfioc.nr = 0; pfioc.nr < mnr; pfioc.nr++) {
-		if (ioctl(pffd, DIOCGETALTQ, &pfioc) != 0) {
-			if (errno == EBUSY)
-				break;
-			warn("altq support getting queue list");
-			close(pffd);
-			return;
-		}
-		if (pfioc.altq.qid == 0)
-			continue;
-		altq = safe_calloc(1, sizeof(*altq));
-		*altq = pfioc.altq;
-		TAILQ_INSERT_TAIL(&altq_entries, altq, entries);
-	}
-	close(pffd);
-}
-
-static u_int32_t
-altq_name_to_qid(const char *name)
-{
-	struct pf_altq *altq;
-
-	altq_fetch();
-	TAILQ_FOREACH(altq, &altq_entries, entries)
-		if (strcmp(name, altq->qname) == 0)
-			break;
-	if (altq == NULL)
-		errx(EX_DATAERR, "altq has no queue named `%s'", name);
-	return altq->qid;
-}
-#endif
-
-#if 0
-static const char *
-altq_qid_to_name(u_int32_t qid)
-{
-	struct pf_altq *altq;
-
-	altq_fetch();
-	TAILQ_FOREACH(altq, &altq_entries, entries)
-		if (qid == altq->qid)
-			break;
-	if (altq == NULL)
-		return NULL;
-	return altq->qname;
-}
-#endif
-
-#if 0
-static void
-fill_altq_qid(u_int32_t *qid, const char *av)
-{
-	*qid = altq_name_to_qid(av);
-}
-
-/*
- * Fill the body of the command with the list of port ranges.
- */
-static int
-fill_newports(ipfw_insn_u16 *cmd, char *av, int proto)
-{
-	uint16_t a, b, *p = cmd->ports;
-	int i = 0;
-	char *s = av;
-
-	while (*s) {
-		a = strtoport(av, &s, 0, proto);
-		if (s == av) 			/* empty or invalid argument */
-			return (0);
-
-		switch (*s) {
-		case '-':			/* a range */
-			av = s + 1;
-			b = strtoport(av, &s, 0, proto);
-			/* Reject expressions like '1-abc' or '1-2-3'. */
-			if (s == av || (*s != ',' && *s != '\0'))
-				return (0);
-			p[0] = a;
-			p[1] = b;
-			break;
-		case ',':			/* comma separated list */
-		case '\0':
-			p[0] = p[1] = a;
-			break;
-		default:
-			warnx("port list: invalid separator <%c> in <%s>",
-				*s, av);
-			return (0);
-		}
-
-		i++;
-		p += 2;
-		av = s + 1;
-	}
-	if (i > 0) {
-		if (i + 1 > F_LEN_MASK)
-			errx(EX_DATAERR, "too many ports/ranges\n");
-		cmd->o.len |= i + 1;	/* leave F_NOT and F_OR untouched */
-	}
-	return (i);
-}
-#endif
-
 struct _s_x icmpcodes[] = {
       { "net",			ICMP_UNREACH_NET },
       { "host",			ICMP_UNREACH_HOST },
@@ -685,34 +405,6 @@ struct _s_x icmpcodes[] = {
       { NULL, 0 }
 };
 
-#if 0
-static void
-fill_reject_code(u_short *codep, char *str)
-{
-	int val;
-	char *s;
-
-	val = strtoul(str, &s, 0);
-	if (s == str || *s != '\0' || val >= 0x100)
-		val = match_token(icmpcodes, str);
-	if (val < 0)
-		errx(EX_DATAERR, "unknown ICMP unreachable code ``%s''", str);
-	*codep = val;
-	return;
-}
-
-static void
-print_reject_code(uint16_t code)
-{
-	char const *s = match_value(icmpcodes, code);
-
-	if (s != NULL)
-		printf("unreach %s", s);
-	else
-		printf("unreach %u", code);
-}
-#endif
-
 struct _s_x icmp6codes[] = {
       { "no-route",		ICMP6_DST_UNREACH_NOROUTE },
       { "admin-prohib",		ICMP6_DST_UNREACH_ADMIN },
@@ -721,4815 +413,391 @@ struct _s_x icmp6codes[] = {
       { NULL, 0 }
 };
 
-#if 0
-static void
-fill_unreach6_code(u_short *codep, char *str)
-{
-	int val;
-	char *s;
-
-	val = strtoul(str, &s, 0);
-	if (s == str || *s != '\0' || val >= 0x100)
-		val = match_token(icmp6codes, str);
-	if (val < 0)
-		errx(EX_DATAERR, "unknown ICMPv6 unreachable code ``%s''", str);
-	*codep = val;
-	return;
-}
-
+/*
+ * This one handles all set-related commands
+ * 	ipfw set { show | enable | disable }
+ * 	ipfw set swap X Y
+ * 	ipfw set move X to Y
+ * 	ipfw set move rule X to Y
+ */
 static void
-print_unreach6_code(uint16_t code)
+sets_handler(int ac, char *av[])
 {
-	char const *s = match_value(icmp6codes, code);
+	uint32_t set_disable, masks[2];
+	int i, nbytes;
+	uint16_t rulenum;
+	uint8_t cmd, new_set;
 
-	if (s != NULL)
-		printf("unreach6 %s", s);
-	else
-		printf("unreach6 %u", code);
-}
+	ac--;
+	av++;
 
-/*
- * Returns the number of bits set (from left) in a contiguous bitmask,
- * or -1 if the mask is not contiguous.
- * XXX this needs a proper fix.
- * This effectively works on masks in big-endian (network) format.
- * when compiled on little endian architectures.
- *
- * First bit is bit 7 of the first byte -- note, for MAC addresses,
- * the first bit on the wire is bit 0 of the first byte.
- * len is the max length in bits.
- */
-static int
-contigmask(uint8_t *p, int len)
-{
-	int i, n;
+	if (!ac)
+		errx(EX_USAGE, "set needs command");
+	if (_substrcmp(*av, "show") == 0) {
+		void *data;
+		char const *msg;
 
-	for (i=0; i<len ; i++)
-		if ( (p[i/8] & (1 << (7 - (i%8)))) == 0) /* first bit unset */
-			break;
-	for (n=i+1; n < len; n++)
-		if ( (p[n/8] & (1 << (7 - (n%8)))) != 0)
-			return -1; /* mask not contiguous */
-	return i;
-}
+		nbytes = sizeof(struct ip_fw);
+		data = safe_calloc(1, nbytes);
+		if (do_cmd(IP_FW_GET, data, (uintptr_t)&nbytes) < 0)
+			err(EX_OSERR, "getsockopt(IP_FW_GET)");
+		bcopy(&((struct ip_fw *)data)->next_rule,
+			&set_disable, sizeof(set_disable));
 
-/*
- * print flags set/clear in the two bitmasks passed as parameters.
- * There is a specialized check for f_tcpflags.
- */
-static void
-print_flags(char const *name, ipfw_insn *cmd, struct _s_x *list)
-{
-	char const *comma = "";
-	int i;
-	uint8_t set = cmd->arg1 & 0xff;
-	uint8_t clear = (cmd->arg1 >> 8) & 0xff;
+		for (i = 0, msg = "disable" ; i < RESVD_SET; i++)
+			if ((set_disable & (1<<i))) {
+				printf("%s %d", msg, i);
+				msg = "";
+			}
+		msg = (set_disable) ? " enable" : "enable";
+		for (i = 0; i < RESVD_SET; i++)
+			if (!(set_disable & (1<<i))) {
+				printf("%s %d", msg, i);
+				msg = "";
+			}
+		printf("\n");
+	} else if (_substrcmp(*av, "swap") == 0) {
+		ac--; av++;
+		if (ac != 2)
+			errx(EX_USAGE, "set swap needs 2 set numbers\n");
+		rulenum = atoi(av[0]);
+		new_set = atoi(av[1]);
+		if (!isdigit(*(av[0])) || rulenum > RESVD_SET)
+			errx(EX_DATAERR, "invalid set number %s\n", av[0]);
+		if (!isdigit(*(av[1])) || new_set > RESVD_SET)
+			errx(EX_DATAERR, "invalid set number %s\n", av[1]);
+		masks[0] = (4 << 24) | (new_set << 16) | (rulenum);
+		i = do_cmd(IP_FW_DEL, masks, sizeof(uint32_t));
+	} else if (_substrcmp(*av, "move") == 0) {
+		ac--; av++;
+		if (ac && _substrcmp(*av, "rule") == 0) {
+			cmd = 2;
+			ac--; av++;
+		} else
+			cmd = 3;
+		if (ac != 3 || _substrcmp(av[1], "to") != 0)
+			errx(EX_USAGE, "syntax: set move [rule] X to Y\n");
+		rulenum = atoi(av[0]);
+		new_set = atoi(av[2]);
+		if (!isdigit(*(av[0])) || (cmd == 3 && rulenum > RESVD_SET) ||
+			(cmd == 2 && rulenum == IPFW_DEFAULT_RULE) )
+			errx(EX_DATAERR, "invalid source number %s\n", av[0]);
+		if (!isdigit(*(av[2])) || new_set > RESVD_SET)
+			errx(EX_DATAERR, "invalid dest. set %s\n", av[1]);
+		masks[0] = (cmd << 24) | (new_set << 16) | (rulenum);
+		i = do_cmd(IP_FW_DEL, masks, sizeof(uint32_t));
+	} else if (_substrcmp(*av, "disable") == 0 ||
+		   _substrcmp(*av, "enable") == 0 ) {
+		int which = _substrcmp(*av, "enable") == 0 ? 1 : 0;
 
-	if (list == f_tcpflags && set == TH_SYN && clear == TH_ACK) {
-		printf(" setup");
-		return;
-	}
+		ac--; av++;
+		masks[0] = masks[1] = 0;
 
-	printf(" %s ", name);
-	for (i=0; list[i].x != 0; i++) {
-		if (set & list[i].x) {
-			set &= ~list[i].x;
-			printf("%s%s", comma, list[i].s);
-			comma = ",";
-		}
-		if (clear & list[i].x) {
-			clear &= ~list[i].x;
-			printf("%s!%s", comma, list[i].s);
-			comma = ",";
+		while (ac) {
+			if (isdigit(**av)) {
+				i = atoi(*av);
+				if (i < 0 || i > RESVD_SET)
+					errx(EX_DATAERR,
+					    "invalid set number %d\n", i);
+				masks[which] |= (1<<i);
+			} else if (_substrcmp(*av, "disable") == 0)
+				which = 0;
+			else if (_substrcmp(*av, "enable") == 0)
+				which = 1;
+			else
+				errx(EX_DATAERR,
+					"invalid set command %s\n", *av);
+			av++; ac--;
 		}
-	}
+		if ( (masks[0] & masks[1]) != 0 )
+			errx(EX_DATAERR,
+			    "cannot enable and disable the same set\n");
+
+		i = do_cmd(IP_FW_DEL, masks, sizeof(masks));
+		if (i)
+			warn("set enable/disable: setsockopt(IP_FW_DEL)");
+	} else
+		errx(EX_USAGE, "invalid set command %s\n", *av);
 }
 
-/*
- * Print the ip address contained in a command.
- */
 static void
-print_ip(ipfw_insn_ip *cmd, char const *s)
+sysctl_handler(int ac, char *av[], int which)
 {
-	struct hostent *he = NULL;
-	int len = F_LEN((ipfw_insn *)cmd);
-	uint32_t *a = ((ipfw_insn_u32 *)cmd)->d;
-
-	printf("%s%s ", cmd->o.len & F_NOT ? " not": "", s);
-
-	if (cmd->o.opcode == O_IP_SRC_ME || cmd->o.opcode == O_IP_DST_ME) {
-		printf("me");
-		return;
-	}
-	if (cmd->o.opcode == O_IP_SRC_LOOKUP ||
-	    cmd->o.opcode == O_IP_DST_LOOKUP) {
-		printf("table(%u", ((ipfw_insn *)cmd)->arg1);
-		if (len == F_INSN_SIZE(ipfw_insn_u32))
-			printf(",%u", *a);
-		printf(")");
-		return;
-	}
-	if (cmd->o.opcode == O_IP_SRC_SET || cmd->o.opcode == O_IP_DST_SET) {
-		uint32_t x, *map = (uint32_t *)&(cmd->mask);
-		int i, j;
-		char comma = '{';
+	ac--;
+	av++;
 
-		x = cmd->o.arg1 - 1;
-		x = htonl( ~x );
-		cmd->addr.s_addr = htonl(cmd->addr.s_addr);
-		printf("%s/%d", inet_ntoa(cmd->addr),
-			contigmask((uint8_t *)&x, 32));
-		x = cmd->addr.s_addr = htonl(cmd->addr.s_addr);
-		x &= 0xff; /* base */
-		/*
-		 * Print bits and ranges.
-		 * Locate first bit set (i), then locate first bit unset (j).
-		 * If we have 3+ consecutive bits set, then print them as a
-		 * range, otherwise only print the initial bit and rescan.
-		 */
-		for (i=0; i < cmd->o.arg1; i++)
-			if (map[i/32] & (1<<(i & 31))) {
-				for (j=i+1; j < cmd->o.arg1; j++)
-					if (!(map[ j/32] & (1<<(j & 31))))
-						break;
-				printf("%c%d", comma, i+x);
-				if (j>i+2) { /* range has at least 3 elements */
-					printf("-%d", j-1+x);
-					i = j-1;
-				}
-				comma = ',';
-			}
-		printf("}");
-		return;
-	}
-	/*
-	 * len == 2 indicates a single IP, whereas lists of 1 or more
-	 * addr/mask pairs have len = (2n+1). We convert len to n so we
-	 * use that to count the number of entries.
-	 */
-    for (len = len / 2; len > 0; len--, a += 2) {
-	int mb =	/* mask length */
-	    (cmd->o.opcode == O_IP_SRC || cmd->o.opcode == O_IP_DST) ?
-		32 : contigmask((uint8_t *)&(a[1]), 32);
-	if (mb == 32 && do_resolv)
-		he = gethostbyaddr((char *)&(a[0]), sizeof(u_long), AF_INET);
-	if (he != NULL)		/* resolved to name */
-		printf("%s", he->h_name);
-	else if (mb == 0)	/* any */
-		printf("any");
-	else {		/* numeric IP followed by some kind of mask */
-		printf("%s", inet_ntoa( *((struct in_addr *)&a[0]) ) );
-		if (mb < 0)
-			printf(":%s", inet_ntoa( *((struct in_addr *)&a[1]) ) );
-		else if (mb < 32)
-			printf("/%d", mb);
-	}
-	if (len > 1)
-		printf(",");
-    }
-}
-
-/*
- * prints a MAC address/mask pair
- */
-static void
-print_mac(uint8_t *addr, uint8_t *mask)
-{
-	int l = contigmask(mask, 48);
-
-	if (l == 0)
-		printf(" any");
-	else {
-		printf(" %02x:%02x:%02x:%02x:%02x:%02x",
-		    addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
-		if (l == -1)
-			printf("&%02x:%02x:%02x:%02x:%02x:%02x",
-			    mask[0], mask[1], mask[2],
-			    mask[3], mask[4], mask[5]);
-		else if (l < 48)
-			printf("/%d", l);
-	}
-}
-
-static void
-fill_icmptypes(ipfw_insn_u32 *cmd, char *av)
-{
-	uint8_t type;
-
-	cmd->d[0] = 0;
-	while (*av) {
-		if (*av == ',')
-			av++;
-
-		type = strtoul(av, &av, 0);
-
-		if (*av != ',' && *av != '\0')
-			errx(EX_DATAERR, "invalid ICMP type");
-
-		if (type > 31)
-			errx(EX_DATAERR, "ICMP type out of range");
-
-		cmd->d[0] |= 1 << type;
-	}
-	cmd->o.opcode = O_ICMPTYPE;
-	cmd->o.len |= F_INSN_SIZE(ipfw_insn_u32);
-}
-
-static void
-print_icmptypes(ipfw_insn_u32 *cmd)
-{
-	int i;
-	char sep= ' ';
-
-	printf(" icmptypes");
-	for (i = 0; i < 32; i++) {
-		if ( (cmd->d[0] & (1 << (i))) == 0)
-			continue;
-		printf("%c%d", sep, i);
-		sep = ',';
+	if (ac == 0) {
+		warnx("missing keyword to enable/disable\n");
+	} else if (_substrcmp(*av, "firewall") == 0) {
+		sysctlbyname("net.inet.ip.fw.enable", NULL, 0,
+		    &which, sizeof(which));
+	} else if (_substrcmp(*av, "one_pass") == 0) {
+		sysctlbyname("net.inet.ip.fw.one_pass", NULL, 0,
+		    &which, sizeof(which));
+	} else if (_substrcmp(*av, "debug") == 0) {
+		sysctlbyname("net.inet.ip.fw.debug", NULL, 0,
+		    &which, sizeof(which));
+	} else if (_substrcmp(*av, "verbose") == 0) {
+		sysctlbyname("net.inet.ip.fw.verbose", NULL, 0,
+		    &which, sizeof(which));
+	} else if (_substrcmp(*av, "dyn_keepalive") == 0) {
+		sysctlbyname("net.inet.ip.fw.dyn_keepalive", NULL, 0,
+		    &which, sizeof(which));
+	} else if (_substrcmp(*av, "altq") == 0) {
+		altq_set_enabled(which);
+	} else {
+		warnx("unrecognize enable/disable keyword: %s\n", *av);
 	}
 }
 
-/* 
- * Print the ip address contained in a command.
- */
-static void
-print_ip6(ipfw_insn_ip6 *cmd, char const *s)
-{
-       struct hostent *he = NULL;
-       int len = F_LEN((ipfw_insn *) cmd) - 1;
-       struct in6_addr *a = &(cmd->addr6);
-       char trad[255];
-
-       printf("%s%s ", cmd->o.len & F_NOT ? " not": "", s);
-
-       if (cmd->o.opcode == O_IP6_SRC_ME || cmd->o.opcode == O_IP6_DST_ME) {
-               printf("me6");
-               return;
-       }
-       if (cmd->o.opcode == O_IP6) {
-               printf(" ip6");
-               return;
-       }
-
-       /*
-        * len == 4 indicates a single IP, whereas lists of 1 or more
-        * addr/mask pairs have len = (2n+1). We convert len to n so we
-        * use that to count the number of entries.
-        */
-
-       for (len = len / 4; len > 0; len -= 2, a += 2) {
-           int mb =        /* mask length */
-               (cmd->o.opcode == O_IP6_SRC || cmd->o.opcode == O_IP6_DST) ?
-               128 : contigmask((uint8_t *)&(a[1]), 128);
-
-           if (mb == 128 && do_resolv)
-               he = gethostbyaddr((char *)a, sizeof(*a), AF_INET6);
-           if (he != NULL)             /* resolved to name */
-               printf("%s", he->h_name);
-           else if (mb == 0)           /* any */
-               printf("any");
-           else {          /* numeric IP followed by some kind of mask */
-               if (inet_ntop(AF_INET6,  a, trad, sizeof( trad ) ) == NULL)
-                   printf("Error ntop in print_ip6\n");
-               printf("%s",  trad );
-               if (mb < 0)     /* XXX not really legal... */
-                   printf(":%s",
-                       inet_ntop(AF_INET6, &a[1], trad, sizeof(trad)));
-               else if (mb < 128)
-                   printf("/%d", mb);
-           }
-           if (len > 2)
-               printf(",");
-       }
-}
-
-static void
-fill_icmp6types(ipfw_insn_icmp6 *cmd, char *av)
-{
-       uint8_t type;
-
-       bzero(cmd, sizeof(*cmd));
-       while (*av) {
-           if (*av == ',')
-               av++;
-           type = strtoul(av, &av, 0);
-           if (*av != ',' && *av != '\0')
-               errx(EX_DATAERR, "invalid ICMP6 type");
-	   /*
-	    * XXX: shouldn't this be 0xFF?  I can't see any reason why
-	    * we shouldn't be able to filter all possiable values
-	    * regardless of the ability of the rest of the kernel to do
-	    * anything useful with them.
-	    */
-           if (type > ICMP6_MAXTYPE)
-               errx(EX_DATAERR, "ICMP6 type out of range");
-           cmd->d[type / 32] |= ( 1 << (type % 32));
-       }
-       cmd->o.opcode = O_ICMP6TYPE;
-       cmd->o.len |= F_INSN_SIZE(ipfw_insn_icmp6);
-}
-
-
-static void
-print_icmp6types(ipfw_insn_u32 *cmd)
-{
-       int i, j;
-       char sep= ' ';
-
-       printf(" ip6 icmp6types");
-       for (i = 0; i < 7; i++)
-               for (j=0; j < 32; ++j) {
-                       if ( (cmd->d[i] & (1 << (j))) == 0)
-                               continue;
-                       printf("%c%d", sep, (i*32 + j));
-                       sep = ',';
-               }
-}
-
-static void
-print_flow6id( ipfw_insn_u32 *cmd)
-{
-       uint16_t i, limit = cmd->o.arg1;
-       char sep = ',';
-
-       printf(" flow-id ");
-       for( i=0; i < limit; ++i) {
-               if (i == limit - 1)
-                       sep = ' ';
-               printf("%d%c", cmd->d[i], sep);
-       }
-}
-
-/* structure and define for the extension header in ipv6 */
-static struct _s_x ext6hdrcodes[] = {
-       { "frag",       EXT_FRAGMENT },
-       { "hopopt",     EXT_HOPOPTS },
-       { "route",      EXT_ROUTING },
-       { "dstopt",     EXT_DSTOPTS },
-       { "ah",         EXT_AH },
-       { "esp",        EXT_ESP },
-       { "rthdr0",     EXT_RTHDR0 },
-       { "rthdr2",     EXT_RTHDR2 },
-       { NULL,         0 }
-};
-
-/* fills command for the extension header filtering */
-static int
-fill_ext6hdr( ipfw_insn *cmd, char *av)
-{
-       int tok;
-       char *s = av;
-
-       cmd->arg1 = 0;
-
-       while(s) {
-           av = strsep( &s, ",") ;
-           tok = match_token(ext6hdrcodes, av);
-           switch (tok) {
-           case EXT_FRAGMENT:
-               cmd->arg1 |= EXT_FRAGMENT;
-               break;
-
-           case EXT_HOPOPTS:
-               cmd->arg1 |= EXT_HOPOPTS;
-               break;
-
-           case EXT_ROUTING:
-               cmd->arg1 |= EXT_ROUTING;
-               break;
-
-           case EXT_DSTOPTS:
-               cmd->arg1 |= EXT_DSTOPTS;
-               break;
-
-           case EXT_AH:
-               cmd->arg1 |= EXT_AH;
-               break;
-
-           case EXT_ESP:
-               cmd->arg1 |= EXT_ESP;
-               break;
-
-           case EXT_RTHDR0:
-               cmd->arg1 |= EXT_RTHDR0;
-               break;
-
-           case EXT_RTHDR2:
-               cmd->arg1 |= EXT_RTHDR2;
-               break;
-
-           default:
-               errx( EX_DATAERR, "invalid option for ipv6 exten header" );
-               break;
-           }
-       }
-       if (cmd->arg1 == 0 )
-           return 0;
-       cmd->opcode = O_EXT_HDR;
-       cmd->len |= F_INSN_SIZE( ipfw_insn );
-       return 1;
-}
-
 static void
-print_ext6hdr( ipfw_insn *cmd )
+show_usage(void)
 {
-       char sep = ' ';
-
-       printf(" extension header:");
-       if (cmd->arg1 & EXT_FRAGMENT ) {
-           printf("%cfragmentation", sep);
-           sep = ',';
-       }
-       if (cmd->arg1 & EXT_HOPOPTS ) {
-           printf("%chop options", sep);
-           sep = ',';
-       }
-       if (cmd->arg1 & EXT_ROUTING ) {
-           printf("%crouting options", sep);
-           sep = ',';
-       }
-       if (cmd->arg1 & EXT_RTHDR0 ) {
-           printf("%crthdr0", sep);
-           sep = ',';
-       }
-       if (cmd->arg1 & EXT_RTHDR2 ) {
-           printf("%crthdr2", sep);
-           sep = ',';
-       }
-       if (cmd->arg1 & EXT_DSTOPTS ) {
-           printf("%cdestination options", sep);
-           sep = ',';
-       }
-       if (cmd->arg1 & EXT_AH ) {
-           printf("%cauthentication header", sep);
-           sep = ',';
-       }
-       if (cmd->arg1 & EXT_ESP ) {
-           printf("%cencapsulated security payload", sep);
-       }
+	fprintf(stderr, "usage: ipfw [options]\n"
+"do \"ipfw -h\" or see ipfw manpage for details\n"
+);
+	exit(EX_USAGE);
 }
 
-/*
- * show_ipfw() prints the body of an ipfw rule.
- * Because the standard rule has at least proto src_ip dst_ip, we use
- * a helper function to produce these entries if not provided explicitly.
- * The first argument is the list of fields we have, the second is
- * the list of fields we want to be printed.
- *
- * Special cases if we have provided a MAC header:
- *   + if the rule does not contain IP addresses/ports, do not print them;
- *   + if the rule does not contain an IP proto, print "all" instead of "ip";
- *
- * Once we have 'have_options', IP header fields are printed as options.
- */
-#define	HAVE_PROTO	0x0001
-#define	HAVE_SRCIP	0x0002
-#define	HAVE_DSTIP	0x0004
-#define	HAVE_PROTO4	0x0008
-#define	HAVE_PROTO6	0x0010
-#define	HAVE_OPTIONS	0x8000
-
-#define	HAVE_IP		(HAVE_PROTO | HAVE_SRCIP | HAVE_DSTIP)
 static void
-show_prerequisites(int *flags, int want, int cmd __unused)
-{
-	if (comment_only)
-		return;
-	if ( (*flags & HAVE_IP) == HAVE_IP)
-		*flags |= HAVE_OPTIONS;
-
-	if ( !(*flags & HAVE_OPTIONS)) {
-		if ( !(*flags & HAVE_PROTO) && (want & HAVE_PROTO)) {
-			if ( (*flags & HAVE_PROTO4))
-				printf(" ip4");
-			else if ( (*flags & HAVE_PROTO6))
-				printf(" ip6");
-			else
-				printf(" ip");
-		}
-		if ( !(*flags & HAVE_SRCIP) && (want & HAVE_SRCIP))
-			printf(" from any");
-		if ( !(*flags & HAVE_DSTIP) && (want & HAVE_DSTIP))
-			printf(" to any");
-	}
-	*flags |= want;
-}
-
-void
-show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
+help(void)
 {
-	static int twidth = 0;
-	int l;
-	ipfw_insn *cmd, *tagptr = NULL;
-	const char *comment = NULL;	/* ptr to comment if we have one */
-	int proto = 0;		/* default */
-	int flags = 0;	/* prerequisites */
-	ipfw_insn_log *logptr = NULL; /* set if we find an O_LOG */
-	ipfw_insn_altq *altqptr = NULL; /* set if we find an O_ALTQ */
-	int or_block = 0;	/* we are in an or block */
-	uint32_t set_disable;
-
-	bcopy(&rule->next_rule, &set_disable, sizeof(set_disable));
-
-	if (set_disable & (1 << rule->set)) { /* disabled */
-		if (!show_sets)
-			return;
-		else
-			printf("# DISABLED ");
-	}
-	printf("%05u ", rule->rulenum);
-
-	if (pcwidth>0 || bcwidth>0)
-		printf("%*llu %*llu ", pcwidth, align_uint64(&rule->pcnt),
-		    bcwidth, align_uint64(&rule->bcnt));
-
-	if (do_time == 2)
-		printf("%10u ", rule->timestamp);
-	else if (do_time == 1) {
-		char timestr[30];
-		time_t t = (time_t)0;
-
-		if (twidth == 0) {
-			strcpy(timestr, ctime(&t));
-			*strchr(timestr, '\n') = '\0';
-			twidth = strlen(timestr);
-		}
-		if (rule->timestamp) {
-			t = _long_to_time(rule->timestamp);
-
-			strcpy(timestr, ctime(&t));
-			*strchr(timestr, '\n') = '\0';

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200901261846.n0QIkbF6059447>