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:
Mon Mar 14 16:15:36 2016 +0000
Revision:
20:08f08bfc3f3d
Parent:
11:4b3f6f8b92d2
Synchronized with git revision fec574a5ed6db26aca1b13992ff271bf527d4a0d

Full URL: https://github.com/mbedmicro/mbed/commit/fec574a5ed6db26aca1b13992ff271bf527d4a0d/

Increased allocated netbufs to handle DTLS handshakes

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 {
bogdanm 11:4b3f6f8b92d2 321 /* Protect against dereferencing NULL pointers by
bogdanm 11:4b3f6f8b92d2 322 treating like ANY, as does ip_addr_set() */
bogdanm 11:4b3f6f8b92d2 323 if (!ipaddr) {
bogdanm 11:4b3f6f8b92d2 324 ipaddr = IP_ADDR_ANY;
bogdanm 11:4b3f6f8b92d2 325 }
bogdanm 11:4b3f6f8b92d2 326
mbed_official 0:51ac1d130fd4 327 /* TODO: Handling of obsolete pcbs */
mbed_official 0:51ac1d130fd4 328 /* See: http://mail.gnu.org/archive/html/lwip-users/2003-03/msg00118.html */
mbed_official 0:51ac1d130fd4 329 #if LWIP_TCP
mbed_official 0:51ac1d130fd4 330 struct tcp_pcb *pcb;
mbed_official 0:51ac1d130fd4 331 struct tcp_pcb_listen *lpcb;
mbed_official 0:51ac1d130fd4 332
mbed_official 0:51ac1d130fd4 333 /* address is actually being changed? */
mbed_official 0:51ac1d130fd4 334 if ((ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0) {
mbed_official 0:51ac1d130fd4 335 /* extern struct tcp_pcb *tcp_active_pcbs; defined by tcp.h */
mbed_official 0:51ac1d130fd4 336 LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: netif address being changed\n"));
mbed_official 0:51ac1d130fd4 337 pcb = tcp_active_pcbs;
mbed_official 0:51ac1d130fd4 338 while (pcb != NULL) {
mbed_official 0:51ac1d130fd4 339 /* PCB bound to current local interface address? */
mbed_official 0:51ac1d130fd4 340 if (ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))
mbed_official 0:51ac1d130fd4 341 #if LWIP_AUTOIP
mbed_official 0:51ac1d130fd4 342 /* connections to link-local addresses must persist (RFC3927 ch. 1.9) */
mbed_official 0:51ac1d130fd4 343 && !ip_addr_islinklocal(&(pcb->local_ip))
mbed_official 0:51ac1d130fd4 344 #endif /* LWIP_AUTOIP */
mbed_official 0:51ac1d130fd4 345 ) {
mbed_official 0:51ac1d130fd4 346 /* this connection must be aborted */
mbed_official 0:51ac1d130fd4 347 struct tcp_pcb *next = pcb->next;
mbed_official 0:51ac1d130fd4 348 LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb));
mbed_official 0:51ac1d130fd4 349 tcp_abort(pcb);
mbed_official 0:51ac1d130fd4 350 pcb = next;
mbed_official 0:51ac1d130fd4 351 } else {
mbed_official 0:51ac1d130fd4 352 pcb = pcb->next;
mbed_official 0:51ac1d130fd4 353 }
mbed_official 0:51ac1d130fd4 354 }
mbed_official 0:51ac1d130fd4 355 for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
mbed_official 0:51ac1d130fd4 356 /* PCB bound to current local interface address? */
mbed_official 0:51ac1d130fd4 357 if ((!(ip_addr_isany(&(lpcb->local_ip)))) &&
mbed_official 0:51ac1d130fd4 358 (ip_addr_cmp(&(lpcb->local_ip), &(netif->ip_addr)))) {
mbed_official 0:51ac1d130fd4 359 /* The PCB is listening to the old ipaddr and
mbed_official 0:51ac1d130fd4 360 * is set to listen to the new one instead */
mbed_official 0:51ac1d130fd4 361 ip_addr_set(&(lpcb->local_ip), ipaddr);
mbed_official 0:51ac1d130fd4 362 }
mbed_official 0:51ac1d130fd4 363 }
mbed_official 0:51ac1d130fd4 364 }
mbed_official 0:51ac1d130fd4 365 #endif
mbed_official 0:51ac1d130fd4 366 snmp_delete_ipaddridx_tree(netif);
mbed_official 0:51ac1d130fd4 367 snmp_delete_iprteidx_tree(0,netif);
mbed_official 0:51ac1d130fd4 368 /* set new IP address to netif */
mbed_official 0:51ac1d130fd4 369 ip_addr_set(&(netif->ip_addr), ipaddr);
mbed_official 0:51ac1d130fd4 370 snmp_insert_ipaddridx_tree(netif);
mbed_official 0:51ac1d130fd4 371 snmp_insert_iprteidx_tree(0,netif);
mbed_official 0:51ac1d130fd4 372
mbed_official 0:51ac1d130fd4 373 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 374 netif->name[0], netif->name[1],
mbed_official 0:51ac1d130fd4 375 ip4_addr1_16(&netif->ip_addr),
mbed_official 0:51ac1d130fd4 376 ip4_addr2_16(&netif->ip_addr),
mbed_official 0:51ac1d130fd4 377 ip4_addr3_16(&netif->ip_addr),
mbed_official 0:51ac1d130fd4 378 ip4_addr4_16(&netif->ip_addr)));
mbed_official 0:51ac1d130fd4 379 }
mbed_official 0:51ac1d130fd4 380
mbed_official 0:51ac1d130fd4 381 /**
mbed_official 0:51ac1d130fd4 382 * Change the default gateway for a network interface
mbed_official 0:51ac1d130fd4 383 *
mbed_official 0:51ac1d130fd4 384 * @param netif the network interface to change
mbed_official 0:51ac1d130fd4 385 * @param gw the new default gateway
mbed_official 0:51ac1d130fd4 386 *
mbed_official 0:51ac1d130fd4 387 * @note call netif_set_addr() if you also want to change ip address and netmask
mbed_official 0:51ac1d130fd4 388 */
mbed_official 0:51ac1d130fd4 389 void
mbed_official 0:51ac1d130fd4 390 netif_set_gw(struct netif *netif, ip_addr_t *gw)
mbed_official 0:51ac1d130fd4 391 {
mbed_official 0:51ac1d130fd4 392 ip_addr_set(&(netif->gw), gw);
mbed_official 0:51ac1d130fd4 393 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 394 netif->name[0], netif->name[1],
mbed_official 0:51ac1d130fd4 395 ip4_addr1_16(&netif->gw),
mbed_official 0:51ac1d130fd4 396 ip4_addr2_16(&netif->gw),
mbed_official 0:51ac1d130fd4 397 ip4_addr3_16(&netif->gw),
mbed_official 0:51ac1d130fd4 398 ip4_addr4_16(&netif->gw)));
mbed_official 0:51ac1d130fd4 399 }
mbed_official 0:51ac1d130fd4 400
mbed_official 0:51ac1d130fd4 401 /**
mbed_official 0:51ac1d130fd4 402 * Change the netmask of a network interface
mbed_official 0:51ac1d130fd4 403 *
mbed_official 0:51ac1d130fd4 404 * @param netif the network interface to change
mbed_official 0:51ac1d130fd4 405 * @param netmask the new netmask
mbed_official 0:51ac1d130fd4 406 *
mbed_official 0:51ac1d130fd4 407 * @note call netif_set_addr() if you also want to change ip address and
mbed_official 0:51ac1d130fd4 408 * default gateway
mbed_official 0:51ac1d130fd4 409 */
mbed_official 0:51ac1d130fd4 410 void
mbed_official 0:51ac1d130fd4 411 netif_set_netmask(struct netif *netif, ip_addr_t *netmask)
mbed_official 0:51ac1d130fd4 412 {
mbed_official 0:51ac1d130fd4 413 snmp_delete_iprteidx_tree(0, netif);
mbed_official 0:51ac1d130fd4 414 /* set new netmask to netif */
mbed_official 0:51ac1d130fd4 415 ip_addr_set(&(netif->netmask), netmask);
mbed_official 0:51ac1d130fd4 416 snmp_insert_iprteidx_tree(0, netif);
mbed_official 0:51ac1d130fd4 417 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 418 netif->name[0], netif->name[1],
mbed_official 0:51ac1d130fd4 419 ip4_addr1_16(&netif->netmask),
mbed_official 0:51ac1d130fd4 420 ip4_addr2_16(&netif->netmask),
mbed_official 0:51ac1d130fd4 421 ip4_addr3_16(&netif->netmask),
mbed_official 0:51ac1d130fd4 422 ip4_addr4_16(&netif->netmask)));
mbed_official 0:51ac1d130fd4 423 }
mbed_official 0:51ac1d130fd4 424
mbed_official 0:51ac1d130fd4 425 /**
mbed_official 0:51ac1d130fd4 426 * Set a network interface as the default network interface
mbed_official 0:51ac1d130fd4 427 * (used to output all packets for which no specific route is found)
mbed_official 0:51ac1d130fd4 428 *
mbed_official 0:51ac1d130fd4 429 * @param netif the default network interface
mbed_official 0:51ac1d130fd4 430 */
mbed_official 0:51ac1d130fd4 431 void
mbed_official 0:51ac1d130fd4 432 netif_set_default(struct netif *netif)
mbed_official 0:51ac1d130fd4 433 {
mbed_official 0:51ac1d130fd4 434 if (netif == NULL) {
mbed_official 0:51ac1d130fd4 435 /* remove default route */
mbed_official 0:51ac1d130fd4 436 snmp_delete_iprteidx_tree(1, netif);
mbed_official 0:51ac1d130fd4 437 } else {
mbed_official 0:51ac1d130fd4 438 /* install default route */
mbed_official 0:51ac1d130fd4 439 snmp_insert_iprteidx_tree(1, netif);
mbed_official 0:51ac1d130fd4 440 }
mbed_official 0:51ac1d130fd4 441 netif_default = netif;
mbed_official 0:51ac1d130fd4 442 LWIP_DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%c\n",
mbed_official 0:51ac1d130fd4 443 netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\''));
mbed_official 0:51ac1d130fd4 444 }
mbed_official 0:51ac1d130fd4 445
mbed_official 0:51ac1d130fd4 446 /**
mbed_official 0:51ac1d130fd4 447 * Bring an interface up, available for processing
mbed_official 0:51ac1d130fd4 448 * traffic.
mbed_official 0:51ac1d130fd4 449 *
mbed_official 0:51ac1d130fd4 450 * @note: Enabling DHCP on a down interface will make it come
mbed_official 0:51ac1d130fd4 451 * up once configured.
mbed_official 0:51ac1d130fd4 452 *
mbed_official 0:51ac1d130fd4 453 * @see dhcp_start()
mbed_official 0:51ac1d130fd4 454 */
mbed_official 0:51ac1d130fd4 455 void netif_set_up(struct netif *netif)
mbed_official 0:51ac1d130fd4 456 {
mbed_official 0:51ac1d130fd4 457 if (!(netif->flags & NETIF_FLAG_UP)) {
mbed_official 0:51ac1d130fd4 458 netif->flags |= NETIF_FLAG_UP;
mbed_official 0:51ac1d130fd4 459
mbed_official 0:51ac1d130fd4 460 #if LWIP_SNMP
mbed_official 0:51ac1d130fd4 461 snmp_get_sysuptime(&netif->ts);
mbed_official 0:51ac1d130fd4 462 #endif /* LWIP_SNMP */
mbed_official 0:51ac1d130fd4 463
mbed_official 0:51ac1d130fd4 464 NETIF_STATUS_CALLBACK(netif);
mbed_official 0:51ac1d130fd4 465
mbed_official 0:51ac1d130fd4 466 if (netif->flags & NETIF_FLAG_LINK_UP) {
mbed_official 0:51ac1d130fd4 467 #if LWIP_ARP
mbed_official 0:51ac1d130fd4 468 /* For Ethernet network interfaces, we would like to send a "gratuitous ARP" */
mbed_official 0:51ac1d130fd4 469 if (netif->flags & (NETIF_FLAG_ETHARP)) {
mbed_official 0:51ac1d130fd4 470 etharp_gratuitous(netif);
mbed_official 0:51ac1d130fd4 471 }
mbed_official 0:51ac1d130fd4 472 #endif /* LWIP_ARP */
mbed_official 0:51ac1d130fd4 473
mbed_official 0:51ac1d130fd4 474 #if LWIP_IGMP
mbed_official 0:51ac1d130fd4 475 /* resend IGMP memberships */
mbed_official 0:51ac1d130fd4 476 if (netif->flags & NETIF_FLAG_IGMP) {
mbed_official 0:51ac1d130fd4 477 igmp_report_groups( netif);
mbed_official 0:51ac1d130fd4 478 }
mbed_official 0:51ac1d130fd4 479 #endif /* LWIP_IGMP */
mbed_official 0:51ac1d130fd4 480 }
mbed_official 0:51ac1d130fd4 481 }
mbed_official 0:51ac1d130fd4 482 }
mbed_official 0:51ac1d130fd4 483
mbed_official 0:51ac1d130fd4 484 /**
mbed_official 0:51ac1d130fd4 485 * Bring an interface down, disabling any traffic processing.
mbed_official 0:51ac1d130fd4 486 *
mbed_official 0:51ac1d130fd4 487 * @note: Enabling DHCP on a down interface will make it come
mbed_official 0:51ac1d130fd4 488 * up once configured.
mbed_official 0:51ac1d130fd4 489 *
mbed_official 0:51ac1d130fd4 490 * @see dhcp_start()
mbed_official 0:51ac1d130fd4 491 */
mbed_official 0:51ac1d130fd4 492 void netif_set_down(struct netif *netif)
mbed_official 0:51ac1d130fd4 493 {
mbed_official 0:51ac1d130fd4 494 if (netif->flags & NETIF_FLAG_UP) {
mbed_official 0:51ac1d130fd4 495 netif->flags &= ~NETIF_FLAG_UP;
mbed_official 0:51ac1d130fd4 496 #if LWIP_SNMP
mbed_official 0:51ac1d130fd4 497 snmp_get_sysuptime(&netif->ts);
mbed_official 0:51ac1d130fd4 498 #endif
mbed_official 0:51ac1d130fd4 499
mbed_official 0:51ac1d130fd4 500 NETIF_STATUS_CALLBACK(netif);
mbed_official 0:51ac1d130fd4 501 }
mbed_official 0:51ac1d130fd4 502 }
mbed_official 0:51ac1d130fd4 503
mbed_official 0:51ac1d130fd4 504 #if LWIP_NETIF_STATUS_CALLBACK
mbed_official 0:51ac1d130fd4 505 /**
mbed_official 0:51ac1d130fd4 506 * Set callback to be called when interface is brought up/down
mbed_official 0:51ac1d130fd4 507 */
mbed_official 0:51ac1d130fd4 508 void netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback)
mbed_official 0:51ac1d130fd4 509 {
mbed_official 0:51ac1d130fd4 510 if (netif) {
mbed_official 0:51ac1d130fd4 511 netif->status_callback = status_callback;
mbed_official 0:51ac1d130fd4 512 }
mbed_official 0:51ac1d130fd4 513 }
mbed_official 0:51ac1d130fd4 514 #endif /* LWIP_NETIF_STATUS_CALLBACK */
mbed_official 0:51ac1d130fd4 515
mbed_official 0:51ac1d130fd4 516 /**
mbed_official 0:51ac1d130fd4 517 * Called by a driver when its link goes up
mbed_official 0:51ac1d130fd4 518 */
mbed_official 0:51ac1d130fd4 519 void netif_set_link_up(struct netif *netif )
mbed_official 0:51ac1d130fd4 520 {
mbed_official 0:51ac1d130fd4 521 if (!(netif->flags & NETIF_FLAG_LINK_UP)) {
mbed_official 0:51ac1d130fd4 522 netif->flags |= NETIF_FLAG_LINK_UP;
mbed_official 0:51ac1d130fd4 523
mbed_official 0:51ac1d130fd4 524 #if LWIP_DHCP
mbed_official 0:51ac1d130fd4 525 if (netif->dhcp) {
mbed_official 0:51ac1d130fd4 526 dhcp_network_changed(netif);
mbed_official 0:51ac1d130fd4 527 }
mbed_official 0:51ac1d130fd4 528 #endif /* LWIP_DHCP */
mbed_official 0:51ac1d130fd4 529
mbed_official 0:51ac1d130fd4 530 #if LWIP_AUTOIP
mbed_official 0:51ac1d130fd4 531 if (netif->autoip) {
mbed_official 0:51ac1d130fd4 532 autoip_network_changed(netif);
mbed_official 0:51ac1d130fd4 533 }
mbed_official 0:51ac1d130fd4 534 #endif /* LWIP_AUTOIP */
mbed_official 0:51ac1d130fd4 535
mbed_official 0:51ac1d130fd4 536 if (netif->flags & NETIF_FLAG_UP) {
mbed_official 0:51ac1d130fd4 537 #if LWIP_ARP
mbed_official 0:51ac1d130fd4 538 /* For Ethernet network interfaces, we would like to send a "gratuitous ARP" */
mbed_official 0:51ac1d130fd4 539 if (netif->flags & NETIF_FLAG_ETHARP) {
mbed_official 0:51ac1d130fd4 540 etharp_gratuitous(netif);
mbed_official 0:51ac1d130fd4 541 }
mbed_official 0:51ac1d130fd4 542 #endif /* LWIP_ARP */
mbed_official 0:51ac1d130fd4 543
mbed_official 0:51ac1d130fd4 544 #if LWIP_IGMP
mbed_official 0:51ac1d130fd4 545 /* resend IGMP memberships */
mbed_official 0:51ac1d130fd4 546 if (netif->flags & NETIF_FLAG_IGMP) {
mbed_official 0:51ac1d130fd4 547 igmp_report_groups( netif);
mbed_official 0:51ac1d130fd4 548 }
mbed_official 0:51ac1d130fd4 549 #endif /* LWIP_IGMP */
mbed_official 0:51ac1d130fd4 550 }
mbed_official 0:51ac1d130fd4 551 NETIF_LINK_CALLBACK(netif);
mbed_official 0:51ac1d130fd4 552 }
mbed_official 0:51ac1d130fd4 553 }
mbed_official 0:51ac1d130fd4 554
mbed_official 0:51ac1d130fd4 555 /**
mbed_official 0:51ac1d130fd4 556 * Called by a driver when its link goes down
mbed_official 0:51ac1d130fd4 557 */
mbed_official 0:51ac1d130fd4 558 void netif_set_link_down(struct netif *netif )
mbed_official 0:51ac1d130fd4 559 {
mbed_official 0:51ac1d130fd4 560 if (netif->flags & NETIF_FLAG_LINK_UP) {
mbed_official 0:51ac1d130fd4 561 netif->flags &= ~NETIF_FLAG_LINK_UP;
mbed_official 0:51ac1d130fd4 562 NETIF_LINK_CALLBACK(netif);
mbed_official 0:51ac1d130fd4 563 }
mbed_official 0:51ac1d130fd4 564 }
mbed_official 0:51ac1d130fd4 565
mbed_official 0:51ac1d130fd4 566 #if LWIP_NETIF_LINK_CALLBACK
mbed_official 0:51ac1d130fd4 567 /**
mbed_official 0:51ac1d130fd4 568 * Set callback to be called when link is brought up/down
mbed_official 0:51ac1d130fd4 569 */
mbed_official 0:51ac1d130fd4 570 void netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callback)
mbed_official 0:51ac1d130fd4 571 {
mbed_official 0:51ac1d130fd4 572 if (netif) {
mbed_official 0:51ac1d130fd4 573 netif->link_callback = link_callback;
mbed_official 0:51ac1d130fd4 574 }
mbed_official 0:51ac1d130fd4 575 }
mbed_official 0:51ac1d130fd4 576 #endif /* LWIP_NETIF_LINK_CALLBACK */
mbed_official 0:51ac1d130fd4 577
mbed_official 0:51ac1d130fd4 578 #if ENABLE_LOOPBACK
mbed_official 0:51ac1d130fd4 579 /**
mbed_official 0:51ac1d130fd4 580 * Send an IP packet to be received on the same netif (loopif-like).
mbed_official 0:51ac1d130fd4 581 * The pbuf is simply copied and handed back to netif->input.
mbed_official 0:51ac1d130fd4 582 * In multithreaded mode, this is done directly since netif->input must put
mbed_official 0:51ac1d130fd4 583 * the packet on a queue.
mbed_official 0:51ac1d130fd4 584 * In callback mode, the packet is put on an internal queue and is fed to
mbed_official 0:51ac1d130fd4 585 * netif->input by netif_poll().
mbed_official 0:51ac1d130fd4 586 *
mbed_official 0:51ac1d130fd4 587 * @param netif the lwip network interface structure
mbed_official 0:51ac1d130fd4 588 * @param p the (IP) packet to 'send'
mbed_official 0:51ac1d130fd4 589 * @param ipaddr the ip address to send the packet to (not used)
mbed_official 0:51ac1d130fd4 590 * @return ERR_OK if the packet has been sent
mbed_official 0:51ac1d130fd4 591 * ERR_MEM if the pbuf used to copy the packet couldn't be allocated
mbed_official 0:51ac1d130fd4 592 */
mbed_official 0:51ac1d130fd4 593 err_t
mbed_official 0:51ac1d130fd4 594 netif_loop_output(struct netif *netif, struct pbuf *p,
mbed_official 0:51ac1d130fd4 595 ip_addr_t *ipaddr)
mbed_official 0:51ac1d130fd4 596 {
mbed_official 0:51ac1d130fd4 597 struct pbuf *r;
mbed_official 0:51ac1d130fd4 598 err_t err;
mbed_official 0:51ac1d130fd4 599 struct pbuf *last;
mbed_official 0:51ac1d130fd4 600 #if LWIP_LOOPBACK_MAX_PBUFS
mbed_official 0:51ac1d130fd4 601 u8_t clen = 0;
mbed_official 0:51ac1d130fd4 602 #endif /* LWIP_LOOPBACK_MAX_PBUFS */
mbed_official 0:51ac1d130fd4 603 /* If we have a loopif, SNMP counters are adjusted for it,
mbed_official 0:51ac1d130fd4 604 * if not they are adjusted for 'netif'. */
mbed_official 0:51ac1d130fd4 605 #if LWIP_SNMP
mbed_official 0:51ac1d130fd4 606 #if LWIP_HAVE_LOOPIF
mbed_official 0:51ac1d130fd4 607 struct netif *stats_if = &loop_netif;
mbed_official 0:51ac1d130fd4 608 #else /* LWIP_HAVE_LOOPIF */
mbed_official 0:51ac1d130fd4 609 struct netif *stats_if = netif;
mbed_official 0:51ac1d130fd4 610 #endif /* LWIP_HAVE_LOOPIF */
mbed_official 0:51ac1d130fd4 611 #endif /* LWIP_SNMP */
mbed_official 0:51ac1d130fd4 612 SYS_ARCH_DECL_PROTECT(lev);
mbed_official 0:51ac1d130fd4 613 LWIP_UNUSED_ARG(ipaddr);
mbed_official 0:51ac1d130fd4 614
mbed_official 0:51ac1d130fd4 615 /* Allocate a new pbuf */
mbed_official 0:51ac1d130fd4 616 r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM);
mbed_official 0:51ac1d130fd4 617 if (r == NULL) {
mbed_official 0:51ac1d130fd4 618 LINK_STATS_INC(link.memerr);
mbed_official 0:51ac1d130fd4 619 LINK_STATS_INC(link.drop);
mbed_official 0:51ac1d130fd4 620 snmp_inc_ifoutdiscards(stats_if);
mbed_official 0:51ac1d130fd4 621 return ERR_MEM;
mbed_official 0:51ac1d130fd4 622 }
mbed_official 0:51ac1d130fd4 623 #if LWIP_LOOPBACK_MAX_PBUFS
mbed_official 0:51ac1d130fd4 624 clen = pbuf_clen(r);
mbed_official 0:51ac1d130fd4 625 /* check for overflow or too many pbuf on queue */
mbed_official 0:51ac1d130fd4 626 if(((netif->loop_cnt_current + clen) < netif->loop_cnt_current) ||
mbed_official 0:51ac1d130fd4 627 ((netif->loop_cnt_current + clen) > LWIP_LOOPBACK_MAX_PBUFS)) {
mbed_official 0:51ac1d130fd4 628 pbuf_free(r);
mbed_official 0:51ac1d130fd4 629 LINK_STATS_INC(link.memerr);
mbed_official 0:51ac1d130fd4 630 LINK_STATS_INC(link.drop);
mbed_official 0:51ac1d130fd4 631 snmp_inc_ifoutdiscards(stats_if);
mbed_official 0:51ac1d130fd4 632 return ERR_MEM;
mbed_official 0:51ac1d130fd4 633 }
mbed_official 0:51ac1d130fd4 634 netif->loop_cnt_current += clen;
mbed_official 0:51ac1d130fd4 635 #endif /* LWIP_LOOPBACK_MAX_PBUFS */
mbed_official 0:51ac1d130fd4 636
mbed_official 0:51ac1d130fd4 637 /* Copy the whole pbuf queue p into the single pbuf r */
mbed_official 0:51ac1d130fd4 638 if ((err = pbuf_copy(r, p)) != ERR_OK) {
mbed_official 0:51ac1d130fd4 639 pbuf_free(r);
mbed_official 0:51ac1d130fd4 640 LINK_STATS_INC(link.memerr);
mbed_official 0:51ac1d130fd4 641 LINK_STATS_INC(link.drop);
mbed_official 0:51ac1d130fd4 642 snmp_inc_ifoutdiscards(stats_if);
mbed_official 0:51ac1d130fd4 643 return err;
mbed_official 0:51ac1d130fd4 644 }
mbed_official 0:51ac1d130fd4 645
mbed_official 0:51ac1d130fd4 646 /* Put the packet on a linked list which gets emptied through calling
mbed_official 0:51ac1d130fd4 647 netif_poll(). */
mbed_official 0:51ac1d130fd4 648
mbed_official 0:51ac1d130fd4 649 /* let last point to the last pbuf in chain r */
mbed_official 0:51ac1d130fd4 650 for (last = r; last->next != NULL; last = last->next);
mbed_official 0:51ac1d130fd4 651
mbed_official 0:51ac1d130fd4 652 SYS_ARCH_PROTECT(lev);
mbed_official 0:51ac1d130fd4 653 if(netif->loop_first != NULL) {
mbed_official 0:51ac1d130fd4 654 LWIP_ASSERT("if first != NULL, last must also be != NULL", netif->loop_last != NULL);
mbed_official 0:51ac1d130fd4 655 netif->loop_last->next = r;
mbed_official 0:51ac1d130fd4 656 netif->loop_last = last;
mbed_official 0:51ac1d130fd4 657 } else {
mbed_official 0:51ac1d130fd4 658 netif->loop_first = r;
mbed_official 0:51ac1d130fd4 659 netif->loop_last = last;
mbed_official 0:51ac1d130fd4 660 }
mbed_official 0:51ac1d130fd4 661 SYS_ARCH_UNPROTECT(lev);
mbed_official 0:51ac1d130fd4 662
mbed_official 0:51ac1d130fd4 663 LINK_STATS_INC(link.xmit);
mbed_official 0:51ac1d130fd4 664 snmp_add_ifoutoctets(stats_if, p->tot_len);
mbed_official 0:51ac1d130fd4 665 snmp_inc_ifoutucastpkts(stats_if);
mbed_official 0:51ac1d130fd4 666
mbed_official 0:51ac1d130fd4 667 #if LWIP_NETIF_LOOPBACK_MULTITHREADING
mbed_official 0:51ac1d130fd4 668 /* For multithreading environment, schedule a call to netif_poll */
mbed_official 0:51ac1d130fd4 669 tcpip_callback((tcpip_callback_fn)netif_poll, netif);
mbed_official 0:51ac1d130fd4 670 #endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
mbed_official 0:51ac1d130fd4 671
mbed_official 0:51ac1d130fd4 672 return ERR_OK;
mbed_official 0:51ac1d130fd4 673 }
mbed_official 0:51ac1d130fd4 674
mbed_official 0:51ac1d130fd4 675 /**
mbed_official 0:51ac1d130fd4 676 * Call netif_poll() in the main loop of your application. This is to prevent
mbed_official 0:51ac1d130fd4 677 * reentering non-reentrant functions like tcp_input(). Packets passed to
mbed_official 0:51ac1d130fd4 678 * netif_loop_output() are put on a list that is passed to netif->input() by
mbed_official 0:51ac1d130fd4 679 * netif_poll().
mbed_official 0:51ac1d130fd4 680 */
mbed_official 0:51ac1d130fd4 681 void
mbed_official 0:51ac1d130fd4 682 netif_poll(struct netif *netif)
mbed_official 0:51ac1d130fd4 683 {
mbed_official 0:51ac1d130fd4 684 struct pbuf *in;
mbed_official 0:51ac1d130fd4 685 /* If we have a loopif, SNMP counters are adjusted for it,
mbed_official 0:51ac1d130fd4 686 * if not they are adjusted for 'netif'. */
mbed_official 0:51ac1d130fd4 687 #if LWIP_SNMP
mbed_official 0:51ac1d130fd4 688 #if LWIP_HAVE_LOOPIF
mbed_official 0:51ac1d130fd4 689 struct netif *stats_if = &loop_netif;
mbed_official 0:51ac1d130fd4 690 #else /* LWIP_HAVE_LOOPIF */
mbed_official 0:51ac1d130fd4 691 struct netif *stats_if = netif;
mbed_official 0:51ac1d130fd4 692 #endif /* LWIP_HAVE_LOOPIF */
mbed_official 0:51ac1d130fd4 693 #endif /* LWIP_SNMP */
mbed_official 0:51ac1d130fd4 694 SYS_ARCH_DECL_PROTECT(lev);
mbed_official 0:51ac1d130fd4 695
mbed_official 0:51ac1d130fd4 696 do {
mbed_official 0:51ac1d130fd4 697 /* Get a packet from the list. With SYS_LIGHTWEIGHT_PROT=1, this is protected */
mbed_official 0:51ac1d130fd4 698 SYS_ARCH_PROTECT(lev);
mbed_official 0:51ac1d130fd4 699 in = netif->loop_first;
mbed_official 0:51ac1d130fd4 700 if (in != NULL) {
mbed_official 0:51ac1d130fd4 701 struct pbuf *in_end = in;
mbed_official 0:51ac1d130fd4 702 #if LWIP_LOOPBACK_MAX_PBUFS
mbed_official 0:51ac1d130fd4 703 u8_t clen = pbuf_clen(in);
mbed_official 0:51ac1d130fd4 704 /* adjust the number of pbufs on queue */
mbed_official 0:51ac1d130fd4 705 LWIP_ASSERT("netif->loop_cnt_current underflow",
mbed_official 0:51ac1d130fd4 706 ((netif->loop_cnt_current - clen) < netif->loop_cnt_current));
mbed_official 0:51ac1d130fd4 707 netif->loop_cnt_current -= clen;
mbed_official 0:51ac1d130fd4 708 #endif /* LWIP_LOOPBACK_MAX_PBUFS */
mbed_official 0:51ac1d130fd4 709 while (in_end->len != in_end->tot_len) {
mbed_official 0:51ac1d130fd4 710 LWIP_ASSERT("bogus pbuf: len != tot_len but next == NULL!", in_end->next != NULL);
mbed_official 0:51ac1d130fd4 711 in_end = in_end->next;
mbed_official 0:51ac1d130fd4 712 }
mbed_official 0:51ac1d130fd4 713 /* 'in_end' now points to the last pbuf from 'in' */
mbed_official 0:51ac1d130fd4 714 if (in_end == netif->loop_last) {
mbed_official 0:51ac1d130fd4 715 /* this was the last pbuf in the list */
mbed_official 0:51ac1d130fd4 716 netif->loop_first = netif->loop_last = NULL;
mbed_official 0:51ac1d130fd4 717 } else {
mbed_official 0:51ac1d130fd4 718 /* pop the pbuf off the list */
mbed_official 0:51ac1d130fd4 719 netif->loop_first = in_end->next;
mbed_official 0:51ac1d130fd4 720 LWIP_ASSERT("should not be null since first != last!", netif->loop_first != NULL);
mbed_official 0:51ac1d130fd4 721 }
mbed_official 0:51ac1d130fd4 722 /* De-queue the pbuf from its successors on the 'loop_' list. */
mbed_official 0:51ac1d130fd4 723 in_end->next = NULL;
mbed_official 0:51ac1d130fd4 724 }
mbed_official 0:51ac1d130fd4 725 SYS_ARCH_UNPROTECT(lev);
mbed_official 0:51ac1d130fd4 726
mbed_official 0:51ac1d130fd4 727 if (in != NULL) {
mbed_official 0:51ac1d130fd4 728 LINK_STATS_INC(link.recv);
mbed_official 0:51ac1d130fd4 729 snmp_add_ifinoctets(stats_if, in->tot_len);
mbed_official 0:51ac1d130fd4 730 snmp_inc_ifinucastpkts(stats_if);
mbed_official 0:51ac1d130fd4 731 /* loopback packets are always IP packets! */
mbed_official 0:51ac1d130fd4 732 if (ip_input(in, netif) != ERR_OK) {
mbed_official 0:51ac1d130fd4 733 pbuf_free(in);
mbed_official 0:51ac1d130fd4 734 }
mbed_official 0:51ac1d130fd4 735 /* Don't reference the packet any more! */
mbed_official 0:51ac1d130fd4 736 in = NULL;
mbed_official 0:51ac1d130fd4 737 }
mbed_official 0:51ac1d130fd4 738 /* go on while there is a packet on the list */
mbed_official 0:51ac1d130fd4 739 } while (netif->loop_first != NULL);
mbed_official 0:51ac1d130fd4 740 }
mbed_official 0:51ac1d130fd4 741
mbed_official 0:51ac1d130fd4 742 #if !LWIP_NETIF_LOOPBACK_MULTITHREADING
mbed_official 0:51ac1d130fd4 743 /**
mbed_official 0:51ac1d130fd4 744 * Calls netif_poll() for every netif on the netif_list.
mbed_official 0:51ac1d130fd4 745 */
mbed_official 0:51ac1d130fd4 746 void
mbed_official 0:51ac1d130fd4 747 netif_poll_all(void)
mbed_official 0:51ac1d130fd4 748 {
mbed_official 0:51ac1d130fd4 749 struct netif *netif = netif_list;
mbed_official 0:51ac1d130fd4 750 /* loop through netifs */
mbed_official 0:51ac1d130fd4 751 while (netif != NULL) {
mbed_official 0:51ac1d130fd4 752 netif_poll(netif);
mbed_official 0:51ac1d130fd4 753 /* proceed to next network interface */
mbed_official 0:51ac1d130fd4 754 netif = netif->next;
mbed_official 0:51ac1d130fd4 755 }
mbed_official 0:51ac1d130fd4 756 }
mbed_official 0:51ac1d130fd4 757 #endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */
mbed_official 0:51ac1d130fd4 758 #endif /* ENABLE_LOOPBACK */