1 |
/* |
/* |
2 |
* Copyright (c) 2001-2003 Swedish Institute of Computer Science. |
* Copyright (c) 2001-2003 Swedish Institute of Computer Science. |
3 |
* All rights reserved. |
* All rights reserved. |
4 |
* |
* |
5 |
* Redistribution and use in source and binary forms, with or without modification, |
* Redistribution and use in source and binary forms, with or without modification, |
6 |
* are permitted provided that the following conditions are met: |
* are permitted provided that the following conditions are met: |
7 |
* |
* |
8 |
* 1. Redistributions of source code must retain the above copyright notice, |
* 1. Redistributions of source code must retain the above copyright notice, |
11 |
* this list of conditions and the following disclaimer in the documentation |
* this list of conditions and the following disclaimer in the documentation |
12 |
* and/or other materials provided with the distribution. |
* and/or other materials provided with the distribution. |
13 |
* 3. The name of the author may not be used to endorse or promote products |
* 3. The name of the author may not be used to endorse or promote products |
14 |
* derived from this software without specific prior written permission. |
* derived from this software without specific prior written permission. |
15 |
* |
* |
16 |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
17 |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
18 |
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT |
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT |
19 |
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
20 |
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT |
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT |
21 |
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
24 |
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY |
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY |
25 |
* OF SUCH DAMAGE. |
* OF SUCH DAMAGE. |
26 |
* |
* |
27 |
* This file is part of the lwIP TCP/IP stack. |
* This file is part of the lwIP TCP/IP stack. |
28 |
* |
* |
29 |
* Author: Adam Dunkels <adam@sics.se> |
* Author: Adam Dunkels <adam@sics.se> |
30 |
* |
* |
31 |
*/ |
*/ |
53 |
struct ip_hdr *iphdr; |
struct ip_hdr *iphdr; |
54 |
struct ip_addr tmpaddr; |
struct ip_addr tmpaddr; |
55 |
u16_t hlen; |
u16_t hlen; |
56 |
|
|
57 |
#ifdef ICMP_STATS |
#ifdef ICMP_STATS |
58 |
++lwip_stats.icmp.recv; |
++lwip_stats.icmp.recv; |
59 |
#endif /* ICMP_STATS */ |
#endif /* ICMP_STATS */ |
60 |
snmp_inc_icmpinmsgs(); |
snmp_inc_icmpinmsgs(); |
61 |
|
|
62 |
|
|
63 |
iphdr = p->payload; |
iphdr = p->payload; |
64 |
hlen = IPH_HL(iphdr) * 4; |
hlen = IPH_HL(iphdr) * 4; |
65 |
if (pbuf_header(p, -((s16_t)hlen)) || (p->tot_len < sizeof(u16_t)*2)) { |
if (pbuf_header(p, -((s16_t)hlen)) || (p->tot_len < sizeof(u16_t)*2)) { |
69 |
++lwip_stats.icmp.lenerr; |
++lwip_stats.icmp.lenerr; |
70 |
#endif /* ICMP_STATS */ |
#endif /* ICMP_STATS */ |
71 |
snmp_inc_icmpinerrors(); |
snmp_inc_icmpinerrors(); |
72 |
return; |
return; |
73 |
} |
} |
74 |
|
|
75 |
type = *((u8_t *)p->payload); |
type = *((u8_t *)p->payload); |
95 |
#endif /* ICMP_STATS */ |
#endif /* ICMP_STATS */ |
96 |
snmp_inc_icmpinerrors(); |
snmp_inc_icmpinerrors(); |
97 |
|
|
98 |
return; |
return; |
99 |
} |
} |
100 |
iecho = p->payload; |
iecho = p->payload; |
101 |
if (inet_chksum_pbuf(p) != 0) { |
if (inet_chksum_pbuf(p) != 0) { |
102 |
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")); |
103 |
pbuf_free(p); |
pbuf_free(p); |
128 |
pbuf_header(p, hlen); |
pbuf_header(p, hlen); |
129 |
ip_output_if (p, &(iphdr->src), IP_HDRINCL, |
ip_output_if (p, &(iphdr->src), IP_HDRINCL, |
130 |
IPH_TTL(iphdr), IP_PROTO_ICMP, inp); |
IPH_TTL(iphdr), IP_PROTO_ICMP, inp); |
131 |
break; |
break; |
132 |
default: |
default: |
133 |
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %d code %d not supported.\n", (int)type, (int)code)); |
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %d code %d not supported.\n", (int)type, (int)code)); |
134 |
#ifdef ICMP_STATS |
#ifdef ICMP_STATS |
145 |
struct pbuf *q; |
struct pbuf *q; |
146 |
struct ip_hdr *iphdr; |
struct ip_hdr *iphdr; |
147 |
struct icmp_dur_hdr *idur; |
struct icmp_dur_hdr *idur; |
148 |
|
|
149 |
q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM); |
q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM); |
150 |
/* ICMP header + IP header + 8 bytes of data */ |
/* ICMP header + IP header + 8 bytes of data */ |
151 |
|
|
152 |
iphdr = p->payload; |
iphdr = p->payload; |
153 |
|
|
154 |
idur = q->payload; |
idur = q->payload; |
155 |
ICMPH_TYPE_SET(idur, ICMP_DUR); |
ICMPH_TYPE_SET(idur, ICMP_DUR); |
156 |
ICMPH_CODE_SET(idur, t); |
ICMPH_CODE_SET(idur, t); |
157 |
|
|
158 |
memcpy((char *)q->payload + 8, p->payload, IP_HLEN + 8); |
memcpy((char *)q->payload + 8, p->payload, IP_HLEN + 8); |
159 |
|
|
160 |
/* calculate checksum */ |
/* calculate checksum */ |
161 |
idur->chksum = 0; |
idur->chksum = 0; |
162 |
idur->chksum = inet_chksum(idur, q->len); |
idur->chksum = inet_chksum(idur, q->len); |
186 |
iphdr = p->payload; |
iphdr = p->payload; |
187 |
#if ICMP_DEBUG |
#if ICMP_DEBUG |
188 |
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from ")); |
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from ")); |
189 |
ip_addr_debug_print(&(iphdr->src)); |
ip_addr_debug_print(ICMP_DEBUG, &(iphdr->src)); |
190 |
LWIP_DEBUGF(ICMP_DEBUG, (" to ")); |
LWIP_DEBUGF(ICMP_DEBUG, (" to ")); |
191 |
ip_addr_debug_print(&(iphdr->dest)); |
ip_addr_debug_print(ICMP_DEBUG, &(iphdr->dest)); |
192 |
LWIP_DEBUGF(ICMP_DEBUG, ("\n")); |
LWIP_DEBUGF(ICMP_DEBUG, ("\n")); |
193 |
#endif /* ICMP_DEBNUG */ |
#endif /* ICMP_DEBNUG */ |
194 |
|
|
198 |
|
|
199 |
/* copy fields from original packet */ |
/* copy fields from original packet */ |
200 |
memcpy((char *)q->payload + 8, (char *)p->payload, IP_HLEN + 8); |
memcpy((char *)q->payload + 8, (char *)p->payload, IP_HLEN + 8); |
201 |
|
|
202 |
/* calculate checksum */ |
/* calculate checksum */ |
203 |
tehdr->chksum = 0; |
tehdr->chksum = 0; |
204 |
tehdr->chksum = inet_chksum(tehdr, q->len); |
tehdr->chksum = inet_chksum(tehdr, q->len); |