ip.c
上传用户:yyhongfa
上传日期:2013-01-18
资源大小:267k
文件大小:16k
开发平台:

C/C++

  1. /* @file
  2.  *
  3.  * This is the IP layer implementation for incoming and outgoing IP traffic.
  4.  * 
  5.  * @see ip_frag.c
  6.  *
  7.  */
  8. /*
  9.  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
  10.  * All rights reserved.
  11.  *
  12.  * Redistribution and use in source and binary forms, with or without modification,
  13.  * are permitted provided that the following conditions are met:
  14.  *
  15.  * 1. Redistributions of source code must retain the above copyright notice,
  16.  *    this list of conditions and the following disclaimer.
  17.  * 2. Redistributions in binary form must reproduce the above copyright notice,
  18.  *    this list of conditions and the following disclaimer in the documentation
  19.  *    and/or other materials provided with the distribution.
  20.  * 3. The name of the author may not be used to endorse or promote products
  21.  *    derived from this software without specific prior written permission.
  22.  *
  23.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
  24.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  25.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
  26.  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  27.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
  28.  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  29.  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  30.  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  31.  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  32.  * OF SUCH DAMAGE.
  33.  *
  34.  * This file is part of the lwIP TCP/IP stack.
  35.  *
  36.  * Author: Adam Dunkels <adam@sics.se>
  37.  *
  38.  */
  39. #include "lwip/opt.h"
  40. #include "lwip/def.h"
  41. #include "lwip/mem.h"
  42. #include "lwip/ip.h"
  43. #include "lwip/ip_frag.h"
  44. #include "lwip/inet.h"
  45. #include "lwip/netif.h"
  46. #include "lwip/icmp.h"
  47. #include "lwip/raw.h"
  48. #include "lwip/udp.h"
  49. #include "lwip/tcp.h"
  50. #include "lwip/stats.h"
  51. #include "arch/perf.h"
  52. #include "lwip/snmp.h"
  53. #if LWIP_DHCP
  54. #  include "lwip/dhcp.h"
  55. #endif /* LWIP_DHCP */
  56. #include "uart.h"
  57. /**
  58.  * Initializes the IP layer.
  59.  */
  60. void
  61. ip_init(void)
  62. {
  63.   /* no initializations as of yet */
  64. }
  65. /**
  66.  * Finds the appropriate network interface for a given IP address. It
  67.  * searches the list of network interfaces linearly. A match is found
  68.  * if the masked IP address of the network interface equals the masked
  69.  * IP address given to the function.
  70.  */
  71. struct netif *
  72. ip_route(struct ip_addr *dest)
  73. {
  74.   struct netif *netif;
  75.   /* iterate through netifs */
  76.   for(netif = netif_list; netif != NULL; netif = netif->next) {
  77.     /* network mask matches? */
  78.     if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
  79.       /* return netif on which to forward IP packet */
  80.       return netif;
  81.     }
  82.   }
  83.   /* no matching netif found, use default netif */
  84.   return netif_default;
  85. }
  86. #if IP_FORWARD
  87. /**
  88.  * Forwards an IP packet. It finds an appropriate route for the
  89.  * packet, decrements the TTL value of the packet, adjusts the
  90.  * checksum and outputs the packet on the appropriate interface.
  91.  */
  92. static struct netif *
  93. ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
  94. {
  95.   struct netif *netif;
  96.   PERF_START;
  97.   /* Find network interface where to forward this IP packet to. */
  98.   netif = ip_route((struct ip_addr *)&(iphdr->dest));
  99.   if (netif == NULL) {
  100.     LWIP_DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for 0x%lx foundn",
  101.                       iphdr->dest.addr));
  102.     snmp_inc_ipnoroutes();
  103.     return (struct netif *)NULL;
  104.   }
  105.   /* Do not forward packets onto the same network interface on which
  106.    * they arrived. */
  107.   if (netif == inp) {
  108.     LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.n"));
  109.     snmp_inc_ipnoroutes();
  110.     return (struct netif *)NULL;
  111.   }
  112.   /* decrement TTL */
  113.   IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1);
  114.   /* send ICMP if TTL == 0 */
  115.   if (IPH_TTL(iphdr) == 0) {
  116.     /* Don't send ICMP messages in response to ICMP messages */
  117.     if (IPH_PROTO(iphdr) != IP_PROTO_ICMP) {
  118.       icmp_time_exceeded(p, ICMP_TE_TTL);
  119.       snmp_inc_icmpouttimeexcds();
  120.     }
  121.     return (struct netif *)NULL;
  122.   }
  123.   /* Incrementally update the IP checksum. */
  124.   if (IPH_CHKSUM(iphdr) >= htons(0xffff - 0x100)) {
  125.     IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100) + 1);
  126.   } else {
  127.     IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100));
  128.   }
  129.   LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to 0x%lxn",
  130.                     iphdr->dest.addr));
  131.   IP_STATS_INC(ip.fw);
  132.   IP_STATS_INC(ip.xmit);
  133.     snmp_inc_ipforwdatagrams();
  134.  // PERF_STOP("ip_forward");
  135.   /* transmit pbuf on chosen interface */
  136.   netif->output(netif, p, (struct ip_addr *)&(iphdr->dest));
  137.   return netif;
  138. }
  139. #endif /* IP_FORWARD */
  140. /**
  141.  * This function is called by the network interface device driver when
  142.  * an IP packet is received. The function does the basic checks of the
  143.  * IP header such as packet size being at least larger than the header
  144.  * size etc. If the packet was not destined for us, the packet is
  145.  * forwarded (using ip_forward). The IP checksum is always checked.
  146.  *
  147.  * Finally, the packet is sent to the upper layer protocol input function.
  148.  * 
  149.  * 
  150.  * 
  151.  */
  152. err_t
  153. ip_input(struct pbuf *p, struct netif *inp) {
  154.   struct ip_hdr *iphdr;
  155.   struct netif *netif;
  156.   u16_t iphdrlen;
  157.   IP_STATS_INC(ip.recv);
  158.   snmp_inc_ipinreceives();
  159.   DEBUG_FUNCTION("ip_input()");
  160.   /* identify the IP header */
  161.   iphdr = p->payload;
  162.   if (IPH_V(iphdr) != 4) {
  163.     LWIP_DEBUGF(IP_DEBUG | 1, ("IP packet dropped due to bad version number %un", IPH_V(iphdr)));
  164.      DEBUG_EVENT("IP packet dropped due to bad version number");
  165.     ip_debug_print(p);
  166.     pbuf_free(p);
  167.     IP_STATS_INC(ip.err);
  168.     IP_STATS_INC(ip.drop);
  169.     snmp_inc_ipunknownprotos();
  170.     return ERR_OK;
  171.   }
  172.   /* obtain IP header length in number of 32-bit words */
  173.   iphdrlen = IPH_HL(iphdr);
  174.   /* calculate IP header length in bytes */
  175.   iphdrlen *= 4;
  176.   /* header length exceeds first pbuf length? */
  177.   if (iphdrlen > p->len) {
  178.     LWIP_DEBUGF(IP_DEBUG | 2, ("IP header (len %u) does not fit in first pbuf (len %u), IP packet droppped.n",
  179.       iphdrlen, p->len));
  180.     /* free (drop) packet pbufs */
  181.     DEBUG_EVENT("IP header (len %u) does not fit in first pbuf (len %u), IP packet droppped.");
  182.     pbuf_free(p);
  183.     IP_STATS_INC(ip.lenerr);
  184.     IP_STATS_INC(ip.drop);
  185.     snmp_inc_ipindiscards();
  186.     return ERR_OK;
  187.   }
  188.   /* verify checksum */
  189. #if CHECKSUM_CHECK_IP
  190.   if (inet_chksum(iphdr, iphdrlen) != 0) {
  191.     LWIP_DEBUGF(IP_DEBUG | 2, ("Checksum (0x%x) failed, IP packet dropped.n", inet_chksum(iphdr, iphdrlen)));
  192.     DEBUG_EVENT("Checksum (0x%x) failed, IP packet dropped..");
  193.     ip_debug_print(p);
  194.     pbuf_free(p);
  195.     IP_STATS_INC(ip.chkerr);
  196.     IP_STATS_INC(ip.drop);
  197.     snmp_inc_ipindiscards();
  198.     return ERR_OK;
  199.   }
  200. #endif
  201.   /* Trim pbuf. This should have been done at the netif layer,
  202.    * but we'll do it anyway just to be sure that its done. */
  203.   pbuf_realloc(p, ntohs(IPH_LEN(iphdr)));
  204.   /* match packet against an interface, i.e. is this packet for us? */
  205.   for (netif = netif_list; netif != NULL; netif = netif->next) {
  206.     LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%lx netif->ip_addr 0x%lx (0x%lx, 0x%lx, 0x%lx)n",
  207.       iphdr->dest.addr, netif->ip_addr.addr,
  208.       iphdr->dest.addr & netif->netmask.addr,
  209.       netif->ip_addr.addr & netif->netmask.addr,
  210.       iphdr->dest.addr & ~(netif->netmask.addr)));
  211.     /* interface is up and configured? */
  212.     if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr))))
  213.     {
  214.   /* unicast to this interface address? */
  215.       if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr)) ||
  216.          /* or broadcast on this interface network address? */
  217.          ip_addr_isbroadcast(&(iphdr->dest), netif)) {
  218.         LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%cn",
  219.           netif->name[0], netif->name[1]));
  220.         /* break out of for loop */
  221.         break;
  222.       }
  223.     }
  224.   }
  225. #if LWIP_DHCP
  226.   /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed
  227.    * using link layer addressing (such as Ethernet MAC) so we must not filter on IP.
  228.    * According to RFC 1542 section 3.1.1, referred by RFC 2131).
  229.    */
  230.   if (netif == NULL) {
  231.     /* remote port is DHCP server? */
  232.     if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {
  233.       LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: UDP packet to DHCP client port %un",
  234.         ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest)));
  235.       if (ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest) == DHCP_CLIENT_PORT) {
  236.         LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: DHCP packet accepted.n"));
  237.         netif = inp;
  238.       }
  239.     }
  240.   }
  241. #endif /* LWIP_DHCP */
  242.   /* packet not for us? */
  243.   if (netif == NULL) {
  244.     /* packet not for us, route or discard */
  245.     LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: packet not for us.n"));
  246.     DEBUG_EVENT("ip_input: packet not for us.");
  247. #if IP_FORWARD
  248.     /* non-broadcast packet? */
  249.     if (!ip_addr_isbroadcast(&(iphdr->dest), inp)) {
  250.       /* try to forward IP packet on (other) interfaces */
  251.       ip_forward(p, iphdr, inp);
  252.     }
  253.     else
  254. #endif /* IP_FORWARD */
  255.     {
  256.       snmp_inc_ipindiscards();
  257.     }
  258.     pbuf_free(p);
  259.     return ERR_OK;
  260.   }
  261.   /* packet consists of multiple fragments? */
  262.   if ((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
  263. #if IP_REASSEMBLY /* packet fragment reassembly code present? */
  264.     LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04x tot_len=%u len=%u MF=%u offset=%u), calling ip_reass()n",
  265.       ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & htons(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8));
  266.     /* reassemble the packet*/
  267.     p = ip_reass(p);
  268.     /* packet not fully reassembled yet? */
  269.     if (p == NULL) {
  270.       return ERR_OK;
  271.     }
  272.     iphdr = p->payload;
  273. #else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */
  274.     pbuf_free(p);
  275.     LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since it was fragmented (0x%x) (while IP_REASSEMBLY == 0).n",
  276.       ntohs(IPH_OFFSET(iphdr))));
  277.     DEBUG_EVENT("IP packet dropped since it was fragmented (0x%x) (while IP_REASSEMBLY == 0)");
  278.     IP_STATS_INC(ip.opterr);
  279.     IP_STATS_INC(ip.drop);
  280.     snmp_inc_ipunknownprotos();
  281.     return ERR_OK;
  282. #endif /* IP_REASSEMBLY */
  283.   }
  284. #if IP_OPTIONS == 0 /* no support for IP options in the IP header? */
  285.   if (iphdrlen > IP_HLEN) {
  286.     LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since there were IP options (while IP_OPTIONS == 0).n"));
  287.      DEBUG_EVENT("IP packet dropped since there were IP options (while IP_OPTIONS == 0).");
  288.  
  289.     pbuf_free(p);
  290.     IP_STATS_INC(ip.opterr);
  291.     IP_STATS_INC(ip.drop);
  292.     snmp_inc_ipunknownprotos();
  293.     return ERR_OK;
  294.   }
  295. #endif /* IP_OPTIONS == 0 */
  296.   /* send to upper layers */
  297.   LWIP_DEBUGF(IP_DEBUG, ("ip_input: n"));
  298.   ip_debug_print(p);
  299.   LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %d p->tot_len %dn", p->len, p->tot_len));
  300. #if LWIP_RAW
  301.   /* raw input did not eat the packet? */
  302.   if (raw_input(p, inp) == 0) {
  303. #endif /* LWIP_RAW */
  304.   switch (IPH_PROTO(iphdr)) {
  305. #if LWIP_UDP
  306.   case IP_PROTO_UDP:
  307.   case IP_PROTO_UDPLITE:
  308.     snmp_inc_ipindelivers();
  309.     udp_input(p, inp);
  310.     break;
  311. #endif /* LWIP_UDP */
  312. #if LWIP_TCP
  313.   case IP_PROTO_TCP:
  314.     snmp_inc_ipindelivers();
  315.     tcp_input(p, inp);
  316.     break;
  317. #endif /* LWIP_TCP */
  318.   case IP_PROTO_ICMP:
  319.     snmp_inc_ipindelivers();
  320.     icmp_input(p, inp);
  321.     break;
  322.   default:
  323.     /* send ICMP destination protocol unreachable unless is was a broadcast */
  324.     if (!ip_addr_isbroadcast(&(iphdr->dest), inp) &&
  325.         !ip_addr_ismulticast(&(iphdr->dest))) {
  326.       p->payload = iphdr;
  327.       icmp_dest_unreach(p, ICMP_DUR_PROTO);
  328.     }
  329.     pbuf_free(p);
  330.     LWIP_DEBUGF(IP_DEBUG | 2, ("Unsupported transport protocol %dn", IPH_PROTO(iphdr)));
  331.     IP_STATS_INC(ip.proterr);
  332.     IP_STATS_INC(ip.drop);
  333.     snmp_inc_ipunknownprotos();
  334.   }
  335. #if LWIP_RAW
  336.   } /* LWIP_RAW */
  337. #endif
  338.   return ERR_OK;
  339. }
  340. /**
  341.  * Sends an IP packet on a network interface. This function constructs
  342.  * the IP header and calculates the IP header checksum. If the source
  343.  * IP address is NULL, the IP address of the outgoing network
  344.  * interface is filled in as source address.
  345.  */
  346. err_t
  347. ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
  348.              u8_t ttl, u8_t tos,
  349.              u8_t proto, struct netif *netif)
  350. {
  351.   struct ip_hdr *iphdr;
  352.   u16_t ip_id = 0;
  353.   snmp_inc_ipoutrequests();
  354.   if (dest != IP_HDRINCL) {
  355.     if (pbuf_header(p, IP_HLEN)) {
  356.       LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: not enough room for IP header in pbufn"));
  357.       IP_STATS_INC(ip.err);
  358.       snmp_inc_ipoutdiscards();
  359.       return ERR_BUF;
  360.     }
  361.     iphdr = p->payload;
  362.     IPH_TTL_SET(iphdr, ttl);
  363.     IPH_PROTO_SET(iphdr, proto);
  364.     ip_addr_set(&(iphdr->dest), dest);
  365.     IPH_VHLTOS_SET(iphdr, 4, IP_HLEN / 4, tos);
  366.     IPH_LEN_SET(iphdr, htons(p->tot_len));
  367.     IPH_OFFSET_SET(iphdr, htons(IP_DF));
  368.     IPH_ID_SET(iphdr, htons(ip_id));
  369.     ++ip_id;
  370.     if (ip_addr_isany(src)) {
  371.       ip_addr_set(&(iphdr->src), &(netif->ip_addr));
  372.     } else {
  373.       ip_addr_set(&(iphdr->src), src);
  374.     }
  375.     IPH_CHKSUM_SET(iphdr, 0);
  376. #if CHECKSUM_GEN_IP
  377.     IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
  378. #endif
  379.   } else {
  380.     iphdr = p->payload;
  381.     dest = &(iphdr->dest);
  382.   }
  383. #if IP_FRAG
  384.   /* don't fragment if interface has mtu set to 0 [loopif] */
  385.   if (netif->mtu && (p->tot_len > netif->mtu))
  386.     return ip_frag(p,netif,dest);
  387. #endif
  388.   IP_STATS_INC(ip.xmit);
  389.   LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%un", netif->name[0], netif->name[1], netif->num));
  390.   ip_debug_print(p);
  391.   LWIP_DEBUGF(IP_DEBUG, ("netif->output()"));
  392.   return netif->output(netif, p, dest);
  393. }
  394. /**
  395.  * Simple interface to ip_output_if. It finds the outgoing network
  396.  * interface and calls upon ip_output_if to do the actual work.
  397.  */
  398. err_t
  399. ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
  400.           u8_t ttl, u8_t tos, u8_t proto)
  401. {
  402.   struct netif *netif;
  403.   if ((netif = ip_route(dest)) == NULL) {
  404.     LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: No route to 0x%lxn", dest->addr));
  405.     IP_STATS_INC(ip.rterr);
  406.     snmp_inc_ipoutdiscards();
  407.     return ERR_RTE;
  408.   }
  409.   return ip_output_if(p, src, dest, ttl, tos, proto, netif);
  410. }
  411. #if IP_DEBUG
  412. void
  413. ip_debug_print(struct pbuf *p)
  414. {
  415.   struct ip_hdr *iphdr = p->payload;
  416.   u8_t *payload;
  417.   payload = (u8_t *)iphdr + IP_HLEN;
  418.   LWIP_DEBUGF(IP_DEBUG, ("IP header:n"));
  419.   LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+n"));
  420.   LWIP_DEBUGF(IP_DEBUG, ("|%2d |%2d |  0x%02x |     %5u     | (v, hl, tos, len)n",
  421.                     IPH_V(iphdr),
  422.                     IPH_HL(iphdr),
  423.                     IPH_TOS(iphdr),
  424.                     ntohs(IPH_LEN(iphdr))));
  425.   LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+n"));
  426.   LWIP_DEBUGF(IP_DEBUG, ("|    %5u      |%u%u%u|    %4u   | (id, flags, offset)n",
  427.                     ntohs(IPH_ID(iphdr)),
  428.                     ntohs(IPH_OFFSET(iphdr)) >> 15 & 1,
  429.                     ntohs(IPH_OFFSET(iphdr)) >> 14 & 1,
  430.                     ntohs(IPH_OFFSET(iphdr)) >> 13 & 1,
  431.                     ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK));
  432.   LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+n"));
  433.   LWIP_DEBUGF(IP_DEBUG, ("|  %3u  |  %3u  |    0x%04x     | (ttl, proto, chksum)n",
  434.                     IPH_TTL(iphdr),
  435.                     IPH_PROTO(iphdr),
  436.                     ntohs(IPH_CHKSUM(iphdr))));
  437.   LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+n"));
  438.   LWIP_DEBUGF(IP_DEBUG, ("|  %3u  |  %3u  |  %3u  |  %3u  | (src)n",
  439.                     ip4_addr1(&iphdr->src),
  440.                     ip4_addr2(&iphdr->src),
  441.                     ip4_addr3(&iphdr->src),
  442.                     ip4_addr4(&iphdr->src)));
  443.   LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+n"));
  444.   LWIP_DEBUGF(IP_DEBUG, ("|  %3u  |  %3u  |  %3u  |  %3u  | (dest)n",
  445.                     ip4_addr1(&iphdr->dest),
  446.                     ip4_addr2(&iphdr->dest),
  447.                     ip4_addr3(&iphdr->dest),
  448.                     ip4_addr4(&iphdr->dest)));
  449.   LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+n"));
  450. }
  451. #endif /* IP_DEBUG */