Official mbed lwIP library (version 1.4.0)

Dependents:   LwIPNetworking NetServicesMin EthernetInterface EthernetInterface_RSF ... more

Legacy Networking Libraries

This is an mbed 2 networking library. For mbed OS 5, lwip has been integrated with built-in networking interfaces. The networking libraries have been revised to better support additional network stacks and thread safety here.

This library is based on the code of lwIP v1.4.0

Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
All rights reserved. 

Redistribution and use in source and binary forms, with or without modification, 
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
   derived from this software without specific prior written permission. 

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
OF SUCH DAMAGE.
Committer:
mbed_official
Date:
Fri Jun 22 09:25:39 2012 +0000
Revision:
0:51ac1d130fd4
Child:
11:4b3f6f8b92d2
Initial import from lwip-1.4.0: http://download.savannah.gnu.org/releases/lwip/lwip-1.4.0.zip

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 0:51ac1d130fd4 1 /**
mbed_official 0:51ac1d130fd4 2 * @file
mbed_official 0:51ac1d130fd4 3 * lwIP network interface abstraction
mbed_official 0:51ac1d130fd4 4 *
mbed_official 0:51ac1d130fd4 5 */
mbed_official 0:51ac1d130fd4 6
mbed_official 0:51ac1d130fd4 7 /*
mbed_official 0:51ac1d130fd4 8 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
mbed_official 0:51ac1d130fd4 9 * All rights reserved.
mbed_official 0:51ac1d130fd4 10 *
mbed_official 0:51ac1d130fd4 11 * Redistribution and use in source and binary forms, with or without modification,
mbed_official 0:51ac1d130fd4 12 * are permitted provided that the following conditions are met:
mbed_official 0:51ac1d130fd4 13 *
mbed_official 0:51ac1d130fd4 14 * 1. Redistributions of source code must retain the above copyright notice,
mbed_official 0:51ac1d130fd4 15 * this list of conditions and the following disclaimer.
mbed_official 0:51ac1d130fd4 16 * 2. Redistributions in binary form must reproduce the above copyright notice,
mbed_official 0:51ac1d130fd4 17 * this list of conditions and the following disclaimer in the documentation
mbed_official 0:51ac1d130fd4 18 * and/or other materials provided with the distribution.
mbed_official 0:51ac1d130fd4 19 * 3. The name of the author may not be used to endorse or promote products
mbed_official 0:51ac1d130fd4 20 * derived from this software without specific prior written permission.
mbed_official 0:51ac1d130fd4 21 *
mbed_official 0:51ac1d130fd4 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
mbed_official 0:51ac1d130fd4 23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
mbed_official 0:51ac1d130fd4 24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
mbed_official 0:51ac1d130fd4 25 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
mbed_official 0:51ac1d130fd4 26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
mbed_official 0:51ac1d130fd4 27 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
mbed_official 0:51ac1d130fd4 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
mbed_official 0:51ac1d130fd4 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
mbed_official 0:51ac1d130fd4 30 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
mbed_official 0:51ac1d130fd4 31 * OF SUCH DAMAGE.
mbed_official 0:51ac1d130fd4 32 *
mbed_official 0:51ac1d130fd4 33 * This file is part of the lwIP TCP/IP stack.
mbed_official 0:51ac1d130fd4 34 *
mbed_official 0:51ac1d130fd4 35 * Author: Adam Dunkels <adam@sics.se>
mbed_official 0:51ac1d130fd4 36 *
mbed_official 0:51ac1d130fd4 37 */
mbed_official 0:51ac1d130fd4 38
mbed_official 0:51ac1d130fd4 39 #include "lwip/opt.h"
mbed_official 0:51ac1d130fd4 40
mbed_official 0:51ac1d130fd4 41 #include "lwip/def.h"
mbed_official 0:51ac1d130fd4 42 #include "lwip/ip_addr.h"
mbed_official 0:51ac1d130fd4 43 #include "lwip/netif.h"
mbed_official 0:51ac1d130fd4 44 #include "lwip/tcp_impl.h"
mbed_official 0:51ac1d130fd4 45 #include "lwip/snmp.h"
mbed_official 0:51ac1d130fd4 46 #include "lwip/igmp.h"
mbed_official 0:51ac1d130fd4 47 #include "netif/etharp.h"
mbed_official 0:51ac1d130fd4 48 #include "lwip/stats.h"
mbed_official 0:51ac1d130fd4 49 #if ENABLE_LOOPBACK
mbed_official 0:51ac1d130fd4 50 #include "lwip/sys.h"
mbed_official 0:51ac1d130fd4 51 #if LWIP_NETIF_LOOPBACK_MULTITHREADING
mbed_official 0:51ac1d130fd4 52 #include "lwip/tcpip.h"
mbed_official 0:51ac1d130fd4 53 #endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
mbed_official 0:51ac1d130fd4 54 #endif /* ENABLE_LOOPBACK */
mbed_official 0:51ac1d130fd4 55
mbed_official 0:51ac1d130fd4 56 #if LWIP_AUTOIP
mbed_official 0:51ac1d130fd4 57 #include "lwip/autoip.h"
mbed_official 0:51ac1d130fd4 58 #endif /* LWIP_AUTOIP */
mbed_official 0:51ac1d130fd4 59 #if LWIP_DHCP
mbed_official 0:51ac1d130fd4 60 #include "lwip/dhcp.h"
mbed_official 0:51ac1d130fd4 61 #endif /* LWIP_DHCP */
mbed_official 0:51ac1d130fd4 62
mbed_official 0:51ac1d130fd4 63 #if LWIP_NETIF_STATUS_CALLBACK
mbed_official 0:51ac1d130fd4 64 #define NETIF_STATUS_CALLBACK(n) do{ if (n->status_callback) { (n->status_callback)(n); }}while(0)
mbed_official 0:51ac1d130fd4 65 #else
mbed_official 0:51ac1d130fd4 66 #define NETIF_STATUS_CALLBACK(n)
mbed_official 0:51ac1d130fd4 67 #endif /* LWIP_NETIF_STATUS_CALLBACK */
mbed_official 0:51ac1d130fd4 68
mbed_official 0:51ac1d130fd4 69 #if LWIP_NETIF_LINK_CALLBACK
mbed_official 0:51ac1d130fd4 70 #define NETIF_LINK_CALLBACK(n) do{ if (n->link_callback) { (n->link_callback)(n); }}while(0)
mbed_official 0:51ac1d130fd4 71 #else
mbed_official 0:51ac1d130fd4 72 #define NETIF_LINK_CALLBACK(n)
mbed_official 0:51ac1d130fd4 73 #endif /* LWIP_NETIF_LINK_CALLBACK */
mbed_official 0:51ac1d130fd4 74
mbed_official 0:51ac1d130fd4 75 struct netif *netif_list;
mbed_official 0:51ac1d130fd4 76 struct netif *netif_default;
mbed_official 0:51ac1d130fd4 77
mbed_official 0:51ac1d130fd4 78 #if LWIP_HAVE_LOOPIF
mbed_official 0:51ac1d130fd4 79 static struct netif loop_netif;
mbed_official 0:51ac1d130fd4 80
mbed_official 0:51ac1d130fd4 81 /**
mbed_official 0:51ac1d130fd4 82 * Initialize a lwip network interface structure for a loopback interface
mbed_official 0:51ac1d130fd4 83 *
mbed_official 0:51ac1d130fd4 84 * @param netif the lwip network interface structure for this loopif
mbed_official 0:51ac1d130fd4 85 * @return ERR_OK if the loopif is initialized
mbed_official 0:51ac1d130fd4 86 * ERR_MEM if private data couldn't be allocated
mbed_official 0:51ac1d130fd4 87 */
mbed_official 0:51ac1d130fd4 88 static err_t
mbed_official 0:51ac1d130fd4 89 netif_loopif_init(struct netif *netif)
mbed_official 0:51ac1d130fd4 90 {
mbed_official 0:51ac1d130fd4 91 /* initialize the snmp variables and counters inside the struct netif
mbed_official 0:51ac1d130fd4 92 * ifSpeed: no assumption can be made!
mbed_official 0:51ac1d130fd4 93 */
mbed_official 0:51ac1d130fd4 94 NETIF_INIT_SNMP(netif, snmp_ifType_softwareLoopback, 0);
mbed_official 0:51ac1d130fd4 95
mbed_official 0:51ac1d130fd4 96 netif->name[0] = 'l';
mbed_official 0:51ac1d130fd4 97 netif->name[1] = 'o';
mbed_official 0:51ac1d130fd4 98 netif->output = netif_loop_output;
mbed_official 0:51ac1d130fd4 99 return ERR_OK;
mbed_official 0:51ac1d130fd4 100 }
mbed_official 0:51ac1d130fd4 101 #endif /* LWIP_HAVE_LOOPIF */
mbed_official 0:51ac1d130fd4 102
mbed_official 0:51ac1d130fd4 103 void
mbed_official 0:51ac1d130fd4 104 netif_init(void)
mbed_official 0:51ac1d130fd4 105 {
mbed_official 0:51ac1d130fd4 106 #if LWIP_HAVE_LOOPIF
mbed_official 0:51ac1d130fd4 107 ip_addr_t loop_ipaddr, loop_netmask, loop_gw;
mbed_official 0:51ac1d130fd4 108 IP4_ADDR(&loop_gw, 127,0,0,1);
mbed_official 0:51ac1d130fd4 109 IP4_ADDR(&loop_ipaddr, 127,0,0,1);
mbed_official 0:51ac1d130fd4 110 IP4_ADDR(&loop_netmask, 255,0,0,0);
mbed_official 0:51ac1d130fd4 111
mbed_official 0:51ac1d130fd4 112 #if NO_SYS
mbed_official 0:51ac1d130fd4 113 netif_add(&loop_netif, &loop_ipaddr, &loop_netmask, &loop_gw, NULL, netif_loopif_init, ip_input);
mbed_official 0:51ac1d130fd4 114 #else /* NO_SYS */
mbed_official 0:51ac1d130fd4 115 netif_add(&loop_netif, &loop_ipaddr, &loop_netmask, &loop_gw, NULL, netif_loopif_init, tcpip_input);
mbed_official 0:51ac1d130fd4 116 #endif /* NO_SYS */
mbed_official 0:51ac1d130fd4 117 netif_set_up(&loop_netif);
mbed_official 0:51ac1d130fd4 118
mbed_official 0:51ac1d130fd4 119 #endif /* LWIP_HAVE_LOOPIF */
mbed_official 0:51ac1d130fd4 120 }
mbed_official 0:51ac1d130fd4 121
mbed_official 0:51ac1d130fd4 122 /**
mbed_official 0:51ac1d130fd4 123 * Add a network interface to the list of lwIP netifs.
mbed_official 0:51ac1d130fd4 124 *
mbed_official 0:51ac1d130fd4 125 * @param netif a pre-allocated netif structure
mbed_official 0:51ac1d130fd4 126 * @param ipaddr IP address for the new netif
mbed_official 0:51ac1d130fd4 127 * @param netmask network mask for the new netif
mbed_official 0:51ac1d130fd4 128 * @param gw default gateway IP address for the new netif
mbed_official 0:51ac1d130fd4 129 * @param state opaque data passed to the new netif
mbed_official 0:51ac1d130fd4 130 * @param init callback function that initializes the interface
mbed_official 0:51ac1d130fd4 131 * @param input callback function that is called to pass
mbed_official 0:51ac1d130fd4 132 * ingress packets up in the protocol layer stack.
mbed_official 0:51ac1d130fd4 133 *
mbed_official 0:51ac1d130fd4 134 * @return netif, or NULL if failed.
mbed_official 0:51ac1d130fd4 135 */
mbed_official 0:51ac1d130fd4 136 struct netif *
mbed_official 0:51ac1d130fd4 137 netif_add(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask,
mbed_official 0:51ac1d130fd4 138 ip_addr_t *gw, void *state, netif_init_fn init, netif_input_fn input)
mbed_official 0:51ac1d130fd4 139 {
mbed_official 0:51ac1d130fd4 140 static u8_t netifnum = 0;
mbed_official 0:51ac1d130fd4 141
mbed_official 0:51ac1d130fd4 142 LWIP_ASSERT("No init function given", init != NULL);
mbed_official 0:51ac1d130fd4 143
mbed_official 0:51ac1d130fd4 144 /* reset new interface configuration state */
mbed_official 0:51ac1d130fd4 145 ip_addr_set_zero(&netif->ip_addr);
mbed_official 0:51ac1d130fd4 146 ip_addr_set_zero(&netif->netmask);
mbed_official 0:51ac1d130fd4 147 ip_addr_set_zero(&netif->gw);
mbed_official 0:51ac1d130fd4 148 netif->flags = 0;
mbed_official 0:51ac1d130fd4 149 #if LWIP_DHCP
mbed_official 0:51ac1d130fd4 150 /* netif not under DHCP control by default */
mbed_official 0:51ac1d130fd4 151 netif->dhcp = NULL;
mbed_official 0:51ac1d130fd4 152 #endif /* LWIP_DHCP */
mbed_official 0:51ac1d130fd4 153 #if LWIP_AUTOIP
mbed_official 0:51ac1d130fd4 154 /* netif not under AutoIP control by default */
mbed_official 0:51ac1d130fd4 155 netif->autoip = NULL;
mbed_official 0:51ac1d130fd4 156 #endif /* LWIP_AUTOIP */
mbed_official 0:51ac1d130fd4 157 #if LWIP_NETIF_STATUS_CALLBACK
mbed_official 0:51ac1d130fd4 158 netif->status_callback = NULL;
mbed_official 0:51ac1d130fd4 159 #endif /* LWIP_NETIF_STATUS_CALLBACK */
mbed_official 0:51ac1d130fd4 160 #if LWIP_NETIF_LINK_CALLBACK
mbed_official 0:51ac1d130fd4 161 netif->link_callback = NULL;
mbed_official 0:51ac1d130fd4 162 #endif /* LWIP_NETIF_LINK_CALLBACK */
mbed_official 0:51ac1d130fd4 163 #if LWIP_IGMP
mbed_official 0:51ac1d130fd4 164 netif->igmp_mac_filter = NULL;
mbed_official 0:51ac1d130fd4 165 #endif /* LWIP_IGMP */
mbed_official 0:51ac1d130fd4 166 #if ENABLE_LOOPBACK
mbed_official 0:51ac1d130fd4 167 netif->loop_first = NULL;
mbed_official 0:51ac1d130fd4 168 netif->loop_last = NULL;
mbed_official 0:51ac1d130fd4 169 #endif /* ENABLE_LOOPBACK */
mbed_official 0:51ac1d130fd4 170
mbed_official 0:51ac1d130fd4 171 /* remember netif specific state information data */
mbed_official 0:51ac1d130fd4 172 netif->state = state;
mbed_official 0:51ac1d130fd4 173 netif->num = netifnum++;
mbed_official 0:51ac1d130fd4 174 netif->input = input;
mbed_official 0:51ac1d130fd4 175 #if LWIP_NETIF_HWADDRHINT
mbed_official 0:51ac1d130fd4 176 netif->addr_hint = NULL;
mbed_official 0:51ac1d130fd4 177 #endif /* LWIP_NETIF_HWADDRHINT*/
mbed_official 0:51ac1d130fd4 178 #if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS
mbed_official 0:51ac1d130fd4 179 netif->loop_cnt_current = 0;
mbed_official 0:51ac1d130fd4 180 #endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */
mbed_official 0:51ac1d130fd4 181
mbed_official 0:51ac1d130fd4 182 netif_set_addr(netif, ipaddr, netmask, gw);
mbed_official 0:51ac1d130fd4 183
mbed_official 0:51ac1d130fd4 184 /* call user specified initialization function for netif */
mbed_official 0:51ac1d130fd4 185 if (init(netif) != ERR_OK) {
mbed_official 0:51ac1d130fd4 186 return NULL;
mbed_official 0:51ac1d130fd4 187 }
mbed_official 0:51ac1d130fd4 188
mbed_official 0:51ac1d130fd4 189 /* add this netif to the list */
mbed_official 0:51ac1d130fd4 190 netif->next = netif_list;
mbed_official 0:51ac1d130fd4 191 netif_list = netif;
mbed_official 0:51ac1d130fd4 192 snmp_inc_iflist();
mbed_official 0:51ac1d130fd4 193
mbed_official 0:51ac1d130fd4 194 #if LWIP_IGMP
mbed_official 0:51ac1d130fd4 195 /* start IGMP processing */
mbed_official 0:51ac1d130fd4 196 if (netif->flags & NETIF_FLAG_IGMP) {
mbed_official 0:51ac1d130fd4 197 igmp_start(netif);
mbed_official 0:51ac1d130fd4 198 }
mbed_official 0:51ac1d130fd4 199 #endif /* LWIP_IGMP */
mbed_official 0:51ac1d130fd4 200
mbed_official 0:51ac1d130fd4 201 LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP addr ",
mbed_official 0:51ac1d130fd4 202 netif->name[0], netif->name[1]));
mbed_official 0:51ac1d130fd4 203 ip_addr_debug_print(NETIF_DEBUG, ipaddr);
mbed_official 0:51ac1d130fd4 204 LWIP_DEBUGF(NETIF_DEBUG, (" netmask "));
mbed_official 0:51ac1d130fd4 205 ip_addr_debug_print(NETIF_DEBUG, netmask);
mbed_official 0:51ac1d130fd4 206 LWIP_DEBUGF(NETIF_DEBUG, (" gw "));
mbed_official 0:51ac1d130fd4 207 ip_addr_debug_print(NETIF_DEBUG, gw);
mbed_official 0:51ac1d130fd4 208 LWIP_DEBUGF(NETIF_DEBUG, ("\n"));
mbed_official 0:51ac1d130fd4 209 return netif;
mbed_official 0:51ac1d130fd4 210 }
mbed_official 0:51ac1d130fd4 211
mbed_official 0:51ac1d130fd4 212 /**
mbed_official 0:51ac1d130fd4 213 * Change IP address configuration for a network interface (including netmask
mbed_official 0:51ac1d130fd4 214 * and default gateway).
mbed_official 0:51ac1d130fd4 215 *
mbed_official 0:51ac1d130fd4 216 * @param netif the network interface to change
mbed_official 0:51ac1d130fd4 217 * @param ipaddr the new IP address
mbed_official 0:51ac1d130fd4 218 * @param netmask the new netmask
mbed_official 0:51ac1d130fd4 219 * @param gw the new default gateway
mbed_official 0:51ac1d130fd4 220 */
mbed_official 0:51ac1d130fd4 221 void
mbed_official 0:51ac1d130fd4 222 netif_set_addr(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask,
mbed_official 0:51ac1d130fd4 223 ip_addr_t *gw)
mbed_official 0:51ac1d130fd4 224 {
mbed_official 0:51ac1d130fd4 225 netif_set_ipaddr(netif, ipaddr);
mbed_official 0:51ac1d130fd4 226 netif_set_netmask(netif, netmask);
mbed_official 0:51ac1d130fd4 227 netif_set_gw(netif, gw);
mbed_official 0:51ac1d130fd4 228 }
mbed_official 0:51ac1d130fd4 229
mbed_official 0:51ac1d130fd4 230 /**
mbed_official 0:51ac1d130fd4 231 * Remove a network interface from the list of lwIP netifs.
mbed_official 0:51ac1d130fd4 232 *
mbed_official 0:51ac1d130fd4 233 * @param netif the network interface to remove
mbed_official 0:51ac1d130fd4 234 */
mbed_official 0:51ac1d130fd4 235 void
mbed_official 0:51ac1d130fd4 236 netif_remove(struct netif *netif)
mbed_official 0:51ac1d130fd4 237 {
mbed_official 0:51ac1d130fd4 238 if (netif == NULL) {
mbed_official 0:51ac1d130fd4 239 return;
mbed_official 0:51ac1d130fd4 240 }
mbed_official 0:51ac1d130fd4 241
mbed_official 0:51ac1d130fd4 242 #if LWIP_IGMP
mbed_official 0:51ac1d130fd4 243 /* stop IGMP processing */
mbed_official 0:51ac1d130fd4 244 if (netif->flags & NETIF_FLAG_IGMP) {
mbed_official 0:51ac1d130fd4 245 igmp_stop(netif);
mbed_official 0:51ac1d130fd4 246 }
mbed_official 0:51ac1d130fd4 247 #endif /* LWIP_IGMP */
mbed_official 0:51ac1d130fd4 248 if (netif_is_up(netif)) {
mbed_official 0:51ac1d130fd4 249 /* set netif down before removing (call callback function) */
mbed_official 0:51ac1d130fd4 250 netif_set_down(netif);
mbed_official 0:51ac1d130fd4 251 }
mbed_official 0:51ac1d130fd4 252
mbed_official 0:51ac1d130fd4 253 snmp_delete_ipaddridx_tree(netif);
mbed_official 0:51ac1d130fd4 254
mbed_official 0:51ac1d130fd4 255 /* is it the first netif? */
mbed_official 0:51ac1d130fd4 256 if (netif_list == netif) {
mbed_official 0:51ac1d130fd4 257 netif_list = netif->next;
mbed_official 0:51ac1d130fd4 258 } else {
mbed_official 0:51ac1d130fd4 259 /* look for netif further down the list */
mbed_official 0:51ac1d130fd4 260 struct netif * tmpNetif;
mbed_official 0:51ac1d130fd4 261 for (tmpNetif = netif_list; tmpNetif != NULL; tmpNetif = tmpNetif->next) {
mbed_official 0:51ac1d130fd4 262 if (tmpNetif->next == netif) {
mbed_official 0:51ac1d130fd4 263 tmpNetif->next = netif->next;
mbed_official 0:51ac1d130fd4 264 break;
mbed_official 0:51ac1d130fd4 265 }
mbed_official 0:51ac1d130fd4 266 }
mbed_official 0:51ac1d130fd4 267 if (tmpNetif == NULL)
mbed_official 0:51ac1d130fd4 268 return; /* we didn't find any netif today */
mbed_official 0:51ac1d130fd4 269 }
mbed_official 0:51ac1d130fd4 270 snmp_dec_iflist();
mbed_official 0:51ac1d130fd4 271 /* this netif is default? */
mbed_official 0:51ac1d130fd4 272 if (netif_default == netif) {
mbed_official 0:51ac1d130fd4 273 /* reset default netif */
mbed_official 0:51ac1d130fd4 274 netif_set_default(NULL);
mbed_official 0:51ac1d130fd4 275 }
mbed_official 0:51ac1d130fd4 276 LWIP_DEBUGF( NETIF_DEBUG, ("netif_remove: removed netif\n") );
mbed_official 0:51ac1d130fd4 277 }
mbed_official 0:51ac1d130fd4 278
mbed_official 0:51ac1d130fd4 279 /**
mbed_official 0:51ac1d130fd4 280 * Find a network interface by searching for its name
mbed_official 0:51ac1d130fd4 281 *
mbed_official 0:51ac1d130fd4 282 * @param name the name of the netif (like netif->name) plus concatenated number
mbed_official 0:51ac1d130fd4 283 * in ascii representation (e.g. 'en0')
mbed_official 0:51ac1d130fd4 284 */
mbed_official 0:51ac1d130fd4 285 struct netif *
mbed_official 0:51ac1d130fd4 286 netif_find(char *name)
mbed_official 0:51ac1d130fd4 287 {
mbed_official 0:51ac1d130fd4 288 struct netif *netif;
mbed_official 0:51ac1d130fd4 289 u8_t num;
mbed_official 0:51ac1d130fd4 290
mbed_official 0:51ac1d130fd4 291 if (name == NULL) {
mbed_official 0:51ac1d130fd4 292 return NULL;
mbed_official 0:51ac1d130fd4 293 }
mbed_official 0:51ac1d130fd4 294
mbed_official 0:51ac1d130fd4 295 num = name[2] - '0';
mbed_official 0:51ac1d130fd4 296
mbed_official 0:51ac1d130fd4 297 for(netif = netif_list; netif != NULL; netif = netif->next) {
mbed_official 0:51ac1d130fd4 298 if (num == netif->num &&
mbed_official 0:51ac1d130fd4 299 name[0] == netif->name[0] &&
mbed_official 0:51ac1d130fd4 300 name[1] == netif->name[1]) {
mbed_official 0:51ac1d130fd4 301 LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: found %c%c\n", name[0], name[1]));
mbed_official 0:51ac1d130fd4 302 return netif;
mbed_official 0:51ac1d130fd4 303 }
mbed_official 0:51ac1d130fd4 304 }
mbed_official 0:51ac1d130fd4 305 LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: didn't find %c%c\n", name[0], name[1]));
mbed_official 0:51ac1d130fd4 306 return NULL;
mbed_official 0:51ac1d130fd4 307 }
mbed_official 0:51ac1d130fd4 308
mbed_official 0:51ac1d130fd4 309 /**
mbed_official 0:51ac1d130fd4 310 * Change the IP address of a network interface
mbed_official 0:51ac1d130fd4 311 *
mbed_official 0:51ac1d130fd4 312 * @param netif the network interface to change
mbed_official 0:51ac1d130fd4 313 * @param ipaddr the new IP address
mbed_official 0:51ac1d130fd4 314 *
mbed_official 0:51ac1d130fd4 315 * @note call netif_set_addr() if you also want to change netmask and
mbed_official 0:51ac1d130fd4 316 * default gateway
mbed_official 0:51ac1d130fd4 317 */
mbed_official 0:51ac1d130fd4 318 void
mbed_official 0:51ac1d130fd4 319 netif_set_ipaddr(struct netif *netif, ip_addr_t *ipaddr)
mbed_official 0:51ac1d130fd4 320 {
mbed_official 0:51ac1d130fd4 321 /* TODO: Handling of obsolete pcbs */
mbed_official 0:51ac1d130fd4 322 /* See: http://mail.gnu.org/archive/html/lwip-users/2003-03/msg00118.html */
mbed_official 0:51ac1d130fd4 323 #if LWIP_TCP
mbed_official 0:51ac1d130fd4 324 struct tcp_pcb *pcb;
mbed_official 0:51ac1d130fd4 325 struct tcp_pcb_listen *lpcb;
mbed_official 0:51ac1d130fd4 326
mbed_official 0:51ac1d130fd4 327 /* address is actually being changed? */
mbed_official 0:51ac1d130fd4 328 if ((ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0) {
mbed_official 0:51ac1d130fd4 329 /* extern struct tcp_pcb *tcp_active_pcbs; defined by tcp.h */
mbed_official 0:51ac1d130fd4 330 LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: netif address being changed\n"));
mbed_official 0:51ac1d130fd4 331 pcb = tcp_active_pcbs;
mbed_official 0:51ac1d130fd4 332 while (pcb != NULL) {
mbed_official 0:51ac1d130fd4 333 /* PCB bound to current local interface address? */
mbed_official 0:51ac1d130fd4 334 if (ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))
mbed_official 0:51ac1d130fd4 335 #if LWIP_AUTOIP
mbed_official 0:51ac1d130fd4 336 /* connections to link-local addresses must persist (RFC3927 ch. 1.9) */
mbed_official 0:51ac1d130fd4 337 && !ip_addr_islinklocal(&(pcb->local_ip))
mbed_official 0:51ac1d130fd4 338 #endif /* LWIP_AUTOIP */
mbed_official 0:51ac1d130fd4 339 ) {
mbed_official 0:51ac1d130fd4 340 /* this connection must be aborted */
mbed_official 0:51ac1d130fd4 341 struct tcp_pcb *next = pcb->next;
mbed_official 0:51ac1d130fd4 342 LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb));
mbed_official 0:51ac1d130fd4 343 tcp_abort(pcb);
mbed_official 0:51ac1d130fd4 344 pcb = next;
mbed_official 0:51ac1d130fd4 345 } else {
mbed_official 0:51ac1d130fd4 346 pcb = pcb->next;
mbed_official 0:51ac1d130fd4 347 }
mbed_official 0:51ac1d130fd4 348 }
mbed_official 0:51ac1d130fd4 349 for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
mbed_official 0:51ac1d130fd4 350 /* PCB bound to current local interface address? */
mbed_official 0:51ac1d130fd4 351 if ((!(ip_addr_isany(&(lpcb->local_ip)))) &&
mbed_official 0:51ac1d130fd4 352 (ip_addr_cmp(&(lpcb->local_ip), &(netif->ip_addr)))) {
mbed_official 0:51ac1d130fd4 353 /* The PCB is listening to the old ipaddr and
mbed_official 0:51ac1d130fd4 354 * is set to listen to the new one instead */
mbed_official 0:51ac1d130fd4 355 ip_addr_set(&(lpcb->local_ip), ipaddr);
mbed_official 0:51ac1d130fd4 356 }
mbed_official 0:51ac1d130fd4 357 }
mbed_official 0:51ac1d130fd4 358 }
mbed_official 0:51ac1d130fd4 359 #endif
mbed_official 0:51ac1d130fd4 360 snmp_delete_ipaddridx_tree(netif);
mbed_official 0:51ac1d130fd4 361 snmp_delete_iprteidx_tree(0,netif);
mbed_official 0:51ac1d130fd4 362 /* set new IP address to netif */
mbed_official 0:51ac1d130fd4 363 ip_addr_set(&(netif->ip_addr), ipaddr);
mbed_official 0:51ac1d130fd4 364 snmp_insert_ipaddridx_tree(netif);
mbed_official 0:51ac1d130fd4 365 snmp_insert_iprteidx_tree(0,netif);
mbed_official 0:51ac1d130fd4 366
mbed_official 0:51ac1d130fd4 367 LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: IP address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
mbed_official 0:51ac1d130fd4 368 netif->name[0], netif->name[1],
mbed_official 0:51ac1d130fd4 369 ip4_addr1_16(&netif->ip_addr),
mbed_official 0:51ac1d130fd4 370 ip4_addr2_16(&netif->ip_addr),
mbed_official 0:51ac1d130fd4 371 ip4_addr3_16(&netif->ip_addr),
mbed_official 0:51ac1d130fd4 372 ip4_addr4_16(&netif->ip_addr)));
mbed_official 0:51ac1d130fd4 373 }
mbed_official 0:51ac1d130fd4 374
mbed_official 0:51ac1d130fd4 375 /**
mbed_official 0:51ac1d130fd4 376 * Change the default gateway for a network interface
mbed_official 0:51ac1d130fd4 377 *
mbed_official 0:51ac1d130fd4 378 * @param netif the network interface to change
mbed_official 0:51ac1d130fd4 379 * @param gw the new default gateway
mbed_official 0:51ac1d130fd4 380 *
mbed_official 0:51ac1d130fd4 381 * @note call netif_set_addr() if you also want to change ip address and netmask
mbed_official 0:51ac1d130fd4 382 */
mbed_official 0:51ac1d130fd4 383 void
mbed_official 0:51ac1d130fd4 384 netif_set_gw(struct netif *netif, ip_addr_t *gw)
mbed_official 0:51ac1d130fd4 385 {
mbed_official 0:51ac1d130fd4 386 ip_addr_set(&(netif->gw), gw);
mbed_official 0:51ac1d130fd4 387 LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: GW address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
mbed_official 0:51ac1d130fd4 388 netif->name[0], netif->name[1],
mbed_official 0:51ac1d130fd4 389 ip4_addr1_16(&netif->gw),
mbed_official 0:51ac1d130fd4 390 ip4_addr2_16(&netif->gw),
mbed_official 0:51ac1d130fd4 391 ip4_addr3_16(&netif->gw),
mbed_official 0:51ac1d130fd4 392 ip4_addr4_16(&netif->gw)));
mbed_official 0:51ac1d130fd4 393 }
mbed_official 0:51ac1d130fd4 394
mbed_official 0:51ac1d130fd4 395 /**
mbed_official 0:51ac1d130fd4 396 * Change the netmask of a network interface
mbed_official 0:51ac1d130fd4 397 *
mbed_official 0:51ac1d130fd4 398 * @param netif the network interface to change
mbed_official 0:51ac1d130fd4 399 * @param netmask the new netmask
mbed_official 0:51ac1d130fd4 400 *
mbed_official 0:51ac1d130fd4 401 * @note call netif_set_addr() if you also want to change ip address and
mbed_official 0:51ac1d130fd4 402 * default gateway
mbed_official 0:51ac1d130fd4 403 */
mbed_official 0:51ac1d130fd4 404 void
mbed_official 0:51ac1d130fd4 405 netif_set_netmask(struct netif *netif, ip_addr_t *netmask)
mbed_official 0:51ac1d130fd4 406 {
mbed_official 0:51ac1d130fd4 407 snmp_delete_iprteidx_tree(0, netif);
mbed_official 0:51ac1d130fd4 408 /* set new netmask to netif */
mbed_official 0:51ac1d130fd4 409 ip_addr_set(&(netif->netmask), netmask);
mbed_official 0:51ac1d130fd4 410 snmp_insert_iprteidx_tree(0, netif);
mbed_official 0:51ac1d130fd4 411 LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: netmask of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
mbed_official 0:51ac1d130fd4 412 netif->name[0], netif->name[1],
mbed_official 0:51ac1d130fd4 413 ip4_addr1_16(&netif->netmask),
mbed_official 0:51ac1d130fd4 414 ip4_addr2_16(&netif->netmask),
mbed_official 0:51ac1d130fd4 415 ip4_addr3_16(&netif->netmask),
mbed_official 0:51ac1d130fd4 416 ip4_addr4_16(&netif->netmask)));
mbed_official 0:51ac1d130fd4 417 }
mbed_official 0:51ac1d130fd4 418
mbed_official 0:51ac1d130fd4 419 /**
mbed_official 0:51ac1d130fd4 420 * Set a network interface as the default network interface
mbed_official 0:51ac1d130fd4 421 * (used to output all packets for which no specific route is found)
mbed_official 0:51ac1d130fd4 422 *
mbed_official 0:51ac1d130fd4 423 * @param netif the default network interface
mbed_official 0:51ac1d130fd4 424 */
mbed_official 0:51ac1d130fd4 425 void
mbed_official 0:51ac1d130fd4 426 netif_set_default(struct netif *netif)
mbed_official 0:51ac1d130fd4 427 {
mbed_official 0:51ac1d130fd4 428 if (netif == NULL) {
mbed_official 0:51ac1d130fd4 429 /* remove default route */
mbed_official 0:51ac1d130fd4 430 snmp_delete_iprteidx_tree(1, netif);
mbed_official 0:51ac1d130fd4 431 } else {
mbed_official 0:51ac1d130fd4 432 /* install default route */
mbed_official 0:51ac1d130fd4 433 snmp_insert_iprteidx_tree(1, netif);
mbed_official 0:51ac1d130fd4 434 }
mbed_official 0:51ac1d130fd4 435 netif_default = netif;
mbed_official 0:51ac1d130fd4 436 LWIP_DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%c\n",
mbed_official 0:51ac1d130fd4 437 netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\''));
mbed_official 0:51ac1d130fd4 438 }
mbed_official 0:51ac1d130fd4 439
mbed_official 0:51ac1d130fd4 440 /**
mbed_official 0:51ac1d130fd4 441 * Bring an interface up, available for processing
mbed_official 0:51ac1d130fd4 442 * traffic.
mbed_official 0:51ac1d130fd4 443 *
mbed_official 0:51ac1d130fd4 444 * @note: Enabling DHCP on a down interface will make it come
mbed_official 0:51ac1d130fd4 445 * up once configured.
mbed_official 0:51ac1d130fd4 446 *
mbed_official 0:51ac1d130fd4 447 * @see dhcp_start()
mbed_official 0:51ac1d130fd4 448 */
mbed_official 0:51ac1d130fd4 449 void netif_set_up(struct netif *netif)
mbed_official 0:51ac1d130fd4 450 {
mbed_official 0:51ac1d130fd4 451 if (!(netif->flags & NETIF_FLAG_UP)) {
mbed_official 0:51ac1d130fd4 452 netif->flags |= NETIF_FLAG_UP;
mbed_official 0:51ac1d130fd4 453
mbed_official 0:51ac1d130fd4 454 #if LWIP_SNMP
mbed_official 0:51ac1d130fd4 455 snmp_get_sysuptime(&netif->ts);
mbed_official 0:51ac1d130fd4 456 #endif /* LWIP_SNMP */
mbed_official 0:51ac1d130fd4 457
mbed_official 0:51ac1d130fd4 458 NETIF_STATUS_CALLBACK(netif);
mbed_official 0:51ac1d130fd4 459
mbed_official 0:51ac1d130fd4 460 if (netif->flags & NETIF_FLAG_LINK_UP) {
mbed_official 0:51ac1d130fd4 461 #if LWIP_ARP
mbed_official 0:51ac1d130fd4 462 /* For Ethernet network interfaces, we would like to send a "gratuitous ARP" */
mbed_official 0:51ac1d130fd4 463 if (netif->flags & (NETIF_FLAG_ETHARP)) {
mbed_official 0:51ac1d130fd4 464 etharp_gratuitous(netif);
mbed_official 0:51ac1d130fd4 465 }
mbed_official 0:51ac1d130fd4 466 #endif /* LWIP_ARP */
mbed_official 0:51ac1d130fd4 467
mbed_official 0:51ac1d130fd4 468 #if LWIP_IGMP
mbed_official 0:51ac1d130fd4 469 /* resend IGMP memberships */
mbed_official 0:51ac1d130fd4 470 if (netif->flags & NETIF_FLAG_IGMP) {
mbed_official 0:51ac1d130fd4 471 igmp_report_groups( netif);
mbed_official 0:51ac1d130fd4 472 }
mbed_official 0:51ac1d130fd4 473 #endif /* LWIP_IGMP */
mbed_official 0:51ac1d130fd4 474 }
mbed_official 0:51ac1d130fd4 475 }
mbed_official 0:51ac1d130fd4 476 }
mbed_official 0:51ac1d130fd4 477
mbed_official 0:51ac1d130fd4 478 /**
mbed_official 0:51ac1d130fd4 479 * Bring an interface down, disabling any traffic processing.
mbed_official 0:51ac1d130fd4 480 *
mbed_official 0:51ac1d130fd4 481 * @note: Enabling DHCP on a down interface will make it come
mbed_official 0:51ac1d130fd4 482 * up once configured.
mbed_official 0:51ac1d130fd4 483 *
mbed_official 0:51ac1d130fd4 484 * @see dhcp_start()
mbed_official 0:51ac1d130fd4 485 */
mbed_official 0:51ac1d130fd4 486 void netif_set_down(struct netif *netif)
mbed_official 0:51ac1d130fd4 487 {
mbed_official 0:51ac1d130fd4 488 if (netif->flags & NETIF_FLAG_UP) {
mbed_official 0:51ac1d130fd4 489 netif->flags &= ~NETIF_FLAG_UP;
mbed_official 0:51ac1d130fd4 490 #if LWIP_SNMP
mbed_official 0:51ac1d130fd4 491 snmp_get_sysuptime(&netif->ts);
mbed_official 0:51ac1d130fd4 492 #endif
mbed_official 0:51ac1d130fd4 493
mbed_official 0:51ac1d130fd4 494 NETIF_STATUS_CALLBACK(netif);
mbed_official 0:51ac1d130fd4 495 }
mbed_official 0:51ac1d130fd4 496 }
mbed_official 0:51ac1d130fd4 497
mbed_official 0:51ac1d130fd4 498 #if LWIP_NETIF_STATUS_CALLBACK
mbed_official 0:51ac1d130fd4 499 /**
mbed_official 0:51ac1d130fd4 500 * Set callback to be called when interface is brought up/down
mbed_official 0:51ac1d130fd4 501 */
mbed_official 0:51ac1d130fd4 502 void netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback)
mbed_official 0:51ac1d130fd4 503 {
mbed_official 0:51ac1d130fd4 504 if (netif) {
mbed_official 0:51ac1d130fd4 505 netif->status_callback = status_callback;
mbed_official 0:51ac1d130fd4 506 }
mbed_official 0:51ac1d130fd4 507 }
mbed_official 0:51ac1d130fd4 508 #endif /* LWIP_NETIF_STATUS_CALLBACK */
mbed_official 0:51ac1d130fd4 509
mbed_official 0:51ac1d130fd4 510 /**
mbed_official 0:51ac1d130fd4 511 * Called by a driver when its link goes up
mbed_official 0:51ac1d130fd4 512 */
mbed_official 0:51ac1d130fd4 513 void netif_set_link_up(struct netif *netif )
mbed_official 0:51ac1d130fd4 514 {
mbed_official 0:51ac1d130fd4 515 if (!(netif->flags & NETIF_FLAG_LINK_UP)) {
mbed_official 0:51ac1d130fd4 516 netif->flags |= NETIF_FLAG_LINK_UP;
mbed_official 0:51ac1d130fd4 517
mbed_official 0:51ac1d130fd4 518 #if LWIP_DHCP
mbed_official 0:51ac1d130fd4 519 if (netif->dhcp) {
mbed_official 0:51ac1d130fd4 520 dhcp_network_changed(netif);
mbed_official 0:51ac1d130fd4 521 }
mbed_official 0:51ac1d130fd4 522 #endif /* LWIP_DHCP */
mbed_official 0:51ac1d130fd4 523
mbed_official 0:51ac1d130fd4 524 #if LWIP_AUTOIP
mbed_official 0:51ac1d130fd4 525 if (netif->autoip) {
mbed_official 0:51ac1d130fd4 526 autoip_network_changed(netif);
mbed_official 0:51ac1d130fd4 527 }
mbed_official 0:51ac1d130fd4 528 #endif /* LWIP_AUTOIP */
mbed_official 0:51ac1d130fd4 529
mbed_official 0:51ac1d130fd4 530 if (netif->flags & NETIF_FLAG_UP) {
mbed_official 0:51ac1d130fd4 531 #if LWIP_ARP
mbed_official 0:51ac1d130fd4 532 /* For Ethernet network interfaces, we would like to send a "gratuitous ARP" */
mbed_official 0:51ac1d130fd4 533 if (netif->flags & NETIF_FLAG_ETHARP) {
mbed_official 0:51ac1d130fd4 534 etharp_gratuitous(netif);
mbed_official 0:51ac1d130fd4 535 }
mbed_official 0:51ac1d130fd4 536 #endif /* LWIP_ARP */
mbed_official 0:51ac1d130fd4 537
mbed_official 0:51ac1d130fd4 538 #if LWIP_IGMP
mbed_official 0:51ac1d130fd4 539 /* resend IGMP memberships */
mbed_official 0:51ac1d130fd4 540 if (netif->flags & NETIF_FLAG_IGMP) {
mbed_official 0:51ac1d130fd4 541 igmp_report_groups( netif);
mbed_official 0:51ac1d130fd4 542 }
mbed_official 0:51ac1d130fd4 543 #endif /* LWIP_IGMP */
mbed_official 0:51ac1d130fd4 544 }
mbed_official 0:51ac1d130fd4 545 NETIF_LINK_CALLBACK(netif);
mbed_official 0:51ac1d130fd4 546 }
mbed_official 0:51ac1d130fd4 547 }
mbed_official 0:51ac1d130fd4 548
mbed_official 0:51ac1d130fd4 549 /**
mbed_official 0:51ac1d130fd4 550 * Called by a driver when its link goes down
mbed_official 0:51ac1d130fd4 551 */
mbed_official 0:51ac1d130fd4 552 void netif_set_link_down(struct netif *netif )
mbed_official 0:51ac1d130fd4 553 {
mbed_official 0:51ac1d130fd4 554 if (netif->flags & NETIF_FLAG_LINK_UP) {
mbed_official 0:51ac1d130fd4 555 netif->flags &= ~NETIF_FLAG_LINK_UP;
mbed_official 0:51ac1d130fd4 556 NETIF_LINK_CALLBACK(netif);
mbed_official 0:51ac1d130fd4 557 }
mbed_official 0:51ac1d130fd4 558 }
mbed_official 0:51ac1d130fd4 559
mbed_official 0:51ac1d130fd4 560 #if LWIP_NETIF_LINK_CALLBACK
mbed_official 0:51ac1d130fd4 561 /**
mbed_official 0:51ac1d130fd4 562 * Set callback to be called when link is brought up/down
mbed_official 0:51ac1d130fd4 563 */
mbed_official 0:51ac1d130fd4 564 void netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callback)
mbed_official 0:51ac1d130fd4 565 {
mbed_official 0:51ac1d130fd4 566 if (netif) {
mbed_official 0:51ac1d130fd4 567 netif->link_callback = link_callback;
mbed_official 0:51ac1d130fd4 568 }
mbed_official 0:51ac1d130fd4 569 }
mbed_official 0:51ac1d130fd4 570 #endif /* LWIP_NETIF_LINK_CALLBACK */
mbed_official 0:51ac1d130fd4 571
mbed_official 0:51ac1d130fd4 572 #if ENABLE_LOOPBACK
mbed_official 0:51ac1d130fd4 573 /**
mbed_official 0:51ac1d130fd4 574 * Send an IP packet to be received on the same netif (loopif-like).
mbed_official 0:51ac1d130fd4 575 * The pbuf is simply copied and handed back to netif->input.
mbed_official 0:51ac1d130fd4 576 * In multithreaded mode, this is done directly since netif->input must put
mbed_official 0:51ac1d130fd4 577 * the packet on a queue.
mbed_official 0:51ac1d130fd4 578 * In callback mode, the packet is put on an internal queue and is fed to
mbed_official 0:51ac1d130fd4 579 * netif->input by netif_poll().
mbed_official 0:51ac1d130fd4 580 *
mbed_official 0:51ac1d130fd4 581 * @param netif the lwip network interface structure
mbed_official 0:51ac1d130fd4 582 * @param p the (IP) packet to 'send'
mbed_official 0:51ac1d130fd4 583 * @param ipaddr the ip address to send the packet to (not used)
mbed_official 0:51ac1d130fd4 584 * @return ERR_OK if the packet has been sent
mbed_official 0:51ac1d130fd4 585 * ERR_MEM if the pbuf used to copy the packet couldn't be allocated
mbed_official 0:51ac1d130fd4 586 */
mbed_official 0:51ac1d130fd4 587 err_t
mbed_official 0:51ac1d130fd4 588 netif_loop_output(struct netif *netif, struct pbuf *p,
mbed_official 0:51ac1d130fd4 589 ip_addr_t *ipaddr)
mbed_official 0:51ac1d130fd4 590 {
mbed_official 0:51ac1d130fd4 591 struct pbuf *r;
mbed_official 0:51ac1d130fd4 592 err_t err;
mbed_official 0:51ac1d130fd4 593 struct pbuf *last;
mbed_official 0:51ac1d130fd4 594 #if LWIP_LOOPBACK_MAX_PBUFS
mbed_official 0:51ac1d130fd4 595 u8_t clen = 0;
mbed_official 0:51ac1d130fd4 596 #endif /* LWIP_LOOPBACK_MAX_PBUFS */
mbed_official 0:51ac1d130fd4 597 /* If we have a loopif, SNMP counters are adjusted for it,
mbed_official 0:51ac1d130fd4 598 * if not they are adjusted for 'netif'. */
mbed_official 0:51ac1d130fd4 599 #if LWIP_SNMP
mbed_official 0:51ac1d130fd4 600 #if LWIP_HAVE_LOOPIF
mbed_official 0:51ac1d130fd4 601 struct netif *stats_if = &loop_netif;
mbed_official 0:51ac1d130fd4 602 #else /* LWIP_HAVE_LOOPIF */
mbed_official 0:51ac1d130fd4 603 struct netif *stats_if = netif;
mbed_official 0:51ac1d130fd4 604 #endif /* LWIP_HAVE_LOOPIF */
mbed_official 0:51ac1d130fd4 605 #endif /* LWIP_SNMP */
mbed_official 0:51ac1d130fd4 606 SYS_ARCH_DECL_PROTECT(lev);
mbed_official 0:51ac1d130fd4 607 LWIP_UNUSED_ARG(ipaddr);
mbed_official 0:51ac1d130fd4 608
mbed_official 0:51ac1d130fd4 609 /* Allocate a new pbuf */
mbed_official 0:51ac1d130fd4 610 r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM);
mbed_official 0:51ac1d130fd4 611 if (r == NULL) {
mbed_official 0:51ac1d130fd4 612 LINK_STATS_INC(link.memerr);
mbed_official 0:51ac1d130fd4 613 LINK_STATS_INC(link.drop);
mbed_official 0:51ac1d130fd4 614 snmp_inc_ifoutdiscards(stats_if);
mbed_official 0:51ac1d130fd4 615 return ERR_MEM;
mbed_official 0:51ac1d130fd4 616 }
mbed_official 0:51ac1d130fd4 617 #if LWIP_LOOPBACK_MAX_PBUFS
mbed_official 0:51ac1d130fd4 618 clen = pbuf_clen(r);
mbed_official 0:51ac1d130fd4 619 /* check for overflow or too many pbuf on queue */
mbed_official 0:51ac1d130fd4 620 if(((netif->loop_cnt_current + clen) < netif->loop_cnt_current) ||
mbed_official 0:51ac1d130fd4 621 ((netif->loop_cnt_current + clen) > LWIP_LOOPBACK_MAX_PBUFS)) {
mbed_official 0:51ac1d130fd4 622 pbuf_free(r);
mbed_official 0:51ac1d130fd4 623 LINK_STATS_INC(link.memerr);
mbed_official 0:51ac1d130fd4 624 LINK_STATS_INC(link.drop);
mbed_official 0:51ac1d130fd4 625 snmp_inc_ifoutdiscards(stats_if);
mbed_official 0:51ac1d130fd4 626 return ERR_MEM;
mbed_official 0:51ac1d130fd4 627 }
mbed_official 0:51ac1d130fd4 628 netif->loop_cnt_current += clen;
mbed_official 0:51ac1d130fd4 629 #endif /* LWIP_LOOPBACK_MAX_PBUFS */
mbed_official 0:51ac1d130fd4 630
mbed_official 0:51ac1d130fd4 631 /* Copy the whole pbuf queue p into the single pbuf r */
mbed_official 0:51ac1d130fd4 632 if ((err = pbuf_copy(r, p)) != ERR_OK) {
mbed_official 0:51ac1d130fd4 633 pbuf_free(r);
mbed_official 0:51ac1d130fd4 634 LINK_STATS_INC(link.memerr);
mbed_official 0:51ac1d130fd4 635 LINK_STATS_INC(link.drop);
mbed_official 0:51ac1d130fd4 636 snmp_inc_ifoutdiscards(stats_if);
mbed_official 0:51ac1d130fd4 637 return err;
mbed_official 0:51ac1d130fd4 638 }
mbed_official 0:51ac1d130fd4 639
mbed_official 0:51ac1d130fd4 640 /* Put the packet on a linked list which gets emptied through calling
mbed_official 0:51ac1d130fd4 641 netif_poll(). */
mbed_official 0:51ac1d130fd4 642
mbed_official 0:51ac1d130fd4 643 /* let last point to the last pbuf in chain r */
mbed_official 0:51ac1d130fd4 644 for (last = r; last->next != NULL; last = last->next);
mbed_official 0:51ac1d130fd4 645
mbed_official 0:51ac1d130fd4 646 SYS_ARCH_PROTECT(lev);
mbed_official 0:51ac1d130fd4 647 if(netif->loop_first != NULL) {
mbed_official 0:51ac1d130fd4 648 LWIP_ASSERT("if first != NULL, last must also be != NULL", netif->loop_last != NULL);
mbed_official 0:51ac1d130fd4 649 netif->loop_last->next = r;
mbed_official 0:51ac1d130fd4 650 netif->loop_last = last;
mbed_official 0:51ac1d130fd4 651 } else {
mbed_official 0:51ac1d130fd4 652 netif->loop_first = r;
mbed_official 0:51ac1d130fd4 653 netif->loop_last = last;
mbed_official 0:51ac1d130fd4 654 }
mbed_official 0:51ac1d130fd4 655 SYS_ARCH_UNPROTECT(lev);
mbed_official 0:51ac1d130fd4 656
mbed_official 0:51ac1d130fd4 657 LINK_STATS_INC(link.xmit);
mbed_official 0:51ac1d130fd4 658 snmp_add_ifoutoctets(stats_if, p->tot_len);
mbed_official 0:51ac1d130fd4 659 snmp_inc_ifoutucastpkts(stats_if);
mbed_official 0:51ac1d130fd4 660
mbed_official 0:51ac1d130fd4 661 #if LWIP_NETIF_LOOPBACK_MULTITHREADING
mbed_official 0:51ac1d130fd4 662 /* For multithreading environment, schedule a call to netif_poll */
mbed_official 0:51ac1d130fd4 663 tcpip_callback((tcpip_callback_fn)netif_poll, netif);
mbed_official 0:51ac1d130fd4 664 #endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
mbed_official 0:51ac1d130fd4 665
mbed_official 0:51ac1d130fd4 666 return ERR_OK;
mbed_official 0:51ac1d130fd4 667 }
mbed_official 0:51ac1d130fd4 668
mbed_official 0:51ac1d130fd4 669 /**
mbed_official 0:51ac1d130fd4 670 * Call netif_poll() in the main loop of your application. This is to prevent
mbed_official 0:51ac1d130fd4 671 * reentering non-reentrant functions like tcp_input(). Packets passed to
mbed_official 0:51ac1d130fd4 672 * netif_loop_output() are put on a list that is passed to netif->input() by
mbed_official 0:51ac1d130fd4 673 * netif_poll().
mbed_official 0:51ac1d130fd4 674 */
mbed_official 0:51ac1d130fd4 675 void
mbed_official 0:51ac1d130fd4 676 netif_poll(struct netif *netif)
mbed_official 0:51ac1d130fd4 677 {
mbed_official 0:51ac1d130fd4 678 struct pbuf *in;
mbed_official 0:51ac1d130fd4 679 /* If we have a loopif, SNMP counters are adjusted for it,
mbed_official 0:51ac1d130fd4 680 * if not they are adjusted for 'netif'. */
mbed_official 0:51ac1d130fd4 681 #if LWIP_SNMP
mbed_official 0:51ac1d130fd4 682 #if LWIP_HAVE_LOOPIF
mbed_official 0:51ac1d130fd4 683 struct netif *stats_if = &loop_netif;
mbed_official 0:51ac1d130fd4 684 #else /* LWIP_HAVE_LOOPIF */
mbed_official 0:51ac1d130fd4 685 struct netif *stats_if = netif;
mbed_official 0:51ac1d130fd4 686 #endif /* LWIP_HAVE_LOOPIF */
mbed_official 0:51ac1d130fd4 687 #endif /* LWIP_SNMP */
mbed_official 0:51ac1d130fd4 688 SYS_ARCH_DECL_PROTECT(lev);
mbed_official 0:51ac1d130fd4 689
mbed_official 0:51ac1d130fd4 690 do {
mbed_official 0:51ac1d130fd4 691 /* Get a packet from the list. With SYS_LIGHTWEIGHT_PROT=1, this is protected */
mbed_official 0:51ac1d130fd4 692 SYS_ARCH_PROTECT(lev);
mbed_official 0:51ac1d130fd4 693 in = netif->loop_first;
mbed_official 0:51ac1d130fd4 694 if (in != NULL) {
mbed_official 0:51ac1d130fd4 695 struct pbuf *in_end = in;
mbed_official 0:51ac1d130fd4 696 #if LWIP_LOOPBACK_MAX_PBUFS
mbed_official 0:51ac1d130fd4 697 u8_t clen = pbuf_clen(in);
mbed_official 0:51ac1d130fd4 698 /* adjust the number of pbufs on queue */
mbed_official 0:51ac1d130fd4 699 LWIP_ASSERT("netif->loop_cnt_current underflow",
mbed_official 0:51ac1d130fd4 700 ((netif->loop_cnt_current - clen) < netif->loop_cnt_current));
mbed_official 0:51ac1d130fd4 701 netif->loop_cnt_current -= clen;
mbed_official 0:51ac1d130fd4 702 #endif /* LWIP_LOOPBACK_MAX_PBUFS */
mbed_official 0:51ac1d130fd4 703 while (in_end->len != in_end->tot_len) {
mbed_official 0:51ac1d130fd4 704 LWIP_ASSERT("bogus pbuf: len != tot_len but next == NULL!", in_end->next != NULL);
mbed_official 0:51ac1d130fd4 705 in_end = in_end->next;
mbed_official 0:51ac1d130fd4 706 }
mbed_official 0:51ac1d130fd4 707 /* 'in_end' now points to the last pbuf from 'in' */
mbed_official 0:51ac1d130fd4 708 if (in_end == netif->loop_last) {
mbed_official 0:51ac1d130fd4 709 /* this was the last pbuf in the list */
mbed_official 0:51ac1d130fd4 710 netif->loop_first = netif->loop_last = NULL;
mbed_official 0:51ac1d130fd4 711 } else {
mbed_official 0:51ac1d130fd4 712 /* pop the pbuf off the list */
mbed_official 0:51ac1d130fd4 713 netif->loop_first = in_end->next;
mbed_official 0:51ac1d130fd4 714 LWIP_ASSERT("should not be null since first != last!", netif->loop_first != NULL);
mbed_official 0:51ac1d130fd4 715 }
mbed_official 0:51ac1d130fd4 716 /* De-queue the pbuf from its successors on the 'loop_' list. */
mbed_official 0:51ac1d130fd4 717 in_end->next = NULL;
mbed_official 0:51ac1d130fd4 718 }
mbed_official 0:51ac1d130fd4 719 SYS_ARCH_UNPROTECT(lev);
mbed_official 0:51ac1d130fd4 720
mbed_official 0:51ac1d130fd4 721 if (in != NULL) {
mbed_official 0:51ac1d130fd4 722 LINK_STATS_INC(link.recv);
mbed_official 0:51ac1d130fd4 723 snmp_add_ifinoctets(stats_if, in->tot_len);
mbed_official 0:51ac1d130fd4 724 snmp_inc_ifinucastpkts(stats_if);
mbed_official 0:51ac1d130fd4 725 /* loopback packets are always IP packets! */
mbed_official 0:51ac1d130fd4 726 if (ip_input(in, netif) != ERR_OK) {
mbed_official 0:51ac1d130fd4 727 pbuf_free(in);
mbed_official 0:51ac1d130fd4 728 }
mbed_official 0:51ac1d130fd4 729 /* Don't reference the packet any more! */
mbed_official 0:51ac1d130fd4 730 in = NULL;
mbed_official 0:51ac1d130fd4 731 }
mbed_official 0:51ac1d130fd4 732 /* go on while there is a packet on the list */
mbed_official 0:51ac1d130fd4 733 } while (netif->loop_first != NULL);
mbed_official 0:51ac1d130fd4 734 }
mbed_official 0:51ac1d130fd4 735
mbed_official 0:51ac1d130fd4 736 #if !LWIP_NETIF_LOOPBACK_MULTITHREADING
mbed_official 0:51ac1d130fd4 737 /**
mbed_official 0:51ac1d130fd4 738 * Calls netif_poll() for every netif on the netif_list.
mbed_official 0:51ac1d130fd4 739 */
mbed_official 0:51ac1d130fd4 740 void
mbed_official 0:51ac1d130fd4 741 netif_poll_all(void)
mbed_official 0:51ac1d130fd4 742 {
mbed_official 0:51ac1d130fd4 743 struct netif *netif = netif_list;
mbed_official 0:51ac1d130fd4 744 /* loop through netifs */
mbed_official 0:51ac1d130fd4 745 while (netif != NULL) {
mbed_official 0:51ac1d130fd4 746 netif_poll(netif);
mbed_official 0:51ac1d130fd4 747 /* proceed to next network interface */
mbed_official 0:51ac1d130fd4 748 netif = netif->next;
mbed_official 0:51ac1d130fd4 749 }
mbed_official 0:51ac1d130fd4 750 }
mbed_official 0:51ac1d130fd4 751 #endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */
mbed_official 0:51ac1d130fd4 752 #endif /* ENABLE_LOOPBACK */