My fork of the HTTPServer (working)

Dependents:   DGWWebServer LAN2

Committer:
screamer
Date:
Mon Aug 06 09:23:14 2012 +0000
Revision:
0:7a64fbb4069d
[mbed] converted /DGWWebServer/HTTPServer

Who changed what in which revision?

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