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 - 1.74
+++ sbin/ipfw/ipfw2.c 24 May 2005 19:19:30 -
@@ -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;
+