Used in Live Traffic Update Nokia LCD Display Project

Fork of NetServices by Segundo Equipo

Committer:
rrajan8
Date:
Wed Mar 06 19:07:23 2013 +0000
Revision:
8:92b57208ab99
Parent:
0:ac1725ba162c
This project utilizes mbed's networking features to display live traffic updates on the Nokia LCD using the MapQuest API's Traffic Web Service.

Who changed what in which revision?

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