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

📄 icmp.c

📁 用于嵌入式系统的TCP/IP协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
  {    for (link = UdpLruList.next_bck;; link = link->next_bck)    {      if (link == &UdpLruList) break;      sock = (SOCKET)link;      if ((sock->flags & SF_CONNECTED) == FALSE) continue;      if ((sock->local.sin_port == src_port) &&          (sock->remote.sin_port == dst_port) &&          (sock->local.sin_addr.s_addr == src_addr) &&          (sock->remote.sin_addr.s_addr == dst_addr))      {        sock->soft_error = error;        break;      }    }  }  /*-------------------------------------------------------------------*/  /* Apply either source quench or error to matching TCP socket.       */  /*-------------------------------------------------------------------*/  for (link = TcpLruList.next_bck;; link = link->next_bck)  {    if (link == &TcpLruList) break;    sock = (SOCKET)link;    if ((sock->flags & SF_CONNECTED) == FALSE) continue;    if ((sock->local.sin_port == src_port) &&        (sock->remote.sin_port == dst_port) &&        (sock->local.sin_addr.s_addr == src_addr) &&        (sock->remote.sin_addr.s_addr == dst_addr))    {      if (error == SOURCE_QUENCH)        sock->snd_cwnd = sock->snd_mss;      else        sock->soft_error = error;      break;    }  }}/***********************************************************************//* Global Function Definitions                                         *//***********************************************************************//***********************************************************************//*  IcmpDestUR: Send ICMP destination unreachable error response       *//*                                                                     *//*      Inputs: code = coded reason that destination is not reachable  *//*              buf = pointer to buffer containing error packet        *//*              src = IP address of host that sent bad packet          *//*              dst = bad packet's destination IP address              *//*                                                                     *//***********************************************************************/void IcmpDestUR(int code, NetBuf *buf, ui32 src, ui32 dst){  simple_msg(ICT_DESTUR, code, buf, src, dst, 0);}/***********************************************************************//*  IcmpTimeEx: Send ICMP time exceeded error response                 *//*                                                                     *//*      Inputs: code = 0/1 (during transit/during fragment assembly)   *//*              buf = pointer to buffer containing error packet        *//*              dest = destination IP address                          *//*                                                                     *//***********************************************************************/void IcmpTimeEx(int code, NetBuf *buf, ui32 src, ui32 dst){  simple_msg(ICT_TIMEX, code, buf, src, dst, 0);}/***********************************************************************//* IcmpRedirect: Send an ICMP redirect message                         *//*                                                                     *//*      Inputs: code = ICC_NETRD or ICC_HOSTRD                         *//*              gw = gateway from which packet arrived                 *//*              dest = destination IP address                          *//*                                                                     *//***********************************************************************/void IcmpRedirect(int code, ui32 gw, ui32 src, ui32 dst){  simple_msg(ICT_REDIRECT, code, RxBuf, src, dst, gw);}/***********************************************************************//*     tcpPing: Send an echo request to a host and decode result       *//*                                                                     *//*      Inputs: dst_addr = IP address of host                          *//*              length = length of data in echo request                *//*              verbose = TRUE if message should be sent to stdout     *//*                                                                     *//*     Returns: 0 if no error, else -1                                 *//*                                                                     *//***********************************************************************/int tcpPing(ui32 dst_addr, uint length, int verbose){  NetBuf *buf;  Ip *ip;  Echo *echo;  Route *route;  int i;  static int seq_num;  PingEntry *entry;  /*-------------------------------------------------------------------*/  /* Verify protocol has been initialized.                             */  /*-------------------------------------------------------------------*/  if (!Net.Initialized)  {    NetError(NULL, ENETDOWN);    return -1;  }  /*-------------------------------------------------------------------*/  /* Verify there is a route to this host.                             */  /*-------------------------------------------------------------------*/  route = RtSearch(dst_addr);  if (route == NULL)  {    NetError(NULL, EHOSTUNREACH);    return -1;  }  /*-------------------------------------------------------------------*/  /* Get network buffer for the echo request.                          */  /*-------------------------------------------------------------------*/  semPend(Net.IntSem, WAIT_FOREVER);  buf = tcpGetBuf(NIMHLEN + IPMHLEN + ICMP_HLEN + length);  semPost(Net.IntSem);  if (buf == NULL)  {    NetError(NULL, ENOBUFS);    return -1;  }  /*-------------------------------------------------------------------*/  /* Gain exclusive access to stack internals.                         */  /*-------------------------------------------------------------------*/  semPend(Net.IntSem, WAIT_FOREVER);  /*-------------------------------------------------------------------*/  /* Find free entry in Ping Table.                                    */  /*-------------------------------------------------------------------*/  for (i = 0; PingTbl[i].taskid;)  {    if (++i == PING_TBL_SZ)    {      semPend(Net.IntSem, WAIT_FOREVER);      tcpRetBuf(&buf);      semPost(Net.IntSem);      NetError(NULL, ENOBUFS);      semPost(Net.IntSem);      return -1;    }  }  /*-------------------------------------------------------------------*/  /* Increment ping request sequence number and initialize table.      */  /*-------------------------------------------------------------------*/  ++seq_num;  entry = &PingTbl[i];  entry->seq_num = htons(seq_num);  entry->taskid = RunningTask;  entry->soft_error = 0;  /*-------------------------------------------------------------------*/  /* Start ICMP header initialization.                                 */  /*-------------------------------------------------------------------*/  echo = buf->ip_data;  echo->type = ICT_ECHORQ;  echo->code = 0;  echo->identifier = 0;  echo->seq_num = htons(seq_num);  /*-------------------------------------------------------------------*/  /* Initialize echo request data to be a counting pattern.            */  /*-------------------------------------------------------------------*/  for (i = 0; i < length; ++i)    echo->data[i] = i + 'a';  /*-------------------------------------------------------------------*/  /* Calculate checksum on completed ICMP packet.                      */  /*-------------------------------------------------------------------*/  echo->checksum = 0;  echo->checksum = IpChecksum(echo, ICMP_HLEN + length);  /*-------------------------------------------------------------------*/  /* Start IP header initialization and request packet to be sent.     */  /*-------------------------------------------------------------------*/  ip = (Ip *)buf->ip_pkt;  ip->src_ip = route->ni->ip_addr;  ip->dst_ip = dst_addr;  icmp_send(buf, ICMP_HLEN + length, ICMP_TOS);  /*-------------------------------------------------------------------*/  /* Release internals access and wait up to 3 seconds for reply.      */  /*-------------------------------------------------------------------*/  taskLock();  semPost(Net.IntSem);  taskSleep(3 * OsTicksPerSec);  /*-------------------------------------------------------------------*/  /* Reacquire access long enough to determine timeout or success.     */  /*-------------------------------------------------------------------*/  semPend(Net.IntSem, WAIT_FOREVER);  if (entry->taskid)  {    entry->taskid = 0;    entry->buf = 0;  }  buf = entry->buf;  semPost(Net.IntSem);  /*-------------------------------------------------------------------*/  /* Respond to timeout or ping response.                              */  /*-------------------------------------------------------------------*/  if (buf == 0)  {    NetError(NULL, entry->soft_error ? entry->soft_error : ETIMEDOUT);    if (verbose)    {      if (entry->soft_error)        perror("Ping error: ");      else        printf("Request timed out.\n");    }    return -1;  }  else  {    /*-----------------------------------------------------------------*/    /* Print response statistics if verbose.                           */    /*-----------------------------------------------------------------*/    if (verbose)    {      ui16 seq_no;      printf("Reply from ");      ip = (Ip *)buf->ip_pkt;      printIP(ip->src_ip);      memcpy(&seq_no, (ui8 *)buf->ip_data + offsetof(Echo, seq_num), 2);      printf(": bytes = %u, seq = 0x%04X, TTL = %u\n", ip->length -                      (IP_HLEN(ip) + ICMP_HLEN), ntohs(seq_no), ip->ttl);    }    /*-----------------------------------------------------------------*/    /* Free response buffer and return success code.                   */    /*-----------------------------------------------------------------*/    semPend(Net.IntSem, WAIT_FOREVER);    tcpRetBuf(&buf);    semPost(Net.IntSem);    return 0;  }}/***********************************************************************//*      IcmpIn: Handle incoming ICMP packet                            *//*                                                                     *//***********************************************************************/void IcmpIn(void){  ui8 *ip_data = RxBuf->ip_data;  /*-------------------------------------------------------------------*/  /* Verify ICMP checksum.                                             */  /*-------------------------------------------------------------------*/  if (IpChecksum(ip_data, RxBuf->length))    return;  /*-------------------------------------------------------------------*/  /* Switch using (possibly unaligned) ICMP message type.              */  /*-------------------------------------------------------------------*/  switch (ip_data[0])  {  case ICT_ECHORQ:    /*-----------------------------------------------------------------*/    /* Respond to an incoming echo request.                            */    /*-----------------------------------------------------------------*/    {      Echo *reply;      Ip *ip_out;      Ip *ip_in = (Ip *)RxBuf->ip_pkt;      NetBuf *rbuf;      int id_offset = offsetof(Echo, identifier);      /*---------------------------------------------------------------*/      /* Get a network buffer for error message.                       */      /*---------------------------------------------------------------*/      rbuf = tcpGetBuf(NIMHLEN + IPMHLEN + RxBuf->length);      if (rbuf == NULL)

⌨️ 快捷键说明

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