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

📄 icmp.c

📁 用于嵌入式系统的TCP/IP协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
/***********************************************************************//*                                                                     *//*   Module:  tcp_ip/icmp.c                                            *//*   Release: 2001.3                                                   *//*   Version: 2001.1                                                   *//*   Purpose: ICMP Related Routines                                    *//*                                                                     *//*---------------------------------------------------------------------*//*                                                                     *//*               Copyright 1999, Blunk Microsystems                    *//*                      ALL RIGHTS RESERVED                            *//*                                                                     *//*   Licensees have the non-exclusive right to use, modify, or extract *//*   this computer program for software development at a single site.  *//*   This program may be resold or disseminated in executable format   *//*   only. The source code may not be redistributed or resold.         *//*                                                                     *//***********************************************************************/#include "tcp_ipp.h"#include <string.h>#include "ip/ip.h"#include "tcp/tcp.h"/***********************************************************************//* Configuration                                                       *//***********************************************************************/#define PING_TBL_SZ     3/***********************************************************************//* Symbol Definitions                                                  *//***********************************************************************/#define ICMP_TOS        0x00  /* default ICMP type of service */#define ICMP_HLEN       8     /* bytes */#define SOURCE_QUENCH   -1    /* apply2sock() flag *//*** ICMP Type Field*/#define ICT_ECHORP      0   /* echo reply */#define ICT_DESTUR      3   /* destination unreachable */#define ICT_SRCQ        4   /* source quench */#define ICT_REDIRECT    5   /* redirect message type */#define ICT_ECHORQ      8   /* echo request */#define ICT_RTADVERT    9   /* router advertisement */#define ICT_TIMEX       11  /* time exceeded */#define ICT_PARAMP      12  /* parameter problem */#define ICT_TIMERQ      13  /* timestamp request */#define ICT_TIMERP      14  /* timestamp reply */#define ICT_MASKRQ      17  /* mask request */#define ICT_MASKRP      18  /* mask reply *//***********************************************************************//* Type Definitions                                                    *//***********************************************************************//*** Simple ICMP Message Structure*/typedef struct{  ui8  type;  ui8  code;  ui16 checksum;  ui32 lword;  ui8  datagram[1];     /* header plus 8 bytes of original */} Icmp;/*** ICMP Echo Structure*/typedef struct{  ui8  type;            /* 0/8 = request/reply */  ui8  code;  ui16 checksum;  ui16 identifier;  ui16 seq_num;  ui8  data[1];} Echo;/*** Mask Request/Reply Structure*/typedef struct{  ui8  type;            /* 17/18 = request/reply */  ui8  code;  ui16 checksum;  ui16 identifier;  ui16 seq_num;  ui32 mask;} Mask;/*** Ping Table Structure*/typedef struct{  ui16 seq_num;  TASK taskid;  NetBuf *buf;  int soft_error;} PingEntry;/***********************************************************************//* Global Variable Definitions                                         *//***********************************************************************/static PingEntry PingTbl[PING_TBL_SZ];/*** ICMP Error Message Counters*/static uint DstUrNetUr, DstUrHostUr, DstUrProtoUr, DstUrPortUr;static uint DstUrFragReq, DstUrSRCRT, DstUrNetUnk, DstUrHostUnk;static uint DstUrNetTyp, DstUrHostTyp, DstUrCommPro, DstUrPrecVio;static uint DstUrPrecCut, SrcQuench;/***********************************************************************//* Local Function Definitions                                          *//***********************************************************************//***********************************************************************//*   icmp_send: Shared ICMP output routine                             *//*                                                                     *//*      Inputs: buf = buffer to send                                   *//*              length = length of data in buffer                      *//*              tos = type of service/priority flag                    *//*                                                                     *//***********************************************************************/static void icmp_send(NetBuf *buf, int length, ui8 tos){  Ip *ip = (Ip *)buf->ip_pkt;  Route *route;  /*-------------------------------------------------------------------*/  /* Route datagram. Drop if no route exists.                          */  /*-------------------------------------------------------------------*/  route = RtSearch(ip->dst_ip);  if (route == NULL)  {    tcpRetBuf(&buf);    return;  }  /*-------------------------------------------------------------------*/  /* Complete protocol field and pass to IP layer.                     */  /*-------------------------------------------------------------------*/  ip->protocol = IPT_ICMP;  IpSend(route, buf, length, tos);}/***********************************************************************//*  simple_msg: Send simple ICMP error responses                       *//*                                                                     *//*      Inputs: type = ICMP message type                               *//*              code = coded reason that destination is not reachable  *//*              buf = pointer to buffer containing error packet        *//*              src = IP address of host that sent packet with error   *//*              route = pointer to destination route                   *//*              lword = value of long word in ICMP message             *//*                                                                     *//***********************************************************************/static void simple_msg(int type, int code, const NetBuf *buf, ui32 src,                       ui32 dst, ui32 lword){  NetBuf *reply;  Icmp *icmp;  Route *route;  Ip *ip = (Ip *)buf->ip_pkt;  int ip_hlen = IP_HLEN(buf->ip_pkt);  /*-------------------------------------------------------------------*/  /* Don't send errors about error packets...                          */  /*-------------------------------------------------------------------*/  if (ip->protocol == IPT_ICMP)  {    /*-----------------------------------------------------------------*/    /* Use "type" field to not respond to error responses.             */    /*-----------------------------------------------------------------*/    switch (*(ui8 *)buf->ip_data)    {      case ICT_DESTUR:      case ICT_SRCQ:      case ICT_REDIRECT:      case ICT_TIMEX:      case ICT_PARAMP:        return;    }  }  /*-------------------------------------------------------------------*/  /* or a fragment other than the first...                             */  /*-------------------------------------------------------------------*/  if (ip->frag_off & IP_FRAGOFF)    return;  /*-------------------------------------------------------------------*/  /* or broadcast packets.                                             */  /*-------------------------------------------------------------------*/  route = RtSearch(dst);  if ((route == NULL) || (route->flags & RT_BRDCST))    return;  /*-------------------------------------------------------------------*/  /* Get a network buffer for error message.                           */  /*-------------------------------------------------------------------*/  reply = tcpGetBuf(NIMHLEN + IPMHLEN + ICMP_HLEN + 8 + ip_hlen);  if (reply == NULL)    return;  /*-------------------------------------------------------------------*/  /* Error reports include header plus first 8 bytes of datagram.      */  /*-------------------------------------------------------------------*/  icmp = reply->ip_data;  memcpy(icmp->datagram, buf->ip_pkt, ip_hlen);  memcpy(icmp->datagram + ip_hlen, buf->ip_data, 8);  /*-------------------------------------------------------------------*/  /* Complete ICMP reply packet fields.                                */  /*-------------------------------------------------------------------*/  icmp->type = type;  icmp->code = code;  icmp->lword = lword;  /*-------------------------------------------------------------------*/  /* Calculate checksum on completed ICMP packet.                      */  /*-------------------------------------------------------------------*/  icmp->checksum = 0;  icmp->checksum = IpChecksum(icmp, ICMP_HLEN + 8 + ip_hlen);  /*-------------------------------------------------------------------*/  /* Send response back to the host that sent the bad packet.          */  /*-------------------------------------------------------------------*/  ip = (Ip *)reply->ip_pkt;  ip->src_ip = route->ni->ip_addr;  ip->dst_ip = src;  icmp_send(reply, ICMP_HLEN + 8 + ip_hlen, ICMP_TOS);}/***********************************************************************//*  apply2sock: Apply ICMP error to application socket                 *//*                                                                     *//*       Input: error = socket error code or SOURCE_QUENCH             *//*                                                                     *//***********************************************************************/static void apply2sock(int error){  ui8 *ip_data = RxBuf->ip_data;  ui8  protocol;  int ip_hlen;  ui16 dst_port, src_port;  ui32 dst_addr, src_addr;  CircLink *link;  SOCKET sock;  /*-------------------------------------------------------------------*/  /* Read destination and source IP address from original datagram.    */  /*-------------------------------------------------------------------*/  memcpy(&dst_addr, ip_data + offsetof(Icmp, datagram)         + offsetof(Ip, dst_ip), sizeof(dst_addr));  memcpy(&src_addr, ip_data + offsetof(Icmp, datagram)         + offsetof(Ip, src_ip), sizeof(src_addr));  /*-------------------------------------------------------------------*/  /* Read IP protocol and IP header length from original datagram.     */  /*-------------------------------------------------------------------*/  protocol = (ip_data + offsetof(Icmp, datagram) +              offsetof(Ip, protocol))[0];  ip_hlen = IP_HLEN(ip_data + offsetof(Icmp, datagram));  /*-------------------------------------------------------------------*/  /* Read the destination and source port numbers.                     */  /*-------------------------------------------------------------------*/  if (protocol == IPT_TCP)  {    memcpy(&dst_port, ip_data + offsetof(Icmp, datagram) + ip_hlen +           + offsetof(Tcp, dst_port), sizeof(dst_port));    memcpy(&src_port, ip_data + offsetof(Icmp, datagram) + ip_hlen +           + offsetof(Tcp, src_port), sizeof(src_port));  }  else if (protocol == IPT_UDP)  {    memcpy(&dst_port, ip_data + offsetof(Icmp, datagram) + ip_hlen +           + offsetof(Udp, dst_port), sizeof(dst_port));    memcpy(&src_port, ip_data + offsetof(Icmp, datagram) + ip_hlen +           + offsetof(Udp, src_port), sizeof(src_port));  }  else    return;  /*-------------------------------------------------------------------*/  /* If error is not source quench, apply to matching UDP socket.      */  /*-------------------------------------------------------------------*/  if (error != SOURCE_QUENCH)

⌨️ 快捷键说明

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