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

📄 icmp.c

📁 用于嵌入式系统的TCP/IP协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
        return;      /*---------------------------------------------------------------*/      /* Complete ICMP reply packet fields.                            */      /*---------------------------------------------------------------*/      reply = rbuf->ip_data;      reply->type = ICT_ECHORP;      /*      ** Copy the consecutive identifier, seq_num, and data fields.      */      memcpy(&reply->identifier, ip_data + id_offset,             RxBuf->length - id_offset);      /*---------------------------------------------------------------*/      /* Calculate checksum on completed ICMP packet.                  */      /*---------------------------------------------------------------*/      reply->checksum = 0;      reply->checksum = IpChecksum(reply, RxBuf->length);      /*---------------------------------------------------------------*/      /* Request IP to send this datagram.                             */      /*---------------------------------------------------------------*/      ip_out = (Ip *)rbuf->ip_pkt;      ip_out->src_ip = Net.Ip->dst_ip;      ip_out->dst_ip = Net.Ip->src_ip;      icmp_send(rbuf, RxBuf->length, ip_in->ip_tos);    }    break;  case ICT_ECHORP:    /*-----------------------------------------------------------------*/    /* Received echo response. Pass to waiting task if possible.       */    /*-----------------------------------------------------------------*/    {      Echo *echo = (Echo *)ip_data;      PingEntry *entry;      /*---------------------------------------------------------------*/      /* Try to match sequence number with entry in Ping Table.        */      /*---------------------------------------------------------------*/      for (entry = &PingTbl[0];; ++entry)      {        if (entry == &PingTbl[PING_TBL_SZ])          return;        if (entry->taskid == 0)          continue;        if (entry->seq_num == echo->seq_num)          break;      }      /*---------------------------------------------------------------*/      /* Matched! Assign buf and use id to wake task.                  */      /*---------------------------------------------------------------*/      entry->buf = RxBuf;      RxBuf = NULL;      taskWake(entry->taskid);      entry->taskid = 0;      return;    }  case ICT_REDIRECT:    /*-----------------------------------------------------------------*/    /* Received indication of a better route.                          */    /*-----------------------------------------------------------------*/    {      Route *route;      ui32 mask, orig_dst;      /*---------------------------------------------------------------*/      /* Get destination IP address from header of original datagam.   */      /*---------------------------------------------------------------*/      memcpy(&orig_dst, ip_data + offsetof(Icmp, datagram)             + offsetof(Ip, dst_ip), sizeof(orig_dst));      /*---------------------------------------------------------------*/      /* Search for a route to this distination.                       */      /*---------------------------------------------------------------*/      route = RtSearch(orig_dst);      /*---------------------------------------------------------------*/      /* Check if route gateway is source of redirect message.         */      /*---------------------------------------------------------------*/      if (route && (route->gw == Net.Ip->src_ip))      {        ui32 new_gw;        ui8 code = *(ip_data + offsetof(Icmp, code)) & 3;        /*-------------------------------------------------------------*/        /* Determine appropriate subnet mask.                          */        /*-------------------------------------------------------------*/        if (code == ICC_HOSTRD)          mask = 0xFFFFFFFF;        else          mask = IpSubnetMask(orig_dst);        /*-------------------------------------------------------------*/        /* Get new gateway address from REDIRECT message.              */        /*-------------------------------------------------------------*/        memcpy(&new_gw, ip_data + offsetof(Icmp, lword), sizeof(new_gw));        /*-------------------------------------------------------------*/        /* Delete old route and add new one.                           */        /*-------------------------------------------------------------*/        RtDel(route->gw, mask, route->addr);        RtAdd(new_gw, mask, route->addr, route->ni, RT_GATEWAY);      }    }    break;  case ICT_MASKRQ:    /*-----------------------------------------------------------------*/    /* Received subnet mask request.                                   */    /*-----------------------------------------------------------------*/    if (Net.IsGateway)    {      NetBuf *rbuf;      Mask *reply;      Ip *ip_out;      int id_offset = offsetof(Mask, identifier);      /*---------------------------------------------------------------*/      /* Get network buffer for subnet mask reply.                     */      /*---------------------------------------------------------------*/      rbuf = tcpGetBuf(NIMHLEN + IPMHLEN + sizeof(Mask));      if (rbuf == NULL)        break;      /*---------------------------------------------------------------*/      /* Start ICMP header initialization.                             */      /*---------------------------------------------------------------*/      reply = rbuf->ip_data;      reply->type = ICT_MASKRP;      reply->code = 0;      /*      ** Copy the consecutive identifier and seq_num fields.      */      memcpy(&reply->identifier, ip_data + id_offset, 2 * sizeof(ui16));      reply->mask = IpSubnetMask(Net.Ip->dst_ip);      /*---------------------------------------------------------------*/      /* Calculate checksum on completed ICMP packet.                  */      /*---------------------------------------------------------------*/      reply->checksum = 0;      reply->checksum = IpChecksum(reply, ICMP_HLEN + sizeof(Mask));      /*---------------------------------------------------------------*/      /* Request IP to send this datagram.                             */      /*---------------------------------------------------------------*/      ip_out = (Ip *)rbuf->ip_pkt;      if (Net.Ip->dst_ip == INADDR_ANY)        ip_out->src_ip = INADDR_BROADCAST;      else        ip_out->src_ip = Net.Ip->dst_ip;      ip_out->dst_ip = Net.Ip->src_ip;      icmp_send(rbuf, ICMP_HLEN + sizeof(Mask), ICMP_TOS);    }    break;  case ICT_DESTUR:    /*-----------------------------------------------------------------*/    /* Received indication that destination is unreachable.            */    /*-----------------------------------------------------------------*/    {      Icmp *icmp = (Icmp *)ip_data;      /*---------------------------------------------------------------*/      /* Update statistics.                                            */      /*---------------------------------------------------------------*/      ++Stats.IcmpDestUr;      switch (icmp->code)      {        case ICC_NETUR:     /* network unreachable */          ++DstUrNetUr;          apply2sock(EHOSTUNREACH);          break;        case ICC_HOSTUR:    /* host unreachable */          ++DstUrHostUr;          apply2sock(EHOSTUNREACH);          break;        case ICC_PROTOUR:   /* protocol unreachable */          ++DstUrProtoUr;          apply2sock(ECONNREFUSED);          break;        case ICC_PORTUR:    /* port unreachable */          ++DstUrPortUr;          apply2sock(ECONNREFUSED);          break;        case ICC_FRAGREQ:   /* frag required but DF bit is set */          ++DstUrFragReq;          apply2sock(EMSGSIZE);          break;        case ICC_SRCRT:     /* source route failed */          ++DstUrSRCRT;          apply2sock(EHOSTUNREACH);          break;        case ICC_NETUNK:    /* destination network unknown */          ++DstUrNetUnk;          apply2sock(EHOSTUNREACH);          break;        case ICC_HOSTUNK:   /* destination host unknown */          ++DstUrHostUnk;          apply2sock(EHOSTUNREACH);          break;        case ICC_NETTYP:    /* network unreachable for type of service */          ++DstUrNetTyp;          apply2sock(EHOSTUNREACH);          break;        case ICC_HOSTTYP:   /* host unreachable for type of service */          ++DstUrHostTyp;          apply2sock(EHOSTUNREACH);          break;        case ICC_COMMPRO:   /* comm administratively prohibited */          ++DstUrCommPro;          break;        case ICC_PRECVIO:   /* host precedence violation */          ++DstUrPrecVio;          break;        case ICC_PRECCUT:   /* precedence cutoff in effect */          ++DstUrPrecCut;          break;      }    }    break;  case ICT_SRCQ:    /*-----------------------------------------------------------------*/    /* Received request to throttle output, apply slow start.          */    /*-----------------------------------------------------------------*/    ++SrcQuench;    apply2sock(SOURCE_QUENCH);    break;  case ICT_PARAMP:    /*-----------------------------------------------------------------*/    /* Parameter problem: IP header bad or required option missing.    */    /*-----------------------------------------------------------------*/    apply2sock(ENOPROTOOPT);    break;  }}#if TCP_PROBE/***********************************************************************//*  IcmpDecode: Parse and decode ICMP packet on stdout                 *//*                                                                     *//***********************************************************************/void IcmpDecode(const NetBuf *buf){  ui8 type = *(ui8 *)buf->ip_data;  printf("ICMP: ");  switch (type)  {    case ICT_ECHORQ:      printf("Echo request");      break;    case ICT_ECHORP:      printf("Echo response");      break;    case ICT_REDIRECT:      printf("Redirect");      break;    case ICT_TIMEX:      printf("Time expired");      break;    case ICT_MASKRQ:      printf("Mask request");      break;    case ICT_DESTUR:      printf("Destination unreachable");      break;    case ICT_SRCQ:      printf("Source quench");      break;    default:      printf("Type = 0x%02X", type);      break;  }  putchar('\n');}#endif

⌨️ 快捷键说明

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