diff --git a/src/sys/net/core/icmp.c b/src/sys/net/core/icmp.c index d2b6657..754ccc6 100644 --- a/src/sys/net/core/icmp.c +++ b/src/sys/net/core/icmp.c @@ -1,99 +1,102 @@ /* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. + * Copyright (c) 2001, Swedish Institute of Computer Science. + * All rights reserved. * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. * * This file is part of the lwIP TCP/IP stack. - * + * * Author: Adam Dunkels * + * $Id$ */ /* Some ICMP messages should be passed to the transport protocols. This is not implemented. */ -#include "net/opt.h" +#include + +#include "net/debug.h" #include "net/ipv4/icmp.h" #include "net/ipv4/inet.h" -#include "net/ip.h" +#include "net/ipv4/ip.h" #include "net/def.h" #include "net/stats.h" -#include "net/snmp.h" - +/*-----------------------------------------------------------------------------------*/ void icmp_input(struct pbuf *p, struct netif *inp) { unsigned char type; - unsigned char code; struct icmp_echo_hdr *iecho; struct ip_hdr *iphdr; struct ip_addr tmpaddr; - u16_t hlen; + uInt16 hlen; + +#ifdef ICMP_STATS + ++stats.icmp.recv; +#endif /* ICMP_STATS */ - ICMP_STATS_INC(icmp.recv); - snmp_inc_icmpinmsgs(); - - + iphdr = p->payload; - hlen = IPH_HL(iphdr) * 4; - if (pbuf_header(p, -((s16_t)hlen)) || (p->tot_len < sizeof(u16_t)*2)) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%u bytes) received\n", p->tot_len)); - pbuf_free(p); - ICMP_STATS_INC(icmp.lenerr); - snmp_inc_icmpinerrors(); - return; - } + hlen = IPH_HL(iphdr) * 4/sizeof(uInt8); + pbuf_header(p, -hlen); - type = *((u8_t *)p->payload); - code = *(((u8_t *)p->payload)+1); - switch (type) { + type = *((uInt8 *)p->payload); + + switch(type) { case ICMP_ECHO: - /* broadcast or multicast destination address? */ - if (ip_addr_isbroadcast(&iphdr->dest, inp) || ip_addr_ismulticast(&iphdr->dest)) { - LWIP_DEBUGF(ICMP_DEBUG, ("Smurf.\n")); - ICMP_STATS_INC(icmp.err); + if(ip_addr_isbroadcast(&iphdr->dest, &inp->netmask) || + ip_addr_ismulticast(&iphdr->dest)) { + DEBUGF(ICMP_DEBUG, ("Smurf.\n")); +#ifdef ICMP_STATS + ++stats.icmp.err; +#endif /* ICMP_STATS */ pbuf_free(p); return; } - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n")); - if (p->tot_len < sizeof(struct icmp_echo_hdr)) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n")); + DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n")); + DEBUGF(DEMO_DEBUG, ("Pong!\n")); + if(p->tot_len < sizeof(struct icmp_echo_hdr)) { + DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n")); pbuf_free(p); - ICMP_STATS_INC(icmp.lenerr); - snmp_inc_icmpinerrors(); +#ifdef ICMP_STATS + ++stats.icmp.lenerr; +#endif /* ICMP_STATS */ - return; + return; } - iecho = p->payload; - if (inet_chksum_pbuf(p) != 0) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n")); + iecho = p->payload; + if(inet_chksum_pbuf(p) != 0) { + DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n")); pbuf_free(p); - ICMP_STATS_INC(icmp.chkerr); - snmp_inc_icmpinerrors(); +#ifdef ICMP_STATS + ++stats.icmp.chkerr; +#endif /* ICMP_STATS */ return; } tmpaddr.addr = iphdr->src.addr; @@ -101,62 +104,59 @@ iphdr->dest.addr = tmpaddr.addr; ICMPH_TYPE_SET(iecho, ICMP_ER); /* adjust the checksum */ - if (iecho->chksum >= htons(0xffff - (ICMP_ECHO << 8))) { + if(iecho->chksum >= htons(0xffff - (ICMP_ECHO << 8))) { iecho->chksum += htons(ICMP_ECHO << 8) + 1; } else { iecho->chksum += htons(ICMP_ECHO << 8); } - ICMP_STATS_INC(icmp.xmit); - /* increase number of messages attempted to send */ - snmp_inc_icmpoutmsgs(); - /* increase number of echo replies attempted to send */ - snmp_inc_icmpoutechoreps(); +#ifdef ICMP_STATS + ++stats.icmp.xmit; +#endif /* ICMP_STATS */ pbuf_header(p, hlen); ip_output_if(p, &(iphdr->src), IP_HDRINCL, - IPH_TTL(iphdr), 0, IP_PROTO_ICMP, inp); - break; + IPH_TTL(iphdr), IP_PROTO_ICMP, inp); + break; default: - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %d code %d not supported.\n", (int)type, (int)code)); - ICMP_STATS_INC(icmp.proterr); - ICMP_STATS_INC(icmp.drop); + DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type not supported.\n")); +#ifdef ICMP_STATS + ++stats.icmp.proterr; + ++stats.icmp.drop; +#endif /* ICMP_STATS */ } pbuf_free(p); } - +/*-----------------------------------------------------------------------------------*/ void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t) { struct pbuf *q; struct ip_hdr *iphdr; struct icmp_dur_hdr *idur; - - q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM); + + q = pbuf_alloc(PBUF_TRANSPORT, 8 + IP_HLEN + 8, PBUF_RAM); /* ICMP header + IP header + 8 bytes of data */ iphdr = p->payload; - + idur = q->payload; ICMPH_TYPE_SET(idur, ICMP_DUR); ICMPH_CODE_SET(idur, t); - memcpy((char *)q->payload + 8, p->payload, IP_HLEN + 8); - + bcopy(p->payload, (char *)q->payload + 8, IP_HLEN + 8); + /* calculate checksum */ idur->chksum = 0; idur->chksum = inet_chksum(idur, q->len); - ICMP_STATS_INC(icmp.xmit); - /* increase number of messages attempted to send */ - snmp_inc_icmpoutmsgs(); - /* increase number of destination unreachable messages attempted to send */ - snmp_inc_icmpoutdestunreachs(); +#ifdef ICMP_STATS + ++stats.icmp.xmit; +#endif /* ICMP_STATS */ ip_output(q, NULL, &(iphdr->src), - ICMP_TTL, 0, IP_PROTO_ICMP); + ICMP_TTL, IP_PROTO_ICMP); pbuf_free(q); } - -#if IP_FORWARD +/*-----------------------------------------------------------------------------------*/ void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t) { @@ -164,36 +164,35 @@ struct ip_hdr *iphdr; struct icmp_te_hdr *tehdr; - q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM); + q = pbuf_alloc(PBUF_TRANSPORT, 8 + IP_HLEN + 8, PBUF_RAM); iphdr = p->payload; - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from ")); - ip_addr_debug_print(ICMP_DEBUG, &(iphdr->src)); - LWIP_DEBUGF(ICMP_DEBUG, (" to ")); - ip_addr_debug_print(ICMP_DEBUG, &(iphdr->dest)); - LWIP_DEBUGF(ICMP_DEBUG, ("\n")); +#if ICMP_DEBUG + DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from ")); + ip_addr_debug_print(&(iphdr->src)); + DEBUGF(ICMP_DEBUG, (" to ")); + ip_addr_debug_print(&(iphdr->dest)); + DEBUGF(ICMP_DEBUG, ("\n")); +#endif /* ICMP_DEBNUG */ tehdr = q->payload; ICMPH_TYPE_SET(tehdr, ICMP_TE); ICMPH_CODE_SET(tehdr, t); /* copy fields from original packet */ - memcpy((char *)q->payload + 8, (char *)p->payload, IP_HLEN + 8); - + bcopy((char *)p->payload, (char *)q->payload + 8, IP_HLEN + 8); + /* calculate checksum */ tehdr->chksum = 0; tehdr->chksum = inet_chksum(tehdr, q->len); - ICMP_STATS_INC(icmp.xmit); - /* increase number of messages attempted to send */ - snmp_inc_icmpoutmsgs(); - /* increase number of destination unreachable messages attempted to send */ - snmp_inc_icmpouttimeexcds(); +#ifdef ICMP_STATS + ++stats.icmp.xmit; +#endif /* ICMP_STATS */ ip_output(q, NULL, &(iphdr->src), - ICMP_TTL, 0, IP_PROTO_ICMP); + ICMP_TTL, IP_PROTO_ICMP); pbuf_free(q); } -#endif /* IP_FORWARD */