A version of LWIP, provided for backwards compatibility.
Dependents: AA_DemoBoard DemoBoard HelloServerDemo DemoBoard_RangeIndicator ... more
netif.c
00001 /** 00002 * @file 00003 * lwIP network interface abstraction 00004 * 00005 */ 00006 00007 /* 00008 * Copyright (c) 2001-2004 Swedish Institute of Computer Science. 00009 * All rights reserved. 00010 * 00011 * Redistribution and use in source and binary forms, with or without modification, 00012 * are permitted provided that the following conditions are met: 00013 * 00014 * 1. Redistributions of source code must retain the above copyright notice, 00015 * this list of conditions and the following disclaimer. 00016 * 2. Redistributions in binary form must reproduce the above copyright notice, 00017 * this list of conditions and the following disclaimer in the documentation 00018 * and/or other materials provided with the distribution. 00019 * 3. The name of the author may not be used to endorse or promote products 00020 * derived from this software without specific prior written permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 00023 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00024 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 00025 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00026 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 00027 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00028 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00029 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 00030 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 00031 * OF SUCH DAMAGE. 00032 * 00033 * This file is part of the lwIP TCP/IP stack. 00034 * 00035 * Author: Adam Dunkels <adam@sics.se> 00036 * 00037 */ 00038 00039 #include "lwip/opt.h" 00040 00041 #include "lwip/def.h" 00042 #include "lwip/ip_addr.h" 00043 #include "lwip/netif.h" 00044 #include "lwip/tcp.h" 00045 #include "lwip/snmp.h" 00046 #include "lwip/igmp.h" 00047 #include "netif/etharp.h" 00048 00049 #if LWIP_NETIF_STATUS_CALLBACK 00050 #define NETIF_STATUS_CALLBACK(n) { if (n->status_callback) (n->status_callback)(n); } 00051 #else 00052 #define NETIF_STATUS_CALLBACK(n) { /* NOP */ } 00053 #endif /* LWIP_NETIF_STATUS_CALLBACK */ 00054 00055 #if LWIP_NETIF_LINK_CALLBACK 00056 #define NETIF_LINK_CALLBACK(n) { if (n->link_callback) (n->link_callback)(n); } 00057 #else 00058 #define NETIF_LINK_CALLBACK(n) { /* NOP */ } 00059 #endif /* LWIP_NETIF_LINK_CALLBACK */ 00060 00061 struct netif *netif_list; 00062 struct netif *netif_default; 00063 00064 /** 00065 * Add a network interface to the list of lwIP netifs. 00066 * 00067 * @param netif a pre-allocated netif structure 00068 * @param ipaddr IP address for the new netif 00069 * @param netmask network mask for the new netif 00070 * @param gw default gateway IP address for the new netif 00071 * @param state opaque data passed to the new netif 00072 * @param init callback function that initializes the interface 00073 * @param input callback function that is called to pass 00074 * ingress packets up in the protocol layer stack. 00075 * 00076 * @return netif, or NULL if failed. 00077 */ 00078 struct netif * 00079 netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask, 00080 struct ip_addr *gw, 00081 void *state, 00082 err_t (* init)(struct netif *netif), 00083 err_t (* input)(struct pbuf *p, struct netif *netif)) 00084 { 00085 static u8_t netifnum = 0; 00086 00087 /* reset new interface configuration state */ 00088 netif->ip_addr.addr = 0; 00089 netif->netmask.addr = 0; 00090 netif->gw.addr = 0; 00091 netif->flags = 0; 00092 #if LWIP_DHCP 00093 /* netif not under DHCP control by default */ 00094 netif->dhcp = NULL; 00095 #endif /* LWIP_DHCP */ 00096 #if LWIP_AUTOIP 00097 /* netif not under AutoIP control by default */ 00098 netif->autoip = NULL; 00099 #endif /* LWIP_AUTOIP */ 00100 #if LWIP_NETIF_STATUS_CALLBACK 00101 netif->status_callback = NULL; 00102 #endif /* LWIP_NETIF_STATUS_CALLBACK */ 00103 #if LWIP_NETIF_LINK_CALLBACK 00104 netif->link_callback = NULL; 00105 #endif /* LWIP_NETIF_LINK_CALLBACK */ 00106 #if LWIP_IGMP 00107 netif->igmp_mac_filter = NULL; 00108 #endif /* LWIP_IGMP */ 00109 00110 /* remember netif specific state information data */ 00111 netif->state = state; 00112 netif->num = netifnum++; 00113 netif->input = input; 00114 #if LWIP_NETIF_HWADDRHINT 00115 netif->addr_hint = NULL; 00116 #endif /* LWIP_NETIF_HWADDRHINT*/ 00117 00118 netif_set_addr(netif, ipaddr, netmask, gw); 00119 00120 /* call user specified initialization function for netif */ 00121 if (init(netif) != ERR_OK) { 00122 return static_cast<struct netif *>(NULL); 00123 } 00124 00125 /* add this netif to the list */ 00126 netif->next = netif_list; 00127 netif_list = netif; 00128 snmp_inc_iflist(); 00129 00130 #if LWIP_IGMP 00131 /* start IGMP processing */ 00132 if (netif->flags & NETIF_FLAG_IGMP) { 00133 igmp_start( netif); 00134 } 00135 #endif /* LWIP_IGMP */ 00136 00137 LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP addr ", 00138 netif->name[0], netif->name[1])); 00139 ip_addr_debug_print(NETIF_DEBUG, ipaddr); 00140 LWIP_DEBUGF(NETIF_DEBUG, (" netmask ")); 00141 ip_addr_debug_print(NETIF_DEBUG, netmask); 00142 LWIP_DEBUGF(NETIF_DEBUG, (" gw ")); 00143 ip_addr_debug_print(NETIF_DEBUG, gw); 00144 LWIP_DEBUGF(NETIF_DEBUG, ("\n")); 00145 return netif; 00146 } 00147 00148 /** 00149 * Change IP address configuration for a network interface (including netmask 00150 * and default gateway). 00151 * 00152 * @param netif the network interface to change 00153 * @param ipaddr the new IP address 00154 * @param netmask the new netmask 00155 * @param gw the new default gateway 00156 */ 00157 void 00158 netif_set_addr(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask, 00159 struct ip_addr *gw) 00160 { 00161 netif_set_ipaddr(netif, ipaddr); 00162 netif_set_netmask(netif, netmask); 00163 netif_set_gw(netif, gw); 00164 } 00165 00166 /** 00167 * Remove a network interface from the list of lwIP netifs. 00168 * 00169 * @param netif the network interface to remove 00170 */ 00171 void netif_remove(struct netif * netif) 00172 { 00173 if ( netif == NULL ) return; 00174 00175 #if LWIP_IGMP 00176 /* stop IGMP processing */ 00177 if (netif->flags & NETIF_FLAG_IGMP) { 00178 igmp_stop( netif); 00179 } 00180 #endif /* LWIP_IGMP */ 00181 00182 snmp_delete_ipaddridx_tree(netif); 00183 00184 /* is it the first netif? */ 00185 if (netif_list == netif) { 00186 netif_list = netif->next; 00187 snmp_dec_iflist(); 00188 } 00189 else { 00190 /* look for netif further down the list */ 00191 struct netif * tmpNetif; 00192 for (tmpNetif = netif_list; tmpNetif != NULL; tmpNetif = tmpNetif->next) { 00193 if (tmpNetif->next == netif) { 00194 tmpNetif->next = netif->next; 00195 snmp_dec_iflist(); 00196 break; 00197 } 00198 } 00199 if (tmpNetif == NULL) 00200 return; /* we didn't find any netif today */ 00201 } 00202 /* this netif is default? */ 00203 if (netif_default == netif) 00204 /* reset default netif */ 00205 netif_set_default(static_cast<struct netif *>(NULL)); 00206 LWIP_DEBUGF( NETIF_DEBUG, ("netif_remove: removed netif\n") ); 00207 } 00208 00209 /** 00210 * Find a network interface by searching for its name 00211 * 00212 * @param name the name of the netif (like netif->name) plus concatenated number 00213 * in ascii representation (e.g. 'en0') 00214 */ 00215 struct netif * 00216 netif_find(char *name) 00217 { 00218 struct netif *netif; 00219 u8_t num; 00220 00221 if (name == NULL) { 00222 return static_cast<struct netif *>(NULL); 00223 } 00224 00225 num = name[2] - '0'; 00226 00227 for(netif = netif_list; netif != NULL; netif = netif->next) { 00228 if (num == netif->num && 00229 name[0] == netif->name[0] && 00230 name[1] == netif->name[1]) { 00231 LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: found %c%c\n", name[0], name[1])); 00232 return netif; 00233 } 00234 } 00235 LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: didn't find %c%c\n", name[0], name[1])); 00236 return static_cast<struct netif *>(NULL); 00237 } 00238 00239 /** 00240 * Change the IP address of a network interface 00241 * 00242 * @param netif the network interface to change 00243 * @param ipaddr the new IP address 00244 * 00245 * @note call netif_set_addr() if you also want to change netmask and 00246 * default gateway 00247 */ 00248 void 00249 netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr) 00250 { 00251 /* TODO: Handling of obsolete pcbs */ 00252 /* See: http://mail.gnu.org/archive/html/lwip-users/2003-03/msg00118.html */ 00253 #if LWIP_TCP 00254 struct tcp_pcb *pcb; 00255 struct tcp_pcb_listen *lpcb; 00256 00257 /* address is actually being changed? */ 00258 if ((ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0) 00259 { 00260 /* extern struct tcp_pcb *tcp_active_pcbs; defined by tcp.h */ 00261 LWIP_DEBUGF(NETIF_DEBUG | 1, ("netif_set_ipaddr: netif address being changed\n")); 00262 pcb = tcp_active_pcbs; 00263 while (pcb != NULL) { 00264 /* PCB bound to current local interface address? */ 00265 if (ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))) { 00266 /* this connection must be aborted */ 00267 struct tcp_pcb *next = pcb->next; 00268 LWIP_DEBUGF(NETIF_DEBUG | 1, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb)); 00269 tcp_abort(pcb); 00270 pcb = next; 00271 } else { 00272 pcb = pcb->next; 00273 } 00274 } 00275 for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { 00276 /* PCB bound to current local interface address? */ 00277 if ((!(ip_addr_isany(&(lpcb->local_ip)))) && 00278 (ip_addr_cmp(&(lpcb->local_ip), &(netif->ip_addr)))) { 00279 /* The PCB is listening to the old ipaddr and 00280 * is set to listen to the new one instead */ 00281 ip_addr_set(&(lpcb->local_ip), ipaddr); 00282 } 00283 } 00284 } 00285 #endif 00286 snmp_delete_ipaddridx_tree(netif); 00287 snmp_delete_iprteidx_tree(0,netif); 00288 /* set new IP address to netif */ 00289 ip_addr_set(&(netif->ip_addr), ipaddr); 00290 snmp_insert_ipaddridx_tree(netif); 00291 snmp_insert_iprteidx_tree(0,netif); 00292 00293 LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | 3, ("netif: IP address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", 00294 netif->name[0], netif->name[1], 00295 ip4_addr1(&netif->ip_addr), 00296 ip4_addr2(&netif->ip_addr), 00297 ip4_addr3(&netif->ip_addr), 00298 ip4_addr4(&netif->ip_addr))); 00299 } 00300 00301 /** 00302 * Change the default gateway for a network interface 00303 * 00304 * @param netif the network interface to change 00305 * @param gw the new default gateway 00306 * 00307 * @note call netif_set_addr() if you also want to change ip address and netmask 00308 */ 00309 void 00310 netif_set_gw(struct netif *netif, struct ip_addr *gw) 00311 { 00312 ip_addr_set(&(netif->gw), gw); 00313 LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | 3, ("netif: GW address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", 00314 netif->name[0], netif->name[1], 00315 ip4_addr1(&netif->gw), 00316 ip4_addr2(&netif->gw), 00317 ip4_addr3(&netif->gw), 00318 ip4_addr4(&netif->gw))); 00319 } 00320 00321 /** 00322 * Change the netmask of a network interface 00323 * 00324 * @param netif the network interface to change 00325 * @param netmask the new netmask 00326 * 00327 * @note call netif_set_addr() if you also want to change ip address and 00328 * default gateway 00329 */ 00330 void 00331 netif_set_netmask(struct netif *netif, struct ip_addr *netmask) 00332 { 00333 snmp_delete_iprteidx_tree(0, netif); 00334 /* set new netmask to netif */ 00335 ip_addr_set(&(netif->netmask), netmask); 00336 snmp_insert_iprteidx_tree(0, netif); 00337 LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | 3, ("netif: netmask of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", 00338 netif->name[0], netif->name[1], 00339 ip4_addr1(&netif->netmask), 00340 ip4_addr2(&netif->netmask), 00341 ip4_addr3(&netif->netmask), 00342 ip4_addr4(&netif->netmask))); 00343 } 00344 00345 /** 00346 * Set a network interface as the default network interface 00347 * (used to output all packets for which no specific route is found) 00348 * 00349 * @param netif the default network interface 00350 */ 00351 void 00352 netif_set_default(struct netif *netif) 00353 { 00354 if (netif == NULL) 00355 { 00356 /* remove default route */ 00357 snmp_delete_iprteidx_tree(1, netif); 00358 } 00359 else 00360 { 00361 /* install default route */ 00362 snmp_insert_iprteidx_tree(1, netif); 00363 } 00364 netif_default = netif; 00365 LWIP_DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%c\n", 00366 netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\'')); 00367 } 00368 00369 /** 00370 * Bring an interface up, available for processing 00371 * traffic. 00372 * 00373 * @note: Enabling DHCP on a down interface will make it come 00374 * up once configured. 00375 * 00376 * @see dhcp_start() 00377 */ 00378 void netif_set_up(struct netif *netif) 00379 { 00380 if ( !(netif->flags & NETIF_FLAG_UP )) { 00381 netif->flags |= NETIF_FLAG_UP; 00382 00383 #if LWIP_SNMP 00384 snmp_get_sysuptime(&netif->ts); 00385 #endif /* LWIP_SNMP */ 00386 00387 NETIF_LINK_CALLBACK(netif); 00388 NETIF_STATUS_CALLBACK(netif); 00389 00390 #if LWIP_ARP 00391 /** For Ethernet network interfaces, we would like to send a 00392 * "gratuitous ARP"; this is an ARP packet sent by a node in order 00393 * to spontaneously cause other nodes to update an entry in their 00394 * ARP cache. From RFC 3220 "IP Mobility Support for IPv4" section 4.6. 00395 */ 00396 if (netif->flags & NETIF_FLAG_ETHARP) { 00397 etharp_query(netif, &(netif->ip_addr), static_cast<struct pbuf *>(NULL)); 00398 } 00399 #endif /* LWIP_ARP */ 00400 00401 } 00402 } 00403 00404 /** 00405 * Bring an interface down, disabling any traffic processing. 00406 * 00407 * @note: Enabling DHCP on a down interface will make it come 00408 * up once configured. 00409 * 00410 * @see dhcp_start() 00411 */ 00412 void netif_set_down(struct netif *netif) 00413 { 00414 if ( netif->flags & NETIF_FLAG_UP ) 00415 { 00416 netif->flags &= ~NETIF_FLAG_UP; 00417 #if LWIP_SNMP 00418 snmp_get_sysuptime(&netif->ts); 00419 #endif 00420 00421 NETIF_LINK_CALLBACK(netif); 00422 NETIF_STATUS_CALLBACK(netif); 00423 } 00424 } 00425 00426 /** 00427 * Ask if an interface is up 00428 */ 00429 u8_t netif_is_up(struct netif *netif) 00430 { 00431 return (netif->flags & NETIF_FLAG_UP)?1:0; 00432 } 00433 00434 #if LWIP_NETIF_STATUS_CALLBACK 00435 /** 00436 * Set callback to be called when interface is brought up/down 00437 */ 00438 void netif_set_status_callback(struct netif *netif, void (* status_callback)(struct netif *netif )) 00439 { 00440 if ( netif ) 00441 netif->status_callback = status_callback; 00442 } 00443 #endif /* LWIP_NETIF_STATUS_CALLBACK */ 00444 00445 #if LWIP_NETIF_LINK_CALLBACK 00446 /** 00447 * Called by a driver when its link goes up 00448 */ 00449 void netif_set_link_up(struct netif *netif ) 00450 { 00451 netif->flags |= NETIF_FLAG_LINK_UP; 00452 00453 #if LWIP_ARP 00454 /** For Ethernet network interfaces, we would like to send a 00455 * "gratuitous ARP"; this is an ARP packet sent by a node in order 00456 * to spontaneously cause other nodes to update an entry in their 00457 * ARP cache. From RFC 3220 "IP Mobility Support for IPv4" section 4.6. 00458 */ 00459 if (netif->flags & NETIF_FLAG_ETHARP) { 00460 etharp_query(netif, &(netif->ip_addr), NULL); 00461 } 00462 #endif /* LWIP_ARP */ 00463 00464 #if LWIP_IGMP 00465 /* resend IGMP memberships */ 00466 if (netif->flags & NETIF_FLAG_IGMP) { 00467 igmp_report_groups( netif); 00468 } 00469 #endif /* LWIP_IGMP */ 00470 00471 NETIF_LINK_CALLBACK(netif); 00472 } 00473 00474 /** 00475 * Called by a driver when its link goes down 00476 */ 00477 void netif_set_link_down(struct netif *netif ) 00478 { 00479 netif->flags &= ~NETIF_FLAG_LINK_UP; 00480 NETIF_LINK_CALLBACK(netif); 00481 } 00482 00483 /** 00484 * Ask if a link is up 00485 */ 00486 u8_t netif_is_link_up(struct netif *netif) 00487 { 00488 return (netif->flags & NETIF_FLAG_LINK_UP) ? 1 : 0; 00489 } 00490 00491 /** 00492 * Set callback to be called when link is brought up/down 00493 */ 00494 void netif_set_link_callback(struct netif *netif, void (* link_callback)(struct netif *netif )) 00495 { 00496 if ( netif ) 00497 netif->link_callback = link_callback; 00498 } 00499 #endif /* LWIP_NETIF_LINK_CALLBACK */
Generated on Tue Jul 12 2022 16:06:18 by 1.7.2