⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 m_icmp.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
字号:
/*
 * FILENAME: icmp.c
 *
 * Copyright  2000 By InterNiche Technologies Inc. All rights reserved
 *
 *
 * MODULE: INET
 *
 * ROUTINES: icmprcv(), icmp_destun(), icmp_du(), icmp_stats(),
 *
 * PORTABLE: yes
 */

/* Additional Copyrights: */
/* Portions Copyright 1990-1994 by NetPort Software. */
/* Portions Copyright 1986 by Carnegie Mellon  */
/* Portions Copyright 1984 by the Massachusetts Institute of Technology  */


#include "ipport.h"
#include "q.h"
#include "netbuf.h"
#include "net.h"
#include "ip.h"
#include "icmp.h"


struct IcmpMib icmp_mib;   /* storage for MIB statistics */

long  icmp_unhand = 0;

/* FUNCTION: icmprcv()
 *
 * ICMP received packet upcall handler. Returns 0 if we processed the 
 * packet, or ENP_NOT_MINE, or a negative error code. 
 *
 * 
 * PARAM1: PACKET p
 *
 * RETURNS: 
 */

int
icmprcv(PACKET p)      /* the incoming packet */
{
   unsigned len;        /* packet length, minus IP & MAC headers */
   ip_addr host;        /* the foreign host */
   struct ping *  e;
   struct ip * pip;

   len = p->nb_plen;    /* adjusted for us by IP layer */
   host = p->fhost;  /* filled in by IP layer */
   pip = ip_head(p);    /* find IP header */
   e = (struct ping *)ip_data(pip); /* ...and icmp header */

#ifdef   NPDEBUG
   if ((NDEBUG & UPCTRACE) && (NDEBUG & IPTRACE))
      dprintf("ICMP: p[%u] from %u.%u.%u.%u\n", len, PUSH_IPADDR(host));
#endif

   icmp_mib.icmpInMsgs++;        /* received one more icmp */

   if(e->ptype == ECHOREQ)  /* got ping request, send reply */
   {
      len -= ip_hlen(pip);    /* strip IP header from reply length */

      /* reset data pointer to IP header since we use p for reply */
      p->nb_prot = (char*)e;
      icmp_mib.icmpInEchos++;
#ifdef   NPDEBUG
      if ((NDEBUG & UPCTRACE) && (NDEBUG & IPTRACE))
         dprintf("ICMP: echo reply to %u.%u.%u.%u\n", PUSH_IPADDR(host));
#endif
      e->ptype = ECHOREP;
      e->pchksum = 0;
      if (len&1)  /* padd odd length packets  for checksum routine */
         ((char *)e)[len] = 0;

      e->pchksum = ~cksum(e, (len+1)>>1);
      pip->ip_src = pip->ip_dest;
      pip->ip_dest = host;
      icmp_mib.icmpOutEchoReps++;
      icmp_mib.icmpOutMsgs++;
      p->fhost = host;
      p->nb_plen = len;
      if (ip_write(ICMP_PROT, p))
      {
#ifdef   NPDEBUG
         if (NDEBUG & (UPCTRACE))
            dprintf("icmp: reply failed\n");
#endif
      }
      /* reused p will be freed by net->xxx_send() */
      return 0;
   }
#ifdef MINI_PING
   else if(e->ptype == ECHOREP)  /* got ping reply */
   {
      icmp_mib.icmpInEchoReps++;      
   }
#endif   /* MINI_PING */
   else
   {
      icmp_unhand++;
   }
   LOCK_NET_RESOURCE(FREEQ_RESID);
   pk_free(p);
   UNLOCK_NET_RESOURCE(FREEQ_RESID);
   return ENP_NOT_MINE;
}


/* FUNCTION: icmp_destun()
 *
 * icmp_destun() - Send an ICMP destination unreachable packet.
 * 
 * PARAM1: ip_addr host
 * PARAM2: struct ip *ip
 * PARAM3: unsigned type
 * PARAM4: net packet came from 
 *
 * RETURNS: void
 */

void
icmp_destun(ip_addr host,  /* host to complain to */
   struct ip * ip,   /* IP header of offending packet */
   unsigned type,    /* type of DU to send (PROT, PORT, HOST) */
   NET   net)        /* interface that this packet came in on */
{
   PACKET p;
   struct destun *   d;
   int   i;

#ifdef NPDEBUG
   if (NDEBUG & PROTERR)
      dprintf("icmp: sending dest unreachable to %u.%u.%u.%u\n",
         PUSH_IPADDR(host));
#endif   /* NPDEBUG */

   LOCK_NET_RESOURCE(FREEQ_RESID);
   p = pk_alloc(512 + IPHSIZ);   /* get packet to send icmp dest unreachable */
   UNLOCK_NET_RESOURCE(FREEQ_RESID);

   if (p == NULL)
   {
#ifdef NPDEBUG
      if (NDEBUG & IPTRACE)
         dprintf("icmp: can't alloc pkt\n");
#endif   /* NPDEBUG */
      icmp_mib.icmpOutErrors++;
      return;
   }

   /* allow space for icmp header */
   p->nb_prot += sizeof(struct ip);
   p->nb_plen -= sizeof(struct ip);
   p->net = net;     /* Put in the interface that this packet came in on */

   d = (struct destun *)p->nb_prot;

   d->dtype = DESTIN;
   d->dcode = (char)type;
   MEMCPY(&d->dip, ip, (sizeof(struct ip) + ICMPDUDATA));

   d->dchksum = 0;
   d->dchksum = ~cksum(d, sizeof(struct destun)>>1);

   p->nb_plen =  sizeof(struct destun);
   p->fhost = host;
   i = ip_write(ICMP_PROT, p);
   if ((i))
   {
      icmp_mib.icmpOutErrors++;
#ifdef   NPDEBUG
      if (NDEBUG & (IPTRACE|NETERR|PROTERR))
         dprintf("ICMP: Can't send dest unreachable\n");
#endif   /* NPDEBUG  */
      return;
   }
   icmp_mib.icmpOutMsgs++;
   icmp_mib.icmpOutDestUnreachs++;
   return;
}


#ifdef NET_STATS

/* FUNCTION: icmp_stats()
 * 
 * icmp_stats() - Printf info about icmp MIB statistics.
 *
 * PARAM1: void * pio
 *
 * RETURNS: 
 */

int
icmp_stats(void * pio)
{
   ns_printf(pio,"ICMP layer stats:\n");
   ns_printf(pio,"icmpInMsgs %lu    icmpInErrors %lu, echoReqs %lu, echoReps %lu, unhandledTypes: %lu\n",
    icmp_mib.icmpInMsgs, icmp_mib.icmpInErrors, icmp_mib.icmpInEchos, icmp_mib.icmpInEchoReps, icmp_unhand);

   ns_printf(pio,"icmpOutMsgs %lu    icmpOutErrors %lu, \n",
    icmp_mib.icmpOutMsgs, icmp_mib.icmpOutErrors,
    icmp_mib.icmpOutEchoReps, icmp_mib.icmpOutRedirects);

   return 0;
}

#endif   /* NET_STATS */

/* end of file icmp.c */


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -