mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2025-01-01 12:00:53 +00:00
Corrected bug #19937: ICMP assumes p_buf has space for ethernet header. Allocating new pbuf if the input pbuf isn't big enough.
This commit is contained in:
parent
d5a159d7af
commit
7abfe74fa4
@ -170,7 +170,13 @@ HISTORY
|
|||||||
|
|
||||||
++ Bug fixes:
|
++ Bug fixes:
|
||||||
|
|
||||||
2007-05-22 Simon Goldschmidt
|
2007-06-03 Simon Goldschmidt
|
||||||
|
* icmp.c: Corrected bug #19937: For responding to an icmp echo request, icmp
|
||||||
|
re-used the input pbuf even if that didn't have enough space to include the
|
||||||
|
link headers. Now the space is tested and a new pbuf is allocated for the
|
||||||
|
echo response packet if the echo request pbuf isn't big enough.
|
||||||
|
|
||||||
|
2007-06-01 Simon Goldschmidt
|
||||||
* sockets.c: Checked in patch #5914: Moved sockopt processing into tcpip_thread.
|
* sockets.c: Checked in patch #5914: Moved sockopt processing into tcpip_thread.
|
||||||
|
|
||||||
2007-05-23 Frédéric Bernon
|
2007-05-23 Frédéric Bernon
|
||||||
|
@ -51,7 +51,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
|
|||||||
struct icmp_echo_hdr *iecho;
|
struct icmp_echo_hdr *iecho;
|
||||||
struct ip_hdr *iphdr;
|
struct ip_hdr *iphdr;
|
||||||
struct ip_addr tmpaddr;
|
struct ip_addr tmpaddr;
|
||||||
u16_t hlen;
|
s16_t hlen;
|
||||||
|
|
||||||
ICMP_STATS_INC(icmp.recv);
|
ICMP_STATS_INC(icmp.recv);
|
||||||
snmp_inc_icmpinmsgs();
|
snmp_inc_icmpinmsgs();
|
||||||
@ -59,12 +59,9 @@ icmp_input(struct pbuf *p, struct netif *inp)
|
|||||||
|
|
||||||
iphdr = p->payload;
|
iphdr = p->payload;
|
||||||
hlen = IPH_HL(iphdr) * 4;
|
hlen = IPH_HL(iphdr) * 4;
|
||||||
if (pbuf_header(p, -((s16_t)hlen)) || (p->tot_len < sizeof(u16_t)*2)) {
|
if (pbuf_header(p, -hlen) || (p->tot_len < sizeof(u16_t)*2)) {
|
||||||
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%"U16_F" bytes) received\n", p->tot_len));
|
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%"U16_F" bytes) received\n", p->tot_len));
|
||||||
pbuf_free(p);
|
goto lenerr;
|
||||||
ICMP_STATS_INC(icmp.lenerr);
|
|
||||||
snmp_inc_icmpinerrors();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type = *((u8_t *)p->payload);
|
type = *((u8_t *)p->payload);
|
||||||
@ -81,13 +78,8 @@ icmp_input(struct pbuf *p, struct netif *inp)
|
|||||||
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n"));
|
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n"));
|
||||||
if (p->tot_len < sizeof(struct icmp_echo_hdr)) {
|
if (p->tot_len < sizeof(struct icmp_echo_hdr)) {
|
||||||
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n"));
|
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n"));
|
||||||
pbuf_free(p);
|
goto lenerr;
|
||||||
ICMP_STATS_INC(icmp.lenerr);
|
|
||||||
snmp_inc_icmpinerrors();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
iecho = p->payload;
|
|
||||||
if (inet_chksum_pbuf(p) != 0) {
|
if (inet_chksum_pbuf(p) != 0) {
|
||||||
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n"));
|
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n"));
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
@ -95,6 +87,48 @@ icmp_input(struct pbuf *p, struct netif *inp)
|
|||||||
snmp_inc_icmpinerrors();
|
snmp_inc_icmpinerrors();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (pbuf_header(p, (PBUF_IP_HLEN + PBUF_LINK_HLEN))) {
|
||||||
|
/* p is not big enough to contain link headers
|
||||||
|
* allocate a new one and copy p into it
|
||||||
|
*/
|
||||||
|
struct pbuf *r;
|
||||||
|
/* switch p->payload to ip header */
|
||||||
|
if (pbuf_header(p, hlen)) {
|
||||||
|
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: moving p->payload to ip header failed\n"));
|
||||||
|
goto memerr;
|
||||||
|
}
|
||||||
|
/* allocate new packet buffer with space for link headers */
|
||||||
|
r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM);
|
||||||
|
if (r == NULL) {
|
||||||
|
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: allocating new pbuf failed\n"));
|
||||||
|
goto memerr;
|
||||||
|
}
|
||||||
|
/* copy the whole packet including ip header */
|
||||||
|
if (pbuf_copy(r, p) != ERR_OK) {
|
||||||
|
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: copying to new pbuf failed\n"));
|
||||||
|
goto memerr;
|
||||||
|
}
|
||||||
|
iphdr = r->payload;
|
||||||
|
/* switch r->payload back to icmp header */
|
||||||
|
if (pbuf_header(r, -hlen)) {
|
||||||
|
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: restoring original p->payload failed\n"));
|
||||||
|
goto memerr;
|
||||||
|
}
|
||||||
|
/* free the original p */
|
||||||
|
pbuf_free(p);
|
||||||
|
/* we now have an identical copy of p that has room for link headers */
|
||||||
|
p = r;
|
||||||
|
} else {
|
||||||
|
/* restore p->payload to point to icmp header */
|
||||||
|
if (pbuf_header(p, -(s16_t)(PBUF_IP_HLEN + PBUF_LINK_HLEN))) {
|
||||||
|
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: restoring original p->payload failed\n"));
|
||||||
|
goto memerr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* At this point, all checks are OK. */
|
||||||
|
/* We generate an answer by switching the dest and src ip addresses,
|
||||||
|
* setting the icmp type to ECHO_RESPONSE and updating the checksum. */
|
||||||
|
iecho = p->payload;
|
||||||
tmpaddr.addr = iphdr->src.addr;
|
tmpaddr.addr = iphdr->src.addr;
|
||||||
iphdr->src.addr = iphdr->dest.addr;
|
iphdr->src.addr = iphdr->dest.addr;
|
||||||
iphdr->dest.addr = tmpaddr.addr;
|
iphdr->dest.addr = tmpaddr.addr;
|
||||||
@ -123,6 +157,17 @@ icmp_input(struct pbuf *p, struct netif *inp)
|
|||||||
ICMP_STATS_INC(icmp.drop);
|
ICMP_STATS_INC(icmp.drop);
|
||||||
}
|
}
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
|
return;
|
||||||
|
lenerr:
|
||||||
|
pbuf_free(p);
|
||||||
|
ICMP_STATS_INC(icmp.lenerr);
|
||||||
|
snmp_inc_icmpinerrors();
|
||||||
|
return;
|
||||||
|
memerr:
|
||||||
|
pbuf_free(p);
|
||||||
|
ICMP_STATS_INC(icmp.err);
|
||||||
|
snmp_inc_icmpinerrors();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user