88 #if LWIP_NETIF_LOOPBACK_MULTITHREADING 111 #if LWIP_NETIF_STATUS_CALLBACK 112 #define NETIF_STATUS_CALLBACK(n) do{ if (n->status_callback) { (n->status_callback)(n); }}while(0) 114 #define NETIF_STATUS_CALLBACK(n) 117 #if LWIP_NETIF_LINK_CALLBACK 118 #define NETIF_LINK_CALLBACK(n) do{ if (n->link_callback) { (n->link_callback)(n); }}while(0) 120 #define NETIF_LINK_CALLBACK(n) 126 static u8_t netif_num;
128 #if LWIP_NUM_NETIF_CLIENT_DATA > 0 129 static u8_t netif_client_id;
132 #define NETIF_REPORT_TYPE_IPV4 0x01 133 #define NETIF_REPORT_TYPE_IPV6 0x02 134 static void netif_issue_reports(
struct netif*
netif, u8_t report_type);
137 static err_t netif_null_output_ip6(
struct netif *
netif,
struct pbuf *p,
const ip6_addr_t *ipaddr);
142 static err_t netif_loop_output_ipv4(
struct netif *
netif,
struct pbuf *p,
const ip4_addr_t* addr);
145 static err_t netif_loop_output_ipv6(
struct netif *
netif,
struct pbuf *p,
const ip6_addr_t* addr);
149 static struct netif loop_netif;
164 MIB2_INIT_NETIF(netif, snmp_ifType_softwareLoopback, 0);
166 netif->
name[0] =
'l';
167 netif->
name[1] =
'o';
169 netif->output = netif_loop_output_ipv4;
172 netif->output_ip6 = netif_loop_output_ipv6;
174 #if LWIP_LOOPIF_MULTICAST 186 #define LOOPIF_ADDRINIT &loop_ipaddr, &loop_netmask, &loop_gw, 187 ip4_addr_t loop_ipaddr, loop_netmask, loop_gw;
188 IP4_ADDR(&loop_gw, 127,0,0,1);
189 IP4_ADDR(&loop_ipaddr, 127,0,0,1);
190 IP4_ADDR(&loop_netmask, 255,0,0,0);
192 #define LOOPIF_ADDRINIT 196 netif_add(&loop_netif, LOOPIF_ADDRINIT NULL, netif_loopif_init, ip_input);
202 IP_ADDR6_HOST(loop_netif.ip6_addr, 0, 0, 0, 0x00000001UL);
203 loop_netif.ip6_addr_state[0] = IP6_ADDR_VALID;
226 return ethernet_input(p, inp);
229 return ip_input(p, inp);
262 const ip4_addr_t *ipaddr,
const ip4_addr_t *netmask,
const ip4_addr_t *gw,
270 LWIP_ASSERT(
"No init function given", init != NULL);
274 ip_addr_set_zero_ip4(&netif->ip_addr);
275 ip_addr_set_zero_ip4(&netif->netmask);
276 ip_addr_set_zero_ip4(&netif->gw);
280 ip_addr_set_zero_ip6(&netif->ip6_addr[i]);
281 netif->ip6_addr_state[i] = IP6_ADDR_INVALID;
283 netif->output_ip6 = netif_null_output_ip6;
285 NETIF_SET_CHECKSUM_CTRL(netif, NETIF_CHECKSUM_ENABLE_ALL);
287 #ifdef netif_get_client_data 288 memset(netif->client_data, 0,
sizeof(netif->client_data));
290 #if LWIP_IPV6_AUTOCONFIG 292 netif->ip6_autoconfig_enabled = 0;
294 #if LWIP_IPV6_SEND_ROUTER_SOLICIT 297 #if LWIP_NETIF_STATUS_CALLBACK 298 netif->status_callback = NULL;
300 #if LWIP_NETIF_LINK_CALLBACK 301 netif->link_callback = NULL;
304 netif->igmp_mac_filter = NULL;
306 #if LWIP_IPV6 && LWIP_IPV6_MLD 307 netif->mld_mac_filter = NULL;
310 netif->loop_first = NULL;
311 netif->loop_last = NULL;
316 netif->
num = netif_num++;
319 NETIF_SET_HWADDRHINT(netif, NULL);
320 #if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS 321 netif->loop_cnt_current = 0;
325 netif_set_addr(netif, ipaddr, netmask, gw);
329 if (init(netif) !=
ERR_OK) {
336 mib2_netif_added(netif);
371 netif_set_addr(
struct netif *
netif,
const ip4_addr_t *ipaddr,
const ip4_addr_t *netmask,
372 const ip4_addr_t *gw)
374 if (ip4_addr_isany(ipaddr)) {
377 netif_set_ipaddr(netif, ipaddr);
378 netif_set_netmask(netif, netmask);
379 netif_set_gw(netif, gw);
381 netif_set_netmask(netif, netmask);
382 netif_set_gw(netif, gw);
384 netif_set_ipaddr(netif, ipaddr);
407 if (!ip4_addr_isany_val(*netif_ip4_addr(netif))) {
409 tcp_netif_ip_addr_changed(netif_ip_addr4(netif), NULL);
412 udp_netif_ip_addr_changed(netif_ip_addr4(netif), NULL);
415 raw_netif_ip_addr_changed(netif_ip_addr4(netif), NULL);
429 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i))) {
431 tcp_netif_ip_addr_changed(netif_ip_addr6(netif, i), NULL);
434 udp_netif_ip_addr_changed(netif_ip_addr6(netif, i), NULL);
437 raw_netif_ip_addr_changed(netif_ip_addr6(netif, i), NULL);
451 mib2_remove_ip4(netif);
454 if (netif_default == netif) {
459 if (netif_list == netif) {
460 netif_list = netif->
next;
463 struct netif * tmp_netif;
464 for (tmp_netif = netif_list; tmp_netif != NULL; tmp_netif = tmp_netif->
next) {
465 if (tmp_netif->
next == netif) {
470 if (tmp_netif == NULL) {
474 mib2_netif_removed(netif);
475 #if LWIP_NETIF_REMOVE_CALLBACK 476 if (netif->remove_callback) {
477 netif->remove_callback(netif);
500 num = (u8_t)(name[2] -
'0');
502 for (netif = netif_list; netif != NULL; netif = netif->
next) {
503 if (num == netif->
num &&
504 name[0] == netif->
name[0] &&
505 name[1] == netif->
name[1]) {
526 netif_set_ipaddr(
struct netif *netif,
const ip4_addr_t *ipaddr)
529 *ip_2_ip4(&new_addr) = (ipaddr ? *ipaddr : *IP4_ADDR_ANY4);
533 if (ip4_addr_cmp(ip_2_ip4(&new_addr), netif_ip4_addr(netif)) == 0) {
536 tcp_netif_ip_addr_changed(netif_ip_addr4(netif), &new_addr);
539 udp_netif_ip_addr_changed(netif_ip_addr4(netif), &new_addr);
542 raw_netif_ip_addr_changed(netif_ip_addr4(netif), &new_addr);
545 mib2_remove_ip4(netif);
546 mib2_remove_route_ip4(0, netif);
548 ip4_addr_set(ip_2_ip4(&netif->ip_addr), ipaddr);
551 mib2_add_route_ip4(0, netif);
553 netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4);
555 NETIF_STATUS_CALLBACK(netif);
560 ip4_addr1_16(netif_ip4_addr(netif)),
561 ip4_addr2_16(netif_ip4_addr(netif)),
562 ip4_addr3_16(netif_ip4_addr(netif)),
563 ip4_addr4_16(netif_ip4_addr(netif))));
576 netif_set_gw(
struct netif *netif,
const ip4_addr_t *gw)
578 ip4_addr_set(ip_2_ip4(&netif->gw), gw);
582 ip4_addr1_16(netif_ip4_gw(netif)),
583 ip4_addr2_16(netif_ip4_gw(netif)),
584 ip4_addr3_16(netif_ip4_gw(netif)),
585 ip4_addr4_16(netif_ip4_gw(netif))));
599 netif_set_netmask(
struct netif *netif,
const ip4_addr_t *netmask)
601 mib2_remove_route_ip4(0, netif);
603 ip4_addr_set(ip_2_ip4(&netif->netmask), netmask);
605 mib2_add_route_ip4(0, netif);
608 ip4_addr1_16(netif_ip4_netmask(netif)),
609 ip4_addr2_16(netif_ip4_netmask(netif)),
610 ip4_addr3_16(netif_ip4_netmask(netif)),
611 ip4_addr4_16(netif_ip4_netmask(netif))));
627 mib2_remove_route_ip4(1, netif);
630 mib2_add_route_ip4(1, netif);
632 netif_default = netif;
634 netif ? netif->
name[0] :
'\'', netif ? netif->
name[1] :
'\''));
648 MIB2_COPY_SYSUPTIME_TO(&netif->ts);
650 NETIF_STATUS_CALLBACK(netif);
653 netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4|NETIF_REPORT_TYPE_IPV6);
661 netif_issue_reports(
struct netif* netif, u8_t report_type)
664 if ((report_type & NETIF_REPORT_TYPE_IPV4) &&
665 !ip4_addr_isany_val(*netif_ip4_addr(netif))) {
669 etharp_gratuitous(netif);
676 igmp_report_groups(netif);
683 if (report_type & NETIF_REPORT_TYPE_IPV6) {
686 mld6_report_groups(netif);
688 #if LWIP_IPV6_SEND_ROUTER_SOLICIT 705 MIB2_COPY_SYSUPTIME_TO(&netif->ts);
707 #if LWIP_IPV4 && LWIP_ARP 709 etharp_cleanup_netif(netif);
714 nd6_cleanup_netif(netif);
717 NETIF_STATUS_CALLBACK(netif);
721 #if LWIP_NETIF_STATUS_CALLBACK 730 netif->status_callback = status_callback;
735 #if LWIP_NETIF_REMOVE_CALLBACK 744 netif->remove_callback = remove_callback;
760 dhcp_network_changed(netif);
764 autoip_network_changed(netif);
768 netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4|NETIF_REPORT_TYPE_IPV6);
770 NETIF_LINK_CALLBACK(netif);
783 NETIF_LINK_CALLBACK(netif);
787 #if LWIP_NETIF_LINK_CALLBACK 796 netif->link_callback = link_callback;
817 netif_loop_output(
struct netif *netif,
struct pbuf *p)
822 #if LWIP_LOOPBACK_MAX_PBUFS 829 struct netif *stats_if = &loop_netif;
831 struct netif *stats_if = netif;
839 LINK_STATS_INC(link.memerr);
840 LINK_STATS_INC(link.drop);
841 MIB2_STATS_NETIF_INC(stats_if, ifoutdiscards);
844 #if LWIP_LOOPBACK_MAX_PBUFS 847 if (((netif->loop_cnt_current + clen) < netif->loop_cnt_current) ||
850 LINK_STATS_INC(link.memerr);
851 LINK_STATS_INC(link.drop);
852 MIB2_STATS_NETIF_INC(stats_if, ifoutdiscards);
855 netif->loop_cnt_current += clen;
861 LINK_STATS_INC(link.memerr);
862 LINK_STATS_INC(link.drop);
863 MIB2_STATS_NETIF_INC(stats_if, ifoutdiscards);
871 for (last = r; last->
next != NULL; last = last->
next);
873 SYS_ARCH_PROTECT(lev);
874 if (netif->loop_first != NULL) {
875 LWIP_ASSERT(
"if first != NULL, last must also be != NULL", netif->loop_last != NULL);
876 netif->loop_last->
next = r;
877 netif->loop_last = last;
879 netif->loop_first = r;
880 netif->loop_last = last;
882 SYS_ARCH_UNPROTECT(lev);
884 LINK_STATS_INC(link.xmit);
885 MIB2_STATS_NETIF_ADD(stats_if, ifoutoctets, p->
tot_len);
886 MIB2_STATS_NETIF_INC(stats_if, ifoutucastpkts);
888 #if LWIP_NETIF_LOOPBACK_MULTITHREADING 899 netif_loop_output_ipv4(
struct netif *netif,
struct pbuf *p,
const ip4_addr_t* addr)
902 return netif_loop_output(netif, p);
908 netif_loop_output_ipv6(
struct netif *netif,
struct pbuf *p,
const ip6_addr_t* addr)
911 return netif_loop_output(netif, p);
924 netif_poll(
struct netif *netif)
930 struct netif *stats_if = &loop_netif;
932 struct netif *stats_if = netif;
938 SYS_ARCH_PROTECT(lev);
939 while (netif->loop_first != NULL) {
940 struct pbuf *in, *in_end;
941 #if LWIP_LOOPBACK_MAX_PBUFS 945 in = in_end = netif->loop_first;
947 LWIP_ASSERT(
"bogus pbuf: len != tot_len but next == NULL!", in_end->
next != NULL);
948 in_end = in_end->
next;
949 #if LWIP_LOOPBACK_MAX_PBUFS 953 #if LWIP_LOOPBACK_MAX_PBUFS 955 LWIP_ASSERT(
"netif->loop_cnt_current underflow",
956 ((netif->loop_cnt_current - clen) < netif->loop_cnt_current));
957 netif->loop_cnt_current -= clen;
961 if (in_end == netif->loop_last) {
963 netif->loop_first = netif->loop_last = NULL;
966 netif->loop_first = in_end->
next;
967 LWIP_ASSERT(
"should not be null since first != last!", netif->loop_first != NULL);
971 SYS_ARCH_UNPROTECT(lev);
973 LINK_STATS_INC(link.recv);
974 MIB2_STATS_NETIF_ADD(stats_if, ifinoctets, in->
tot_len);
975 MIB2_STATS_NETIF_INC(stats_if, ifinucastpkts);
977 if (ip_input(in, netif) !=
ERR_OK) {
980 SYS_ARCH_PROTECT(lev);
982 SYS_ARCH_UNPROTECT(lev);
985 #if !LWIP_NETIF_LOOPBACK_MULTITHREADING 994 while (netif != NULL) {
1003 #if LWIP_NUM_NETIF_CLIENT_DATA > 0 1011 netif_alloc_client_data_id(
void)
1013 u8_t result = netif_client_id;
1017 return result + LWIP_NETIF_CLIENT_DATA_INDEX_MAX;
1033 netif_ip6_addr_set(
struct netif *netif, s8_t addr_idx,
const ip6_addr_t *addr6)
1035 LWIP_ASSERT(
"addr6 != NULL", addr6 != NULL);
1036 netif_ip6_addr_set_parts(netif, addr_idx, addr6->addr[0], addr6->addr[1],
1037 addr6->addr[2], addr6->addr[3]);
1051 netif_ip6_addr_set_parts(
struct netif *netif, s8_t addr_idx, u32_t i0, u32_t i1, u32_t i2, u32_t i3)
1053 const ip6_addr_t *old_addr;
1054 LWIP_ASSERT(
"netif != NULL", netif != NULL);
1057 old_addr = netif_ip6_addr(netif, addr_idx);
1059 if ((old_addr->addr[0] != i0) || (old_addr->addr[1] != i1) ||
1060 (old_addr->addr[2] != i2) || (old_addr->addr[3] != i3)) {
1063 if (netif_ip6_addr_state(netif, addr_idx) & IP6_ADDR_VALID) {
1064 #if LWIP_TCP || LWIP_UDP 1065 ip_addr_t new_ipaddr;
1066 IP_ADDR6(&new_ipaddr, i0, i1, i2, i3);
1069 tcp_netif_ip_addr_changed(netif_ip_addr6(netif, addr_idx), &new_ipaddr);
1072 udp_netif_ip_addr_changed(netif_ip_addr6(netif, addr_idx), &new_ipaddr);
1075 raw_netif_ip_addr_changed(netif_ip_addr6(netif, addr_idx), &new_ipaddr);
1080 IP6_ADDR(ip_2_ip6(&(netif->ip6_addr[addr_idx])), i0, i1, i2, i3);
1083 if (netif_ip6_addr_state(netif, addr_idx) & IP6_ADDR_VALID) {
1084 netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV6);
1085 NETIF_STATUS_CALLBACK(netif);
1090 addr_idx, netif->
name[0], netif->
name[1], ip6addr_ntoa(netif_ip6_addr(netif, addr_idx)),
1091 netif_ip6_addr_state(netif, addr_idx)));
1105 netif_ip6_addr_set_state(
struct netif* netif, s8_t addr_idx, u8_t
state)
1108 LWIP_ASSERT(
"netif != NULL", netif != NULL);
1111 old_state = netif_ip6_addr_state(netif, addr_idx);
1113 if (old_state != state) {
1114 u8_t old_valid = old_state & IP6_ADDR_VALID;
1115 u8_t new_valid = state & IP6_ADDR_VALID;
1121 nd6_adjust_mld_membership(netif, addr_idx, state);
1125 if (old_valid && !new_valid) {
1128 tcp_netif_ip_addr_changed(netif_ip_addr6(netif, addr_idx), NULL);
1131 udp_netif_ip_addr_changed(netif_ip_addr6(netif, addr_idx), NULL);
1134 raw_netif_ip_addr_changed(netif_ip_addr6(netif, addr_idx), NULL);
1138 netif->ip6_addr_state[addr_idx] =
state;
1140 if (!old_valid && new_valid) {
1143 netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV6);
1145 if ((old_state & IP6_ADDR_PREFERRED) != (state & IP6_ADDR_PREFERRED)) {
1148 NETIF_STATUS_CALLBACK(netif);
1153 addr_idx, netif->
name[0], netif->
name[1], ip6addr_ntoa(netif_ip6_addr(netif, addr_idx)),
1154 netif_ip6_addr_state(netif, addr_idx)));
1167 netif_get_ip6_addr_match(
struct netif *netif,
const ip6_addr_t *ip6addr)
1171 if (!ip6_addr_isinvalid(netif_ip6_addr_state(netif, i)) &&
1172 ip6_addr_cmp(netif_ip6_addr(netif, i), ip6addr)) {
1188 netif_create_ip6_linklocal_address(
struct netif *netif, u8_t from_mac_48bit)
1193 ip_2_ip6(&netif->ip6_addr[0])->addr[0] = PP_HTONL(0xfe800000ul);
1194 ip_2_ip6(&netif->ip6_addr[0])->addr[1] = 0;
1197 if (from_mac_48bit) {
1199 ip_2_ip6(&netif->ip6_addr[0])->addr[2] = lwip_htonl((((u32_t)(netif->
hwaddr[0] ^ 0x02)) << 24) |
1200 ((u32_t)(netif->
hwaddr[1]) << 16) |
1201 ((u32_t)(netif->
hwaddr[2]) << 8) |
1203 ip_2_ip6(&netif->ip6_addr[0])->addr[3] = lwip_htonl((0xfeul << 24) |
1204 ((u32_t)(netif->
hwaddr[3]) << 16) |
1205 ((u32_t)(netif->
hwaddr[4]) << 8) |
1209 ip_2_ip6(&netif->ip6_addr[0])->addr[2] = 0;
1210 ip_2_ip6(&netif->ip6_addr[0])->addr[3] = 0;
1213 for (i = 0; (i < 8) && (i < netif->
hwaddr_len); i++) {
1217 ip_2_ip6(&netif->ip6_addr[0])->addr[addr_index] |= ((u32_t)(netif->
hwaddr[netif->
hwaddr_len - i - 1])) << (8 * (i & 0x03));
1222 #if LWIP_IPV6_DUP_DETECT_ATTEMPTS 1224 netif_ip6_addr_set_state(netif, 0, IP6_ADDR_TENTATIVE);
1227 netif_ip6_addr_set_state(netif, 0, IP6_ADDR_PREFERRED);
1242 netif_add_ip6_address(
struct netif *netif,
const ip6_addr_t *ip6addr, s8_t *chosen_idx)
1246 i = netif_get_ip6_addr_match(netif, ip6addr);
1249 if (chosen_idx != NULL) {
1257 if (ip6_addr_isinvalid(netif_ip6_addr_state(netif, i))) {
1258 ip_addr_copy_from_ip6(netif->ip6_addr[i], *ip6addr);
1259 netif_ip6_addr_set_state(netif, i, IP6_ADDR_TENTATIVE);
1260 if (chosen_idx != NULL) {
1267 if (chosen_idx != NULL) {
1276 netif_null_output_ip6(
struct netif *netif,
struct pbuf *p,
const ip6_addr_t *ipaddr)
err_t(* netif_input_fn)(struct pbuf *p, struct netif *inp)
u8_t hwaddr[NETIF_MAX_HWADDR_LEN]
struct netif * netif_list
void(* netif_status_callback_fn)(struct netif *netif)
u16_t pbuf_clen(const struct pbuf *p)
struct netif * netif_default
void(* tcpip_callback_fn)(void *ctx)
struct netif * netif_add(struct netif *netif, void *state, netif_init_fn init, netif_input_fn input)
err_t tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block)
err_t pbuf_copy(struct pbuf *p_to, const struct pbuf *p_from)
err_t netif_input(struct pbuf *p, struct netif *inp)
#define SYS_ARCH_DECL_PROTECT(lev)
#define LWIP_ND6_MAX_MULTICAST_SOLICIT
void netif_set_link_down(struct netif *netif)
#define NETIF_FLAG_ETHERNET
err_t tcpip_input(struct pbuf *p, struct netif *inp)
#define NETIF_FLAG_LINK_UP
err_t(* netif_init_fn)(struct netif *netif)
void netif_set_up(struct netif *netif)
void netif_remove(struct netif *netif)
void netif_set_default(struct netif *netif)
struct netif * netif_find(const char *name)
#define LWIP_DEBUGF(debug, message)
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
#define netif_is_up(netif)
#define LWIP_NUM_NETIF_CLIENT_DATA
#define NETIF_FLAG_ETHARP
#define LWIP_LOOPBACK_MAX_PBUFS
#define LWIP_UNUSED_ARG(x)
u8_t pbuf_free(struct pbuf *p)
#define LWIP_IPV6_NUM_ADDRESSES
void netif_set_down(struct netif *netif)
void netif_set_link_up(struct netif *netif)