diff options
Diffstat (limited to 'sys/netinet/ip_icmp.c')
-rw-r--r-- | sys/netinet/ip_icmp.c | 32 |
1 files changed, 13 insertions, 19 deletions
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c index f6b4c3c8f80..bfb394bdc82 100644 --- a/sys/netinet/ip_icmp.c +++ b/sys/netinet/ip_icmp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_icmp.c,v 1.180 2018/11/05 21:50:39 claudio Exp $ */ +/* $OpenBSD: ip_icmp.c,v 1.181 2018/11/28 08:15:29 claudio Exp $ */ /* $NetBSD: ip_icmp.c,v 1.19 1996/02/13 23:42:22 christos Exp $ */ /* @@ -212,7 +212,8 @@ icmp_do_error(struct mbuf *n, int type, int code, u_int32_t dest, int destmtu) icmplen = MCLBYTES - ICMP_MINLEN - sizeof (struct ip); m = m_gethdr(M_DONTWAIT, MT_HEADER); - if (m && (sizeof (struct ip) + icmplen + ICMP_MINLEN > MHLEN)) { + if (m && ((sizeof (struct ip) + icmplen + ICMP_MINLEN + + sizeof(long) - 1) &~ (sizeof(long) - 1)) > MHLEN) { MCLGET(m, M_DONTWAIT); if ((m->m_flags & M_EXT) == 0) { m_freem(m); @@ -221,14 +222,14 @@ icmp_do_error(struct mbuf *n, int type, int code, u_int32_t dest, int destmtu) } if (m == NULL) goto freeit; - /* keep in same rtable */ + /* keep in same rtable and preserve other pkthdr bits */ m->m_pkthdr.ph_rtableid = n->m_pkthdr.ph_rtableid; - m->m_len = icmplen + ICMP_MINLEN; - if ((m->m_flags & M_EXT) == 0) - MH_ALIGN(m, m->m_len); - else - m->m_data += (m->m_ext.ext_size - m->m_len) & - ~(sizeof(long) - 1); + m->m_pkthdr.ph_ifidx = n->m_pkthdr.ph_ifidx; + /* move PF_GENERATED to new packet, if existent XXX preserve more? */ + if (n->m_pkthdr.pf.flags & PF_TAG_GENERATED) + m->m_pkthdr.pf.flags |= PF_TAG_GENERATED; + m->m_pkthdr.len = m->m_len = icmplen + ICMP_MINLEN; + m_align(m, m->m_len); icp = mtod(m, struct icmp *); if ((u_int)type > ICMP_MAXTYPE) panic("icmp_error"); @@ -257,12 +258,9 @@ icmp_do_error(struct mbuf *n, int type, int code, u_int32_t dest, int destmtu) * Now, copy old ip header (without options) * in front of icmp message. */ - if (m_leadingspace(m) < sizeof(struct ip)) - panic("icmp len"); - m->m_data -= sizeof(struct ip); - m->m_len += sizeof(struct ip); - m->m_pkthdr.len = m->m_len; - m->m_pkthdr.ph_ifidx = n->m_pkthdr.ph_ifidx; + m = m_prepend(m, sizeof(struct ip), M_DONTWAIT); + if (m == NULL) + goto freeit; nip = mtod(m, struct ip *); /* ip_v set in ip_output */ nip->ip_hl = sizeof(struct ip) >> 2; @@ -275,10 +273,6 @@ icmp_do_error(struct mbuf *n, int type, int code, u_int32_t dest, int destmtu) nip->ip_src = oip->ip_src; nip->ip_dst = oip->ip_dst; - /* move PF_GENERATED to new packet, if existent XXX preserve more? */ - if (n->m_pkthdr.pf.flags & PF_TAG_GENERATED) - m->m_pkthdr.pf.flags |= PF_TAG_GENERATED; - m_freem(n); return (m); |