/[lwip]/lwip/src/core/ipv4/ip.c
ViewVC logotype

Diff of /lwip/src/core/ipv4/ip.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.24 by kieranm, Tue Jun 10 10:45:29 2003 UTC revision 1.25 by likewise, Wed Jun 11 22:34:51 2003 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (c) 2001-2003 Swedish Institute of Computer Science.   * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
3   * All rights reserved.   * All rights reserved.
4   *   *
5   * Redistribution and use in source and binary forms, with or without modification,   * Redistribution and use in source and binary forms, with or without modification,
6   * are permitted provided that the following conditions are met:   * are permitted provided that the following conditions are met:
7   *   *
8   * 1. Redistributions of source code must retain the above copyright notice,   * 1. Redistributions of source code must retain the above copyright notice,
# Line 11  Line 11 
11   *    this list of conditions and the following disclaimer in the documentation   *    this list of conditions and the following disclaimer in the documentation
12   *    and/or other materials provided with the distribution.   *    and/or other materials provided with the distribution.
13   * 3. The name of the author may not be used to endorse or promote products   * 3. The name of the author may not be used to endorse or promote products
14   *    derived from this software without specific prior written permission.   *    derived from this software without specific prior written permission.
15   *   *
16   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18   * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT   * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19   * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,   * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
21   * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS   * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24   * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY   * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
25   * OF SUCH DAMAGE.   * OF SUCH DAMAGE.
26   *   *
27   * This file is part of the lwIP TCP/IP stack.   * This file is part of the lwIP TCP/IP stack.
28   *   *
29   * Author: Adam Dunkels <adam@sics.se>   * Author: Adam Dunkels <adam@sics.se>
30   *   *
31   */   */
# Line 36  Line 36 
36   *   *
37   * This is the code for the IP layer.   * This is the code for the IP layer.
38   *   *
39   */     */
40  /*-----------------------------------------------------------------------------------*/  /*-----------------------------------------------------------------------------------*/
41    
42  #include "lwip/opt.h"  #include "lwip/opt.h"
# Line 104  ip_lookup(void *header, struct netif *in Line 104  ip_lookup(void *header, struct netif *in
104      return 0;      return 0;
105    }    }
106  #endif /* IP_OPTIONS == 0 */  #endif /* IP_OPTIONS == 0 */
107      
108    switch (IPH_PROTO(iphdr)) {    switch (IPH_PROTO(iphdr)) {
109  #if LWIP_UDP > 0  #if LWIP_UDP > 0
110    case IP_PROTO_UDP:    case IP_PROTO_UDP:
111      return udp_lookup(iphdr, inp);      return udp_lookup(iphdr, inp);
112  #endif /* LWIP_UDP */  #endif /* LWIP_UDP */
113  #if LWIP_TCP > 0      #if LWIP_TCP > 0
114    case IP_PROTO_TCP:    case IP_PROTO_TCP:
115      return 1;      return 1;
116  #endif /* LWIP_TCP */  #endif /* LWIP_TCP */
# Line 135  ip_route(struct ip_addr *dest) Line 135  ip_route(struct ip_addr *dest)
135  {  {
136    struct netif *netif;    struct netif *netif;
137    
138    /* iterate through netifs */      /* iterate through netifs */
139    for(netif = netif_list; netif != NULL; netif = netif->next) {    for(netif = netif_list; netif != NULL; netif = netif->next) {
140      /* network mask matches? */      /* network mask matches? */
141      if (ip_addr_maskcmp(dest, &(netif->ip_addr), &(netif->netmask))) {      if (ip_addr_maskcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
# Line 159  static void Line 159  static void
159  ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)  ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
160  {  {
161    struct netif *netif;    struct netif *netif;
162      
163    PERF_START;    PERF_START;
164    /* Find network interface where to forward this IP packet to. */    /* Find network interface where to forward this IP packet to. */
165    netif = ip_route((struct ip_addr *)&(iphdr->dest));    netif = ip_route((struct ip_addr *)&(iphdr->dest));
# Line 176  ip_forward(struct pbuf *p, struct ip_hdr Line 176  ip_forward(struct pbuf *p, struct ip_hdr
176      snmp_inc_ipnoroutes();      snmp_inc_ipnoroutes();
177      return;      return;
178    }    }
179      
180    /* decrement TTL */    /* decrement TTL */
181    IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1);    IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1);
182    /* send ICMP if TTL == 0 */    /* send ICMP if TTL == 0 */
# Line 186  ip_forward(struct pbuf *p, struct ip_hdr Line 186  ip_forward(struct pbuf *p, struct ip_hdr
186        icmp_time_exceeded(p, ICMP_TE_TTL);        icmp_time_exceeded(p, ICMP_TE_TTL);
187        snmp_inc_icmpouttimeexcds();        snmp_inc_icmpouttimeexcds();
188      }      }
189      return;            return;
190    }    }
191      
192    /* Incrementally update the IP checksum. */    /* Incrementally update the IP checksum. */
193    if (IPH_CHKSUM(iphdr) >= htons(0xffff - 0x100)) {    if (IPH_CHKSUM(iphdr) >= htons(0xffff - 0x100)) {
194      IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100) + 1);      IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100) + 1);
# Line 227  ip_input(struct pbuf *p, struct netif *i Line 227  ip_input(struct pbuf *p, struct netif *i
227    static struct ip_hdr *iphdr;    static struct ip_hdr *iphdr;
228    static struct netif *netif;    static struct netif *netif;
229    static u16_t iphdrlen;    static u16_t iphdrlen;
230      
231  #ifdef IP_STATS  #ifdef IP_STATS
232    ++lwip_stats.ip.recv;    ++lwip_stats.ip.recv;
233  #endif /* IP_STATS */  #endif /* IP_STATS */
# Line 236  ip_input(struct pbuf *p, struct netif *i Line 236  ip_input(struct pbuf *p, struct netif *i
236    /* identify the IP header */    /* identify the IP header */
237    iphdr = p->payload;    iphdr = p->payload;
238    if (IPH_V(iphdr) != 4) {    if (IPH_V(iphdr) != 4) {
239      LWIP_DEBUGF(IP_DEBUG | 1, ("IP packet dropped due to bad version number %d\n", IPH_V(iphdr)));      LWIP_DEBUGF(IP_DEBUG | 1, ("IP packet dropped due to bad version number %u\n", IPH_V(iphdr)));
240  #if IP_DEBUG  #if IP_DEBUG
241      ip_debug_print(p);      ip_debug_print(p);
242  #endif /* IP_DEBUG */  #endif /* IP_DEBUG */
# Line 253  ip_input(struct pbuf *p, struct netif *i Line 253  ip_input(struct pbuf *p, struct netif *i
253    /* calculate IP header length in bytes */    /* calculate IP header length in bytes */
254    iphdrlen *= 4;    iphdrlen *= 4;
255    
256    /* header length exceeds first pbuf length? */      /* header length exceeds first pbuf length? */
257    if (iphdrlen > p->len) {    if (iphdrlen > p->len) {
258      LWIP_DEBUGF(IP_DEBUG | 2, ("IP header (len %u) does not fit in first pbuf (len %u), IP packet droppped.\n",      LWIP_DEBUGF(IP_DEBUG | 2, ("IP header (len %u) does not fit in first pbuf (len %u), IP packet droppped.\n",
259        iphdrlen, p->len));        iphdrlen, p->len));
# Line 282  ip_input(struct pbuf *p, struct netif *i Line 282  ip_input(struct pbuf *p, struct netif *i
282      snmp_inc_ipindiscards();      snmp_inc_ipindiscards();
283      return ERR_OK;      return ERR_OK;
284    }    }
285      
286    /* Trim pbuf. This should have been done at the netif layer,    /* Trim pbuf. This should have been done at the netif layer,
287       but we'll do it anyway just to be sure that its done. */       but we'll do it anyway just to be sure that its done. */
288    pbuf_realloc(p, ntohs(IPH_LEN(iphdr)));    pbuf_realloc(p, ntohs(IPH_LEN(iphdr)));
# Line 329  ip_input(struct pbuf *p, struct netif *i Line 329  ip_input(struct pbuf *p, struct netif *i
329      }      }
330    }    }
331  #endif /* LWIP_DHCP */  #endif /* LWIP_DHCP */
332          /* packet not for us? */            /* packet not for us? */
333    if (netif == NULL) {    if (netif == NULL) {
334      /* packet not for us, route or discard */      /* packet not for us, route or discard */
335      LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: packet not for us.\n"));      LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: packet not for us.\n"));
# Line 350  ip_input(struct pbuf *p, struct netif *i Line 350  ip_input(struct pbuf *p, struct netif *i
350    
351  #if IP_REASSEMBLY  #if IP_REASSEMBLY
352    if ((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {    if ((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
353      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", ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & htons(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8));      LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04x tot_len=%u len=%u MF=%u offset=%u),
354          calling ip_reass()\n", ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & htons(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8));
355      p = ip_reass(p);      p = ip_reass(p);
356      if (p == NULL) {      if (p == NULL) {
357        return ERR_OK;        return ERR_OK;
# Line 370  ip_input(struct pbuf *p, struct netif *i Line 371  ip_input(struct pbuf *p, struct netif *i
371      return ERR_OK;      return ERR_OK;
372    }    }
373  #endif /* IP_REASSEMBLY */  #endif /* IP_REASSEMBLY */
374      
375  #if IP_OPTIONS == 0  #if IP_OPTIONS == 0
376    if (iphdrlen > IP_HLEN) {    if (iphdrlen > IP_HLEN) {
377      LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since there were IP options (while IP_OPTIONS == 0).\n"));      LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since there were IP options (while IP_OPTIONS == 0).\n"));
378      pbuf_free(p);          pbuf_free(p);
379  #ifdef IP_STATS  #ifdef IP_STATS
380      ++lwip_stats.ip.opterr;      ++lwip_stats.ip.opterr;
381      ++lwip_stats.ip.drop;      ++lwip_stats.ip.drop;
382  #endif /* IP_STATS */  #endif /* IP_STATS */
383      snmp_inc_ipunknownprotos();      snmp_inc_ipunknownprotos();
384      return ERR_OK;      return ERR_OK;
385    }      }
386  #endif /* IP_OPTIONS == 0 */  #endif /* IP_OPTIONS == 0 */
387    
388    /* send to upper layers */    /* send to upper layers */
# Line 389  ip_input(struct pbuf *p, struct netif *i Line 390  ip_input(struct pbuf *p, struct netif *i
390    LWIP_DEBUGF(IP_DEBUG, ("ip_input: \n"));    LWIP_DEBUGF(IP_DEBUG, ("ip_input: \n"));
391    ip_debug_print(p);    ip_debug_print(p);
392    LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %d p->tot_len %d\n", p->len, p->tot_len));    LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %d p->tot_len %d\n", p->len, p->tot_len));
393  #endif /* IP_DEBUG */    #endif /* IP_DEBUG */
394    
395    switch (IPH_PROTO(iphdr)) {    switch (IPH_PROTO(iphdr)) {
396  #if LWIP_UDP > 0      #if LWIP_UDP > 0
397    case IP_PROTO_UDP:    case IP_PROTO_UDP:
398      snmp_inc_ipindelivers();      snmp_inc_ipindelivers();
399      udp_input(p, inp);      udp_input(p, inp);
400      break;      break;
401  #endif /* LWIP_UDP */  #endif /* LWIP_UDP */
402  #if LWIP_TCP > 0      #if LWIP_TCP > 0
403    case IP_PROTO_TCP:    case IP_PROTO_TCP:
404      snmp_inc_ipindelivers();      snmp_inc_ipindelivers();
405      tcp_input(p, inp);      tcp_input(p, inp);
# Line 447  ip_output_if (struct pbuf *p, struct ip_ Line 448  ip_output_if (struct pbuf *p, struct ip_
448    static u16_t ip_id = 0;    static u16_t ip_id = 0;
449    
450    snmp_inc_ipoutrequests();    snmp_inc_ipoutrequests();
451      
452    if (dest != IP_HDRINCL) {    if (dest != IP_HDRINCL) {
453      if (pbuf_header(p, IP_HLEN)) {      if (pbuf_header(p, IP_HLEN)) {
454        LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: not enough room for IP header in pbuf\n"));        LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: not enough room for IP header in pbuf\n"));
455          
456  #ifdef IP_STATS  #ifdef IP_STATS
457        ++lwip_stats.ip.err;        ++lwip_stats.ip.err;
458  #endif /* IP_STATS */  #endif /* IP_STATS */
459        snmp_inc_ipoutdiscards();        snmp_inc_ipoutdiscards();
460        return ERR_BUF;        return ERR_BUF;
461      }      }
462        
463      iphdr = p->payload;      iphdr = p->payload;
464        
465      IPH_TTL_SET(iphdr, ttl);      IPH_TTL_SET(iphdr, ttl);
466      IPH_PROTO_SET(iphdr, proto);      IPH_PROTO_SET(iphdr, proto);
467        
468      ip_addr_set(&(iphdr->dest), dest);      ip_addr_set(&(iphdr->dest), dest);
469    
470      IPH_VHLTOS_SET(iphdr, 4, IP_HLEN / 4, 0);      IPH_VHLTOS_SET(iphdr, 4, IP_HLEN / 4, 0);
# Line 485  ip_output_if (struct pbuf *p, struct ip_ Line 486  ip_output_if (struct pbuf *p, struct ip_
486      dest = &(iphdr->dest);      dest = &(iphdr->dest);
487    }    }
488    
489  #if IP_FRAG      #if IP_FRAG
490    /* don't fragment if interface has mtu set to 0 [loopif] */    /* don't fragment if interface has mtu set to 0 [loopif] */
491    if (netif->mtu && (p->tot_len > netif->mtu))    if (netif->mtu && (p->tot_len > netif->mtu))
492      return ip_frag(p,netif,dest);      return ip_frag(p,netif,dest);
493  #endif  #endif
494      
495  #ifdef IP_STATS  #ifdef IP_STATS
496    lwip_stats.ip.xmit++;    lwip_stats.ip.xmit++;
497  #endif /* IP_STATS */  #endif /* IP_STATS */
# Line 501  ip_output_if (struct pbuf *p, struct ip_ Line 502  ip_output_if (struct pbuf *p, struct ip_
502    
503    LWIP_DEBUGF(IP_DEBUG, ("netif->output()"));    LWIP_DEBUGF(IP_DEBUG, ("netif->output()"));
504    
505    return netif->output(netif, p, dest);      return netif->output(netif, p, dest);
506  }  }
507  /*-----------------------------------------------------------------------------------*/  /*-----------------------------------------------------------------------------------*/
508  /* ip_output:  /* ip_output:
# Line 515  ip_output(struct pbuf *p, struct ip_addr Line 516  ip_output(struct pbuf *p, struct ip_addr
516            u8_t ttl, u8_t proto)            u8_t ttl, u8_t proto)
517  {  {
518    struct netif *netif;    struct netif *netif;
519      
520    if ((netif = ip_route(dest)) == NULL) {    if ((netif = ip_route(dest)) == NULL) {
521      LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: No route to 0x%lx\n", dest->addr));      LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: No route to 0x%lx\n", dest->addr));
522    
# Line 537  ip_debug_print(struct pbuf *p) Line 538  ip_debug_print(struct pbuf *p)
538    u8_t *payload;    u8_t *payload;
539    
540    payload = (u8_t *)iphdr + IP_HLEN;    payload = (u8_t *)iphdr + IP_HLEN;
541      
542    LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));    LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));
543    LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));    LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
544    LWIP_DEBUGF(IP_DEBUG, ("|%2d |%2d |  0x%02x |     %5u     | (v, hl, tos, len)\n",    LWIP_DEBUGF(IP_DEBUG, ("|%2d |%2d |  0x%02x |     %5u     | (v, hl, tos, len)\n",

Legend:
Removed from v.1.24  
changed lines
  Added in v.1.25

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26