STM32F769IDiscovery  1.00
uDANTE Audio Networking with STM32F7 DISCO board
netif.c
Go to the documentation of this file.
1 
7 /*
8  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without modification,
12  * are permitted provided that the following conditions are met:
13  *
14  * 1. Redistributions of source code must retain the above copyright notice,
15  * this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright notice,
17  * this list of conditions and the following disclaimer in the documentation
18  * and/or other materials provided with the distribution.
19  * 3. The name of the author may not be used to endorse or promote products
20  * derived from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
23  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
25  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
27  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
31  * OF SUCH DAMAGE.
32  *
33  * This file is part of the lwIP TCP/IP stack.
34  *
35  * Author: Adam Dunkels <adam@sics.se>
36  *
37  */
38 
39 #include "lwip/opt.h"
40 
41 #include "lwip/def.h"
42 #include "lwip/ip_addr.h"
43 #include "lwip/ip6_addr.h"
44 #include "lwip/netif.h"
45 #include "lwip/priv/tcp_priv.h"
46 #include "lwip/udp.h"
47 #include "lwip/snmp.h"
48 #include "lwip/igmp.h"
49 #include "netif/etharp.h"
50 #include "lwip/stats.h"
51 #include "lwip/sys.h"
52 #if ENABLE_LOOPBACK
53 #include "lwip/sys.h"
54 #if LWIP_NETIF_LOOPBACK_MULTITHREADING
55 #include "lwip/tcpip.h"
56 #endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
57 #endif /* ENABLE_LOOPBACK */
58 
59 #if LWIP_AUTOIP
60 #include "lwip/autoip.h"
61 #endif /* LWIP_AUTOIP */
62 #if LWIP_DHCP
63 #include "lwip/dhcp.h"
64 #endif /* LWIP_DHCP */
65 #if LWIP_IPV6_DHCP6
66 #include "lwip/dhcp6.h"
67 #endif /* LWIP_IPV6_DHCP6 */
68 #if LWIP_IPV6_MLD
69 #include "lwip/mld6.h"
70 #endif /* LWIP_IPV6_MLD */
71 
72 #if LWIP_NETIF_STATUS_CALLBACK
73 #define NETIF_STATUS_CALLBACK(n) do{ if (n->status_callback) { (n->status_callback)(n); }}while(0)
74 #else
75 #define NETIF_STATUS_CALLBACK(n)
76 #endif /* LWIP_NETIF_STATUS_CALLBACK */
77 
78 #if LWIP_NETIF_LINK_CALLBACK
79 #define NETIF_LINK_CALLBACK(n) do{ if (n->link_callback) { (n->link_callback)(n); }}while(0)
80 #else
81 #define NETIF_LINK_CALLBACK(n)
82 #endif /* LWIP_NETIF_LINK_CALLBACK */
83 
84 struct netif *netif_list;
86 
87 static u8_t netif_num;
88 
89 #define NETIF_REPORT_TYPE_IPV4 0x01
90 #define NETIF_REPORT_TYPE_IPV6 0x02
91 static void netif_issue_reports(struct netif* netif, u8_t report_type);
92 
93 #if LWIP_IPV6
94 static err_t netif_null_output_ip6(struct netif *netif, struct pbuf *p, const ip6_addr_t *ipaddr);
95 #endif /* LWIP_IPV6 */
96 
97 #if LWIP_HAVE_LOOPIF
98 #if LWIP_IPV4
99 static err_t netif_loop_output_ipv4(struct netif *netif, struct pbuf *p, const ip4_addr_t* addr);
100 #endif
101 #if LWIP_IPV6
102 static err_t netif_loop_output_ipv6(struct netif *netif, struct pbuf *p, const ip6_addr_t* addr);
103 #endif
104 
105 
106 static struct netif loop_netif;
107 
115 static err_t
116 netif_loopif_init(struct netif *netif)
117 {
118  /* initialize the snmp variables and counters inside the struct netif
119  * ifSpeed: no assumption can be made!
120  */
121  MIB2_INIT_NETIF(netif, snmp_ifType_softwareLoopback, 0);
122 
123  netif->name[0] = 'l';
124  netif->name[1] = 'o';
125 #if LWIP_IPV4
126  netif->output = netif_loop_output_ipv4;
127 #endif
128 #if LWIP_IPV6
129  netif->output_ip6 = netif_loop_output_ipv6;
130 #endif
131 #if LWIP_LOOPIF_MULTICAST
132  netif->flags |= NETIF_FLAG_IGMP;
133 #endif
134  return ERR_OK;
135 }
136 #endif /* LWIP_HAVE_LOOPIF */
137 
138 void
140 {
141 #if LWIP_HAVE_LOOPIF
142 #if LWIP_IPV4
143 #define LOOPIF_ADDRINIT &loop_ipaddr, &loop_netmask, &loop_gw,
144  ip4_addr_t loop_ipaddr, loop_netmask, loop_gw;
145  IP4_ADDR(&loop_gw, 127,0,0,1);
146  IP4_ADDR(&loop_ipaddr, 127,0,0,1);
147  IP4_ADDR(&loop_netmask, 255,0,0,0);
148 #else /* LWIP_IPV4 */
149 #define LOOPIF_ADDRINIT
150 #endif /* LWIP_IPV4 */
151 
152 #if NO_SYS
153  netif_add(&loop_netif, LOOPIF_ADDRINIT NULL, netif_loopif_init, ip_input);
154 #else /* NO_SYS */
155  netif_add(&loop_netif, LOOPIF_ADDRINIT NULL, netif_loopif_init, tcpip_input);
156 #endif /* NO_SYS */
157 
158 #if LWIP_IPV6
159  IP_ADDR6(loop_netif.ip6_addr, 0, 0, 0, PP_HTONL(0x00000001UL));
160  loop_netif.ip6_addr_state[0] = IP6_ADDR_VALID;
161 #endif /* LWIP_IPV6 */
162 
163  netif_set_link_up(&loop_netif);
164  netif_set_up(&loop_netif);
165 
166 #endif /* LWIP_HAVE_LOOPIF */
167 }
168 
183 struct netif *
185 #if LWIP_IPV4
186  const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw,
187 #endif /* LWIP_IPV4 */
189 {
190 #if LWIP_IPV6
191  u32_t i;
192 #endif
193 
194  LWIP_ASSERT("No init function given", init != NULL);
195 
196  /* reset new interface configuration state */
197 #if LWIP_IPV4
198  ip_addr_set_zero_ip4(&netif->ip_addr);
199  ip_addr_set_zero_ip4(&netif->netmask);
200  ip_addr_set_zero_ip4(&netif->gw);
201 #endif /* LWIP_IPV4 */
202 #if LWIP_IPV6
203  for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
204  ip_addr_set_zero_ip6(&netif->ip6_addr[i]);
205  netif_ip6_addr_set_state(netif, i, IP6_ADDR_INVALID);
206  }
207  netif->output_ip6 = netif_null_output_ip6;
208 #endif /* LWIP_IPV6 */
209  NETIF_SET_CHECKSUM_CTRL(netif, NETIF_CHECKSUM_ENABLE_ALL);
210  netif->flags = 0;
211 #if LWIP_DHCP
212  /* netif not under DHCP control by default */
213  netif->dhcp = NULL;
214 #endif /* LWIP_DHCP */
215 #if LWIP_AUTOIP
216  /* netif not under AutoIP control by default */
217  netif->autoip = NULL;
218 #endif /* LWIP_AUTOIP */
219 #if LWIP_IPV6_AUTOCONFIG
220  /* IPv6 address autoconfiguration not enabled by default */
221  netif->ip6_autoconfig_enabled = 0;
222 #endif /* LWIP_IPV6_AUTOCONFIG */
223 #if LWIP_IPV6_SEND_ROUTER_SOLICIT
224  netif->rs_count = LWIP_ND6_MAX_MULTICAST_SOLICIT;
225 #endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */
226 #if LWIP_IPV6_DHCP6
227  /* netif not under DHCPv6 control by default */
228  netif->dhcp6 = NULL;
229 #endif /* LWIP_IPV6_DHCP6 */
230 #if LWIP_NETIF_STATUS_CALLBACK
231  netif->status_callback = NULL;
232 #endif /* LWIP_NETIF_STATUS_CALLBACK */
233 #if LWIP_NETIF_LINK_CALLBACK
234  netif->link_callback = NULL;
235 #endif /* LWIP_NETIF_LINK_CALLBACK */
236 #if LWIP_IGMP
237  netif->igmp_mac_filter = NULL;
238 #endif /* LWIP_IGMP */
239 #if LWIP_IPV6 && LWIP_IPV6_MLD
240  netif->mld_mac_filter = NULL;
241 #endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
242 #if ENABLE_LOOPBACK
243  netif->loop_first = NULL;
244  netif->loop_last = NULL;
245 #endif /* ENABLE_LOOPBACK */
246 
247  /* remember netif specific state information data */
248  netif->state = state;
249  netif->num = netif_num++;
250  netif->input = input;
251  NETIF_SET_HWADDRHINT(netif, NULL);
252 #if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS
253  netif->loop_cnt_current = 0;
254 #endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */
255 
256 #if LWIP_IPV4
257  netif_set_addr(netif, ipaddr, netmask, gw);
258 #endif /* LWIP_IPV4 */
259 
260  /* call user specified initialization function for netif */
261  if (init)
262  if (init(netif) != ERR_OK) {
263  return NULL;
264  }
265 
266  /* add this netif to the list */
267  netif->next = netif_list;
268  netif_list = netif;
269  mib2_netif_added(netif);
270 
271 #if LWIP_IGMP
272  /* start IGMP processing */
273  if (netif->flags & NETIF_FLAG_IGMP) {
274  igmp_start(netif);
275  }
276 #endif /* LWIP_IGMP */
277 
278  LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP",
279  netif->name[0], netif->name[1]));
280 #if LWIP_IPV4
281  LWIP_DEBUGF(NETIF_DEBUG, (" addr "));
282  ip4_addr_debug_print(NETIF_DEBUG, ipaddr);
283  LWIP_DEBUGF(NETIF_DEBUG, (" netmask "));
284  ip4_addr_debug_print(NETIF_DEBUG, netmask);
285  LWIP_DEBUGF(NETIF_DEBUG, (" gw "));
286  ip4_addr_debug_print(NETIF_DEBUG, gw);
287 #endif /* LWIP_IPV4 */
288  LWIP_DEBUGF(NETIF_DEBUG, ("\n"));
289  return netif;
290 }
291 
292 #if LWIP_IPV4
293 
302 void
303 netif_set_addr(struct netif *netif, const ip4_addr_t *ipaddr, const ip4_addr_t *netmask,
304  const ip4_addr_t *gw)
305 {
306  netif_set_netmask(netif, netmask);
307  netif_set_gw(netif, gw);
308  /* set ipaddr last to ensure netmask/gw have been set when status callback is called */
309  netif_set_ipaddr(netif, ipaddr);
310 }
311 #endif /* LWIP_IPV4*/
312 
318 void
319 netif_remove(struct netif *netif)
320 {
321  if (netif == NULL) {
322  return;
323  }
324 
325 #if LWIP_IPV4
326  if (!ip4_addr_isany_val(*netif_ip4_addr(netif))) {
327 #if LWIP_TCP
328  tcp_netif_ipv4_addr_changed(netif_ip4_addr(netif), NULL);
329 #endif /* LWIP_TCP */
330  /* cannot do this for UDP, as there is no 'err' callback in udp pcbs */
331  }
332 
333 #if LWIP_IGMP
334  /* stop IGMP processing */
335  if (netif->flags & NETIF_FLAG_IGMP) {
336  igmp_stop(netif);
337  }
338 #endif /* LWIP_IGMP */
339 #endif /* LWIP_IPV4*/
340 
341 #if LWIP_IPV6 && LWIP_IPV6_MLD
342  /* stop MLD processing */
343  mld6_stop(netif);
344 #endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
345  if (netif_is_up(netif)) {
346  /* set netif down before removing (call callback function) */
347  netif_set_down(netif);
348  }
349 
350  mib2_remove_ip4(netif);
351 
352  /* this netif is default? */
353  if (netif_default == netif) {
354  /* reset default netif */
356  }
357  /* is it the first netif? */
358  if (netif_list == netif) {
359  netif_list = netif->next;
360  } else {
361  /* look for netif further down the list */
362  struct netif * tmp_netif;
363  for (tmp_netif = netif_list; tmp_netif != NULL; tmp_netif = tmp_netif->next) {
364  if (tmp_netif->next == netif) {
365  tmp_netif->next = netif->next;
366  break;
367  }
368  }
369  if (tmp_netif == NULL) {
370  return; /* netif is not on the list */
371  }
372  }
373  mib2_netif_removed(netif);
374 #if LWIP_NETIF_REMOVE_CALLBACK
375  if (netif->remove_callback) {
376  netif->remove_callback(netif);
377  }
378 #endif /* LWIP_NETIF_REMOVE_CALLBACK */
379  LWIP_DEBUGF( NETIF_DEBUG, ("netif_remove: removed netif\n") );
380 }
381 
388 struct netif *
389 netif_find(const char *name)
390 {
391  struct netif *netif;
392  u8_t num;
393 
394  if (name == NULL) {
395  return NULL;
396  }
397 
398  num = name[2] - '0';
399 
400  for (netif = netif_list; netif != NULL; netif = netif->next) {
401  if (num == netif->num &&
402  name[0] == netif->name[0] &&
403  name[1] == netif->name[1]) {
404  LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: found %c%c\n", name[0], name[1]));
405  return netif;
406  }
407  }
408  LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: didn't find %c%c\n", name[0], name[1]));
409  return NULL;
410 }
411 
412 #if LWIP_IPV4
413 
422 void
423 netif_set_ipaddr(struct netif *netif, const ip4_addr_t *ipaddr)
424 {
425  ip4_addr_t new_addr = (ipaddr ? *ipaddr : *IP4_ADDR_ANY);
426  /* address is actually being changed? */
427  if (ip4_addr_cmp(&new_addr, netif_ip4_addr(netif)) == 0) {
428  LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: netif address being changed\n"));
429 #if LWIP_TCP
430  tcp_netif_ipv4_addr_changed(netif_ip4_addr(netif), ipaddr);
431 #endif /* LWIP_TCP */
432 #if LWIP_UDP
433  udp_netif_ipv4_addr_changed(netif_ip4_addr(netif), ipaddr);
434 #endif /* LWIP_UDP */
435 
436  mib2_remove_ip4(netif);
437  mib2_remove_route_ip4(0, netif);
438  /* set new IP address to netif */
439  ip4_addr_set(ip_2_ip4(&netif->ip_addr), ipaddr);
440  IP_SET_TYPE_VAL(netif->ip_addr, IPADDR_TYPE_V4);
441  mib2_add_ip4(netif);
442  mib2_add_route_ip4(0, netif);
443 
444  netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4);
445 
446  NETIF_STATUS_CALLBACK(netif);
447  }
448 
449  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",
450  netif->name[0], netif->name[1],
451  ip4_addr1_16(netif_ip4_addr(netif)),
452  ip4_addr2_16(netif_ip4_addr(netif)),
453  ip4_addr3_16(netif_ip4_addr(netif)),
454  ip4_addr4_16(netif_ip4_addr(netif))));
455 }
456 
465 void
466 netif_set_gw(struct netif *netif, const ip4_addr_t *gw)
467 {
468  ip4_addr_set(ip_2_ip4(&netif->gw), gw);
469  IP_SET_TYPE_VAL(netif->gw, IPADDR_TYPE_V4);
470  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",
471  netif->name[0], netif->name[1],
472  ip4_addr1_16(netif_ip4_gw(netif)),
473  ip4_addr2_16(netif_ip4_gw(netif)),
474  ip4_addr3_16(netif_ip4_gw(netif)),
475  ip4_addr4_16(netif_ip4_gw(netif))));
476 }
477 
487 void
488 netif_set_netmask(struct netif *netif, const ip4_addr_t *netmask)
489 {
490  mib2_remove_route_ip4(0, netif);
491  /* set new netmask to netif */
492  ip4_addr_set(ip_2_ip4(&netif->netmask), netmask);
493  IP_SET_TYPE_VAL(netif->netmask, IPADDR_TYPE_V4);
494  mib2_add_route_ip4(0, netif);
495  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",
496  netif->name[0], netif->name[1],
497  ip4_addr1_16(netif_ip4_netmask(netif)),
498  ip4_addr2_16(netif_ip4_netmask(netif)),
499  ip4_addr3_16(netif_ip4_netmask(netif)),
500  ip4_addr4_16(netif_ip4_netmask(netif))));
501 }
502 #endif /* LWIP_IPV4 */
503 
510 void
511 netif_set_default(struct netif *netif)
512 {
513  if (netif == NULL) {
514  /* remove default route */
515  mib2_remove_route_ip4(1, netif);
516  } else {
517  /* install default route */
518  mib2_add_route_ip4(1, netif);
519  }
520  netif_default = netif;
521  LWIP_DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%c\n",
522  netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\''));
523 }
524 
529 void
530 netif_set_up(struct netif *netif)
531 {
532  if (!(netif->flags & NETIF_FLAG_UP)) {
533  netif->flags |= NETIF_FLAG_UP;
534 
535  MIB2_COPY_SYSUPTIME_TO(&netif->ts);
536 
537  NETIF_STATUS_CALLBACK(netif);
538 
539  if (netif->flags & NETIF_FLAG_LINK_UP) {
540  netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4|NETIF_REPORT_TYPE_IPV6);
541  }
542  }
543 }
544 
547 static void
548 netif_issue_reports(struct netif* netif, u8_t report_type)
549 {
550 #if LWIP_IPV4
551  if ((report_type & NETIF_REPORT_TYPE_IPV4) &&
552  !ip4_addr_isany_val(*netif_ip4_addr(netif))) {
553 #if LWIP_ARP
554  /* For Ethernet network interfaces, we would like to send a "gratuitous ARP" */
555  if (netif->flags & (NETIF_FLAG_ETHARP)) {
556  etharp_gratuitous(netif);
557  }
558 #endif /* LWIP_ARP */
559 
560 #if LWIP_IGMP
561  /* resend IGMP memberships */
562  if (netif->flags & NETIF_FLAG_IGMP) {
563  igmp_report_groups(netif);
564  }
565 #endif /* LWIP_IGMP */
566  }
567 #endif /* LWIP_IPV4 */
568 
569 #if LWIP_IPV6
570  if (report_type & NETIF_REPORT_TYPE_IPV6) {
571 #if LWIP_IPV6_MLD
572  /* send mld memberships */
573  mld6_report_groups(netif);
574 #endif /* LWIP_IPV6_MLD */
575 #if LWIP_IPV6_SEND_ROUTER_SOLICIT
576  /* Send Router Solicitation messages. */
577  netif->rs_count = LWIP_ND6_MAX_MULTICAST_SOLICIT;
578 #endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */
579  }
580 #endif /* LWIP_IPV6 */
581 }
582 
586 void
587 netif_set_down(struct netif *netif)
588 {
589  if (netif->flags & NETIF_FLAG_UP) {
590  netif->flags &= ~NETIF_FLAG_UP;
591  MIB2_COPY_SYSUPTIME_TO(&netif->ts);
592 
593 #if LWIP_IPV4 && LWIP_ARP
594  if (netif->flags & NETIF_FLAG_ETHARP) {
595  etharp_cleanup_netif(netif);
596  }
597 #endif /* LWIP_IPV4 && LWIP_ARP */
598  NETIF_STATUS_CALLBACK(netif);
599  }
600 }
601 
602 #if LWIP_NETIF_STATUS_CALLBACK
603 
606 void
607 netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback)
608 {
609  if (netif) {
610  netif->status_callback = status_callback;
611  }
612 }
613 #endif /* LWIP_NETIF_STATUS_CALLBACK */
614 
615 #if LWIP_NETIF_REMOVE_CALLBACK
616 
619 void
620 netif_set_remove_callback(struct netif *netif, netif_status_callback_fn remove_callback)
621 {
622  if (netif) {
623  netif->remove_callback = remove_callback;
624  }
625 }
626 #endif /* LWIP_NETIF_REMOVE_CALLBACK */
627 
631 void
632 netif_set_link_up(struct netif *netif)
633 {
634  if (!(netif->flags & NETIF_FLAG_LINK_UP)) {
635  netif->flags |= NETIF_FLAG_LINK_UP;
636 
637 #if LWIP_DHCP
638  if (netif->dhcp) {
639  dhcp_network_changed(netif);
640  }
641 #endif /* LWIP_DHCP */
642 
643 #if LWIP_AUTOIP
644  if (netif->autoip) {
645  autoip_network_changed(netif);
646  }
647 #endif /* LWIP_AUTOIP */
648 
649  if (netif->flags & NETIF_FLAG_UP) {
650  netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4|NETIF_REPORT_TYPE_IPV6);
651  }
652  NETIF_LINK_CALLBACK(netif);
653  }
654 }
655 
659 void
660 netif_set_link_down(struct netif *netif )
661 {
662  if (netif->flags & NETIF_FLAG_LINK_UP) {
663  netif->flags &= ~NETIF_FLAG_LINK_UP;
664  NETIF_LINK_CALLBACK(netif);
665  }
666 }
667 
668 #if LWIP_NETIF_LINK_CALLBACK
669 
672 void
673 netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callback)
674 {
675  if (netif) {
676  netif->link_callback = link_callback;
677  }
678 }
679 #endif /* LWIP_NETIF_LINK_CALLBACK */
680 
681 #if ENABLE_LOOPBACK
682 
695 err_t
696 netif_loop_output(struct netif *netif, struct pbuf *p)
697 {
698  struct pbuf *r;
699  err_t err;
700  struct pbuf *last;
701 #if LWIP_LOOPBACK_MAX_PBUFS
702  u8_t clen = 0;
703 #endif /* LWIP_LOOPBACK_MAX_PBUFS */
704  /* If we have a loopif, SNMP counters are adjusted for it,
705  * if not they are adjusted for 'netif'. */
706 #if MIB2_STATS
707 #if LWIP_HAVE_LOOPIF
708  struct netif *stats_if = &loop_netif;
709 #else /* LWIP_HAVE_LOOPIF */
710  struct netif *stats_if = netif;
711 #endif /* LWIP_HAVE_LOOPIF */
712 #endif /* MIB2_STATS */
714 
715  /* Allocate a new pbuf */
717  if (r == NULL) {
718  LINK_STATS_INC(link.memerr);
719  LINK_STATS_INC(link.drop);
720  MIB2_STATS_NETIF_INC(stats_if, ifoutdiscards);
721  return ERR_MEM;
722  }
723 #if LWIP_LOOPBACK_MAX_PBUFS
724  clen = pbuf_clen(r);
725  /* check for overflow or too many pbuf on queue */
726  if (((netif->loop_cnt_current + clen) < netif->loop_cnt_current) ||
727  ((netif->loop_cnt_current + clen) > LWIP_LOOPBACK_MAX_PBUFS)) {
728  pbuf_free(r);
729  LINK_STATS_INC(link.memerr);
730  LINK_STATS_INC(link.drop);
731  MIB2_STATS_NETIF_INC(stats_if, ifoutdiscards);
732  return ERR_MEM;
733  }
734  netif->loop_cnt_current += clen;
735 #endif /* LWIP_LOOPBACK_MAX_PBUFS */
736 
737  /* Copy the whole pbuf queue p into the single pbuf r */
738  if ((err = pbuf_copy(r, p)) != ERR_OK) {
739  pbuf_free(r);
740  LINK_STATS_INC(link.memerr);
741  LINK_STATS_INC(link.drop);
742  MIB2_STATS_NETIF_INC(stats_if, ifoutdiscards);
743  return err;
744  }
745 
746  /* Put the packet on a linked list which gets emptied through calling
747  netif_poll(). */
748 
749  /* let last point to the last pbuf in chain r */
750  for (last = r; last->next != NULL; last = last->next);
751 
752  SYS_ARCH_PROTECT(lev);
753  if (netif->loop_first != NULL) {
754  LWIP_ASSERT("if first != NULL, last must also be != NULL", netif->loop_last != NULL);
755  netif->loop_last->next = r;
756  netif->loop_last = last;
757  } else {
758  netif->loop_first = r;
759  netif->loop_last = last;
760  }
761  SYS_ARCH_UNPROTECT(lev);
762 
763  LINK_STATS_INC(link.xmit);
764  MIB2_STATS_NETIF_ADD(stats_if, ifoutoctets, p->tot_len);
765  MIB2_STATS_NETIF_INC(stats_if, ifoutucastpkts);
766 
767 #if LWIP_NETIF_LOOPBACK_MULTITHREADING
768  /* For multithreading environment, schedule a call to netif_poll */
769  tcpip_callback_with_block((tcpip_callback_fn)netif_poll, netif, 0);
770 #endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
771 
772  return ERR_OK;
773 }
774 
775 #if LWIP_HAVE_LOOPIF
776 #if LWIP_IPV4
777 static err_t
778 netif_loop_output_ipv4(struct netif *netif, struct pbuf *p, const ip4_addr_t* addr)
779 {
780  LWIP_UNUSED_ARG(addr);
781  return netif_loop_output(netif, p);
782 }
783 #endif /* LWIP_IPV4 */
784 
785 #if LWIP_IPV6
786 static err_t
787 netif_loop_output_ipv6(struct netif *netif, struct pbuf *p, const ip6_addr_t* addr)
788 {
789  LWIP_UNUSED_ARG(addr);
790  return netif_loop_output(netif, p);
791 }
792 #endif /* LWIP_IPV6 */
793 #endif /* LWIP_HAVE_LOOPIF */
794 
795 
802 void
803 netif_poll(struct netif *netif)
804 {
805  struct pbuf *in;
806  /* If we have a loopif, SNMP counters are adjusted for it,
807  * if not they are adjusted for 'netif'. */
808 #if MIB2_STATS
809 #if LWIP_HAVE_LOOPIF
810  struct netif *stats_if = &loop_netif;
811 #else /* LWIP_HAVE_LOOPIF */
812  struct netif *stats_if = netif;
813 #endif /* LWIP_HAVE_LOOPIF */
814 #endif /* MIB2_STATS */
816 
817  do {
818  /* Get a packet from the list. With SYS_LIGHTWEIGHT_PROT=1, this is protected */
819  SYS_ARCH_PROTECT(lev);
820  in = netif->loop_first;
821  if (in != NULL) {
822  struct pbuf *in_end = in;
823 #if LWIP_LOOPBACK_MAX_PBUFS
824  u8_t clen = 1;
825 #endif /* LWIP_LOOPBACK_MAX_PBUFS */
826  while (in_end->len != in_end->tot_len) {
827  LWIP_ASSERT("bogus pbuf: len != tot_len but next == NULL!", in_end->next != NULL);
828  in_end = in_end->next;
829 #if LWIP_LOOPBACK_MAX_PBUFS
830  clen++;
831 #endif /* LWIP_LOOPBACK_MAX_PBUFS */
832  }
833 #if LWIP_LOOPBACK_MAX_PBUFS
834  /* adjust the number of pbufs on queue */
835  LWIP_ASSERT("netif->loop_cnt_current underflow",
836  ((netif->loop_cnt_current - clen) < netif->loop_cnt_current));
837  netif->loop_cnt_current -= clen;
838 #endif /* LWIP_LOOPBACK_MAX_PBUFS */
839 
840  /* 'in_end' now points to the last pbuf from 'in' */
841  if (in_end == netif->loop_last) {
842  /* this was the last pbuf in the list */
843  netif->loop_first = netif->loop_last = NULL;
844  } else {
845  /* pop the pbuf off the list */
846  netif->loop_first = in_end->next;
847  LWIP_ASSERT("should not be null since first != last!", netif->loop_first != NULL);
848  }
849  /* De-queue the pbuf from its successors on the 'loop_' list. */
850  in_end->next = NULL;
851  }
852  SYS_ARCH_UNPROTECT(lev);
853 
854  if (in != NULL) {
855  LINK_STATS_INC(link.recv);
856  MIB2_STATS_NETIF_ADD(stats_if, ifinoctets, in->tot_len);
857  MIB2_STATS_NETIF_INC(stats_if, ifinucastpkts);
858  /* loopback packets are always IP packets! */
859  if (ip_input(in, netif) != ERR_OK) {
860  pbuf_free(in);
861  }
862  /* Don't reference the packet any more! */
863  in = NULL;
864  }
865  /* go on while there is a packet on the list */
866  } while (netif->loop_first != NULL);
867 }
868 
869 #if !LWIP_NETIF_LOOPBACK_MULTITHREADING
870 
873 void
874 netif_poll_all(void)
875 {
876  struct netif *netif = netif_list;
877  /* loop through netifs */
878  while (netif != NULL) {
879  netif_poll(netif);
880  /* proceed to next network interface */
881  netif = netif->next;
882  }
883 }
884 #endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */
885 #endif /* ENABLE_LOOPBACK */
886 
887 #if LWIP_IPV6
888 
896 s8_t
897 netif_get_ip6_addr_match(struct netif *netif, const ip6_addr_t *ip6addr)
898 {
899  s8_t i;
900  for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
901  if (!ip6_addr_isinvalid(netif_ip6_addr_state(netif, i)) &&
902  ip6_addr_cmp(netif_ip6_addr(netif, i), ip6addr)) {
903  return i;
904  }
905  }
906  return -1;
907 }
908 
915 void
916 netif_create_ip6_linklocal_address(struct netif *netif, u8_t from_mac_48bit)
917 {
918  u8_t i, addr_index;
919 
920  /* Link-local prefix. */
921  ip_2_ip6(&netif->ip6_addr[0])->addr[0] = PP_HTONL(0xfe800000ul);
922  ip_2_ip6(&netif->ip6_addr[0])->addr[1] = 0;
923 
924  /* Generate interface ID. */
925  if (from_mac_48bit) {
926  /* Assume hwaddr is a 48-bit IEEE 802 MAC. Convert to EUI-64 address. Complement Group bit. */
927  ip_2_ip6(&netif->ip6_addr[0])->addr[2] = htonl((((u32_t)(netif->hwaddr[0] ^ 0x02)) << 24) |
928  ((u32_t)(netif->hwaddr[1]) << 16) |
929  ((u32_t)(netif->hwaddr[2]) << 8) |
930  (0xff));
931  ip_2_ip6(&netif->ip6_addr[0])->addr[3] = htonl((0xfeul << 24) |
932  ((u32_t)(netif->hwaddr[3]) << 16) |
933  ((u32_t)(netif->hwaddr[4]) << 8) |
934  (netif->hwaddr[5]));
935  } else {
936  /* Use hwaddr directly as interface ID. */
937  ip_2_ip6(&netif->ip6_addr[0])->addr[2] = 0;
938  ip_2_ip6(&netif->ip6_addr[0])->addr[3] = 0;
939 
940  addr_index = 3;
941  for (i = 0; (i < 8) && (i < netif->hwaddr_len); i++) {
942  if (i == 4) {
943  addr_index--;
944  }
945  ip_2_ip6(&netif->ip6_addr[0])->addr[addr_index] |= ((u32_t)(netif->hwaddr[netif->hwaddr_len - i - 1])) << (8 * (i & 0x03));
946  }
947  }
948 
949  /* Set address state. */
950 #if LWIP_IPV6_DUP_DETECT_ATTEMPTS
951  /* Will perform duplicate address detection (DAD). */
952  netif->ip6_addr_state[0] = IP6_ADDR_TENTATIVE;
953 #else
954  /* Consider address valid. */
955  netif->ip6_addr_state[0] = IP6_ADDR_PREFERRED;
956 #endif /* LWIP_IPV6_AUTOCONFIG */
957 }
958 
967 err_t
968 netif_add_ip6_address(struct netif *netif, const ip6_addr_t *ip6addr, s8_t *chosen_idx)
969 {
970  s8_t i;
971 
972  i = netif_get_ip6_addr_match(netif, ip6addr);
973  if (i >= 0) {
974  /* Address already added */
975  if (chosen_idx != NULL) {
976  *chosen_idx = i;
977  }
978  return ERR_OK;
979  }
980 
981  /* Find a free slot -- musn't be the first one (reserved for link local) */
982  for (i = 1; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
983  if (!ip6_addr_isvalid(netif->ip6_addr_state[i])) {
984  ip_addr_copy_from_ip6(netif->ip6_addr[i], *ip6addr);
985  netif_ip6_addr_set_state(netif, i, IP6_ADDR_TENTATIVE);
986  if (chosen_idx != NULL) {
987  *chosen_idx = i;
988  }
989  return ERR_OK;
990  }
991  }
992 
993  if (chosen_idx != NULL) {
994  *chosen_idx = -1;
995  }
996  return ERR_VAL;
997 }
998 
1001 static err_t
1002 netif_null_output_ip6(struct netif *netif, struct pbuf *p, const ip6_addr_t *ipaddr)
1003 {
1004  LWIP_UNUSED_ARG(netif);
1005  LWIP_UNUSED_ARG(p);
1006  LWIP_UNUSED_ARG(ipaddr);
1007 
1008  return ERR_IF;
1009 }
1010 #endif /* LWIP_IPV6 */
1011 
#define PP_HTONL(x)
Definition: def.h:99
err_t(* netif_input_fn)(struct pbuf *p, struct netif *inp)
Definition: netif.h:131
#define NETIF_REPORT_TYPE_IPV4
Definition: netif.c:89
u8_t flags
Definition: netif.h:269
struct netif * netif_list
Definition: netif.c:84
void(* netif_status_callback_fn)(struct netif *netif)
Definition: netif.h:167
void * state
Definition: netif.h:234
struct netif * netif_default
Definition: netif.c:85
void(* tcpip_callback_fn)(void *ctx)
Definition: tcpip.h:51
#define ip_2_ip6(ipaddr)
Definition: ip_addr.h:200
#define ip_addr_set_zero_ip6(ipaddr)
Definition: ip_addr.h:208
#define U16_F
Definition: cc.h:48
signed char s8_t
Definition: cc.h:39
u8_t hwaddr[NETIF_MAX_HWADDR_LEN]
Definition: netif.h:267
#define NETIF_FLAG_UP
Definition: netif.h:77
void netif_set_link_down(struct netif *netif)
Definition: netif.c:660
#define ERR_VAL
Definition: err.h:58
err_t tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block)
Definition: tcpip.c:276
#define mib2_remove_ip4(ni)
Definition: snmp.h:168
netif_input_fn input
Definition: netif.h:201
struct netif * next
Definition: netif.h:184
#define LWIP_IPV4
Definition: opt.h:549
#define NETIF_FLAG_LINK_UP
Definition: netif.h:86
err_t ip_input(struct pbuf *p, struct netif *inp)
#define NETIF_DEBUG
Definition: opt.h:2781
void netif_set_default(struct netif *netif)
Definition: netif.c:511
u16_t len
Definition: pbuf.h:125
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
Definition: pbuf.c:199
Definition: pbuf.h:77
void netif_init(void)
Definition: netif.c:139
#define MIB2_STATS_NETIF_ADD(n, x, val)
Definition: snmp.h:122
#define LWIP_DBG_STATE
Definition: debug.h:59
#define mib2_add_route_ip4(dflt, ni)
Definition: snmp.h:169
void netif_set_up(struct netif *netif)
Definition: netif.c:530
#define SYS_ARCH_DECL_PROTECT(lev)
Definition: sys.h:304
Definition: pbuf.h:66
char name[2]
Definition: netif.h:271
#define NETIF_STATUS_CALLBACK(n)
Definition: netif.c:75
#define mib2_netif_added(ni)
Definition: snmp.h:159
#define NULL
Definition: usbd_def.h:53
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:652
err_t pbuf_copy(struct pbuf *p_to, struct pbuf *p_from)
Definition: pbuf.c:886
unsigned long u32_t
Definition: cc.h:42
#define NETIF_FLAG_ETHARP
Definition: netif.h:90
#define MIB2_COPY_SYSUPTIME_TO(ptrToVal)
Definition: snmp.h:118
u8_t num
Definition: netif.h:273
struct netif * netif_find(const char *name)
Definition: netif.c:389
err_t tcpip_input(struct pbuf *p, struct netif *inp)
Definition: tcpip.c:186
#define ERR_OK
Definition: err.h:52
#define ERR_IF
Definition: err.h:73
u16_t tot_len
Definition: pbuf.h:122
#define NETIF_SET_HWADDRHINT(netif, hint)
Definition: netif.h:411
#define LWIP_DBG_TRACE
Definition: debug.h:57
Definition: pbuf.h:108
s8_t err_t
Definition: err.h:47
#define NETIF_SET_CHECKSUM_CTRL(netif, chksumflags)
Definition: netif.h:312
#define LINK_STATS_INC(x)
Definition: stats.h:318
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:70
Definition: netif.h:182
void netif_remove(struct netif *netif)
Definition: netif.c:319
u8_t hwaddr_len
Definition: netif.h:265
#define IP_SET_TYPE_VAL(ipaddr, iptype)
Definition: ip_addr.h:198
#define IP_ADDR6(ipaddr, i0, i1, i2, i3)
Definition: ip_addr.h:201
err_t(* netif_init_fn)(struct netif *netif)
Definition: netif.h:124
struct pbuf * next
Definition: pbuf.h:110
#define NETIF_FLAG_IGMP
Definition: netif.h:97
#define ip_addr_copy_from_ip6(dest, src)
Definition: ip_addr.h:204
#define LWIP_IPV6_NUM_ADDRESSES
Definition: opt.h:2451
void netif_set_down(struct netif *netif)
Definition: netif.c:587
u8_t pbuf_clen(struct pbuf *p)
Definition: pbuf.c:738
#define NETIF_REPORT_TYPE_IPV6
Definition: netif.c:90
#define NETIF_LINK_CALLBACK(n)
Definition: netif.c:81
#define LWIP_ND6_MAX_MULTICAST_SOLICIT
Definition: opt.h:2559
unsigned char u8_t
Definition: cc.h:38
#define LWIP_LOOPBACK_MAX_PBUFS
Definition: opt.h:1273
#define SYS_ARCH_PROTECT(lev)
Definition: sys.h:305
#define mib2_remove_route_ip4(dflt, ni)
Definition: snmp.h:170
#define SYS_ARCH_UNPROTECT(lev)
Definition: sys.h:306
#define MIB2_INIT_NETIF(netif, type, speed)
Definition: snmp.h:120
#define mib2_netif_removed(ni)
Definition: snmp.h:160
#define MIB2_STATS_NETIF_INC(n, x)
Definition: snmp.h:121
void netif_set_link_up(struct netif *netif)
Definition: netif.c:632
struct netif * netif_add(struct netif *netif, void *state, netif_init_fn init, netif_input_fn input)
Definition: netif.c:184
#define netif_is_up(netif)
Definition: netif.h:356
#define mib2_add_ip4(ni)
Definition: snmp.h:167
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:113
#define ERR_MEM
Definition: err.h:53
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:89
#define htonl(x)
Definition: def.h:88