Used in Live Traffic Update Nokia LCD Display Project

Fork of NetServices by Segundo Equipo

Committer:
rrajan8
Date:
Wed Mar 06 19:07:23 2013 +0000
Revision:
8:92b57208ab99
Parent:
0:ac1725ba162c
This project utilizes mbed's networking features to display live traffic updates on the Nokia LCD using the MapQuest API's Traffic Web Service.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
segundo 0:ac1725ba162c 1 /**
segundo 0:ac1725ba162c 2 * @file
segundo 0:ac1725ba162c 3 * ICMP - Internet Control Message Protocol
segundo 0:ac1725ba162c 4 *
segundo 0:ac1725ba162c 5 */
segundo 0:ac1725ba162c 6
segundo 0:ac1725ba162c 7 /*
segundo 0:ac1725ba162c 8 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
segundo 0:ac1725ba162c 9 * All rights reserved.
segundo 0:ac1725ba162c 10 *
segundo 0:ac1725ba162c 11 * Redistribution and use in source and binary forms, with or without modification,
segundo 0:ac1725ba162c 12 * are permitted provided that the following conditions are met:
segundo 0:ac1725ba162c 13 *
segundo 0:ac1725ba162c 14 * 1. Redistributions of source code must retain the above copyright notice,
segundo 0:ac1725ba162c 15 * this list of conditions and the following disclaimer.
segundo 0:ac1725ba162c 16 * 2. Redistributions in binary form must reproduce the above copyright notice,
segundo 0:ac1725ba162c 17 * this list of conditions and the following disclaimer in the documentation
segundo 0:ac1725ba162c 18 * and/or other materials provided with the distribution.
segundo 0:ac1725ba162c 19 * 3. The name of the author may not be used to endorse or promote products
segundo 0:ac1725ba162c 20 * derived from this software without specific prior written permission.
segundo 0:ac1725ba162c 21 *
segundo 0:ac1725ba162c 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
segundo 0:ac1725ba162c 23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
segundo 0:ac1725ba162c 24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
segundo 0:ac1725ba162c 25 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
segundo 0:ac1725ba162c 26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
segundo 0:ac1725ba162c 27 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
segundo 0:ac1725ba162c 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
segundo 0:ac1725ba162c 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
segundo 0:ac1725ba162c 30 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
segundo 0:ac1725ba162c 31 * OF SUCH DAMAGE.
segundo 0:ac1725ba162c 32 *
segundo 0:ac1725ba162c 33 * This file is part of the lwIP TCP/IP stack.
segundo 0:ac1725ba162c 34 *
segundo 0:ac1725ba162c 35 * Author: Adam Dunkels <adam@sics.se>
segundo 0:ac1725ba162c 36 *
segundo 0:ac1725ba162c 37 */
segundo 0:ac1725ba162c 38
segundo 0:ac1725ba162c 39 /* Some ICMP messages should be passed to the transport protocols. This
segundo 0:ac1725ba162c 40 is not implemented. */
segundo 0:ac1725ba162c 41
segundo 0:ac1725ba162c 42 #include "lwip/opt.h"
segundo 0:ac1725ba162c 43
segundo 0:ac1725ba162c 44 #if LWIP_ICMP /* don't build if not configured for use in lwipopts.h */
segundo 0:ac1725ba162c 45
segundo 0:ac1725ba162c 46 #include "lwip/icmp.h"
segundo 0:ac1725ba162c 47 #include "lwip/inet_chksum.h"
segundo 0:ac1725ba162c 48 #include "lwip/ip.h"
segundo 0:ac1725ba162c 49 #include "lwip/def.h"
segundo 0:ac1725ba162c 50 #include "lwip/stats.h"
segundo 0:ac1725ba162c 51 #include "lwip/snmp.h"
segundo 0:ac1725ba162c 52
segundo 0:ac1725ba162c 53 #include <string.h>
segundo 0:ac1725ba162c 54
segundo 0:ac1725ba162c 55 /** Small optimization: set to 0 if incoming PBUF_POOL pbuf always can be
segundo 0:ac1725ba162c 56 * used to modify and send a response packet (and to 1 if this is not the case,
segundo 0:ac1725ba162c 57 * e.g. when link header is stripped of when receiving) */
segundo 0:ac1725ba162c 58 #ifndef LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN
segundo 0:ac1725ba162c 59 #define LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN 1
segundo 0:ac1725ba162c 60 #endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */
segundo 0:ac1725ba162c 61
segundo 0:ac1725ba162c 62 /* The amount of data from the original packet to return in a dest-unreachable */
segundo 0:ac1725ba162c 63 #define ICMP_DEST_UNREACH_DATASIZE 8
segundo 0:ac1725ba162c 64
segundo 0:ac1725ba162c 65 static void icmp_send_response(struct pbuf *p, u8_t type, u8_t code);
segundo 0:ac1725ba162c 66
segundo 0:ac1725ba162c 67 /**
segundo 0:ac1725ba162c 68 * Processes ICMP input packets, called from ip_input().
segundo 0:ac1725ba162c 69 *
segundo 0:ac1725ba162c 70 * Currently only processes icmp echo requests and sends
segundo 0:ac1725ba162c 71 * out the echo response.
segundo 0:ac1725ba162c 72 *
segundo 0:ac1725ba162c 73 * @param p the icmp echo request packet, p->payload pointing to the ip header
segundo 0:ac1725ba162c 74 * @param inp the netif on which this packet was received
segundo 0:ac1725ba162c 75 */
segundo 0:ac1725ba162c 76 void
segundo 0:ac1725ba162c 77 icmp_input(struct pbuf *p, struct netif *inp)
segundo 0:ac1725ba162c 78 {
segundo 0:ac1725ba162c 79 u8_t type;
segundo 0:ac1725ba162c 80 #ifdef LWIP_DEBUG
segundo 0:ac1725ba162c 81 u8_t code;
segundo 0:ac1725ba162c 82 #endif /* LWIP_DEBUG */
segundo 0:ac1725ba162c 83 struct icmp_echo_hdr *iecho;
segundo 0:ac1725ba162c 84 struct ip_hdr *iphdr;
segundo 0:ac1725ba162c 85 s16_t hlen;
segundo 0:ac1725ba162c 86
segundo 0:ac1725ba162c 87 ICMP_STATS_INC(icmp.recv);
segundo 0:ac1725ba162c 88 snmp_inc_icmpinmsgs();
segundo 0:ac1725ba162c 89
segundo 0:ac1725ba162c 90
segundo 0:ac1725ba162c 91 iphdr = (struct ip_hdr *)p->payload;
segundo 0:ac1725ba162c 92 hlen = IPH_HL(iphdr) * 4;
segundo 0:ac1725ba162c 93 if (pbuf_header(p, -hlen) || (p->tot_len < sizeof(u16_t)*2)) {
segundo 0:ac1725ba162c 94 LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%"U16_F" bytes) received\n", p->tot_len));
segundo 0:ac1725ba162c 95 goto lenerr;
segundo 0:ac1725ba162c 96 }
segundo 0:ac1725ba162c 97
segundo 0:ac1725ba162c 98 type = *((u8_t *)p->payload);
segundo 0:ac1725ba162c 99 #ifdef LWIP_DEBUG
segundo 0:ac1725ba162c 100 code = *(((u8_t *)p->payload)+1);
segundo 0:ac1725ba162c 101 #endif /* LWIP_DEBUG */
segundo 0:ac1725ba162c 102 switch (type) {
segundo 0:ac1725ba162c 103 case ICMP_ER:
segundo 0:ac1725ba162c 104 /* This is OK, echo reply might have been parsed by a raw PCB
segundo 0:ac1725ba162c 105 (as obviously, an echo request has been sent, too). */
segundo 0:ac1725ba162c 106 break;
segundo 0:ac1725ba162c 107 case ICMP_ECHO:
segundo 0:ac1725ba162c 108 #if !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING
segundo 0:ac1725ba162c 109 {
segundo 0:ac1725ba162c 110 int accepted = 1;
segundo 0:ac1725ba162c 111 #if !LWIP_MULTICAST_PING
segundo 0:ac1725ba162c 112 /* multicast destination address? */
segundo 0:ac1725ba162c 113 if (ip_addr_ismulticast(&current_iphdr_dest)) {
segundo 0:ac1725ba162c 114 accepted = 0;
segundo 0:ac1725ba162c 115 }
segundo 0:ac1725ba162c 116 #endif /* LWIP_MULTICAST_PING */
segundo 0:ac1725ba162c 117 #if !LWIP_BROADCAST_PING
segundo 0:ac1725ba162c 118 /* broadcast destination address? */
segundo 0:ac1725ba162c 119 if (ip_addr_isbroadcast(&current_iphdr_dest, inp)) {
segundo 0:ac1725ba162c 120 accepted = 0;
segundo 0:ac1725ba162c 121 }
segundo 0:ac1725ba162c 122 #endif /* LWIP_BROADCAST_PING */
segundo 0:ac1725ba162c 123 /* broadcast or multicast destination address not acceptd? */
segundo 0:ac1725ba162c 124 if (!accepted) {
segundo 0:ac1725ba162c 125 LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to multicast or broadcast pings\n"));
segundo 0:ac1725ba162c 126 ICMP_STATS_INC(icmp.err);
segundo 0:ac1725ba162c 127 pbuf_free(p);
segundo 0:ac1725ba162c 128 return;
segundo 0:ac1725ba162c 129 }
segundo 0:ac1725ba162c 130 }
segundo 0:ac1725ba162c 131 #endif /* !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING */
segundo 0:ac1725ba162c 132 LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n"));
segundo 0:ac1725ba162c 133 if (p->tot_len < sizeof(struct icmp_echo_hdr)) {
segundo 0:ac1725ba162c 134 LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n"));
segundo 0:ac1725ba162c 135 goto lenerr;
segundo 0:ac1725ba162c 136 }
segundo 0:ac1725ba162c 137 if (inet_chksum_pbuf(p) != 0) {
segundo 0:ac1725ba162c 138 LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n"));
segundo 0:ac1725ba162c 139 pbuf_free(p);
segundo 0:ac1725ba162c 140 ICMP_STATS_INC(icmp.chkerr);
segundo 0:ac1725ba162c 141 snmp_inc_icmpinerrors();
segundo 0:ac1725ba162c 142 return;
segundo 0:ac1725ba162c 143 }
segundo 0:ac1725ba162c 144 #if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN
segundo 0:ac1725ba162c 145 if (pbuf_header(p, (PBUF_IP_HLEN + PBUF_LINK_HLEN))) {
segundo 0:ac1725ba162c 146 /* p is not big enough to contain link headers
segundo 0:ac1725ba162c 147 * allocate a new one and copy p into it
segundo 0:ac1725ba162c 148 */
segundo 0:ac1725ba162c 149 struct pbuf *r;
segundo 0:ac1725ba162c 150 /* switch p->payload to ip header */
segundo 0:ac1725ba162c 151 if (pbuf_header(p, hlen)) {
segundo 0:ac1725ba162c 152 LWIP_ASSERT("icmp_input: moving p->payload to ip header failed\n", 0);
segundo 0:ac1725ba162c 153 goto memerr;
segundo 0:ac1725ba162c 154 }
segundo 0:ac1725ba162c 155 /* allocate new packet buffer with space for link headers */
segundo 0:ac1725ba162c 156 r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM);
segundo 0:ac1725ba162c 157 if (r == NULL) {
segundo 0:ac1725ba162c 158 LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: allocating new pbuf failed\n"));
segundo 0:ac1725ba162c 159 goto memerr;
segundo 0:ac1725ba162c 160 }
segundo 0:ac1725ba162c 161 LWIP_ASSERT("check that first pbuf can hold struct the ICMP header",
segundo 0:ac1725ba162c 162 (r->len >= hlen + sizeof(struct icmp_echo_hdr)));
segundo 0:ac1725ba162c 163 /* copy the whole packet including ip header */
segundo 0:ac1725ba162c 164 if (pbuf_copy(r, p) != ERR_OK) {
segundo 0:ac1725ba162c 165 LWIP_ASSERT("icmp_input: copying to new pbuf failed\n", 0);
segundo 0:ac1725ba162c 166 goto memerr;
segundo 0:ac1725ba162c 167 }
segundo 0:ac1725ba162c 168 iphdr = (struct ip_hdr *)r->payload;
segundo 0:ac1725ba162c 169 /* switch r->payload back to icmp header */
segundo 0:ac1725ba162c 170 if (pbuf_header(r, -hlen)) {
segundo 0:ac1725ba162c 171 LWIP_ASSERT("icmp_input: restoring original p->payload failed\n", 0);
segundo 0:ac1725ba162c 172 goto memerr;
segundo 0:ac1725ba162c 173 }
segundo 0:ac1725ba162c 174 /* free the original p */
segundo 0:ac1725ba162c 175 pbuf_free(p);
segundo 0:ac1725ba162c 176 /* we now have an identical copy of p that has room for link headers */
segundo 0:ac1725ba162c 177 p = r;
segundo 0:ac1725ba162c 178 } else {
segundo 0:ac1725ba162c 179 /* restore p->payload to point to icmp header */
segundo 0:ac1725ba162c 180 if (pbuf_header(p, -(s16_t)(PBUF_IP_HLEN + PBUF_LINK_HLEN))) {
segundo 0:ac1725ba162c 181 LWIP_ASSERT("icmp_input: restoring original p->payload failed\n", 0);
segundo 0:ac1725ba162c 182 goto memerr;
segundo 0:ac1725ba162c 183 }
segundo 0:ac1725ba162c 184 }
segundo 0:ac1725ba162c 185 #endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */
segundo 0:ac1725ba162c 186 /* At this point, all checks are OK. */
segundo 0:ac1725ba162c 187 /* We generate an answer by switching the dest and src ip addresses,
segundo 0:ac1725ba162c 188 * setting the icmp type to ECHO_RESPONSE and updating the checksum. */
segundo 0:ac1725ba162c 189 iecho = (struct icmp_echo_hdr *)p->payload;
segundo 0:ac1725ba162c 190 ip_addr_copy(iphdr->src, *ip_current_dest_addr());
segundo 0:ac1725ba162c 191 ip_addr_copy(iphdr->dest, *ip_current_src_addr());
segundo 0:ac1725ba162c 192 ICMPH_TYPE_SET(iecho, ICMP_ER);
segundo 0:ac1725ba162c 193 /* adjust the checksum */
segundo 0:ac1725ba162c 194 if (iecho->chksum >= PP_HTONS(0xffff - (ICMP_ECHO << 8))) {
segundo 0:ac1725ba162c 195 iecho->chksum += PP_HTONS(ICMP_ECHO << 8) + 1;
segundo 0:ac1725ba162c 196 } else {
segundo 0:ac1725ba162c 197 iecho->chksum += PP_HTONS(ICMP_ECHO << 8);
segundo 0:ac1725ba162c 198 }
segundo 0:ac1725ba162c 199
segundo 0:ac1725ba162c 200 /* Set the correct TTL and recalculate the header checksum. */
segundo 0:ac1725ba162c 201 IPH_TTL_SET(iphdr, ICMP_TTL);
segundo 0:ac1725ba162c 202 IPH_CHKSUM_SET(iphdr, 0);
segundo 0:ac1725ba162c 203 #if CHECKSUM_GEN_IP
segundo 0:ac1725ba162c 204 IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
segundo 0:ac1725ba162c 205 #endif /* CHECKSUM_GEN_IP */
segundo 0:ac1725ba162c 206
segundo 0:ac1725ba162c 207 ICMP_STATS_INC(icmp.xmit);
segundo 0:ac1725ba162c 208 /* increase number of messages attempted to send */
segundo 0:ac1725ba162c 209 snmp_inc_icmpoutmsgs();
segundo 0:ac1725ba162c 210 /* increase number of echo replies attempted to send */
segundo 0:ac1725ba162c 211 snmp_inc_icmpoutechoreps();
segundo 0:ac1725ba162c 212
segundo 0:ac1725ba162c 213 if(pbuf_header(p, hlen)) {
segundo 0:ac1725ba162c 214 LWIP_ASSERT("Can't move over header in packet", 0);
segundo 0:ac1725ba162c 215 } else {
segundo 0:ac1725ba162c 216 err_t ret;
segundo 0:ac1725ba162c 217 /* send an ICMP packet, src addr is the dest addr of the curren packet */
segundo 0:ac1725ba162c 218 ret = ip_output_if(p, ip_current_dest_addr(), IP_HDRINCL,
segundo 0:ac1725ba162c 219 ICMP_TTL, 0, IP_PROTO_ICMP, inp);
segundo 0:ac1725ba162c 220 if (ret != ERR_OK) {
segundo 0:ac1725ba162c 221 LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ip_output_if returned an error: %c.\n", ret));
segundo 0:ac1725ba162c 222 }
segundo 0:ac1725ba162c 223 }
segundo 0:ac1725ba162c 224 break;
segundo 0:ac1725ba162c 225 default:
segundo 0:ac1725ba162c 226 LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %"S16_F" code %"S16_F" not supported.\n",
segundo 0:ac1725ba162c 227 (s16_t)type, (s16_t)code));
segundo 0:ac1725ba162c 228 ICMP_STATS_INC(icmp.proterr);
segundo 0:ac1725ba162c 229 ICMP_STATS_INC(icmp.drop);
segundo 0:ac1725ba162c 230 }
segundo 0:ac1725ba162c 231 pbuf_free(p);
segundo 0:ac1725ba162c 232 return;
segundo 0:ac1725ba162c 233 lenerr:
segundo 0:ac1725ba162c 234 pbuf_free(p);
segundo 0:ac1725ba162c 235 ICMP_STATS_INC(icmp.lenerr);
segundo 0:ac1725ba162c 236 snmp_inc_icmpinerrors();
segundo 0:ac1725ba162c 237 return;
segundo 0:ac1725ba162c 238 #if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN
segundo 0:ac1725ba162c 239 memerr:
segundo 0:ac1725ba162c 240 pbuf_free(p);
segundo 0:ac1725ba162c 241 ICMP_STATS_INC(icmp.err);
segundo 0:ac1725ba162c 242 snmp_inc_icmpinerrors();
segundo 0:ac1725ba162c 243 return;
segundo 0:ac1725ba162c 244 #endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */
segundo 0:ac1725ba162c 245 }
segundo 0:ac1725ba162c 246
segundo 0:ac1725ba162c 247 /**
segundo 0:ac1725ba162c 248 * Send an icmp 'destination unreachable' packet, called from ip_input() if
segundo 0:ac1725ba162c 249 * the transport layer protocol is unknown and from udp_input() if the local
segundo 0:ac1725ba162c 250 * port is not bound.
segundo 0:ac1725ba162c 251 *
segundo 0:ac1725ba162c 252 * @param p the input packet for which the 'unreachable' should be sent,
segundo 0:ac1725ba162c 253 * p->payload pointing to the IP header
segundo 0:ac1725ba162c 254 * @param t type of the 'unreachable' packet
segundo 0:ac1725ba162c 255 */
segundo 0:ac1725ba162c 256 void
segundo 0:ac1725ba162c 257 icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t)
segundo 0:ac1725ba162c 258 {
segundo 0:ac1725ba162c 259 icmp_send_response(p, ICMP_DUR, t);
segundo 0:ac1725ba162c 260 }
segundo 0:ac1725ba162c 261
segundo 0:ac1725ba162c 262 #if IP_FORWARD || IP_REASSEMBLY
segundo 0:ac1725ba162c 263 /**
segundo 0:ac1725ba162c 264 * Send a 'time exceeded' packet, called from ip_forward() if TTL is 0.
segundo 0:ac1725ba162c 265 *
segundo 0:ac1725ba162c 266 * @param p the input packet for which the 'time exceeded' should be sent,
segundo 0:ac1725ba162c 267 * p->payload pointing to the IP header
segundo 0:ac1725ba162c 268 * @param t type of the 'time exceeded' packet
segundo 0:ac1725ba162c 269 */
segundo 0:ac1725ba162c 270 void
segundo 0:ac1725ba162c 271 icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t)
segundo 0:ac1725ba162c 272 {
segundo 0:ac1725ba162c 273 icmp_send_response(p, ICMP_TE, t);
segundo 0:ac1725ba162c 274 }
segundo 0:ac1725ba162c 275
segundo 0:ac1725ba162c 276 #endif /* IP_FORWARD || IP_REASSEMBLY */
segundo 0:ac1725ba162c 277
segundo 0:ac1725ba162c 278 /**
segundo 0:ac1725ba162c 279 * Send an icmp packet in response to an incoming packet.
segundo 0:ac1725ba162c 280 *
segundo 0:ac1725ba162c 281 * @param p the input packet for which the 'unreachable' should be sent,
segundo 0:ac1725ba162c 282 * p->payload pointing to the IP header
segundo 0:ac1725ba162c 283 * @param type Type of the ICMP header
segundo 0:ac1725ba162c 284 * @param code Code of the ICMP header
segundo 0:ac1725ba162c 285 */
segundo 0:ac1725ba162c 286 static void
segundo 0:ac1725ba162c 287 icmp_send_response(struct pbuf *p, u8_t type, u8_t code)
segundo 0:ac1725ba162c 288 {
segundo 0:ac1725ba162c 289 struct pbuf *q;
segundo 0:ac1725ba162c 290 struct ip_hdr *iphdr;
segundo 0:ac1725ba162c 291 /* we can use the echo header here */
segundo 0:ac1725ba162c 292 struct icmp_echo_hdr *icmphdr;
segundo 0:ac1725ba162c 293 ip_addr_t iphdr_src;
segundo 0:ac1725ba162c 294
segundo 0:ac1725ba162c 295 /* ICMP header + IP header + 8 bytes of data */
segundo 0:ac1725ba162c 296 q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE,
segundo 0:ac1725ba162c 297 PBUF_RAM);
segundo 0:ac1725ba162c 298 if (q == NULL) {
segundo 0:ac1725ba162c 299 LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMP packet.\n"));
segundo 0:ac1725ba162c 300 return;
segundo 0:ac1725ba162c 301 }
segundo 0:ac1725ba162c 302 LWIP_ASSERT("check that first pbuf can hold icmp message",
segundo 0:ac1725ba162c 303 (q->len >= (sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE)));
segundo 0:ac1725ba162c 304
segundo 0:ac1725ba162c 305 iphdr = (struct ip_hdr *)p->payload;
segundo 0:ac1725ba162c 306 LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from "));
segundo 0:ac1725ba162c 307 ip_addr_debug_print(ICMP_DEBUG, &(iphdr->src));
segundo 0:ac1725ba162c 308 LWIP_DEBUGF(ICMP_DEBUG, (" to "));
segundo 0:ac1725ba162c 309 ip_addr_debug_print(ICMP_DEBUG, &(iphdr->dest));
segundo 0:ac1725ba162c 310 LWIP_DEBUGF(ICMP_DEBUG, ("\n"));
segundo 0:ac1725ba162c 311
segundo 0:ac1725ba162c 312 icmphdr = (struct icmp_echo_hdr *)q->payload;
segundo 0:ac1725ba162c 313 icmphdr->type = type;
segundo 0:ac1725ba162c 314 icmphdr->code = code;
segundo 0:ac1725ba162c 315 icmphdr->id = 0;
segundo 0:ac1725ba162c 316 icmphdr->seqno = 0;
segundo 0:ac1725ba162c 317
segundo 0:ac1725ba162c 318 /* copy fields from original packet */
segundo 0:ac1725ba162c 319 SMEMCPY((u8_t *)q->payload + sizeof(struct icmp_echo_hdr), (u8_t *)p->payload,
segundo 0:ac1725ba162c 320 IP_HLEN + ICMP_DEST_UNREACH_DATASIZE);
segundo 0:ac1725ba162c 321
segundo 0:ac1725ba162c 322 /* calculate checksum */
segundo 0:ac1725ba162c 323 icmphdr->chksum = 0;
segundo 0:ac1725ba162c 324 icmphdr->chksum = inet_chksum(icmphdr, q->len);
segundo 0:ac1725ba162c 325 ICMP_STATS_INC(icmp.xmit);
segundo 0:ac1725ba162c 326 /* increase number of messages attempted to send */
segundo 0:ac1725ba162c 327 snmp_inc_icmpoutmsgs();
segundo 0:ac1725ba162c 328 /* increase number of destination unreachable messages attempted to send */
segundo 0:ac1725ba162c 329 snmp_inc_icmpouttimeexcds();
segundo 0:ac1725ba162c 330 ip_addr_copy(iphdr_src, iphdr->src);
segundo 0:ac1725ba162c 331 ip_output(q, NULL, &iphdr_src, ICMP_TTL, 0, IP_PROTO_ICMP);
segundo 0:ac1725ba162c 332 pbuf_free(q);
segundo 0:ac1725ba162c 333 }
segundo 0:ac1725ba162c 334
segundo 0:ac1725ba162c 335 #endif /* LWIP_ICMP */