diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netinet/ip_input.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 339a16356b3..0a3f285fd0d 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_input.c,v 1.166 2009/07/28 14:01:50 dlg Exp $ */ +/* $OpenBSD: ip_input.c,v 1.167 2009/08/10 11:48:02 henning Exp $ */ /* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */ /* @@ -1423,10 +1423,10 @@ ip_forward(m, srcrt) struct ip *ip = mtod(m, struct ip *); struct sockaddr_in *sin; struct rtentry *rt; - int error, type = 0, code = 0, destmtu = 0; + int error, type = 0, code = 0, destmtu = 0, len; u_int rtableid = 0; - struct mbuf *mcopy; n_long dest; + struct mbuf mfake, *mcopy; dest = 0; #ifdef DIAGNOSTIC @@ -1472,11 +1472,14 @@ ip_forward(m, srcrt) /* * Save at most 68 bytes of the packet in case * we need to generate an ICMP message to the src. - * Pullup to avoid sharing mbuf cluster between m and mcopy. */ - mcopy = m_copym(m, 0, min(ntohs(ip->ip_len), 68), M_DONTWAIT); - if (mcopy) - mcopy = m_pullup(mcopy, min(ntohs(ip->ip_len), 68)); + bzero(&mfake.m_hdr, sizeof(mfake.m_hdr)); + mfake.m_type = m->m_type; + M_DUP_PKTHDR(&mfake, m); + mfake.m_data = mfake.m_pktdat; + len = min(ntohs(ip->ip_len), 68); + bcopy(ip, mfake.m_pktdat, len); + mfake.m_pkthdr.len = mfake.m_len = len; ip->ip_ttl -= IPTTLDEC; @@ -1525,8 +1528,6 @@ ip_forward(m, srcrt) else goto freecopy; } - if (mcopy == NULL) - goto freert; switch (error) { @@ -1576,7 +1577,9 @@ ip_forward(m, srcrt) #endif } - icmp_error(mcopy, type, code, dest, destmtu); + mcopy = m_copym(&mfake, 0, len, M_DONTWAIT); + if (mcopy) + icmp_error(mcopy, type, code, dest, destmtu); goto freert; freecopy: |