On world IPv6 day I was asked by bz@ to re-spin the patch supplied in
the PR with the second and third IPv6 fragment issues listed in the PR
fixed, but not the first (discarding IPv6 packets with a fragment header
but not fragmented). Attached is the revised patch, against 8.2R
--- ip_fw_log.c.orig 2011-06-24 19:46:44.000000000 +1200
+++ ip_fw_log.c 2011-06-24 20:14:55.724751000 +1200
@@ -168,6 +168,7 @@ ipfw_log(struct ip_fw *f, u_int hlen, st
char *action;
int limit_reached = 0;
char action2[40], proto[128], fragment[32];
+ u_short mf = 0;
if (V_fw_verbose == 0) {
#ifndef WITHOUT_BPF
@@ -337,6 +338,8 @@ ipfw_log(struct ip_fw *f, u_int hlen, st
snprintf(dst, sizeof(dst), "[%s]",
ip6_sprintf(ip6buf, &args->f_id.dst_ip6));
+ mf = offset & IP6F_MORE_FRAG;
+ offset &= IP6F_OFF_MASK;
ip6 = (struct ip6_hdr *)ip;
tcp = (struct tcphdr *)(((char *)ip) + hlen);
udp = (struct udphdr *)(((char *)ip) + hlen);
@@ -406,13 +409,13 @@ ipfw_log(struct ip_fw *f, u_int hlen, st
#ifdef INET6
if (IS_IP6_FLOW_ID(&(args->f_id))) {
- if (offset & (IP6F_OFF_MASK | IP6F_MORE_FRAG))
+ if (offset || mf)
snprintf(SNPARGS(fragment, 0),
" (frag %08x:%d@%d%s)",
args->f_id.extra,
ntohs(ip6->ip6_plen) - hlen,
- ntohs(offset & IP6F_OFF_MASK) << 3,
- (offset & IP6F_MORE_FRAG) ? "+" : "");
+ ntohs(offset) << 3,
+ mf ? "+" : "");
} else
#endif
{
--- ip_fw2.c.orig 2011-06-24 19:31:28.000000000 +1200
+++ ip_fw2.c 2011-06-24 20:14:55.724751000 +1200
@@ -838,16 +838,13 @@ ipfw_chk(struct ip_fw_args *args)
/*
* offset The offset of a fragment. offset != 0 means that
- * we have a fragment at this offset of an IPv4 packet.
- * offset == 0 means that (if this is an IPv4 packet)
- * this is the first or only fragment.
- * For IPv6 offset == 0 means there is no Fragment Header.
- * If offset != 0 for IPv6 always use correct mask to
- * get the correct offset because we add IP6F_MORE_FRAG
- * to be able to dectect the first fragment which would
- * otherwise have offset = 0.
+ * we have a fragment at this offset.
+ * offset == 0 means that this is the first or only fragment.
+ *
+ * mf The MF bit masked out of IPv6 packets.
*/
u_short offset = 0;
+ u_short mf = 0;
/*
* Local copies of addresses. They are only valid if we have
@@ -940,7 +937,7 @@ do {
\
proto = ip6->ip6_nxt;
/* Search extension headers to find upper layer protocols */
- while (ulp == NULL) {
+ while (ulp == NULL && offset == 0) {
switch (proto) {
case IPPROTO_ICMPV6:
PULLUP_TO(hlen, ulp, struct icmp6_hdr);
@@ -1005,11 +1002,9 @@ do {
\
proto = ((struct ip6_frag *)ulp)->ip6f_nxt;
offset = ((struct ip6_frag *)ulp)->ip6f_offlg &
IP6F_OFF_MASK;
- /* Add IP6F_MORE_FRAG for offset of first
- * fragment to be != 0. */
- offset |= ((struct ip6_frag *)ulp)->ip6f_offlg &
+ mf = ((struct ip6_frag *)ulp)->ip6f_offlg &
IP6F_MORE_FRAG;
- if (offset == 0) {
+ if (offset == 0 && mf == 0) {
printf("IPFW2: IPV6 - Invalid Fragment "
"Header\n");
if (V_fw_deny_unknown_exthdrs)
@@ -1650,7 +1645,7 @@ do {
\
case O_LOG:
ipfw_log(f, hlen, args, m,
- oif, offset, tablearg, ip);
+ oif, offset|mf, tablearg, ip);
match = 1;
break;
_______________________________________________
freebsd-bugs@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"