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

C/C++

  1. /**
  2.  * @file
  3.  *
  4.  * lwIP network interface abstraction
  5.  */
  6. /*
  7.  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
  8.  * All rights reserved.
  9.  *
  10.  * Redistribution and use in source and binary forms, with or without modification,
  11.  * are permitted provided that the following conditions are met:
  12.  *
  13.  * 1. Redistributions of source code must retain the above copyright notice,
  14.  *    this list of conditions and the following disclaimer.
  15.  * 2. Redistributions in binary form must reproduce the above copyright notice,
  16.  *    this list of conditions and the following disclaimer in the documentation
  17.  *    and/or other materials provided with the distribution.
  18.  * 3. The name of the author may not be used to endorse or promote products
  19.  *    derived from this software without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
  22.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  23.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
  24.  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  25.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
  26.  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  27.  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  28.  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  29.  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  30.  * OF SUCH DAMAGE.
  31.  *
  32.  * This file is part of the lwIP TCP/IP stack.
  33.  *
  34.  * Author: Adam Dunkels <adam@sics.se>
  35.  *
  36.  */
  37. #include "lwip/opt.h"
  38. #include "lwip/def.h"
  39. #include "lwip/ip_addr.h"
  40. #include "lwip/netif.h"
  41. #include "lwip/tcp.h"
  42. struct netif *netif_list = NULL;
  43. struct netif *netif_default = NULL;
  44. /**
  45.  * Add a network interface to the list of lwIP netifs.
  46.  *
  47.  * @param netif a pre-allocated netif structure
  48.  * @param ipaddr IP address for the new netif
  49.  * @param netmask network mask for the new netif
  50.  * @param gw default gateway IP address for the new netif
  51.  * @param state opaque data passed to the new netif
  52.  * @param init callback function that initializes the interface
  53.  * @param input callback function that is called to pass
  54.  * ingress packets up in the protocol layer stack.
  55.  *
  56.  * @return netif, or NULL if failed.
  57.  */
  58. struct netif *
  59. netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,
  60.   struct ip_addr *gw,
  61.   void *state,
  62.   err_t (* init)(struct netif *netif),
  63.   err_t (* input)(struct pbuf *p, struct netif *netif))
  64. {
  65.   static int netifnum = 0;
  66.   
  67. #if LWIP_DHCP
  68.   /* netif not under DHCP control by default */
  69.   netif->dhcp = NULL;
  70. #endif
  71.   /* remember netif specific state information data */
  72.   netif->state = state;
  73.   netif->num = netifnum++;
  74.   netif->input = input;
  75.   netif_set_addr(netif, ipaddr, netmask, gw);
  76.   /* call user specified initialization function for netif */
  77.   if (init(netif) != ERR_OK) {
  78.     return NULL;
  79.   }
  80.   /* add this netif to the list */
  81.   netif->next = netif_list;
  82.   netif_list = netif;
  83.   LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP addr ",
  84.     netif->name[0], netif->name[1]));
  85.   ip_addr_debug_print(NETIF_DEBUG, ipaddr);
  86.   LWIP_DEBUGF(NETIF_DEBUG, (" netmask "));
  87.   ip_addr_debug_print(NETIF_DEBUG, netmask);
  88.   LWIP_DEBUGF(NETIF_DEBUG, (" gw "));
  89.   ip_addr_debug_print(NETIF_DEBUG, gw);
  90.   LWIP_DEBUGF(NETIF_DEBUG, ("n"));
  91.   return netif;
  92. }
  93. void
  94. netif_set_addr(struct netif *netif,struct ip_addr *ipaddr, struct ip_addr *netmask,
  95.     struct ip_addr *gw)
  96. {
  97.   netif_set_ipaddr(netif, ipaddr);
  98.   netif_set_netmask(netif, netmask);
  99.   netif_set_gw(netif, gw);
  100. }
  101. void netif_remove(struct netif * netif)
  102. {
  103.   if ( netif == NULL ) return;
  104.   /*  is it the first netif? */
  105.   if (netif_list == netif) {
  106.     netif_list = netif->next;
  107.   }
  108.   else {
  109.     /*  look for netif further down the list */
  110.     struct netif * tmpNetif;
  111.     for (tmpNetif = netif_list; tmpNetif != NULL; tmpNetif = tmpNetif->next) {
  112.       if (tmpNetif->next == netif) {
  113.         tmpNetif->next = netif->next;
  114.         break;
  115.         }
  116.     }
  117.     if (tmpNetif == NULL)
  118.       return; /*  we didn't find any netif today */
  119.   }
  120.   /* this netif is default? */
  121.   if (netif_default == netif)
  122.     /* reset default netif */
  123.     netif_default = NULL;
  124.   LWIP_DEBUGF( NETIF_DEBUG, ("netif_remove: removed netifn") );
  125. }
  126. struct netif *
  127. netif_find(char *name)
  128. {
  129.   struct netif *netif;
  130.   u8_t num;
  131.   if (name == NULL) {
  132.     return NULL;
  133.   }
  134.   num = name[2] - '0';
  135.   for(netif = netif_list; netif != NULL; netif = netif->next) {
  136.     if (num == netif->num &&
  137.        name[0] == netif->name[0] &&
  138.        name[1] == netif->name[1]) {
  139.       LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: found %c%cn", name[0], name[1]));
  140.       return netif;
  141.     }
  142.   }
  143.   LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: didn't find %c%cn", name[0], name[1]));
  144.   return NULL;
  145. }
  146. void
  147. netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr)
  148. {
  149.   /* TODO: Handling of obsolete pcbs */
  150.   /* See:  http://mail.gnu.org/archive/html/lwip-users/2003-03/msg00118.html */
  151. #if LWIP_TCP
  152.   struct tcp_pcb *pcb;
  153.   struct tcp_pcb_listen *lpcb;
  154.   /* address is actually being changed? */
  155.   if ((ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0)
  156.   {
  157.     /* extern struct tcp_pcb *tcp_active_pcbs; defined by tcp.h */
  158.     LWIP_DEBUGF(NETIF_DEBUG | 1, ("netif_set_ipaddr: netif address being changedn"));
  159.     pcb = tcp_active_pcbs;
  160.     while (pcb != NULL) {
  161.       /* PCB bound to current local interface address? */
  162.       if (ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))) {
  163.         /* this connection must be aborted */
  164.         struct tcp_pcb *next = pcb->next;
  165.         LWIP_DEBUGF(NETIF_DEBUG | 1, ("netif_set_ipaddr: aborting TCP pcb %pn", (void *)pcb));
  166.         tcp_abort(pcb);
  167.         pcb = next;
  168.       } else {
  169.         pcb = pcb->next;
  170.       }
  171.     }
  172.     for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
  173.       /* PCB bound to current local interface address? */
  174.       if (ip_addr_cmp(&(lpcb->local_ip), &(netif->ip_addr))) {
  175.         /* The PCB is listening to the old ipaddr and
  176.          * is set to listen to the new one instead */
  177.         ip_addr_set(&(lpcb->local_ip), ipaddr);
  178.       }
  179.     }
  180.   }
  181. #endif
  182.   ip_addr_set(&(netif->ip_addr), ipaddr);
  183. #if 0 /* only allowed for Ethernet interfaces TODO: how can we check? */
  184.   /** For Ethernet network interfaces, we would like to send a
  185.    *  "gratuitous ARP"; this is an ARP packet sent by a node in order
  186.    *  to spontaneously cause other nodes to update an entry in their
  187.    *  ARP cache. From RFC 3220 "IP Mobility Support for IPv4" section 4.6.
  188.    */ 
  189.   etharp_query(netif, ipaddr, NULL);
  190. #endif
  191.   LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: IP address of interface %c%c set to %u.%u.%u.%un",
  192.     netif->name[0], netif->name[1],
  193.     ip4_addr1(&netif->ip_addr),
  194.     ip4_addr2(&netif->ip_addr),
  195.     ip4_addr3(&netif->ip_addr),
  196.     ip4_addr4(&netif->ip_addr)));
  197. }
  198. void
  199. netif_set_gw(struct netif *netif, struct ip_addr *gw)
  200. {
  201.   ip_addr_set(&(netif->gw), gw);
  202.   LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: GW address of interface %c%c set to %u.%u.%u.%un",
  203.     netif->name[0], netif->name[1],
  204.     ip4_addr1(&netif->gw),
  205.     ip4_addr2(&netif->gw),
  206.     ip4_addr3(&netif->gw),
  207.     ip4_addr4(&netif->gw)));
  208. }
  209. void
  210. netif_set_netmask(struct netif *netif, struct ip_addr *netmask)
  211. {
  212.   ip_addr_set(&(netif->netmask), netmask);
  213.   LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: netmask of interface %c%c set to %u.%u.%u.%un",
  214.     netif->name[0], netif->name[1],
  215.     ip4_addr1(&netif->netmask),
  216.     ip4_addr2(&netif->netmask),
  217.     ip4_addr3(&netif->netmask),
  218.     ip4_addr4(&netif->netmask)));
  219. }
  220. void
  221. netif_set_default(struct netif *netif)
  222. {
  223.   netif_default = netif;
  224.   LWIP_DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%cn",
  225.            netif ? netif->name[0] : ''', netif ? netif->name[1] : '''));
  226. }
  227. /**
  228.  * Bring an interface up, available for processing
  229.  * traffic.
  230.  * 
  231.  * @note: Enabling DHCP on a down interface will make it come
  232.  * up once configured.
  233.  * 
  234.  * @see dhcp_start()
  235.  */ 
  236. void netif_set_up(struct netif *netif)
  237. {
  238.   netif->flags |= NETIF_FLAG_UP;
  239. }
  240. /**
  241.  * Ask if an interface is up
  242.  */ 
  243. u8_t netif_is_up(struct netif *netif)
  244. {
  245.   return (netif->flags & NETIF_FLAG_UP)?1:0;
  246. }
  247. /**
  248.  * Bring an interface down, disabling any traffic processing.
  249.  *
  250.  * @note: Enabling DHCP on a down interface will make it come
  251.  * up once configured.
  252.  * 
  253.  * @see dhcp_start()
  254.  */ 
  255. void netif_set_down(struct netif *netif)
  256. {
  257.   netif->flags &= ~NETIF_FLAG_UP;
  258. }
  259. void
  260. netif_init(void)
  261. {
  262.   netif_list = netif_default = NULL;
  263. }