1 /** 2 * @file 3 * lwIP network interface abstraction 4 * 5 * @defgroup netif Network interface (NETIF) 6 * @ingroup callbackstyle_api 7 * 8 * @defgroup netif_ip4 IPv4 address handling 9 * @ingroup netif 10 * 11 * @defgroup netif_ip6 IPv6 address handling 12 * @ingroup netif 13 * 14 * @defgroup netif_cd Client data handling 15 * Store data (void*) on a netif for application usage. 16 * @see @ref LWIP_NUM_NETIF_CLIENT_DATA 17 * @ingroup netif 18 */ 19 20 /* 21 * Copyright (c) 2001-2004 Swedish Institute of Computer Science. 22 * All rights reserved. 23 * 24 * Redistribution and use in source and binary forms, with or without modification, 25 * are permitted provided that the following conditions are met: 26 * 27 * 1. Redistributions of source code must retain the above copyright notice, 28 * this list of conditions and the following disclaimer. 29 * 2. Redistributions in binary form must reproduce the above copyright notice, 30 * this list of conditions and the following disclaimer in the documentation 31 * and/or other materials provided with the distribution. 32 * 3. The name of the author may not be used to endorse or promote products 33 * derived from this software without specific prior written permission. 34 * 35 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 36 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 37 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 38 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 39 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 40 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 41 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 42 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 43 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 44 * OF SUCH DAMAGE. 45 * 46 * This file is part of the lwIP TCP/IP stack. 47 * 48 * Author: Adam Dunkels <adam@sics.se> 49 */ 50 51 #include "lwip/opt.h" 52 53 #include <string.h> /* memset */ 54 #include <stdlib.h> /* atoi */ 55 56 #include "lwip/def.h" 57 #include "lwip/ip_addr.h" 58 #include "lwip/ip6_addr.h" 59 #include "lwip/netif.h" 60 #include "lwip/priv/tcp_priv.h" 61 #include "lwip/udp.h" 62 #include "lwip/raw.h" 63 #include "lwip/snmp.h" 64 #include "lwip/igmp.h" 65 #include "lwip/etharp.h" 66 #include "lwip/stats.h" 67 #include "lwip/sys.h" 68 #include "lwip/ip.h" 69 #if ENABLE_LOOPBACK 70 #if LWIP_NETIF_LOOPBACK_MULTITHREADING 71 #include "lwip/tcpip.h" 72 #endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */ 73 #endif /* ENABLE_LOOPBACK */ 74 75 #include "netif/ethernet.h" 76 77 #if LWIP_AUTOIP 78 #include "lwip/autoip.h" 79 #endif /* LWIP_AUTOIP */ 80 #if LWIP_DHCP 81 #include "lwip/dhcp.h" 82 #endif /* LWIP_DHCP */ 83 #if LWIP_IPV6_DHCP6 84 #include "lwip/dhcp6.h" 85 #endif /* LWIP_IPV6_DHCP6 */ 86 #if LWIP_IPV6_MLD 87 #include "lwip/mld6.h" 88 #endif /* LWIP_IPV6_MLD */ 89 #if LWIP_IPV6 90 #include "lwip/nd6.h" 91 #endif 92 93 #if LWIP_NETIF_STATUS_CALLBACK 94 #define NETIF_STATUS_CALLBACK(n) do{ if (n->status_callback) { (n->status_callback)(n); }}while(0) 95 #else 96 #define NETIF_STATUS_CALLBACK(n) 97 #endif /* LWIP_NETIF_STATUS_CALLBACK */ 98 99 #if LWIP_NETIF_LINK_CALLBACK 100 #define NETIF_LINK_CALLBACK(n) do{ if (n->link_callback) { (n->link_callback)(n); }}while(0) 101 #else 102 #define NETIF_LINK_CALLBACK(n) 103 #endif /* LWIP_NETIF_LINK_CALLBACK */ 104 105 #if LWIP_NETIF_EXT_STATUS_CALLBACK 106 static netif_ext_callback_t* ext_callback; 107 #endif 108 109 #if !LWIP_SINGLE_NETIF 110 struct netif *netif_list; 111 #endif /* !LWIP_SINGLE_NETIF */ 112 struct netif *netif_default; 113 114 #define netif_index_to_num(index) ((index) - 1) 115 static u8_t netif_num; 116 117 #if LWIP_NUM_NETIF_CLIENT_DATA > 0 118 static u8_t netif_client_id; 119 #endif 120 121 #define NETIF_REPORT_TYPE_IPV4 0x01 122 #define NETIF_REPORT_TYPE_IPV6 0x02 123 static void netif_issue_reports(struct netif* netif, u8_t report_type); 124 125 #if LWIP_IPV6 126 static err_t netif_null_output_ip6(struct netif *netif, struct pbuf *p, const ip6_addr_t *ipaddr); 127 #endif /* LWIP_IPV6 */ 128 129 #if LWIP_HAVE_LOOPIF 130 #if LWIP_IPV4 131 static err_t netif_loop_output_ipv4(struct netif *netif, struct pbuf *p, const ip4_addr_t* addr); 132 #endif 133 #if LWIP_IPV6 134 static err_t netif_loop_output_ipv6(struct netif *netif, struct pbuf *p, const ip6_addr_t* addr); 135 #endif 136 137 138 static struct netif loop_netif; 139 140 /** 141 * Initialize a lwip network interface structure for a loopback interface 142 * 143 * @param netif the lwip network interface structure for this loopif 144 * @return ERR_OK if the loopif is initialized 145 * ERR_MEM if private data couldn't be allocated 146 */ 147 static err_t 148 netif_loopif_init(struct netif *netif) 149 { 150 /* initialize the snmp variables and counters inside the struct netif 151 * ifSpeed: no assumption can be made! 152 */ 153 MIB2_INIT_NETIF(netif, snmp_ifType_softwareLoopback, 0); 154 155 netif->name[0] = 'l'; 156 netif->name[1] = 'o'; 157 #if LWIP_IPV4 158 netif->output = netif_loop_output_ipv4; 159 #endif 160 #if LWIP_IPV6 161 netif->output_ip6 = netif_loop_output_ipv6; 162 #endif 163 #if LWIP_LOOPIF_MULTICAST 164 netif->flags |= NETIF_FLAG_IGMP; 165 #endif 166 return ERR_OK; 167 } 168 #endif /* LWIP_HAVE_LOOPIF */ 169 170 void 171 netif_init(void) 172 { 173 #if LWIP_HAVE_LOOPIF 174 #if LWIP_IPV4 175 #define LOOPIF_ADDRINIT &loop_ipaddr, &loop_netmask, &loop_gw, 176 ip4_addr_t loop_ipaddr, loop_netmask, loop_gw; 177 IP4_ADDR(&loop_gw, 127,0,0,1); 178 IP4_ADDR(&loop_ipaddr, 127,0,0,1); 179 IP4_ADDR(&loop_netmask, 255,0,0,0); 180 #else /* LWIP_IPV4 */ 181 #define LOOPIF_ADDRINIT 182 #endif /* LWIP_IPV4 */ 183 184 #if NO_SYS 185 netif_add(&loop_netif, LOOPIF_ADDRINIT NULL, netif_loopif_init, ip_input); 186 #else /* NO_SYS */ 187 netif_add(&loop_netif, LOOPIF_ADDRINIT NULL, netif_loopif_init, tcpip_input); 188 #endif /* NO_SYS */ 189 190 #if LWIP_IPV6 191 IP_ADDR6_HOST(loop_netif.ip6_addr, 0, 0, 0, 0x00000001UL); 192 loop_netif.ip6_addr_state[0] = IP6_ADDR_VALID; 193 #endif /* LWIP_IPV6 */ 194 195 netif_set_link_up(&loop_netif); 196 netif_set_up(&loop_netif); 197 198 #endif /* LWIP_HAVE_LOOPIF */ 199 } 200 201 /** 202 * @ingroup lwip_nosys 203 * Forwards a received packet for input processing with 204 * ethernet_input() or ip_input() depending on netif flags. 205 * Don't call directly, pass to netif_add() and call 206 * netif->input(). 207 * Only works if the netif driver correctly sets 208 * NETIF_FLAG_ETHARP and/or NETIF_FLAG_ETHERNET flag! 209 */ 210 err_t 211 netif_input(struct pbuf *p, struct netif *inp) 212 { 213 #if LWIP_ETHERNET 214 if (inp->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) { 215 return ethernet_input(p, inp); 216 } else 217 #endif /* LWIP_ETHERNET */ 218 return ip_input(p, inp); 219 } 220 221 /** 222 * @ingroup netif 223 * Add a network interface to the list of lwIP netifs. 224 * 225 * @param netif a pre-allocated netif structure 226 * @param ipaddr IP address for the new netif 227 * @param netmask network mask for the new netif 228 * @param gw default gateway IP address for the new netif 229 * @param state opaque data passed to the new netif 230 * @param init callback function that initializes the interface 231 * @param input callback function that is called to pass 232 * ingress packets up in the protocol layer stack.\n 233 * It is recommended to use a function that passes the input directly 234 * to the stack (netif_input(), NO_SYS=1 mode) or via sending a 235 * message to TCPIP thread (tcpip_input(), NO_SYS=0 mode).\n 236 * These functions use netif flags NETIF_FLAG_ETHARP and NETIF_FLAG_ETHERNET 237 * to decide whether to forward to ethernet_input() or ip_input(). 238 * In other words, the functions only work when the netif 239 * driver is implemented correctly!\n 240 * Most members of struct netif should be be initialized by the 241 * netif init function = netif driver (init parameter of this function).\n 242 * IPv6: Don't forget to call netif_create_ip6_linklocal_address() after 243 * setting the MAC address in struct netif.hwaddr 244 * (IPv6 requires a link-local address). 245 * 246 * @return netif, or NULL if failed. 247 */ 248 struct netif * 249 netif_add(struct netif *netif, 250 #if LWIP_IPV4 251 const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw, 252 #endif /* LWIP_IPV4 */ 253 void *state, netif_init_fn init, netif_input_fn input) 254 { 255 #if LWIP_IPV6 256 s8_t i; 257 #endif 258 259 #if LWIP_SINGLE_NETIF 260 if (netif_default != NULL) { 261 LWIP_ASSERT("single netif already set", 0); 262 return NULL; 263 } 264 #endif 265 266 LWIP_ASSERT("No init function given", init != NULL); 267 268 /* reset new interface configuration state */ 269 #if LWIP_IPV4 270 ip_addr_set_zero_ip4(&netif->ip_addr); 271 ip_addr_set_zero_ip4(&netif->netmask); 272 ip_addr_set_zero_ip4(&netif->gw); 273 #endif /* LWIP_IPV4 */ 274 #if LWIP_IPV6 275 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { 276 ip_addr_set_zero_ip6(&netif->ip6_addr[i]); 277 netif->ip6_addr_state[i] = IP6_ADDR_INVALID; 278 #if LWIP_IPV6_ADDRESS_LIFETIMES 279 netif->ip6_addr_valid_life[i] = IP6_ADDR_LIFE_STATIC; 280 netif->ip6_addr_pref_life[i] = IP6_ADDR_LIFE_STATIC; 281 #endif /* LWIP_IPV6_ADDRESS_LIFETIMES */ 282 } 283 netif->output_ip6 = netif_null_output_ip6; 284 #endif /* LWIP_IPV6 */ 285 NETIF_SET_CHECKSUM_CTRL(netif, NETIF_CHECKSUM_ENABLE_ALL); 286 netif->flags = 0; 287 #ifdef netif_get_client_data 288 memset(netif->client_data, 0, sizeof(netif->client_data)); 289 #endif /* LWIP_NUM_NETIF_CLIENT_DATA */ 290 #if LWIP_IPV6_AUTOCONFIG 291 /* IPv6 address autoconfiguration not enabled by default */ 292 netif->ip6_autoconfig_enabled = 0; 293 #endif /* LWIP_IPV6_AUTOCONFIG */ 294 #if LWIP_IPV6_SEND_ROUTER_SOLICIT 295 netif->rs_count = LWIP_ND6_MAX_MULTICAST_SOLICIT; 296 #endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ 297 #if LWIP_NETIF_STATUS_CALLBACK 298 netif->status_callback = NULL; 299 #endif /* LWIP_NETIF_STATUS_CALLBACK */ 300 #if LWIP_NETIF_LINK_CALLBACK 301 netif->link_callback = NULL; 302 #endif /* LWIP_NETIF_LINK_CALLBACK */ 303 #if LWIP_IGMP 304 netif->igmp_mac_filter = NULL; 305 #endif /* LWIP_IGMP */ 306 #if LWIP_IPV6 && LWIP_IPV6_MLD 307 netif->mld_mac_filter = NULL; 308 #endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ 309 #if ENABLE_LOOPBACK 310 netif->loop_first = NULL; 311 netif->loop_last = NULL; 312 #endif /* ENABLE_LOOPBACK */ 313 314 /* remember netif specific state information data */ 315 netif->state = state; 316 netif->num = netif_num; 317 netif->input = input; 318 319 NETIF_SET_HWADDRHINT(netif, NULL); 320 #if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS 321 netif->loop_cnt_current = 0; 322 #endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */ 323 324 #if LWIP_IPV4 325 netif_set_addr(netif, ipaddr, netmask, gw); 326 #endif /* LWIP_IPV4 */ 327 328 /* call user specified initialization function for netif */ 329 if (init(netif) != ERR_OK) { 330 return NULL; 331 } 332 333 #if !LWIP_SINGLE_NETIF 334 /* Assign a unique netif number in the range [0..254], so that (num+1) can 335 serve as an interface index that fits in a u8_t. 336 We assume that the new netif has not yet been added to the list here. 337 This algorithm is O(n^2), but that should be OK for lwIP. 338 */ 339 { 340 struct netif *netif2; 341 int num_netifs; 342 do { 343 if (netif->num == 255) { 344 netif->num = 0; 345 } 346 num_netifs = 0; 347 for (netif2 = netif_list; netif2 != NULL; netif2 = netif2->next) { 348 num_netifs++; 349 LWIP_ASSERT("too many netifs, max. supported number is 255", num_netifs <= 255); 350 if (netif2->num == netif->num) { 351 netif->num++; 352 break; 353 } 354 } 355 } while (netif2 != NULL); 356 } 357 netif_num = netif->num + 1; 358 359 /* add this netif to the list */ 360 netif->next = netif_list; 361 netif_list = netif; 362 #endif /* "LWIP_SINGLE_NETIF */ 363 mib2_netif_added(netif); 364 365 #if LWIP_IGMP 366 /* start IGMP processing */ 367 if (netif->flags & NETIF_FLAG_IGMP) { 368 igmp_start(netif); 369 } 370 #endif /* LWIP_IGMP */ 371 372 LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP", 373 netif->name[0], netif->name[1])); 374 #if LWIP_IPV4 375 LWIP_DEBUGF(NETIF_DEBUG, (" addr ")); 376 ip4_addr_debug_print(NETIF_DEBUG, ipaddr); 377 LWIP_DEBUGF(NETIF_DEBUG, (" netmask ")); 378 ip4_addr_debug_print(NETIF_DEBUG, netmask); 379 LWIP_DEBUGF(NETIF_DEBUG, (" gw ")); 380 ip4_addr_debug_print(NETIF_DEBUG, gw); 381 #endif /* LWIP_IPV4 */ 382 LWIP_DEBUGF(NETIF_DEBUG, ("\n")); 383 384 netif_invoke_ext_callback(netif, LWIP_NSC_NETIF_ADDED, NULL); 385 386 return netif; 387 } 388 389 #if LWIP_IPV4 390 /** 391 * @ingroup netif_ip4 392 * Change IP address configuration for a network interface (including netmask 393 * and default gateway). 394 * 395 * @param netif the network interface to change 396 * @param ipaddr the new IP address 397 * @param netmask the new netmask 398 * @param gw the new default gateway 399 */ 400 void 401 netif_set_addr(struct netif *netif, const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, 402 const ip4_addr_t *gw) 403 { 404 if (ip4_addr_isany(ipaddr)) { 405 /* when removing an address, we have to remove it *before* changing netmask/gw 406 to ensure that tcp RST segment can be sent correctly */ 407 netif_set_ipaddr(netif, ipaddr); 408 netif_set_netmask(netif, netmask); 409 netif_set_gw(netif, gw); 410 } else { 411 netif_set_netmask(netif, netmask); 412 netif_set_gw(netif, gw); 413 /* set ipaddr last to ensure netmask/gw have been set when status callback is called */ 414 netif_set_ipaddr(netif, ipaddr); 415 } 416 417 netif_invoke_ext_callback(netif, LWIP_NSC_IPV4_SETTINGS_CHANGED, NULL); 418 } 419 #endif /* LWIP_IPV4*/ 420 421 /** 422 * @ingroup netif 423 * Remove a network interface from the list of lwIP netifs. 424 * 425 * @param netif the network interface to remove 426 */ 427 void 428 netif_remove(struct netif *netif) 429 { 430 #if LWIP_IPV6 431 int i; 432 #endif 433 434 if (netif == NULL) { 435 return; 436 } 437 438 netif_invoke_ext_callback(netif, LWIP_NSC_NETIF_REMOVED, NULL); 439 440 #if LWIP_IPV4 441 if (!ip4_addr_isany_val(*netif_ip4_addr(netif))) { 442 #if LWIP_TCP 443 tcp_netif_ip_addr_changed(netif_ip_addr4(netif), NULL); 444 #endif /* LWIP_TCP */ 445 #if LWIP_UDP 446 udp_netif_ip_addr_changed(netif_ip_addr4(netif), NULL); 447 #endif /* LWIP_UDP */ 448 #if LWIP_RAW 449 raw_netif_ip_addr_changed(netif_ip_addr4(netif), NULL); 450 #endif /* LWIP_RAW */ 451 } 452 453 #if LWIP_IGMP 454 /* stop IGMP processing */ 455 if (netif->flags & NETIF_FLAG_IGMP) { 456 igmp_stop(netif); 457 } 458 #endif /* LWIP_IGMP */ 459 #endif /* LWIP_IPV4*/ 460 461 #if LWIP_IPV6 462 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { 463 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i))) { 464 #if LWIP_TCP 465 tcp_netif_ip_addr_changed(netif_ip_addr6(netif, i), NULL); 466 #endif /* LWIP_TCP */ 467 #if LWIP_UDP 468 udp_netif_ip_addr_changed(netif_ip_addr6(netif, i), NULL); 469 #endif /* LWIP_UDP */ 470 #if LWIP_RAW 471 raw_netif_ip_addr_changed(netif_ip_addr6(netif, i), NULL); 472 #endif /* LWIP_RAW */ 473 } 474 } 475 #if LWIP_IPV6_MLD 476 /* stop MLD processing */ 477 mld6_stop(netif); 478 #endif /* LWIP_IPV6_MLD */ 479 #endif /* LWIP_IPV6 */ 480 if (netif_is_up(netif)) { 481 /* set netif down before removing (call callback function) */ 482 netif_set_down(netif); 483 } 484 485 mib2_remove_ip4(netif); 486 487 /* this netif is default? */ 488 if (netif_default == netif) { 489 /* reset default netif */ 490 netif_set_default(NULL); 491 } 492 #if !LWIP_SINGLE_NETIF 493 /* is it the first netif? */ 494 if (netif_list == netif) { 495 netif_list = netif->next; 496 } else { 497 /* look for netif further down the list */ 498 struct netif * tmp_netif; 499 for (tmp_netif = netif_list; tmp_netif != NULL; tmp_netif = tmp_netif->next) { 500 if (tmp_netif->next == netif) { 501 tmp_netif->next = netif->next; 502 break; 503 } 504 } 505 if (tmp_netif == NULL) { 506 return; /* netif is not on the list */ 507 } 508 } 509 #endif /* !LWIP_SINGLE_NETIF */ 510 mib2_netif_removed(netif); 511 #if LWIP_NETIF_REMOVE_CALLBACK 512 if (netif->remove_callback) { 513 netif->remove_callback(netif); 514 } 515 #endif /* LWIP_NETIF_REMOVE_CALLBACK */ 516 LWIP_DEBUGF( NETIF_DEBUG, ("netif_remove: removed netif\n") ); 517 } 518 519 #if LWIP_IPV4 520 /** 521 * @ingroup netif_ip4 522 * Change the IP address of a network interface 523 * 524 * @param netif the network interface to change 525 * @param ipaddr the new IP address 526 * 527 * @note call netif_set_addr() if you also want to change netmask and 528 * default gateway 529 */ 530 void 531 netif_set_ipaddr(struct netif *netif, const ip4_addr_t *ipaddr) 532 { 533 ip_addr_t new_addr; 534 *ip_2_ip4(&new_addr) = (ipaddr ? *ipaddr : *IP4_ADDR_ANY4); 535 IP_SET_TYPE_VAL(new_addr, IPADDR_TYPE_V4); 536 537 /* address is actually being changed? */ 538 if (ip4_addr_cmp(ip_2_ip4(&new_addr), netif_ip4_addr(netif)) == 0) { 539 ip_addr_t old_addr; 540 ip_addr_copy(old_addr, *netif_ip_addr4(netif)); 541 542 LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: netif address being changed\n")); 543 #if LWIP_TCP 544 tcp_netif_ip_addr_changed(&old_addr, &new_addr); 545 #endif /* LWIP_TCP */ 546 #if LWIP_UDP 547 udp_netif_ip_addr_changed(&old_addr, &new_addr); 548 #endif /* LWIP_UDP */ 549 #if LWIP_RAW 550 raw_netif_ip_addr_changed(&old_addr, &new_addr); 551 #endif /* LWIP_RAW */ 552 553 mib2_remove_ip4(netif); 554 mib2_remove_route_ip4(0, netif); 555 /* set new IP address to netif */ 556 ip4_addr_set(ip_2_ip4(&netif->ip_addr), ipaddr); 557 IP_SET_TYPE_VAL(netif->ip_addr, IPADDR_TYPE_V4); 558 mib2_add_ip4(netif); 559 mib2_add_route_ip4(0, netif); 560 561 netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4); 562 563 NETIF_STATUS_CALLBACK(netif); 564 #if LWIP_NETIF_EXT_STATUS_CALLBACK 565 { 566 netif_ext_callback_args_t args; 567 args.ipv4_changed.old_address = &old_addr; 568 netif_invoke_ext_callback(netif, LWIP_NSC_IPV4_ADDRESS_CHANGED, &args); 569 } 570 #endif 571 } 572 573 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", 574 netif->name[0], netif->name[1], 575 ip4_addr1_16(netif_ip4_addr(netif)), 576 ip4_addr2_16(netif_ip4_addr(netif)), 577 ip4_addr3_16(netif_ip4_addr(netif)), 578 ip4_addr4_16(netif_ip4_addr(netif)))); 579 } 580 581 /** 582 * @ingroup netif_ip4 583 * Change the default gateway for a network interface 584 * 585 * @param netif the network interface to change 586 * @param gw the new default gateway 587 * 588 * @note call netif_set_addr() if you also want to change ip address and netmask 589 */ 590 void 591 netif_set_gw(struct netif *netif, const ip4_addr_t *gw) 592 { 593 #if LWIP_NETIF_EXT_STATUS_CALLBACK 594 netif_ext_callback_args_t args; 595 ip_addr_t old_addr; 596 ip_addr_copy(old_addr, *netif_ip_gw4(netif)); 597 args.ipv4_gw_changed.old_address = &old_addr; 598 #endif 599 600 ip4_addr_set(ip_2_ip4(&netif->gw), gw); 601 IP_SET_TYPE_VAL(netif->gw, IPADDR_TYPE_V4); 602 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", 603 netif->name[0], netif->name[1], 604 ip4_addr1_16(netif_ip4_gw(netif)), 605 ip4_addr2_16(netif_ip4_gw(netif)), 606 ip4_addr3_16(netif_ip4_gw(netif)), 607 ip4_addr4_16(netif_ip4_gw(netif)))); 608 609 netif_invoke_ext_callback(netif, LWIP_NSC_IPV4_GATEWAY_CHANGED, &args); 610 } 611 612 /** 613 * @ingroup netif_ip4 614 * Change the netmask of a network interface 615 * 616 * @param netif the network interface to change 617 * @param netmask the new netmask 618 * 619 * @note call netif_set_addr() if you also want to change ip address and 620 * default gateway 621 */ 622 void 623 netif_set_netmask(struct netif *netif, const ip4_addr_t *netmask) 624 { 625 #if LWIP_NETIF_EXT_STATUS_CALLBACK 626 netif_ext_callback_args_t args; 627 ip_addr_t old_addr; 628 ip_addr_copy(old_addr, *netif_ip_netmask4(netif)); 629 args.ipv4_nm_changed.old_address = &old_addr; 630 #endif 631 632 mib2_remove_route_ip4(0, netif); 633 /* set new netmask to netif */ 634 ip4_addr_set(ip_2_ip4(&netif->netmask), netmask); 635 IP_SET_TYPE_VAL(netif->netmask, IPADDR_TYPE_V4); 636 mib2_add_route_ip4(0, netif); 637 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", 638 netif->name[0], netif->name[1], 639 ip4_addr1_16(netif_ip4_netmask(netif)), 640 ip4_addr2_16(netif_ip4_netmask(netif)), 641 ip4_addr3_16(netif_ip4_netmask(netif)), 642 ip4_addr4_16(netif_ip4_netmask(netif)))); 643 644 netif_invoke_ext_callback(netif, LWIP_NSC_IPV4_NETMASK_CHANGED, &args); 645 } 646 #endif /* LWIP_IPV4 */ 647 648 /** 649 * @ingroup netif 650 * Set a network interface as the default network interface 651 * (used to output all packets for which no specific route is found) 652 * 653 * @param netif the default network interface 654 */ 655 void 656 netif_set_default(struct netif *netif) 657 { 658 if (netif == NULL) { 659 /* remove default route */ 660 mib2_remove_route_ip4(1, netif); 661 } else { 662 /* install default route */ 663 mib2_add_route_ip4(1, netif); 664 } 665 netif_default = netif; 666 LWIP_DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%c\n", 667 netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\'')); 668 } 669 670 /** 671 * @ingroup netif 672 * Bring an interface up, available for processing 673 * traffic. 674 */ 675 void 676 netif_set_up(struct netif *netif) 677 { 678 if (!(netif->flags & NETIF_FLAG_UP)) { 679 netif->flags |= NETIF_FLAG_UP; 680 681 MIB2_COPY_SYSUPTIME_TO(&netif->ts); 682 683 NETIF_STATUS_CALLBACK(netif); 684 685 #if LWIP_NETIF_EXT_STATUS_CALLBACK 686 { 687 netif_ext_callback_args_t args; 688 args.status_changed.state = 1; 689 netif_invoke_ext_callback(netif, LWIP_NSC_STATUS_CHANGED, &args); 690 } 691 #endif 692 693 if (netif->flags & NETIF_FLAG_LINK_UP) { 694 netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4|NETIF_REPORT_TYPE_IPV6); 695 } 696 } 697 } 698 699 /** Send ARP/IGMP/MLD/RS events, e.g. on link-up/netif-up or addr-change 700 */ 701 static void 702 netif_issue_reports(struct netif* netif, u8_t report_type) 703 { 704 #if LWIP_IPV4 705 if ((report_type & NETIF_REPORT_TYPE_IPV4) && 706 !ip4_addr_isany_val(*netif_ip4_addr(netif))) { 707 #if LWIP_ARP 708 /* For Ethernet network interfaces, we would like to send a "gratuitous ARP" */ 709 if (netif->flags & (NETIF_FLAG_ETHARP)) { 710 etharp_gratuitous(netif); 711 } 712 #endif /* LWIP_ARP */ 713 714 #if LWIP_IGMP 715 /* resend IGMP memberships */ 716 if (netif->flags & NETIF_FLAG_IGMP) { 717 igmp_report_groups(netif); 718 } 719 #endif /* LWIP_IGMP */ 720 } 721 #endif /* LWIP_IPV4 */ 722 723 #if LWIP_IPV6 724 if (report_type & NETIF_REPORT_TYPE_IPV6) { 725 #if LWIP_IPV6_MLD 726 /* send mld memberships */ 727 mld6_report_groups(netif); 728 #endif /* LWIP_IPV6_MLD */ 729 #if LWIP_IPV6_SEND_ROUTER_SOLICIT 730 /* Send Router Solicitation messages. */ 731 netif->rs_count = LWIP_ND6_MAX_MULTICAST_SOLICIT; 732 #endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ 733 } 734 #endif /* LWIP_IPV6 */ 735 } 736 737 /** 738 * @ingroup netif 739 * Bring an interface down, disabling any traffic processing. 740 */ 741 void 742 netif_set_down(struct netif *netif) 743 { 744 if (netif->flags & NETIF_FLAG_UP) { 745 #if LWIP_NETIF_EXT_STATUS_CALLBACK 746 { 747 netif_ext_callback_args_t args; 748 args.status_changed.state = 0; 749 netif_invoke_ext_callback(netif, LWIP_NSC_STATUS_CHANGED, &args); 750 } 751 #endif 752 753 netif->flags &= ~NETIF_FLAG_UP; 754 MIB2_COPY_SYSUPTIME_TO(&netif->ts); 755 756 #if LWIP_IPV4 && LWIP_ARP 757 if (netif->flags & NETIF_FLAG_ETHARP) { 758 etharp_cleanup_netif(netif); 759 } 760 #endif /* LWIP_IPV4 && LWIP_ARP */ 761 762 #if LWIP_IPV6 763 nd6_cleanup_netif(netif); 764 #endif /* LWIP_IPV6 */ 765 766 NETIF_STATUS_CALLBACK(netif); 767 } 768 } 769 770 #if LWIP_NETIF_STATUS_CALLBACK 771 /** 772 * @ingroup netif 773 * Set callback to be called when interface is brought up/down or address is changed while up 774 */ 775 void 776 netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback) 777 { 778 if (netif) { 779 netif->status_callback = status_callback; 780 } 781 } 782 #endif /* LWIP_NETIF_STATUS_CALLBACK */ 783 784 #if LWIP_NETIF_REMOVE_CALLBACK 785 /** 786 * @ingroup netif 787 * Set callback to be called when the interface has been removed 788 */ 789 void 790 netif_set_remove_callback(struct netif *netif, netif_status_callback_fn remove_callback) 791 { 792 if (netif) { 793 netif->remove_callback = remove_callback; 794 } 795 } 796 #endif /* LWIP_NETIF_REMOVE_CALLBACK */ 797 798 /** 799 * @ingroup netif 800 * Called by a driver when its link goes up 801 */ 802 void 803 netif_set_link_up(struct netif *netif) 804 { 805 if (!(netif->flags & NETIF_FLAG_LINK_UP)) { 806 netif->flags |= NETIF_FLAG_LINK_UP; 807 808 #if LWIP_DHCP 809 dhcp_network_changed(netif); 810 #endif /* LWIP_DHCP */ 811 812 #if LWIP_AUTOIP 813 autoip_network_changed(netif); 814 #endif /* LWIP_AUTOIP */ 815 816 if (netif->flags & NETIF_FLAG_UP) { 817 netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4|NETIF_REPORT_TYPE_IPV6); 818 } 819 NETIF_LINK_CALLBACK(netif); 820 #if LWIP_NETIF_EXT_STATUS_CALLBACK 821 { 822 netif_ext_callback_args_t args; 823 args.link_changed.state = 1; 824 netif_invoke_ext_callback(netif, LWIP_NSC_LINK_CHANGED, &args); 825 } 826 #endif 827 } 828 } 829 830 /** 831 * @ingroup netif 832 * Called by a driver when its link goes down 833 */ 834 void 835 netif_set_link_down(struct netif *netif ) 836 { 837 if (netif->flags & NETIF_FLAG_LINK_UP) { 838 netif->flags &= ~NETIF_FLAG_LINK_UP; 839 NETIF_LINK_CALLBACK(netif); 840 #if LWIP_NETIF_EXT_STATUS_CALLBACK 841 { 842 netif_ext_callback_args_t args; 843 args.link_changed.state = 0; 844 netif_invoke_ext_callback(netif, LWIP_NSC_LINK_CHANGED, &args); 845 } 846 #endif 847 } 848 } 849 850 #if LWIP_NETIF_LINK_CALLBACK 851 /** 852 * @ingroup netif 853 * Set callback to be called when link is brought up/down 854 */ 855 void 856 netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callback) 857 { 858 if (netif) { 859 netif->link_callback = link_callback; 860 } 861 } 862 #endif /* LWIP_NETIF_LINK_CALLBACK */ 863 864 #if ENABLE_LOOPBACK 865 /** 866 * @ingroup netif 867 * Send an IP packet to be received on the same netif (loopif-like). 868 * The pbuf is simply copied and handed back to netif->input. 869 * In multithreaded mode, this is done directly since netif->input must put 870 * the packet on a queue. 871 * In callback mode, the packet is put on an internal queue and is fed to 872 * netif->input by netif_poll(). 873 * 874 * @param netif the lwip network interface structure 875 * @param p the (IP) packet to 'send' 876 * @return ERR_OK if the packet has been sent 877 * ERR_MEM if the pbuf used to copy the packet couldn't be allocated 878 */ 879 err_t 880 netif_loop_output(struct netif *netif, struct pbuf *p) 881 { 882 struct pbuf *r; 883 err_t err; 884 struct pbuf *last; 885 #if LWIP_LOOPBACK_MAX_PBUFS 886 u16_t clen = 0; 887 #endif /* LWIP_LOOPBACK_MAX_PBUFS */ 888 /* If we have a loopif, SNMP counters are adjusted for it, 889 * if not they are adjusted for 'netif'. */ 890 #if MIB2_STATS 891 #if LWIP_HAVE_LOOPIF 892 struct netif *stats_if = &loop_netif; 893 #else /* LWIP_HAVE_LOOPIF */ 894 struct netif *stats_if = netif; 895 #endif /* LWIP_HAVE_LOOPIF */ 896 #endif /* MIB2_STATS */ 897 SYS_ARCH_DECL_PROTECT(lev); 898 899 /* Allocate a new pbuf */ 900 r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM); 901 if (r == NULL) { 902 LINK_STATS_INC(link.memerr); 903 LINK_STATS_INC(link.drop); 904 MIB2_STATS_NETIF_INC(stats_if, ifoutdiscards); 905 return ERR_MEM; 906 } 907 #if LWIP_LOOPBACK_MAX_PBUFS 908 clen = pbuf_clen(r); 909 /* check for overflow or too many pbuf on queue */ 910 if (((netif->loop_cnt_current + clen) < netif->loop_cnt_current) || 911 ((netif->loop_cnt_current + clen) > LWIP_LOOPBACK_MAX_PBUFS)) { 912 pbuf_free(r); 913 LINK_STATS_INC(link.memerr); 914 LINK_STATS_INC(link.drop); 915 MIB2_STATS_NETIF_INC(stats_if, ifoutdiscards); 916 return ERR_MEM; 917 } 918 netif->loop_cnt_current += clen; 919 #endif /* LWIP_LOOPBACK_MAX_PBUFS */ 920 921 /* Copy the whole pbuf queue p into the single pbuf r */ 922 if ((err = pbuf_copy(r, p)) != ERR_OK) { 923 pbuf_free(r); 924 LINK_STATS_INC(link.memerr); 925 LINK_STATS_INC(link.drop); 926 MIB2_STATS_NETIF_INC(stats_if, ifoutdiscards); 927 return err; 928 } 929 930 /* Put the packet on a linked list which gets emptied through calling 931 netif_poll(). */ 932 933 /* let last point to the last pbuf in chain r */ 934 for (last = r; last->next != NULL; last = last->next); 935 936 SYS_ARCH_PROTECT(lev); 937 if (netif->loop_first != NULL) { 938 LWIP_ASSERT("if first != NULL, last must also be != NULL", netif->loop_last != NULL); 939 netif->loop_last->next = r; 940 netif->loop_last = last; 941 } else { 942 netif->loop_first = r; 943 netif->loop_last = last; 944 } 945 SYS_ARCH_UNPROTECT(lev); 946 947 LINK_STATS_INC(link.xmit); 948 MIB2_STATS_NETIF_ADD(stats_if, ifoutoctets, p->tot_len); 949 MIB2_STATS_NETIF_INC(stats_if, ifoutucastpkts); 950 951 #if LWIP_NETIF_LOOPBACK_MULTITHREADING 952 /* For multithreading environment, schedule a call to netif_poll */ 953 tcpip_callback_with_block((tcpip_callback_fn)netif_poll, netif, 0); 954 #endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */ 955 956 return ERR_OK; 957 } 958 959 #if LWIP_HAVE_LOOPIF 960 #if LWIP_IPV4 961 static err_t 962 netif_loop_output_ipv4(struct netif *netif, struct pbuf *p, const ip4_addr_t* addr) 963 { 964 LWIP_UNUSED_ARG(addr); 965 return netif_loop_output(netif, p); 966 } 967 #endif /* LWIP_IPV4 */ 968 969 #if LWIP_IPV6 970 static err_t 971 netif_loop_output_ipv6(struct netif *netif, struct pbuf *p, const ip6_addr_t* addr) 972 { 973 LWIP_UNUSED_ARG(addr); 974 return netif_loop_output(netif, p); 975 } 976 #endif /* LWIP_IPV6 */ 977 #endif /* LWIP_HAVE_LOOPIF */ 978 979 980 /** 981 * Call netif_poll() in the main loop of your application. This is to prevent 982 * reentering non-reentrant functions like tcp_input(). Packets passed to 983 * netif_loop_output() are put on a list that is passed to netif->input() by 984 * netif_poll(). 985 */ 986 void 987 netif_poll(struct netif *netif) 988 { 989 /* If we have a loopif, SNMP counters are adjusted for it, 990 * if not they are adjusted for 'netif'. */ 991 #if MIB2_STATS 992 #if LWIP_HAVE_LOOPIF 993 struct netif *stats_if = &loop_netif; 994 #else /* LWIP_HAVE_LOOPIF */ 995 struct netif *stats_if = netif; 996 #endif /* LWIP_HAVE_LOOPIF */ 997 #endif /* MIB2_STATS */ 998 SYS_ARCH_DECL_PROTECT(lev); 999 1000 /* Get a packet from the list. With SYS_LIGHTWEIGHT_PROT=1, this is protected */ 1001 SYS_ARCH_PROTECT(lev); 1002 while (netif->loop_first != NULL) { 1003 struct pbuf *in, *in_end; 1004 #if LWIP_LOOPBACK_MAX_PBUFS 1005 u8_t clen = 1; 1006 #endif /* LWIP_LOOPBACK_MAX_PBUFS */ 1007 1008 in = in_end = netif->loop_first; 1009 while (in_end->len != in_end->tot_len) { 1010 LWIP_ASSERT("bogus pbuf: len != tot_len but next == NULL!", in_end->next != NULL); 1011 in_end = in_end->next; 1012 #if LWIP_LOOPBACK_MAX_PBUFS 1013 clen++; 1014 #endif /* LWIP_LOOPBACK_MAX_PBUFS */ 1015 } 1016 #if LWIP_LOOPBACK_MAX_PBUFS 1017 /* adjust the number of pbufs on queue */ 1018 LWIP_ASSERT("netif->loop_cnt_current underflow", 1019 ((netif->loop_cnt_current - clen) < netif->loop_cnt_current)); 1020 netif->loop_cnt_current -= clen; 1021 #endif /* LWIP_LOOPBACK_MAX_PBUFS */ 1022 1023 /* 'in_end' now points to the last pbuf from 'in' */ 1024 if (in_end == netif->loop_last) { 1025 /* this was the last pbuf in the list */ 1026 netif->loop_first = netif->loop_last = NULL; 1027 } else { 1028 /* pop the pbuf off the list */ 1029 netif->loop_first = in_end->next; 1030 LWIP_ASSERT("should not be null since first != last!", netif->loop_first != NULL); 1031 } 1032 /* De-queue the pbuf from its successors on the 'loop_' list. */ 1033 in_end->next = NULL; 1034 SYS_ARCH_UNPROTECT(lev); 1035 1036 LINK_STATS_INC(link.recv); 1037 MIB2_STATS_NETIF_ADD(stats_if, ifinoctets, in->tot_len); 1038 MIB2_STATS_NETIF_INC(stats_if, ifinucastpkts); 1039 /* loopback packets are always IP packets! */ 1040 if (ip_input(in, netif) != ERR_OK) { 1041 pbuf_free(in); 1042 } 1043 SYS_ARCH_PROTECT(lev); 1044 } 1045 SYS_ARCH_UNPROTECT(lev); 1046 } 1047 1048 #if !LWIP_NETIF_LOOPBACK_MULTITHREADING 1049 /** 1050 * Calls netif_poll() for every netif on the netif_list. 1051 */ 1052 void 1053 netif_poll_all(void) 1054 { 1055 struct netif *netif; 1056 /* loop through netifs */ 1057 NETIF_FOREACH(netif) { 1058 netif_poll(netif); 1059 } 1060 } 1061 #endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ 1062 #endif /* ENABLE_LOOPBACK */ 1063 1064 #if LWIP_NUM_NETIF_CLIENT_DATA > 0 1065 /** 1066 * @ingroup netif_cd 1067 * Allocate an index to store data in client_data member of struct netif. 1068 * Returned value is an index in mentioned array. 1069 * @see LWIP_NUM_NETIF_CLIENT_DATA 1070 */ 1071 u8_t 1072 netif_alloc_client_data_id(void) 1073 { 1074 u8_t result = netif_client_id; 1075 netif_client_id++; 1076 1077 LWIP_ASSERT("Increase LWIP_NUM_NETIF_CLIENT_DATA in lwipopts.h", result < LWIP_NUM_NETIF_CLIENT_DATA); 1078 return result + LWIP_NETIF_CLIENT_DATA_INDEX_MAX; 1079 } 1080 #endif 1081 1082 #if LWIP_IPV6 1083 /** 1084 * @ingroup netif_ip6 1085 * Change an IPv6 address of a network interface 1086 * 1087 * @param netif the network interface to change 1088 * @param addr_idx index of the IPv6 address 1089 * @param addr6 the new IPv6 address 1090 * 1091 * @note call netif_ip6_addr_set_state() to set the address valid/temptative 1092 */ 1093 void 1094 netif_ip6_addr_set(struct netif *netif, s8_t addr_idx, const ip6_addr_t *addr6) 1095 { 1096 LWIP_ASSERT("addr6 != NULL", addr6 != NULL); 1097 netif_ip6_addr_set_parts(netif, addr_idx, addr6->addr[0], addr6->addr[1], 1098 addr6->addr[2], addr6->addr[3]); 1099 } 1100 1101 /* 1102 * Change an IPv6 address of a network interface (internal version taking 4 * u32_t) 1103 * 1104 * @param netif the network interface to change 1105 * @param addr_idx index of the IPv6 address 1106 * @param i0 word0 of the new IPv6 address 1107 * @param i1 word1 of the new IPv6 address 1108 * @param i2 word2 of the new IPv6 address 1109 * @param i3 word3 of the new IPv6 address 1110 */ 1111 void 1112 netif_ip6_addr_set_parts(struct netif *netif, s8_t addr_idx, u32_t i0, u32_t i1, u32_t i2, u32_t i3) 1113 { 1114 ip_addr_t old_addr; 1115 ip_addr_t new_ipaddr; 1116 LWIP_ASSERT("netif != NULL", netif != NULL); 1117 LWIP_ASSERT("invalid index", addr_idx < LWIP_IPV6_NUM_ADDRESSES); 1118 1119 ip6_addr_copy(*ip_2_ip6(&old_addr), *netif_ip6_addr(netif, addr_idx)); 1120 IP_SET_TYPE_VAL(old_addr, IPADDR_TYPE_V6); 1121 1122 /* address is actually being changed? */ 1123 if ((ip_2_ip6(&old_addr)->addr[0] != i0) || (ip_2_ip6(&old_addr)->addr[1] != i1) || 1124 (ip_2_ip6(&old_addr)->addr[2] != i2) || (ip_2_ip6(&old_addr)->addr[3] != i3)) { 1125 LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_ip6_addr_set: netif address being changed\n")); 1126 1127 IP_ADDR6(&new_ipaddr, i0, i1, i2, i3); 1128 ip6_addr_assign_zone(ip_2_ip6(&new_ipaddr), IP6_UNICAST, netif); 1129 1130 if (netif_ip6_addr_state(netif, addr_idx) & IP6_ADDR_VALID) { 1131 #if LWIP_TCP 1132 tcp_netif_ip_addr_changed(netif_ip_addr6(netif, addr_idx), &new_ipaddr); 1133 #endif /* LWIP_TCP */ 1134 #if LWIP_UDP 1135 udp_netif_ip_addr_changed(netif_ip_addr6(netif, addr_idx), &new_ipaddr); 1136 #endif /* LWIP_UDP */ 1137 #if LWIP_RAW 1138 raw_netif_ip_addr_changed(netif_ip_addr6(netif, addr_idx), &new_ipaddr); 1139 #endif /* LWIP_RAW */ 1140 } 1141 /* @todo: remove/readd mib2 ip6 entries? */ 1142 1143 ip_addr_copy(netif->ip6_addr[addr_idx], new_ipaddr); 1144 1145 if (netif_ip6_addr_state(netif, addr_idx) & IP6_ADDR_VALID) { 1146 netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV6); 1147 NETIF_STATUS_CALLBACK(netif); 1148 } 1149 1150 #if LWIP_NETIF_EXT_STATUS_CALLBACK 1151 { 1152 netif_ext_callback_args_t args; 1153 args.ipv6_set.addr_index = addr_idx; 1154 args.ipv6_set.old_address = &old_addr; 1155 netif_invoke_ext_callback(netif, LWIP_NSC_IPV6_SET, &args); 1156 } 1157 #endif 1158 } 1159 1160 LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: IPv6 address %d of interface %c%c set to %s/0x%"X8_F"\n", 1161 addr_idx, netif->name[0], netif->name[1], ip6addr_ntoa(netif_ip6_addr(netif, addr_idx)), 1162 netif_ip6_addr_state(netif, addr_idx))); 1163 } 1164 1165 /** 1166 * @ingroup netif_ip6 1167 * Change the state of an IPv6 address of a network interface 1168 * (INVALID, TEMPTATIVE, PREFERRED, DEPRECATED, where TEMPTATIVE 1169 * includes the number of checks done, see ip6_addr.h) 1170 * 1171 * @param netif the network interface to change 1172 * @param addr_idx index of the IPv6 address 1173 * @param state the new IPv6 address state 1174 */ 1175 void 1176 netif_ip6_addr_set_state(struct netif* netif, s8_t addr_idx, u8_t state) 1177 { 1178 u8_t old_state; 1179 LWIP_ASSERT("netif != NULL", netif != NULL); 1180 LWIP_ASSERT("invalid index", addr_idx < LWIP_IPV6_NUM_ADDRESSES); 1181 1182 old_state = netif_ip6_addr_state(netif, addr_idx); 1183 /* state is actually being changed? */ 1184 if (old_state != state) { 1185 u8_t old_valid = old_state & IP6_ADDR_VALID; 1186 u8_t new_valid = state & IP6_ADDR_VALID; 1187 LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_ip6_addr_set_state: netif address state being changed\n")); 1188 1189 #if LWIP_IPV6_MLD 1190 /* Reevaluate solicited-node multicast group membership. */ 1191 if (netif->flags & NETIF_FLAG_MLD6) { 1192 nd6_adjust_mld_membership(netif, addr_idx, state); 1193 } 1194 #endif /* LWIP_IPV6_MLD */ 1195 1196 if (old_valid && !new_valid) { 1197 /* address about to be removed by setting invalid */ 1198 #if LWIP_TCP 1199 tcp_netif_ip_addr_changed(netif_ip_addr6(netif, addr_idx), NULL); 1200 #endif /* LWIP_TCP */ 1201 #if LWIP_UDP 1202 udp_netif_ip_addr_changed(netif_ip_addr6(netif, addr_idx), NULL); 1203 #endif /* LWIP_UDP */ 1204 #if LWIP_RAW 1205 raw_netif_ip_addr_changed(netif_ip_addr6(netif, addr_idx), NULL); 1206 #endif /* LWIP_RAW */ 1207 /* @todo: remove mib2 ip6 entries? */ 1208 } 1209 netif->ip6_addr_state[addr_idx] = state; 1210 1211 if (!old_valid && new_valid) { 1212 /* address added by setting valid */ 1213 /* This is a good moment to check that the address is properly zoned. */ 1214 IP6_ADDR_ZONECHECK_NETIF(netif_ip6_addr(netif, addr_idx), netif); 1215 /* @todo: add mib2 ip6 entries? */ 1216 netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV6); 1217 } 1218 if ((old_state & ~IP6_ADDR_TENTATIVE_COUNT_MASK) != 1219 (state & ~IP6_ADDR_TENTATIVE_COUNT_MASK)) { 1220 /* address state has changed -> call the callback function */ 1221 NETIF_STATUS_CALLBACK(netif); 1222 } 1223 } 1224 1225 #if LWIP_NETIF_EXT_STATUS_CALLBACK 1226 { 1227 netif_ext_callback_args_t args; 1228 args.ipv6_addr_state_changed.addr_index = addr_idx; 1229 args.ipv6_addr_state_changed.address = netif_ip_addr6(netif, addr_idx); 1230 netif_invoke_ext_callback(netif, LWIP_NSC_IPV6_ADDR_STATE_CHANGED, &args); 1231 } 1232 #endif 1233 1234 LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: IPv6 address %d of interface %c%c set to %s/0x%"X8_F"\n", 1235 addr_idx, netif->name[0], netif->name[1], ip6addr_ntoa(netif_ip6_addr(netif, addr_idx)), 1236 netif_ip6_addr_state(netif, addr_idx))); 1237 } 1238 1239 /** 1240 * Checks if a specific local address is present on the netif and returns its 1241 * index. Depending on its state, it may or may not be assigned to the 1242 * interface (as per RFC terminology). 1243 * 1244 * The given address may or may not be zoned (i.e., have a zone index other 1245 * than IP6_NO_ZONE). If the address is zoned, it must have the correct zone 1246 * for the given netif, or no match will be found. 1247 * 1248 * @param netif the netif to check 1249 * @param ip6addr the IPv6 address to find 1250 * @return >= 0: address found, this is its index 1251 * -1: address not found on this netif 1252 */ 1253 s8_t 1254 netif_get_ip6_addr_match(struct netif *netif, const ip6_addr_t *ip6addr) 1255 { 1256 s8_t i; 1257 1258 #if LWIP_IPV6_SCOPES 1259 if (ip6_addr_has_zone(ip6addr) && !ip6_addr_test_zone(ip6addr, netif)) { 1260 return -1; /* wrong zone, no match */ 1261 } 1262 #endif /* LWIP_IPV6_SCOPES */ 1263 1264 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { 1265 if (!ip6_addr_isinvalid(netif_ip6_addr_state(netif, i)) && 1266 ip6_addr_cmp_zoneless(netif_ip6_addr(netif, i), ip6addr)) { 1267 return i; 1268 } 1269 } 1270 return -1; 1271 } 1272 1273 /** 1274 * @ingroup netif_ip6 1275 * Create a link-local IPv6 address on a netif (stored in slot 0) 1276 * 1277 * @param netif the netif to create the address on 1278 * @param from_mac_48bit if != 0, assume hwadr is a 48-bit MAC address (std conversion) 1279 * if == 0, use hwaddr directly as interface ID 1280 */ 1281 void 1282 netif_create_ip6_linklocal_address(struct netif *netif, u8_t from_mac_48bit) 1283 { 1284 u8_t i, addr_index; 1285 1286 /* Link-local prefix. */ 1287 ip_2_ip6(&netif->ip6_addr[0])->addr[0] = PP_HTONL(0xfe800000ul); 1288 ip_2_ip6(&netif->ip6_addr[0])->addr[1] = 0; 1289 1290 /* Generate interface ID. */ 1291 if (from_mac_48bit) { 1292 /* Assume hwaddr is a 48-bit IEEE 802 MAC. Convert to EUI-64 address. Complement Group bit. */ 1293 ip_2_ip6(&netif->ip6_addr[0])->addr[2] = lwip_htonl((((u32_t)(netif->hwaddr[0] ^ 0x02)) << 24) | 1294 ((u32_t)(netif->hwaddr[1]) << 16) | 1295 ((u32_t)(netif->hwaddr[2]) << 8) | 1296 (0xff)); 1297 ip_2_ip6(&netif->ip6_addr[0])->addr[3] = lwip_htonl((0xfeul << 24) | 1298 ((u32_t)(netif->hwaddr[3]) << 16) | 1299 ((u32_t)(netif->hwaddr[4]) << 8) | 1300 (netif->hwaddr[5])); 1301 } else { 1302 /* Use hwaddr directly as interface ID. */ 1303 ip_2_ip6(&netif->ip6_addr[0])->addr[2] = 0; 1304 ip_2_ip6(&netif->ip6_addr[0])->addr[3] = 0; 1305 1306 addr_index = 3; 1307 for (i = 0; (i < 8) && (i < netif->hwaddr_len); i++) { 1308 if (i == 4) { 1309 addr_index--; 1310 } 1311 ip_2_ip6(&netif->ip6_addr[0])->addr[addr_index] |= ((u32_t)(netif->hwaddr[netif->hwaddr_len - i - 1])) << (8 * (i & 0x03)); 1312 } 1313 } 1314 1315 /* Set a link-local zone. Even though the zone is implied by the owning 1316 * netif, setting the zone anyway has two important conceptual advantages: 1317 * 1) it avoids the need for a ton of exceptions in internal code, allowing 1318 * e.g. ip6_addr_cmp() to be used on local addresses; 1319 * 2) the properly zoned address is visible externally, e.g. when any outside 1320 * code enumerates available addresses or uses one to bind a socket. 1321 * Any external code unaware of address scoping is likely to just ignore the 1322 * zone field, so this should not create any compatibility problems. */ 1323 ip6_addr_assign_zone(ip_2_ip6(&netif->ip6_addr[0]), IP6_UNICAST, netif); 1324 1325 /* Set address state. */ 1326 #if LWIP_IPV6_DUP_DETECT_ATTEMPTS 1327 /* Will perform duplicate address detection (DAD). */ 1328 netif_ip6_addr_set_state(netif, 0, IP6_ADDR_TENTATIVE); 1329 #else 1330 /* Consider address valid. */ 1331 netif_ip6_addr_set_state(netif, 0, IP6_ADDR_PREFERRED); 1332 #endif /* LWIP_IPV6_AUTOCONFIG */ 1333 } 1334 1335 /** 1336 * @ingroup netif_ip6 1337 * This function allows for the easy addition of a new IPv6 address to an interface. 1338 * It takes care of finding an empty slot and then sets the address tentative 1339 * (to make sure that all the subsequent processing happens). 1340 * 1341 * @param netif netif to add the address on 1342 * @param ip6addr address to add 1343 * @param chosen_idx if != NULL, the chosen IPv6 address index will be stored here 1344 */ 1345 err_t 1346 netif_add_ip6_address(struct netif *netif, const ip6_addr_t *ip6addr, s8_t *chosen_idx) 1347 { 1348 s8_t i; 1349 1350 i = netif_get_ip6_addr_match(netif, ip6addr); 1351 if (i >= 0) { 1352 /* Address already added */ 1353 if (chosen_idx != NULL) { 1354 *chosen_idx = i; 1355 } 1356 return ERR_OK; 1357 } 1358 1359 /* Find a free slot. The first one is reserved for link-local addresses. */ 1360 for (i = ip6_addr_islinklocal(ip6addr) ? 0 : 1; i < LWIP_IPV6_NUM_ADDRESSES; i++) { 1361 if (ip6_addr_isinvalid(netif_ip6_addr_state(netif, i))) { 1362 ip_addr_copy_from_ip6(netif->ip6_addr[i], *ip6addr); 1363 ip6_addr_assign_zone(ip_2_ip6(&netif->ip6_addr[i]), IP6_UNICAST, netif); 1364 netif_ip6_addr_set_state(netif, i, IP6_ADDR_TENTATIVE); 1365 if (chosen_idx != NULL) { 1366 *chosen_idx = i; 1367 } 1368 return ERR_OK; 1369 } 1370 } 1371 1372 if (chosen_idx != NULL) { 1373 *chosen_idx = -1; 1374 } 1375 return ERR_VAL; 1376 } 1377 1378 /** Dummy IPv6 output function for netifs not supporting IPv6 1379 */ 1380 static err_t 1381 netif_null_output_ip6(struct netif *netif, struct pbuf *p, const ip6_addr_t *ipaddr) 1382 { 1383 LWIP_UNUSED_ARG(netif); 1384 LWIP_UNUSED_ARG(p); 1385 LWIP_UNUSED_ARG(ipaddr); 1386 1387 return ERR_IF; 1388 } 1389 #endif /* LWIP_IPV6 */ 1390 1391 /** 1392 * @ingroup netif 1393 * Return the interface index for the netif with name 1394 * or 0 (invalid interface) if not found/on error 1395 * 1396 * @param name the name of the netif 1397 */ 1398 u8_t 1399 netif_name_to_index(const char *name) 1400 { 1401 struct netif *netif = netif_find(name); 1402 if (netif != NULL) { 1403 return netif_get_index(netif); 1404 } 1405 /* No name found, return invalid index */ 1406 return 0; 1407 } 1408 1409 /** 1410 * @ingroup netif 1411 * Return the interface name for the netif matching index 1412 * or NULL if not found/on error 1413 * 1414 * @param idx the interface index of the netif 1415 * @param name char buffer of at least NETIF_NAMESIZE bytes 1416 */ 1417 char * 1418 netif_index_to_name(u8_t idx, char *name) 1419 { 1420 struct netif *netif = netif_get_by_index(idx); 1421 1422 if (netif != NULL) { 1423 name[0] = netif->name[0]; 1424 name[1] = netif->name[1]; 1425 lwip_itoa(&name[2], NETIF_NAMESIZE - 2, netif_index_to_num(idx)); 1426 return name; 1427 } 1428 return NULL; 1429 } 1430 1431 /** 1432 * @ingroup netif 1433 * Return the interface for the netif index 1434 * 1435 * @param idx index of netif to find 1436 */ 1437 struct netif* 1438 netif_get_by_index(u8_t idx) 1439 { 1440 struct netif* netif; 1441 1442 if (idx != NETIF_NO_INDEX) { 1443 NETIF_FOREACH(netif) { 1444 if (idx == netif_get_index(netif)) { 1445 return netif; /* found! */ 1446 } 1447 } 1448 } 1449 1450 return NULL; 1451 } 1452 1453 /** 1454 * @ingroup netif 1455 * Find a network interface by searching for its name 1456 * 1457 * @param name the name of the netif (like netif->name) plus concatenated number 1458 * in ascii representation (e.g. 'en0') 1459 */ 1460 struct netif * 1461 netif_find(const char *name) 1462 { 1463 struct netif *netif; 1464 u8_t num; 1465 1466 if (name == NULL) { 1467 return NULL; 1468 } 1469 1470 num = (u8_t)atoi(&name[2]); 1471 1472 NETIF_FOREACH(netif) { 1473 if (num == netif->num && 1474 name[0] == netif->name[0] && 1475 name[1] == netif->name[1]) { 1476 LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: found %c%c\n", name[0], name[1])); 1477 return netif; 1478 } 1479 } 1480 LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: didn't find %c%c\n", name[0], name[1])); 1481 return NULL; 1482 } 1483 1484 #if LWIP_NETIF_EXT_STATUS_CALLBACK 1485 /** 1486 * @ingroup netif 1487 * Add extended netif events listener 1488 * @param callback pointer to listener structure 1489 * @param fn callback function 1490 */ 1491 void netif_add_ext_callback(netif_ext_callback_t* callback, netif_ext_callback_fn fn) 1492 { 1493 LWIP_ASSERT("callback must be != NULL", callback != NULL); 1494 LWIP_ASSERT("fn must be != NULL", fn != NULL); 1495 1496 callback->callback_fn = fn; 1497 callback->next = ext_callback; 1498 ext_callback = callback; 1499 } 1500 1501 /** 1502 * Invoke extended netif status event 1503 * @param netif netif that is affected by change 1504 * @param reason change reason 1505 * @param args depends on reason, see reason description 1506 */ 1507 void netif_invoke_ext_callback(struct netif* netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t* args) 1508 { 1509 netif_ext_callback_t* callback = ext_callback; 1510 1511 LWIP_ASSERT("netif must be != NULL", netif != NULL); 1512 1513 while (callback != NULL) 1514 { 1515 callback->callback_fn(netif, reason, args); 1516 callback = callback->next; 1517 } 1518 } 1519 #endif /* LWIP_NETIF_EXT_STATUS_CALLBACK */ 1520