All,

with the recent merge of IPv6 functionality into ipfw2, ip6fw is obsolete.  As 
the latter is neither locked nor using the pfil_hooks API, it was decided 
that it should be be removed.  Of course, this means that ipfw2 has to 
provide all the functionality that ip6fw provided before.

In order to achieve this, there is one feature missing [for all I know, please 
scream now if you have anything else]: IPv4 only rules.  Previously, it was 
possible to do:

  ipfw add 100 deny all from any to any

to block all IPv4 traffic.  With IPv6 incooperated into ipfw2 this does no 
longer work as it will block IPv6 traffic as well.  With the patch attached 
you can now do:
  
  ipfw add 100 deny ipv4 from any to any
or
  ipfw add 100 deny ipv6 from any to any

to block IPv4 or IPv6.

If you are running a IPv6/IPv4 host/gateway/firewall on current, please test 
the patch and send you feedback.  Be sure to have kernel and userland in 
sync!

-- 
/"\  Best regards,                      | [EMAIL PROTECTED]
\ /  Max Laier                          | ICQ #67774661
 X   http://pf4freebsd.love2party.net/  | [EMAIL PROTECTED]
/ \  ASCII Ribbon Campaign              | Against HTML Mail and News
Index: sbin/ipfw/ipfw2.c
===================================================================
RCS file: /usr/store/mlaier/fcvs/src/sbin/ipfw/ipfw2.c,v
retrieving revision 1.74
diff -u -r1.74 ipfw2.c
--- sbin/ipfw/ipfw2.c	21 May 2005 03:27:33 -0000	1.74
+++ sbin/ipfw/ipfw2.c	24 May 2005 19:19:30 -0000
@@ -275,6 +275,8 @@
 	TOK_EXT6HDR,
 	TOK_DSTIP6,
 	TOK_SRCIP6,
+
+	TOK_IPV4,
 };
 
 struct _s_x dummynet_params[] = {
@@ -395,6 +397,8 @@
 	{ "flow-id",		TOK_FLOWID},
 	{ "ipv6",		TOK_IPV6},
 	{ "ip6",		TOK_IPV6},
+	{ "ipv4",		TOK_IPV4},
+	{ "ip4",		TOK_IPV4},
 	{ "dst-ipv6",		TOK_DSTIP6},
 	{ "dst-ip6",		TOK_DSTIP6},
 	{ "src-ipv6",		TOK_SRCIP6},
@@ -1260,6 +1264,7 @@
 #define	HAVE_DSTIP	0x0004
 #define	HAVE_MAC	0x0008
 #define	HAVE_MACTYPE	0x0010
+#define	HAVE_PROTO4	0x0040
 #define	HAVE_PROTO6	0x0080
 #define	HAVE_OPTIONS	0x8000
 
@@ -1283,11 +1288,14 @@
 		return;
 	}
 	if ( !(*flags & HAVE_OPTIONS)) {
-		/* XXX BED: !(*flags & HAVE_PROTO) in patch */
-		if ( !(*flags & HAVE_PROTO6) && (want & HAVE_PROTO6))
-			printf(" ipv6");
 		if ( !(*flags & HAVE_PROTO) && (want & HAVE_PROTO))
-			printf(" ip");
+			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))
@@ -1468,9 +1476,23 @@
 	/*
 	 * then print the body.
 	 */
+        for (l = rule->act_ofs, cmd = rule->cmd ;
+			l > 0 ; l -= F_LEN(cmd) , cmd += F_LEN(cmd)) {
+		if ((cmd->len & F_OR) || (cmd->len & F_NOT))
+			continue;
+		if (cmd->opcode == O_IP4) {
+			flags |= HAVE_PROTO4;
+			break;
+		} else if (cmd->opcode == O_IP6) {
+			flags |= HAVE_PROTO6;
+			break;
+		}			
+	}
 	if (rule->_pad & 1) {	/* empty rules before options */
-		if (!do_compact)
-			printf(" ip from any to any");
+		if (!do_compact) {
+			show_prerequisites(&flags, HAVE_PROTO, 0);
+			printf(" from any to any");
+		}
 		flags |= HAVE_IP | HAVE_OPTIONS;
 	}
 
@@ -1611,6 +1633,12 @@
 			break;
 
 		default: /*options ... */
+			if (!(cmd->len & (F_OR|F_NOT)))
+				if (((cmd->opcode == O_IP6) &&
+				    (flags & HAVE_PROTO6)) ||
+				    ((cmd->opcode == O_IP4) &&
+				    (flags & HAVE_PROTO4)))
+					break;
 			show_prerequisites(&flags, HAVE_IP | HAVE_OPTIONS, 0);
 			if ((cmd->len & F_OR) && !or_block)
 				printf(" {");
@@ -1810,10 +1838,14 @@
 			    }
 				break;
 
