Date: Mon, 12 Jan 2009 23:17:12 +0000 (UTC) From: Paolo Pisati <piso@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r187122 - user/piso/sys/netinet Message-ID: <200901122317.n0CNHC1L079235@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: piso Date: Mon Jan 12 23:17:12 2009 New Revision: 187122 URL: http://svn.freebsd.org/changeset/base/187122 Log: In case of fragments, reassemble the packet before passing it to libalias. Modified: user/piso/sys/netinet/ip_fw_nat.c Modified: user/piso/sys/netinet/ip_fw_nat.c ============================================================================== --- user/piso/sys/netinet/ip_fw_nat.c Mon Jan 12 22:53:26 2009 (r187121) +++ user/piso/sys/netinet/ip_fw_nat.c Mon Jan 12 23:17:12 2009 (r187122) @@ -252,7 +252,7 @@ ipfw_nat(struct ip_fw_args *args, struct struct mbuf *mcl; struct ip *ip; /* XXX - libalias duct tape */ - int ldt, retval; + int ldt, retval, off; char *c; ldt = 0; @@ -261,7 +261,51 @@ ipfw_nat(struct ip_fw_args *args, struct NULL) goto badnat; ip = mtod(mcl, struct ip *); - if (args->eh == NULL) { + /* + * In case of fragments, reassemble the packet + * before passing it to libalias. + */ + off = (args->eh == NULL) ? ip->ip_off : ntohs(ip->ip_off); + if (off & (IP_MF | IP_OFFMASK)) { + struct mbuf *reass; + + /* + * Ip_reass() expects len & off in host byte order: + * fix them in case we come from layer2. + */ + if (args->eh != NULL) { + ip->ip_len = ntohs(ip->ip_len); + ip->ip_off = ntohs(ip->ip_off); + } + + /* Reassemble packet. */ + reass = ip_reass(mcl); + + /* + * IP header checksum fixup after reassembly and leave header + * in network byte order. + */ + if (reass != NULL) { + int hlen; + + ip = mtod(reass, struct ip *); + hlen = ip->ip_hl << 2; + ip->ip_len = htons(ip->ip_len); + ip->ip_off = htons(ip->ip_off); + ip->ip_sum = 0; + if (hlen == sizeof(struct ip)) + ip->ip_sum = in_cksum_hdr(ip); + else + ip->ip_sum = in_cksum(reass, hlen); + if ((mcl = m_megapullup(reass, reass->m_pkthdr.len)) == + NULL) + goto badnat; + ip = mtod(mcl, struct ip *); + } else { + mcl = NULL; + goto badnat; + } + } else if (args->eh == NULL) { ip->ip_len = htons(ip->ip_len); ip->ip_off = htons(ip->ip_off); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200901122317.n0CNHC1L079235>