00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "lwip/opt.h"
00040
00041 #include "lwip/def.h"
00042 #include "lwip/ip_addr.h"
00043 #include "lwip/netif.h"
00044 #include "lwip/tcp.h"
00045 #include "lwip/snmp.h"
00046 #include "lwip/igmp.h"
00047 #include "netif/etharp.h"
00048 #if ENABLE_LOOPBACK
00049 #include "lwip/sys.h"
00050 #if LWIP_NETIF_LOOPBACK_MULTITHREADING
00051 #include "lwip/tcpip.h"
00052 #endif
00053 #endif
00054
00055 #if LWIP_AUTOIP
00056 #include "lwip/autoip.h"
00057 #endif
00058 #if LWIP_DHCP
00059 #include "lwip/dhcp.h"
00060 #endif
00061
00062 #if LWIP_NETIF_STATUS_CALLBACK
00063 #define NETIF_STATUS_CALLBACK(n) { if (n->status_callback) (n->status_callback)(n); }
00064 #else
00065 #define NETIF_STATUS_CALLBACK(n) { }
00066 #endif
00067
00068 #if LWIP_NETIF_LINK_CALLBACK
00069 #define NETIF_LINK_CALLBACK(n) { if (n->link_callback) (n->link_callback)(n); }
00070 #else
00071 #define NETIF_LINK_CALLBACK(n) { }
00072 #endif
00073
00074 struct netif *netif_list;
00075 struct netif *netif_default;
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 struct netif *
00092 netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,
00093 struct ip_addr *gw,
00094 void *state,
00095 err_t (* init)(struct netif *netif),
00096 err_t (* input)(struct pbuf *p, struct netif *netif))
00097 {
00098 static u8_t netifnum = 0;
00099
00100
00101 netif->ip_addr.addr = 0;
00102 netif->netmask.addr = 0;
00103 netif->gw.addr = 0;
00104 netif->flags = 0;
00105 #if LWIP_DHCP
00106
00107 netif->dhcp = NULL;
00108 #endif
00109 #if LWIP_AUTOIP
00110
00111 netif->autoip = NULL;
00112 #endif
00113 #if LWIP_NETIF_STATUS_CALLBACK
00114 netif->status_callback = NULL;
00115 #endif
00116 #if LWIP_NETIF_LINK_CALLBACK
00117 netif->link_callback = NULL;
00118 #endif
00119 #if LWIP_IGMP
00120 netif->igmp_mac_filter = NULL;
00121 #endif
00122 #if ENABLE_LOOPBACK
00123 netif->loop_first = NULL;
00124 netif->loop_last = NULL;
00125 #endif
00126
00127
00128 netif->state = state;
00129 netif->num = netifnum++;
00130 netif->input = input;
00131 #if LWIP_NETIF_HWADDRHINT
00132 netif->addr_hint = NULL;
00133 #endif
00134 #if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS
00135 netif->loop_cnt_current = 0;
00136 #endif
00137
00138 netif_set_addr(netif, ipaddr, netmask, gw);
00139
00140
00141 if (init(netif) != ERR_OK) {
00142 return NULL;
00143 }
00144
00145
00146 netif->next = netif_list;
00147 netif_list = netif;
00148 snmp_inc_iflist();
00149
00150 #if LWIP_IGMP
00151
00152 if (netif->flags & NETIF_FLAG_IGMP) {
00153 igmp_start( netif);
00154 }
00155 #endif
00156
00157 LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP addr ",
00158 netif->name[0], netif->name[1]));
00159 ip_addr_debug_print(NETIF_DEBUG, ipaddr);
00160 LWIP_DEBUGF(NETIF_DEBUG, (" netmask "));
00161 ip_addr_debug_print(NETIF_DEBUG, netmask);
00162 LWIP_DEBUGF(NETIF_DEBUG, (" gw "));
00163 ip_addr_debug_print(NETIF_DEBUG, gw);
00164 LWIP_DEBUGF(NETIF_DEBUG, ("\n"));
00165 return netif;
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 void
00178 netif_set_addr(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,
00179 struct ip_addr *gw)
00180 {
00181 netif_set_ipaddr(netif, ipaddr);
00182 netif_set_netmask(netif, netmask);
00183 netif_set_gw(netif, gw);
00184 }
00185
00186
00187
00188
00189
00190
00191 void netif_remove(struct netif * netif)
00192 {
00193 if ( netif == NULL ) return;
00194
00195 #if LWIP_IGMP
00196
00197 if (netif->flags & NETIF_FLAG_IGMP) {
00198 igmp_stop( netif);
00199 }
00200 #endif
00201
00202 snmp_delete_ipaddridx_tree(netif);
00203
00204
00205 if (netif_list == netif) {
00206 netif_list = netif->next;
00207 snmp_dec_iflist();
00208 }
00209 else {
00210
00211 struct netif * tmpNetif;
00212 for (tmpNetif = netif_list; tmpNetif != NULL; tmpNetif = tmpNetif->next) {
00213 if (tmpNetif->next == netif) {
00214 tmpNetif->next = netif->next;
00215 snmp_dec_iflist();
00216 break;
00217 }
00218 }
00219 if (tmpNetif == NULL)
00220 return;
00221 }
00222
00223 if (netif_default == netif)
00224
00225 netif_set_default(NULL);
00226 LWIP_DEBUGF( NETIF_DEBUG, ("netif_remove: removed netif\n") );
00227 }
00228
00229
00230
00231
00232
00233
00234
00235 struct netif *
00236 netif_find(char *name)
00237 {
00238 struct netif *netif;
00239 u8_t num;
00240
00241 if (name == NULL) {
00242 return NULL;
00243 }
00244
00245 num = name[2] - '0';
00246
00247 for(netif = netif_list; netif != NULL; netif = netif->next) {
00248 if (num == netif->num &&
00249 name[0] == netif->name[0] &&
00250 name[1] == netif->name[1]) {
00251 LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: found %c%c\n", name[0], name[1]));
00252 return netif;
00253 }
00254 }
00255 LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: didn't find %c%c\n", name[0], name[1]));
00256 return NULL;
00257 }
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 void
00269 netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr)
00270 {
00271
00272
00273 #if LWIP_TCP
00274 struct tcp_pcb *pcb;
00275 struct tcp_pcb_listen *lpcb;
00276
00277
00278 if ((ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0)
00279 {
00280
00281 LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: netif address being changed\n"));
00282 pcb = tcp_active_pcbs;
00283 while (pcb != NULL) {
00284
00285 if (ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))) {
00286
00287 struct tcp_pcb *next = pcb->next;
00288 LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb));
00289 tcp_abort(pcb);
00290 pcb = next;
00291 } else {
00292 pcb = pcb->next;
00293 }
00294 }
00295 for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
00296
00297 if ((!(ip_addr_isany(&(lpcb->local_ip)))) &&
00298 (ip_addr_cmp(&(lpcb->local_ip), &(netif->ip_addr)))) {
00299
00300
00301 ip_addr_set(&(lpcb->local_ip), ipaddr);
00302 }
00303 }
00304 }
00305 #endif
00306 snmp_delete_ipaddridx_tree(netif);
00307 snmp_delete_iprteidx_tree(0,netif);
00308
00309 ip_addr_set(&(netif->ip_addr), ipaddr);
00310 snmp_insert_ipaddridx_tree(netif);
00311 snmp_insert_iprteidx_tree(0,netif);
00312
00313 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",
00314 netif->name[0], netif->name[1],
00315 ip4_addr1(&netif->ip_addr),
00316 ip4_addr2(&netif->ip_addr),
00317 ip4_addr3(&netif->ip_addr),
00318 ip4_addr4(&netif->ip_addr)));
00319 }
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 void
00330 netif_set_gw(struct netif *netif, struct ip_addr *gw)
00331 {
00332 ip_addr_set(&(netif->gw), gw);
00333 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",
00334 netif->name[0], netif->name[1],
00335 ip4_addr1(&netif->gw),
00336 ip4_addr2(&netif->gw),
00337 ip4_addr3(&netif->gw),
00338 ip4_addr4(&netif->gw)));
00339 }
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 void
00351 netif_set_netmask(struct netif *netif, struct ip_addr *netmask)
00352 {
00353 snmp_delete_iprteidx_tree(0, netif);
00354
00355 ip_addr_set(&(netif->netmask), netmask);
00356 snmp_insert_iprteidx_tree(0, netif);
00357 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",
00358 netif->name[0], netif->name[1],
00359 ip4_addr1(&netif->netmask),
00360 ip4_addr2(&netif->netmask),
00361 ip4_addr3(&netif->netmask),
00362 ip4_addr4(&netif->netmask)));
00363 }
00364
00365
00366
00367
00368
00369
00370
00371 void
00372 netif_set_default(struct netif *netif)
00373 {
00374 if (netif == NULL)
00375 {
00376
00377 snmp_delete_iprteidx_tree(1, netif);
00378 }
00379 else
00380 {
00381
00382 snmp_insert_iprteidx_tree(1, netif);
00383 }
00384 netif_default = netif;
00385 LWIP_DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%c\n",
00386 netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\''));
00387 }
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398 void netif_set_up(struct netif *netif)
00399 {
00400 if ( !(netif->flags & NETIF_FLAG_UP )) {
00401 netif->flags |= NETIF_FLAG_UP;
00402
00403 #if LWIP_SNMP
00404 snmp_get_sysuptime(&netif->ts);
00405 #endif
00406
00407 NETIF_LINK_CALLBACK(netif);
00408 NETIF_STATUS_CALLBACK(netif);
00409
00410 #if LWIP_ARP
00411
00412 if (netif->flags & NETIF_FLAG_ETHARP) {
00413 etharp_gratuitous(netif);
00414 }
00415 #endif
00416
00417 #if LWIP_IGMP
00418
00419 if (netif->flags & NETIF_FLAG_IGMP) {
00420 igmp_report_groups( netif);
00421 }
00422 #endif
00423 }
00424 }
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434 void netif_set_down(struct netif *netif)
00435 {
00436 if ( netif->flags & NETIF_FLAG_UP )
00437 {
00438 netif->flags &= ~NETIF_FLAG_UP;
00439 #if LWIP_SNMP
00440 snmp_get_sysuptime(&netif->ts);
00441 #endif
00442
00443 NETIF_LINK_CALLBACK(netif);
00444 NETIF_STATUS_CALLBACK(netif);
00445 }
00446 }
00447
00448
00449
00450
00451 u8_t netif_is_up(struct netif *netif)
00452 {
00453 return (netif->flags & NETIF_FLAG_UP)?1:0;
00454 }
00455
00456 #if LWIP_NETIF_STATUS_CALLBACK
00457
00458
00459
00460 void netif_set_status_callback(struct netif *netif, void (* status_callback)(struct netif *netif ))
00461 {
00462 if ( netif )
00463 netif->status_callback = status_callback;
00464 }
00465 #endif
00466
00467 #if LWIP_NETIF_LINK_CALLBACK
00468
00469
00470
00471 void netif_set_link_up(struct netif *netif )
00472 {
00473 netif->flags |= NETIF_FLAG_LINK_UP;
00474
00475 #if LWIP_DHCP
00476 if (netif->dhcp) {
00477 dhcp_network_changed(netif);
00478 }
00479 #endif
00480
00481 #if LWIP_AUTOIP
00482 if (netif->autoip) {
00483 autoip_network_changed(netif);
00484 }
00485 #endif
00486
00487 if (netif->flags & NETIF_FLAG_UP) {
00488 #if LWIP_ARP
00489
00490 if (netif->flags & NETIF_FLAG_ETHARP) {
00491 etharp_gratuitous(netif);
00492 }
00493 #endif
00494
00495 #if LWIP_IGMP
00496
00497 if (netif->flags & NETIF_FLAG_IGMP) {
00498 igmp_report_groups( netif);
00499 }
00500 #endif
00501 }
00502 NETIF_LINK_CALLBACK(netif);
00503 }
00504
00505
00506
00507
00508 void netif_set_link_down(struct netif *netif )
00509 {
00510 netif->flags &= ~NETIF_FLAG_LINK_UP;
00511 NETIF_LINK_CALLBACK(netif);
00512 }
00513
00514
00515
00516
00517 u8_t netif_is_link_up(struct netif *netif)
00518 {
00519 return (netif->flags & NETIF_FLAG_LINK_UP) ? 1 : 0;
00520 }
00521
00522
00523
00524
00525 void netif_set_link_callback(struct netif *netif, void (* link_callback)(struct netif *netif ))
00526 {
00527 if (netif) {
00528 netif->link_callback = link_callback;
00529 }
00530 }
00531 #endif
00532
00533 #if ENABLE_LOOPBACK
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548 err_t
00549 netif_loop_output(struct netif *netif, struct pbuf *p,
00550 struct ip_addr *ipaddr)
00551 {
00552 struct pbuf *r;
00553 err_t err;
00554 struct pbuf *last;
00555 #if LWIP_LOOPBACK_MAX_PBUFS
00556 u8_t clen = 0;
00557 #endif
00558 SYS_ARCH_DECL_PROTECT(lev);
00559 LWIP_UNUSED_ARG(ipaddr);
00560
00561
00562 r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM);
00563 if (r == NULL) {
00564 return ERR_MEM;
00565 }
00566 #if LWIP_LOOPBACK_MAX_PBUFS
00567 clen = pbuf_clen(r);
00568
00569 if(((netif->loop_cnt_current + clen) < netif->loop_cnt_current) ||
00570 ((netif->loop_cnt_current + clen) > LWIP_LOOPBACK_MAX_PBUFS)) {
00571 pbuf_free(r);
00572 r = NULL;
00573 return ERR_MEM;
00574 }
00575 netif->loop_cnt_current += clen;
00576 #endif
00577
00578
00579 if ((err = pbuf_copy(r, p)) != ERR_OK) {
00580 pbuf_free(r);
00581 r = NULL;
00582 return err;
00583 }
00584
00585
00586
00587
00588
00589 for (last = r; last->next != NULL; last = last->next);
00590
00591 SYS_ARCH_PROTECT(lev);
00592 if(netif->loop_first != NULL) {
00593 LWIP_ASSERT("if first != NULL, last must also be != NULL", netif->loop_last != NULL);
00594 netif->loop_last->next = r;
00595 netif->loop_last = last;
00596 } else {
00597 netif->loop_first = r;
00598 netif->loop_last = last;
00599 }
00600 SYS_ARCH_UNPROTECT(lev);
00601
00602 #if LWIP_NETIF_LOOPBACK_MULTITHREADING
00603
00604 tcpip_callback((void (*)(void *))(netif_poll), netif);
00605 #endif
00606
00607 return ERR_OK;
00608 }
00609
00610
00611
00612
00613
00614
00615
00616 void
00617 netif_poll(struct netif *netif)
00618 {
00619 struct pbuf *in;
00620 SYS_ARCH_DECL_PROTECT(lev);
00621
00622 do {
00623
00624 SYS_ARCH_PROTECT(lev);
00625 in = netif->loop_first;
00626 if(in != NULL) {
00627 struct pbuf *in_end = in;
00628 #if LWIP_LOOPBACK_MAX_PBUFS
00629 u8_t clen = pbuf_clen(in);
00630
00631 LWIP_ASSERT("netif->loop_cnt_current underflow",
00632 ((netif->loop_cnt_current - clen) < netif->loop_cnt_current));
00633 netif->loop_cnt_current -= clen;
00634 #endif
00635 while(in_end->len != in_end->tot_len) {
00636 LWIP_ASSERT("bogus pbuf: len != tot_len but next == NULL!", in_end->next != NULL);
00637 in_end = in_end->next;
00638 }
00639
00640 if(in_end == netif->loop_last) {
00641
00642 netif->loop_first = netif->loop_last = NULL;
00643 } else {
00644
00645 netif->loop_first = in_end->next;
00646 LWIP_ASSERT("should not be null since first != last!", netif->loop_first != NULL);
00647 }
00648
00649 in_end->next = NULL;
00650 }
00651 SYS_ARCH_UNPROTECT(lev);
00652
00653 if(in != NULL) {
00654
00655 if(ip_input(in, netif) != ERR_OK) {
00656 pbuf_free(in);
00657 }
00658
00659 in = NULL;
00660 }
00661
00662 } while(netif->loop_first != NULL);
00663 }
00664
00665 #if !LWIP_NETIF_LOOPBACK_MULTITHREADING
00666
00667
00668
00669 void
00670 netif_poll_all(void)
00671 {
00672 struct netif *netif = netif_list;
00673
00674 while (netif != NULL) {
00675 netif_poll(netif);
00676
00677 netif = netif->next;
00678 }
00679 }
00680 #endif
00681 #endif