uip-input.c

来自「這是一個實時嵌入式作業系統 實作了MCS51 ARM等MCU」· C语言 代码 · 共 526 行 · 第 1/2 页

C
526
字号
         * now on.         */        BUF->ipoffset[0] = BUF->ipoffset[1] = 0;        BUF->len[0] = uip_reasslen >> 8;        BUF->len[1] = uip_reasslen & 0xff;        BUF->ipchksum = 0;        BUF->ipchksum = ~(uip_ipchksum(dev));        return uip_reasslen;      }  }nullreturn:  return 0;}#endif /* UIP_REASSEMBLY *//**************************************************************************** * Public Functions ****************************************************************************//**************************************************************************** * Function: uip_input * * Description: * * Assumptions: * ****************************************************************************/void uip_input(struct uip_driver_s *dev){  /* This is where the input processing starts. */#ifdef CONFIG_NET_STATISTICS  uip_stat.ip.recv++;#endif  /* Start of IP input header processing code. */#ifdef CONFIG_NET_IPv6  /* Check validity of the IP header. */  if ((BUF->vtc & 0xf0) != 0x60)     {      /* IP version and header length. */#ifdef CONFIG_NET_STATISTICS      uip_stat.ip.drop++;      uip_stat.ip.vhlerr++;#endif      ndbg("Invalid IPv6 version: %d\n", BUF->vtc >> 4);      goto drop;    }#else /* CONFIG_NET_IPv6 */  /* Check validity of the IP header. */  if (BUF->vhl != 0x45)    {      /* IP version and header length. */#ifdef CONFIG_NET_STATISTICS      uip_stat.ip.drop++;      uip_stat.ip.vhlerr++;#endif      ndbg("Invalid IP version or header length: %02x\n", BUF->vhl);      goto drop;    }#endif /* CONFIG_NET_IPv6 */  /* Check the size of the packet. If the size reported to us in d_len is   * smaller the size reported in the IP header, we assume that the packet   * has been corrupted in transit. If the size of d_len is larger than the   * size reported in the IP packet header, the packet has been padded and   * we set d_len to the correct value.   */  if ((BUF->len[0] << 8) + BUF->len[1] <= dev->d_len)    {      dev->d_len = (BUF->len[0] << 8) + BUF->len[1];#ifdef CONFIG_NET_IPv6      /* The length reported in the IPv6 header is the length of the       * payload that follows the header. However, uIP uses the d_len       * variable for holding the size of the entire packet, including the       * IP header. For IPv4 this is not a problem as the length field in       * the IPv4 header contains the length of the entire packet. But       * for IPv6 we need to add the size of the IPv6 header (40 bytes).       */      dev->d_len += 40;#endif /* CONFIG_NET_IPv6 */    }  else    {      ndbg("IP packet shorter than length in IP header\n");      goto drop;    }#ifndef CONFIG_NET_IPv6  /* Check the fragment flag. */  if ((BUF->ipoffset[0] & 0x3f) != 0 || BUF->ipoffset[1] != 0)    {#if UIP_REASSEMBLY      dev->d_len = uip_reass();      if (dev->d_len == 0)        {          goto drop;        }#else /* UIP_REASSEMBLY */#ifdef CONFIG_NET_STATISTICS      uip_stat.ip.drop++;      uip_stat.ip.fragerr++;#endif      ndbg("IP fragment dropped\n");      goto drop;#endif /* UIP_REASSEMBLY */    }#endif /* CONFIG_NET_IPv6 */   /* If IP broadcast support is configured, we check for a broadcast    * UDP packet, which may be destined to us (even if there is no IP    * address yet assigned to the device as is the case when we are    * negotiating over DHCP for an address).    */#if defined(CONFIG_NET_BROADCAST) && defined(CONFIG_NET_UDP)  if (BUF->proto == UIP_PROTO_UDP &&#ifndef CONFIG_NET_IPv6      uip_ipaddr_cmp(uip_ip4addr_conv(BUF->destipaddr), g_alloneaddr))#else      uip_ipaddr_cmp(BUF->destipaddr, g_alloneaddr))#endif    {      uip_udpinput(dev);      return;    }  /* In most other cases, the device must be assigned a non-zero IP   * address.  Another exception is when CONFIG_NET_PINGADDRCONF is   * enabled...   */  else#endif  if (uip_ipaddr_cmp(dev->d_ipaddr, g_allzeroaddr))    {      /* If we are configured to use ping IP address configuration and       * hasn't been assigned an IP address yet, we accept all ICMP       * packets.       */#if defined(CONFIG_NET_PINGADDRCONF) && !defined(CONFIG_NET_IPv6)      if (BUF->proto == UIP_PROTO_ICMP)        {          ndbg("Possible ping config packet received\n");          uip_icmpinput(dev);          goto done;        }      else#endif        {          ndbg("No IP address assigned\n");          goto drop;        }    }  /* Check if the pack is destined for out IP address */  else    {      /* Check if the packet is destined for our IP address. */#ifndef CONFIG_NET_IPv6      if (!uip_ipaddr_cmp(uip_ip4addr_conv(BUF->destipaddr), dev->d_ipaddr))        {#ifdef CONFIG_NET_STATISTICS          uip_stat.ip.drop++;#endif          goto drop;        }#else /* CONFIG_NET_IPv6 */      /* For IPv6, packet reception is a little trickier as we need to       * make sure that we listen to certain multicast addresses (all       * hosts multicast address, and the solicited-node multicast       * address) as well. However, we will cheat here and accept all       * multicast packets that are sent to the ff02::/16 addresses.       */      if (!uip_ipaddr_cmp(BUF->destipaddr, dev->d_ipaddr) &&           BUF->destipaddr & HTONL(0xffff0000) != HTONL(0xff020000))        {#ifdef CONFIG_NET_STATISTICS          uip_stat.ip.drop++;#endif          goto drop;        }#endif /* CONFIG_NET_IPv6 */    }#ifndef CONFIG_NET_IPv6  if (uip_ipchksum(dev) != 0xffff)    {      /* Compute and check the IP header checksum. */#ifdef CONFIG_NET_STATISTICS      uip_stat.ip.drop++;      uip_stat.ip.chkerr++;#endif      ndbg("Bad IP checksum\n");      goto drop;    }#endif /* CONFIG_NET_IPv6 */  /* Everything looks good so far.  Now process the incoming packet   * according to the protocol.   */  switch (BUF->proto)    {#ifdef CONFIG_NET_TCP      case UIP_PROTO_TCP:   /* TCP input */        uip_tcpinput(dev);        break;#endif#ifdef CONFIG_NET_UDP      case UIP_PROTO_UDP:   /* UDP input */        uip_udpinput(dev);        break;#endif  /* Check for ICMP input */#ifdef CONFIG_NET_ICMP#ifndef CONFIG_NET_IPv6      case UIP_PROTO_ICMP:  /* ICMP input */#else      case UIP_PROTO_ICMP6: /* ICMP6 input */#endif        uip_icmpinput(dev);        break;#endif      default:              /* Unrecognized/unsupported protocol */#ifdef CONFIG_NET_STATISTICS        uip_stat.ip.drop++;        uip_stat.ip.protoerr++;#endif        ndbg("Unrecognized IP protocol\n");        goto drop;    }  /* Return and let the caller do any actual transmission. */  return;drop:  dev->d_len = 0;}#endif /* CONFIG_NET */

⌨️ 快捷键说明

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