When delivering an ICMP packet to the ctlinput function, ensure that
the outer IP header, the ICMP header, the inner IP header and the first n bytes are stored in contgous memory. The ctlinput functions currently rely on this for n = 8. This fixes a bug in case the inner IP header had options. While there, remove the options from the outer header and provide a way to increase n to allow improved ICMP handling for SCTP. This will be added in another commit. MFC after: 1 week
This commit is contained in:
parent
9b8f7eaf6a
commit
f77b842746
@ -475,6 +475,23 @@ icmp_input(struct mbuf **mp, int *offp, int proto)
|
|||||||
* XXX if the packet contains [IPv4 AH TCP], we can't make a
|
* XXX if the packet contains [IPv4 AH TCP], we can't make a
|
||||||
* notification to TCP layer.
|
* notification to TCP layer.
|
||||||
*/
|
*/
|
||||||
|
i = sizeof(struct ip) + min(icmplen, ICMP_ADVLENPREF(icp));
|
||||||
|
ip_stripoptions(m);
|
||||||
|
if (m->m_len < i && (m = m_pullup(m, i)) == NULL) {
|
||||||
|
/* This should actually not happen */
|
||||||
|
ICMPSTAT_INC(icps_tooshort);
|
||||||
|
return (IPPROTO_DONE);
|
||||||
|
}
|
||||||
|
ip = mtod(m, struct ip *);
|
||||||
|
icp = (struct icmp *)(ip + 1);
|
||||||
|
/*
|
||||||
|
* The upper layer handler can rely on:
|
||||||
|
* - The outer IP header has no options.
|
||||||
|
* - The outer IP header, the ICMP header, the inner IP header,
|
||||||
|
* and the first n bytes of the inner payload are contiguous.
|
||||||
|
* n is at least 8, but might be larger based on
|
||||||
|
* ICMP_ADVLENPREF. See its definition in ip_icmp.h.
|
||||||
|
*/
|
||||||
ctlfunc = inetsw[ip_protox[icp->icmp_ip.ip_p]].pr_ctlinput;
|
ctlfunc = inetsw[ip_protox[icp->icmp_ip.ip_p]].pr_ctlinput;
|
||||||
if (ctlfunc)
|
if (ctlfunc)
|
||||||
(*ctlfunc)(code, (struct sockaddr *)&icmpsrc,
|
(*ctlfunc)(code, (struct sockaddr *)&icmpsrc,
|
||||||
|
@ -136,6 +136,12 @@ struct icmp {
|
|||||||
#define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */
|
#define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */
|
||||||
#define ICMP_ADVLEN(p) (8 + ((p)->icmp_ip.ip_hl << 2) + 8)
|
#define ICMP_ADVLEN(p) (8 + ((p)->icmp_ip.ip_hl << 2) + 8)
|
||||||
/* N.B.: must separately check that ip_hl >= 5 */
|
/* N.B.: must separately check that ip_hl >= 5 */
|
||||||
|
/* This is the minimum length required by RFC 792. */
|
||||||
|
/*
|
||||||
|
* ICMP_ADVLENPREF is the preferred number of bytes which should be contiguous.
|
||||||
|
* It currently reflects the required minimum.
|
||||||
|
*/
|
||||||
|
#define ICMP_ADVLENPREF(p) (8 + ((p)->icmp_ip.ip_hl << 2) + 8)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Definition of type and code field values.
|
* Definition of type and code field values.
|
||||||
|
Loading…
Reference in New Issue
Block a user