-			case O_IP6:   
+			case O_IP6:
 				printf(" ipv6");
 				break;
 
+			case O_IP4:
+				printf(" ipv4");
+				break;
+
 			case O_ICMP6TYPE:
 				print_icmp6types((ipfw_insn_u32 *)cmd);
 				break;
@@ -3506,13 +3538,18 @@
 	*proto = IPPROTO_IP;
 
 	if (_substrcmp(av, "all") == 0)
-		; /* same as "ip" */
-	else if ((*proto = atoi(av)) > 0)
+		; /* do not set O_IP4 nor O_IP6 */
+	else if (strcmp(av, "ipv4") == 0 || strcmp(av, "ip4") == 0)
+		/* explicit "just IPv4" rule */
+		fill_cmd(cmd, O_IP4, 0, 0);
+	else if (strcmp(av, "ipv6") == 0 || strcmp(av, "ip6") == 0) {
+		/* explicit "just IPv6" rule */
+		*proto = IPPROTO_IPV6;
+		fill_cmd(cmd, O_IP6, 0, 0);
+	} else if ((*proto = atoi(av)) > 0)
 		; /* all done! */
 	else if ((pe = getprotobyname(av)) != NULL)
 		*proto = pe->p_proto;
-	else if (strcmp(av, "ipv6") == 0 || strcmp(av, "ip6") == 0)
-		*proto = IPPROTO_IPV6;
 	else
 		return NULL;
 	if (*proto != IPPROTO_IP && *proto != IPPROTO_IPV6)
@@ -4347,8 +4384,6 @@
 		case TOK_PROTO:
 			NEED1("missing protocol");
 			if (add_proto(cmd, *av, &proto)) {
-				if (proto == IPPROTO_IPV6)
-					fill_cmd(cmd, O_IP6, 0, 0);
 				ac--; av++;
 			} else
 				errx(EX_DATAERR, "invalid protocol ``%s''",
@@ -4435,6 +4470,10 @@
 			fill_cmd(cmd, O_IP6, 0, 0);
 			break;
 
+		case TOK_IPV4:
+			fill_cmd(cmd, O_IP4, 0, 0);
+			break;
+
 		case TOK_EXT6HDR:
 			fill_ext6hdr( cmd, *av );
 			ac--; av++;
Index: sys/netinet/ip_fw.h
===================================================================
RCS file: /usr/store/mlaier/fcvs/src/sys/netinet/ip_fw.h,v
retrieving revision 1.99
diff -u -r1.99 ip_fw.h
--- sys/netinet/ip_fw.h	4 May 2005 13:12:52 -0000	1.99
+++ sys/netinet/ip_fw.h	19 May 2005 00:30:39 -0000
@@ -153,6 +153,8 @@
 	O_NETGRAPH,		/* send to ng_ipfw		*/
 	O_NGTEE,		/* copy to ng_ipfw		*/
 
+	O_IP4,
+
 	O_LAST_OPCODE		/* not an opcode!		*/
 };
 
Index: sys/netinet/ip_fw2.c
===================================================================
RCS file: /usr/store/mlaier/fcvs/src/sys/netinet/ip_fw2.c,v
retrieving revision 1.97
diff -u -r1.97 ip_fw2.c
--- sys/netinet/ip_fw2.c	4 May 2005 13:12:52 -0000	1.97
+++ sys/netinet/ip_fw2.c	19 May 2005 00:32:55 -0000
@@ -1961,6 +1961,7 @@
 	int is_ipv6 = 0;
 	u_int16_t ext_hd = 0;	/* bits vector for extension header filtering */
 	/* end of ipv6 variables */
+	int is_ipv4 = 0;
 
 	if (m->m_flags & M_SKIP_FIREWALL)
 		return (IP_FW_PASS);	/* accept */
@@ -2071,6 +2072,7 @@
 	} else if (pktlen >= sizeof(struct ip) &&
 	    (args->eh == NULL || ntohs(args->eh->ether_type) == ETHERTYPE_IP) &&
 	    mtod(m, struct ip *)->ip_v == 4) {
+	    	is_ipv4 = 1;
 		ip = mtod(m, struct ip *);
 		hlen = ip->ip_hl << 2;
 		args->f_id.addr_type = 4;
@@ -2672,6 +2674,10 @@
 				break;
 #endif
 
+			case O_IP4:
+				match = is_ipv4;
+				break;
+
 			/*
 			 * The second set of opcodes represents 'actions',
 			 * i.e. the terminal part of a rule once the packet
@@ -3317,6 +3323,7 @@
 		case O_IP6_DST_ME:
 		case O_EXT_HDR:
 		case O_IP6:
+		case O_IP4:
 			if (cmdlen != F_INSN_SIZE(ipfw_insn))
 				goto bad_size;
 			break;

Attachment: pgpi0rFYIFH2I.pgp
Description: PGP signature

Reply via email to