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;
pgpi0rFYIFH2I.pgp
Description: PGP signature