Date: Wed, 25 May 2005 16:34:23 +0200 From: Max Laier <max@love2party.net> To: freebsd-ipfw@freebsd.org Subject: [PATCH] ipv4 only rules (test and feedback) Message-ID: <200505251634.34478.max@love2party.net>
next in thread | raw e-mail | index | archive | help
--nextPart3147247.EOBnkcBnR9 Content-Type: multipart/mixed; boundary="Boundary-01=_wzIlCq5E0qbcCzR" Content-Transfer-Encoding: 7bit Content-Disposition: inline --Boundary-01=_wzIlCq5E0qbcCzR Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline All, with the recent merge of IPv6 functionality into ipfw2, ip6fw is obsolete. = As=20 the latter is neither locked nor using the pfil_hooks API, it was decided=20 that it should be be removed. Of course, this means that ipfw2 has to=20 provide all the functionality that ip6fw provided before. In order to achieve this, there is one feature missing [for all I know, ple= ase=20 scream now if you have anything else]: IPv4 only rules. Previously, it was= =20 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= =20 longer work as it will block IPv6 traffic as well. With the patch attached= =20 you can now do: =20 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 tes= t=20 the patch and send you feedback. Be sure to have kernel and userland in=20 sync! =2D-=20 /"\ Best regards, | mlaier@freebsd.org \ / Max Laier | ICQ #67774661 X http://pf4freebsd.love2party.net/ | mlaier@EFnet / \ ASCII Ribbon Campaign | Against HTML Mail and News --Boundary-01=_wzIlCq5E0qbcCzR Content-Type: text/x-diff; charset="us-ascii"; name="ipv4-only.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="ipv4-only.patch" Index: sbin/ipfw/ipfw2.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /usr/store/mlaier/fcvs/src/sbin/ipfw/ipfw2.c,v retrieving revision 1.74 diff -u -r1.74 ipfw2.c =2D-- 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, }; =20 struct _s_x dummynet_params[] =3D { @@ -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 =20 @@ -1283,11 +1288,14 @@ return; } if ( !(*flags & HAVE_OPTIONS)) { =2D /* XXX BED: !(*flags & HAVE_PROTO) in patch */ =2D if ( !(*flags & HAVE_PROTO6) && (want & HAVE_PROTO6)) =2D printf(" ipv6"); if ( !(*flags & HAVE_PROTO) && (want & HAVE_PROTO)) =2D 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 =3D rule->act_ofs, cmd =3D rule->cmd ; + l > 0 ; l -=3D F_LEN(cmd) , cmd +=3D F_LEN(cmd)) { + if ((cmd->len & F_OR) || (cmd->len & F_NOT)) + continue; + if (cmd->opcode =3D=3D O_IP4) { + flags |=3D HAVE_PROTO4; + break; + } else if (cmd->opcode =3D=3D O_IP6) { + flags |=3D HAVE_PROTO6; + break; + } =09 + } if (rule->_pad & 1) { /* empty rules before options */ =2D if (!do_compact) =2D printf(" ip from any to any"); + if (!do_compact) { + show_prerequisites(&flags, HAVE_PROTO, 0); + printf(" from any to any"); + } flags |=3D HAVE_IP | HAVE_OPTIONS; } =20 @@ -1611,6 +1633,12 @@ break; =20 default: /*options ... */ + if (!(cmd->len & (F_OR|F_NOT))) + if (((cmd->opcode =3D=3D O_IP6) && + (flags & HAVE_PROTO6)) || + ((cmd->opcode =3D=3D 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; =20 =2D case O_IP6: =20 + case O_IP6: printf(" ipv6"); break; =20 + case O_IP4: + printf(" ipv4"); + break; + case O_ICMP6TYPE: print_icmp6types((ipfw_insn_u32 *)cmd); break; @@ -3506,13 +3538,18 @@ *proto =3D IPPROTO_IP; =20 if (_substrcmp(av, "all") =3D=3D 0) =2D ; /* same as "ip" */ =2D else if ((*proto =3D atoi(av)) > 0) + ; /* do not set O_IP4 nor O_IP6 */ + else if (strcmp(av, "ipv4") =3D=3D 0 || strcmp(av, "ip4") =3D=3D 0) + /* explicit "just IPv4" rule */ + fill_cmd(cmd, O_IP4, 0, 0); + else if (strcmp(av, "ipv6") =3D=3D 0 || strcmp(av, "ip6") =3D=3D 0) { + /* explicit "just IPv6" rule */ + *proto =3D IPPROTO_IPV6; + fill_cmd(cmd, O_IP6, 0, 0); + } else if ((*proto =3D atoi(av)) > 0) ; /* all done! */ else if ((pe =3D getprotobyname(av)) !=3D NULL) *proto =3D pe->p_proto; =2D else if (strcmp(av, "ipv6") =3D=3D 0 || strcmp(av, "ip6") =3D=3D 0) =2D *proto =3D IPPROTO_IPV6; else return NULL; if (*proto !=3D IPPROTO_IP && *proto !=3D IPPROTO_IPV6) @@ -4347,8 +4384,6 @@ case TOK_PROTO: NEED1("missing protocol"); if (add_proto(cmd, *av, &proto)) { =2D if (proto =3D=3D IPPROTO_IPV6) =2D 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; =20 + 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /usr/store/mlaier/fcvs/src/sys/netinet/ip_fw.h,v retrieving revision 1.99 diff -u -r1.99 ip_fw.h =2D-- 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 */ =20 + O_IP4, + O_LAST_OPCODE /* not an opcode! */ }; =20 Index: sys/netinet/ip_fw2.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /usr/store/mlaier/fcvs/src/sys/netinet/ip_fw2.c,v retrieving revision 1.97 diff -u -r1.97 ip_fw2.c =2D-- 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 =3D 0; u_int16_t ext_hd =3D 0; /* bits vector for extension header filtering */ /* end of ipv6 variables */ + int is_ipv4 =3D 0; =20 if (m->m_flags & M_SKIP_FIREWALL) return (IP_FW_PASS); /* accept */ @@ -2071,6 +2072,7 @@ } else if (pktlen >=3D sizeof(struct ip) && (args->eh =3D=3D NULL || ntohs(args->eh->ether_type) =3D=3D ETHERTYPE= _IP) && mtod(m, struct ip *)->ip_v =3D=3D 4) { + is_ipv4 =3D 1; ip =3D mtod(m, struct ip *); hlen =3D ip->ip_hl << 2; args->f_id.addr_type =3D 4; @@ -2672,6 +2674,10 @@ break; #endif =20 + case O_IP4: + match =3D 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 !=3D F_INSN_SIZE(ipfw_insn)) goto bad_size; break; --Boundary-01=_wzIlCq5E0qbcCzR-- --nextPart3147247.EOBnkcBnR9 Content-Type: application/pgp-signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.1 (FreeBSD) iD8DBQBClIz6XyyEoT62BG0RAinwAJ9nZ+7c4Qpfmm4v4yRdoftvOk6zzgCfTsFw vDu6vg1BrhGhrnWO1uJxV3s= =kNwn -----END PGP SIGNATURE----- --nextPart3147247.EOBnkcBnR9--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200505251634.34478.max>