Warning, cross-references for /kernel/lwip/core/netif.c need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 #include "lwip/opt.h"
0040
0041 #include "lwip/def.h"
0042 #include "lwip/ip_addr.h"
0043 #include "lwip/netif.h"
0044 #include "lwip/tcp.h"
0045 #include "lwip/snmp.h"
0046 #include "lwip/igmp.h"
0047 #include "netif/etharp.h"
0048 #if ENABLE_LOOPBACK
0049 #include "lwip/sys.h"
0050 #if LWIP_NETIF_LOOPBACK_MULTITHREADING
0051 #include "lwip/tcpip.h"
0052 #endif
0053 #endif
0054
0055 #if LWIP_AUTOIP
0056 #include "lwip/autoip.h"
0057 #endif
0058 #if LWIP_DHCP
0059 #include "lwip/dhcp.h"
0060 #endif
0061
0062 #if LWIP_NETIF_STATUS_CALLBACK
0063 #define NETIF_STATUS_CALLBACK(n) { if (n->status_callback) (n->status_callback)(n); }
0064 #else
0065 #define NETIF_STATUS_CALLBACK(n) { }
0066 #endif
0067
0068 #if LWIP_NETIF_LINK_CALLBACK
0069 #define NETIF_LINK_CALLBACK(n) { if (n->link_callback) (n->link_callback)(n); }
0070 #else
0071 #define NETIF_LINK_CALLBACK(n) { }
0072 #endif
0073
0074 struct netif *netif_list;
0075 struct netif *netif_default;
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091 struct netif *
0092 netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,
0093 struct ip_addr *gw,
0094 void *state,
0095 err_t (* init)(struct netif *netif),
0096 err_t (* input)(struct pbuf *p, struct netif *netif))
0097 {
0098 static u8_t netifnum = 0;
0099
0100
0101 netif->ip_addr.addr = 0;
0102 netif->netmask.addr = 0;
0103 netif->gw.addr = 0;
0104 netif->flags = 0;
0105 #if LWIP_DHCP
0106
0107 netif->dhcp = NULL;
0108 #endif
0109 #if LWIP_AUTOIP
0110
0111 netif->autoip = NULL;
0112 #endif
0113 #if LWIP_NETIF_STATUS_CALLBACK
0114 netif->status_callback = NULL;
0115 #endif
0116 #if LWIP_NETIF_LINK_CALLBACK
0117 netif->link_callback = NULL;
0118 #endif
0119 #if LWIP_IGMP
0120 netif->igmp_mac_filter = NULL;
0121 #endif
0122 #if ENABLE_LOOPBACK
0123 netif->loop_first = NULL;
0124 netif->loop_last = NULL;
0125 #endif
0126
0127
0128 netif->state = state;
0129 netif->num = netifnum++;
0130 netif->input = input;
0131 #if LWIP_NETIF_HWADDRHINT
0132 netif->addr_hint = NULL;
0133 #endif
0134 #if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS
0135 netif->loop_cnt_current = 0;
0136 #endif
0137
0138 netif_set_addr(netif, ipaddr, netmask, gw);
0139
0140
0141 if (init(netif) != ERR_OK) {
0142 return NULL;
0143 }
0144
0145
0146 netif->next = netif_list;
0147 netif_list = netif;
0148 snmp_inc_iflist();
0149
0150 #if LWIP_IGMP
0151
0152 if (netif->flags & NETIF_FLAG_IGMP) {
0153 igmp_start( netif);
0154 }
0155 #endif
0156
0157 LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP addr ",
0158 netif->name[0], netif->name[1]));
0159 ip_addr_debug_print(NETIF_DEBUG, ipaddr);
0160 LWIP_DEBUGF(NETIF_DEBUG, (" netmask "));
0161 ip_addr_debug_print(NETIF_DEBUG, netmask);
0162 LWIP_DEBUGF(NETIF_DEBUG, (" gw "));
0163 ip_addr_debug_print(NETIF_DEBUG, gw);
0164 LWIP_DEBUGF(NETIF_DEBUG, ("\n"));
0165 return netif;
0166 }
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177 void
0178 netif_set_addr(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,
0179 struct ip_addr *gw)
0180 {
0181 netif_set_ipaddr(netif, ipaddr);
0182 netif_set_netmask(netif, netmask);
0183 netif_set_gw(netif, gw);
0184 }
0185
0186
0187
0188
0189
0190
0191 void netif_remove(struct netif * netif)
0192 {
0193 if ( netif == NULL ) return;
0194
0195 #if LWIP_IGMP
0196
0197 if (netif->flags & NETIF_FLAG_IGMP) {
0198 igmp_stop( netif);
0199 }
0200 #endif
0201
0202 snmp_delete_ipaddridx_tree(netif);
0203
0204
0205 if (netif_list == netif) {
0206 netif_list = netif->next;
0207 snmp_dec_iflist();
0208 }
0209 else {
0210
0211 struct netif * tmpNetif;
0212 for (tmpNetif = netif_list; tmpNetif != NULL; tmpNetif = tmpNetif->next) {
0213 if (tmpNetif->next == netif) {
0214 tmpNetif->next = netif->next;
0215 snmp_dec_iflist();
0216 break;
0217 }
0218 }
0219 if (tmpNetif == NULL)
0220 return;
0221 }
0222
0223 if (netif_default == netif)
0224
0225 netif_set_default(NULL);
0226 LWIP_DEBUGF( NETIF_DEBUG, ("netif_remove: removed netif\n") );
0227 }
0228
0229
0230
0231
0232
0233
0234
0235 struct netif *
0236 netif_find(char *name)
0237 {
0238 struct netif *netif;
0239 u8_t num;
0240
0241 if (name == NULL) {
0242 return NULL;
0243 }
0244
0245 num = name[2] - '0';
0246
0247 for(netif = netif_list; netif != NULL; netif = netif->next) {
0248 if (num == netif->num &&
0249 name[0] == netif->name[0] &&
0250 name[1] == netif->name[1]) {
0251 LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: found %c%c\n", name[0], name[1]));
0252 return netif;
0253 }
0254 }
0255 LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: didn't find %c%c\n", name[0], name[1]));
0256 return NULL;
0257 }
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268 void
0269 netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr)
0270 {
0271
0272
0273 #if LWIP_TCP
0274 struct tcp_pcb *pcb;
0275 struct tcp_pcb_listen *lpcb;
0276
0277
0278 if ((ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0)
0279 {
0280
0281 LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: netif address being changed\n"));
0282 pcb = tcp_active_pcbs;
0283 while (pcb != NULL) {
0284
0285 if (ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))) {
0286
0287 struct tcp_pcb *next = pcb->next;
0288 LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb));
0289 tcp_abort(pcb);
0290 pcb = next;
0291 } else {
0292 pcb = pcb->next;
0293 }
0294 }
0295 for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
0296
0297 if ((!(ip_addr_isany(&(lpcb->local_ip)))) &&
0298 (ip_addr_cmp(&(lpcb->local_ip), &(netif->ip_addr)))) {
0299
0300
0301 ip_addr_set(&(lpcb->local_ip), ipaddr);
0302 }
0303 }
0304 }
0305 #endif
0306 snmp_delete_ipaddridx_tree(netif);
0307 snmp_delete_iprteidx_tree(0,netif);
0308
0309 ip_addr_set(&(netif->ip_addr), ipaddr);
0310 snmp_insert_ipaddridx_tree(netif);
0311 snmp_insert_iprteidx_tree(0,netif);
0312
0313 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",
0314 netif->name[0], netif->name[1],
0315 ip4_addr1(&netif->ip_addr),
0316 ip4_addr2(&netif->ip_addr),
0317 ip4_addr3(&netif->ip_addr),
0318 ip4_addr4(&netif->ip_addr)));
0319 }
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329 void
0330 netif_set_gw(struct netif *netif, struct ip_addr *gw)
0331 {
0332 ip_addr_set(&(netif->gw), gw);
0333 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",
0334 netif->name[0], netif->name[1],
0335 ip4_addr1(&netif->gw),
0336 ip4_addr2(&netif->gw),
0337 ip4_addr3(&netif->gw),
0338 ip4_addr4(&netif->gw)));
0339 }
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350 void
0351 netif_set_netmask(struct netif *netif, struct ip_addr *netmask)
0352 {
0353 snmp_delete_iprteidx_tree(0, netif);
0354
0355 ip_addr_set(&(netif->netmask), netmask);
0356 snmp_insert_iprteidx_tree(0, netif);
0357 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",
0358 netif->name[0], netif->name[1],
0359 ip4_addr1(&netif->netmask),
0360 ip4_addr2(&netif->netmask),
0361 ip4_addr3(&netif->netmask),
0362 ip4_addr4(&netif->netmask)));
0363 }
0364
0365
0366
0367
0368
0369
0370
0371 void
0372 netif_set_default(struct netif *netif)
0373 {
0374 if (netif == NULL)
0375 {
0376
0377 snmp_delete_iprteidx_tree(1, netif);
0378 }
0379 else
0380 {
0381
0382 snmp_insert_iprteidx_tree(1, netif);
0383 }
0384 netif_default = netif;
0385 LWIP_DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%c\n",
0386 netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\''));
0387 }
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398 void netif_set_up(struct netif *netif)
0399 {
0400 if ( !(netif->flags & NETIF_FLAG_UP )) {
0401 netif->flags |= NETIF_FLAG_UP;
0402
0403 #if LWIP_SNMP
0404 snmp_get_sysuptime(&netif->ts);
0405 #endif
0406
0407 NETIF_LINK_CALLBACK(netif);
0408 NETIF_STATUS_CALLBACK(netif);
0409
0410 #if LWIP_ARP
0411
0412 if (netif->flags & NETIF_FLAG_ETHARP) {
0413 etharp_gratuitous(netif);
0414 }
0415 #endif
0416
0417 #if LWIP_IGMP
0418
0419 if (netif->flags & NETIF_FLAG_IGMP) {
0420 igmp_report_groups( netif);
0421 }
0422 #endif
0423 }
0424 }
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434 void netif_set_down(struct netif *netif)
0435 {
0436 if ( netif->flags & NETIF_FLAG_UP )
0437 {
0438 netif->flags &= ~NETIF_FLAG_UP;
0439 #if LWIP_SNMP
0440 snmp_get_sysuptime(&netif->ts);
0441 #endif
0442
0443 NETIF_LINK_CALLBACK(netif);
0444 NETIF_STATUS_CALLBACK(netif);
0445 }
0446 }
0447
0448
0449
0450
0451 u8_t netif_is_up(struct netif *netif)
0452 {
0453 return (netif->flags & NETIF_FLAG_UP)?1:0;
0454 }
0455
0456 #if LWIP_NETIF_STATUS_CALLBACK
0457
0458
0459
0460 void netif_set_status_callback(struct netif *netif, void (* status_callback)(struct netif *netif ))
0461 {
0462 if ( netif )
0463 netif->status_callback = status_callback;
0464 }
0465 #endif
0466
0467 #if LWIP_NETIF_LINK_CALLBACK
0468
0469
0470
0471 void netif_set_link_up(struct netif *netif )
0472 {
0473 netif->flags |= NETIF_FLAG_LINK_UP;
0474
0475 #if LWIP_DHCP
0476 if (netif->dhcp) {
0477 dhcp_network_changed(netif);
0478 }
0479 #endif
0480
0481 #if LWIP_AUTOIP
0482 if (netif->autoip) {
0483 autoip_network_changed(netif);
0484 }
0485 #endif
0486
0487 if (netif->flags & NETIF_FLAG_UP) {
0488 #if LWIP_ARP
0489
0490 if (netif->flags & NETIF_FLAG_ETHARP) {
0491 etharp_gratuitous(netif);
0492 }
0493 #endif
0494
0495 #if LWIP_IGMP
0496
0497 if (netif->flags & NETIF_FLAG_IGMP) {
0498 igmp_report_groups( netif);
0499 }
0500 #endif
0501 }
0502 NETIF_LINK_CALLBACK(netif);
0503 }
0504
0505
0506
0507
0508 void netif_set_link_down(struct netif *netif )
0509 {
0510 netif->flags &= ~NETIF_FLAG_LINK_UP;
0511 NETIF_LINK_CALLBACK(netif);
0512 }
0513
0514
0515
0516
0517 u8_t netif_is_link_up(struct netif *netif)
0518 {
0519 return (netif->flags & NETIF_FLAG_LINK_UP) ? 1 : 0;
0520 }
0521
0522
0523
0524
0525 void netif_set_link_callback(struct netif *netif, void (* link_callback)(struct netif *netif ))
0526 {
0527 if (netif) {
0528 netif->link_callback = link_callback;
0529 }
0530 }
0531 #endif
0532
0533 #if ENABLE_LOOPBACK
0534
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545
0546
0547
0548 err_t
0549 netif_loop_output(struct netif *netif, struct pbuf *p,
0550 struct ip_addr *ipaddr)
0551 {
0552 struct pbuf *r;
0553 err_t err;
0554 struct pbuf *last;
0555 #if LWIP_LOOPBACK_MAX_PBUFS
0556 u8_t clen = 0;
0557 #endif
0558 SYS_ARCH_DECL_PROTECT(lev);
0559 LWIP_UNUSED_ARG(ipaddr);
0560
0561
0562 r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM);
0563 if (r == NULL) {
0564 return ERR_MEM;
0565 }
0566 #if LWIP_LOOPBACK_MAX_PBUFS
0567 clen = pbuf_clen(r);
0568
0569 if(((netif->loop_cnt_current + clen) < netif->loop_cnt_current) ||
0570 ((netif->loop_cnt_current + clen) > LWIP_LOOPBACK_MAX_PBUFS)) {
0571 pbuf_free(r);
0572 r = NULL;
0573 return ERR_MEM;
0574 }
0575 netif->loop_cnt_current += clen;
0576 #endif
0577
0578
0579 if ((err = pbuf_copy(r, p)) != ERR_OK) {
0580 pbuf_free(r);
0581 r = NULL;
0582 return err;
0583 }
0584
0585
0586
0587
0588
0589 for (last = r; last->next != NULL; last = last->next);
0590
0591 SYS_ARCH_PROTECT(lev);
0592 if(netif->loop_first != NULL) {
0593 LWIP_ASSERT("if first != NULL, last must also be != NULL", netif->loop_last != NULL);
0594 netif->loop_last->next = r;
0595 netif->loop_last = last;
0596 } else {
0597 netif->loop_first = r;
0598 netif->loop_last = last;
0599 }
0600 SYS_ARCH_UNPROTECT(lev);
0601
0602 #if LWIP_NETIF_LOOPBACK_MULTITHREADING
0603
0604 tcpip_callback((void (*)(void *))(netif_poll), netif);
0605 #endif
0606
0607 return ERR_OK;
0608 }
0609
0610
0611
0612
0613
0614
0615
0616 void
0617 netif_poll(struct netif *netif)
0618 {
0619 struct pbuf *in;
0620 SYS_ARCH_DECL_PROTECT(lev);
0621
0622 do {
0623
0624 SYS_ARCH_PROTECT(lev);
0625 in = netif->loop_first;
0626 if(in != NULL) {
0627 struct pbuf *in_end = in;
0628 #if LWIP_LOOPBACK_MAX_PBUFS
0629 u8_t clen = pbuf_clen(in);
0630
0631 LWIP_ASSERT("netif->loop_cnt_current underflow",
0632 ((netif->loop_cnt_current - clen) < netif->loop_cnt_current));
0633 netif->loop_cnt_current -= clen;
0634 #endif
0635 while(in_end->len != in_end->tot_len) {
0636 LWIP_ASSERT("bogus pbuf: len != tot_len but next == NULL!", in_end->next != NULL);
0637 in_end = in_end->next;
0638 }
0639
0640 if(in_end == netif->loop_last) {
0641
0642 netif->loop_first = netif->loop_last = NULL;
0643 } else {
0644
0645 netif->loop_first = in_end->next;
0646 LWIP_ASSERT("should not be null since first != last!", netif->loop_first != NULL);
0647 }
0648
0649 in_end->next = NULL;
0650 }
0651 SYS_ARCH_UNPROTECT(lev);
0652
0653 if(in != NULL) {
0654
0655 if(ip_input(in, netif) != ERR_OK) {
0656 pbuf_free(in);
0657 }
0658
0659 in = NULL;
0660 }
0661
0662 } while(netif->loop_first != NULL);
0663 }
0664
0665 #if !LWIP_NETIF_LOOPBACK_MULTITHREADING
0666
0667
0668
0669 void
0670 netif_poll_all(void)
0671 {
0672 struct netif *netif = netif_list;
0673
0674 while (netif != NULL) {
0675 netif_poll(netif);
0676
0677 netif = netif->next;
0678 }
0679 }
0680 #endif
0681 #endif