From owner-svn-src-user@FreeBSD.ORG Mon Jan 12 23:17:12 2009 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8AC541065697; Mon, 12 Jan 2009 23:17:12 +0000 (UTC) (envelope-from piso@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 60A048FC13; Mon, 12 Jan 2009 23:17:12 +0000 (UTC) (envelope-from piso@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n0CNHC5L079236; Mon, 12 Jan 2009 23:17:12 GMT (envelope-from piso@svn.freebsd.org) Received: (from piso@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n0CNHC1L079235; Mon, 12 Jan 2009 23:17:12 GMT (envelope-from piso@svn.freebsd.org) Message-Id: <200901122317.n0CNHC1L079235@svn.freebsd.org> From: Paolo Pisati Date: Mon, 12 Jan 2009 23:17:12 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r187122 - user/piso/sys/netinet X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 12 Jan 2009 23:17:12 -0000 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); }