Always quote the entire TCP header when responding and allocate an mbuf
cluster if needed. Fixes the TCP issues raised in I-D draft-gont-icmp-payload-00.txt. This aids in-the-wild debugging a lot and allows the receiver to do more elaborate checks on the validity of the response. MFC after: 2 weeks Sponsored by: TCP/IP Optimization Fundraise 2005
This commit is contained in:
parent
1afbca0a45
commit
ef76245e90
@ -183,7 +183,7 @@ icmp_error(n, type, code, dest, mtu)
|
|||||||
/*
|
/*
|
||||||
* First, formulate icmp message
|
* First, formulate icmp message
|
||||||
*/
|
*/
|
||||||
m = m_gethdr(M_DONTWAIT, MT_HEADER);
|
MGETHDR(m, M_DONTWAIT, MT_HEADER);
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
goto freeit;
|
goto freeit;
|
||||||
#ifdef MAC
|
#ifdef MAC
|
||||||
@ -193,11 +193,31 @@ icmp_error(n, type, code, dest, mtu)
|
|||||||
* Calculate length to quote from original packet and
|
* Calculate length to quote from original packet and
|
||||||
* prevent the ICMP mbuf from overflowing.
|
* prevent the ICMP mbuf from overflowing.
|
||||||
*/
|
*/
|
||||||
icmplen = min(oiplen + max(8, icmp_quotelen), oip->ip_len);
|
if (oip->ip_p == IPPROTO_TCP) {
|
||||||
icmplen = min(icmplen, M_TRAILINGSPACE(m) -
|
struct tcphdr *th;
|
||||||
(ICMP_MINLEN + sizeof(struct ip)));
|
int tcphlen;
|
||||||
|
|
||||||
|
if (n->m_len < oiplen + sizeof(struct tcphdr) &&
|
||||||
|
((n = m_pullup(n, oiplen + sizeof(struct tcphdr))) == NULL))
|
||||||
|
goto freeit;
|
||||||
|
th = (struct tcphdr *)((caddr_t)oip + oiplen);
|
||||||
|
tcphlen = th->th_off << 2;
|
||||||
|
if (tcphlen < sizeof(struct tcphdr))
|
||||||
|
goto freeit;
|
||||||
|
if (oip->ip_len < oiplen + tcphlen)
|
||||||
|
goto freeit;
|
||||||
|
if (n->m_len < oiplen + tcphlen &&
|
||||||
|
((n = m_pullup(n, oiplen + tcphlen)) == NULL))
|
||||||
|
goto freeit;
|
||||||
|
icmplen = max(oiplen + tcphlen, min(icmp_quotelen, oip->ip_len));
|
||||||
|
} else
|
||||||
|
icmplen = min(oiplen + max(8, icmp_quotelen), oip->ip_len);
|
||||||
if (icmplen < sizeof(struct ip))
|
if (icmplen < sizeof(struct ip))
|
||||||
panic("icmp_error: bad length");
|
panic("icmp_error: bad length");
|
||||||
|
if (icmplen + ICMP_MINLEN + sizeof(struct ip) > MHLEN)
|
||||||
|
MCLGET(m, M_DONTWAIT);
|
||||||
|
if (!(m->m_flags & M_EXT))
|
||||||
|
goto freeit;
|
||||||
m->m_len = icmplen + ICMP_MINLEN;
|
m->m_len = icmplen + ICMP_MINLEN;
|
||||||
MH_ALIGN(m, m->m_len);
|
MH_ALIGN(m, m->m_len);
|
||||||
icp = mtod(m, struct icmp *);
|
icp = mtod(m, struct icmp *);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user