static int proxy_ip6_is_mapped_loopback(struct netif *netif, ip6_addr_t *dst) { int i; /* XXX: TODO: check netif is a proxying netif! */ LWIP_ASSERT1(dst != NULL); for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) { if (ip6_addr_ispreferred(netif_ip6_addr_state(netif, i)) && ip6_addr_isuniquelocal(netif_ip6_addr(netif, i))) { ip6_addr_t *ifaddr = netif_ip6_addr(netif, i); if (memcmp(dst, ifaddr, sizeof(ip6_addr_t) - 1) == 0 && ((IP6_ADDR_BLOCK8(dst) & 0xff) == (IP6_ADDR_BLOCK8(ifaddr) & 0xff) + 1)) { return 1; } } } return 0; }
/** * Mapping from local network to loopback for outbound connections. * * Copy "src" to "dst" with ip6_addr_set(dst, src), but if "src" is a * local network address that maps host's loopback address, copy IPv6 * loopback address to "dst". */ int pxremap_outbound_ip6(ip6_addr_t *dst, ip6_addr_t *src) { struct netif *netif; int i; LWIP_ASSERT1(dst != NULL); LWIP_ASSERT1(src != NULL); for (netif = netif_list; netif != NULL; netif = netif->next) { if (!netif_is_up(netif) /* || this is not a proxy netif */) { continue; } for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) { if (ip6_addr_ispreferred(netif_ip6_addr_state(netif, i)) && ip6_addr_isuniquelocal(netif_ip6_addr(netif, i))) { ip6_addr_t *ifaddr = netif_ip6_addr(netif, i); if (memcmp(src, ifaddr, sizeof(ip6_addr_t) - 1) == 0 && ((IP6_ADDR_BLOCK8(src) & 0xff) == (IP6_ADDR_BLOCK8(ifaddr) & 0xff) + 1)) { ip6_addr_set_loopback(dst); return PXREMAP_MAPPED; } } } } /* not remapped, just copy src */ ip6_addr_set(dst, src); return PXREMAP_ASIS; }
/** * Mapping from loopback to local network for inbound (port-forwarded) * connections. * * Copy "src" to "dst" with ip6_addr_set(dst, src), but if "src" is a * host's loopback address, copy local network address that maps it to * "dst". */ int pxremap_inbound_ip6(ip6_addr_t *dst, ip6_addr_t *src) { ip6_addr_t loopback; struct netif *netif; int i; ip6_addr_set_loopback(&loopback); if (!ip6_addr_cmp(src, &loopback)) { ip6_addr_set(dst, src); return PXREMAP_ASIS; } #if 0 /* ?TODO: with multiple interfaces we need to consider fwspec::dst */ netif = ip6_route_fwd(target); if (netif == NULL) { return PXREMAP_FAILED; } #else netif = netif_list; LWIP_ASSERT1(netif != NULL); LWIP_ASSERT1(netif->next == NULL); #endif for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) { ip6_addr_t *ifaddr = netif_ip6_addr(netif, i); if (ip6_addr_ispreferred(netif_ip6_addr_state(netif, i)) && ip6_addr_isuniquelocal(ifaddr)) { ip6_addr_set(dst, ifaddr); ++((u8_t *)&dst->addr[3])[3]; return PXREMAP_MAPPED; } } return PXREMAP_FAILED; }
/** * Select the best IPv6 source address for a given destination * IPv6 address. Loosely follows RFC 3484. "Strong host" behavior * is assumed. * * @param netif the netif on which to send a packet * @param dest the destination we are trying to reach * @return the most suitable source address to use, or NULL if no suitable * source address is found */ const ip_addr_t * ip6_select_source_address(struct netif *netif, const ip6_addr_t * dest) { const ip_addr_t *src = NULL; u8_t i; /* If dest is link-local, choose a link-local source. */ if (ip6_addr_islinklocal(dest) || ip6_addr_ismulticast_linklocal(dest) || ip6_addr_ismulticast_iflocal(dest)) { for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && ip6_addr_islinklocal(netif_ip6_addr(netif, i))) { return netif_ip_addr6(netif, i); } } } /* Choose a site-local with matching prefix. */ if (ip6_addr_issitelocal(dest) || ip6_addr_ismulticast_sitelocal(dest)) { for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && ip6_addr_issitelocal(netif_ip6_addr(netif, i)) && ip6_addr_netcmp(dest, netif_ip6_addr(netif, i))) { return netif_ip_addr6(netif, i); } } } /* Choose a unique-local with matching prefix. */ if (ip6_addr_isuniquelocal(dest) || ip6_addr_ismulticast_orglocal(dest)) { for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && ip6_addr_isuniquelocal(netif_ip6_addr(netif, i)) && ip6_addr_netcmp(dest, netif_ip6_addr(netif, i))) { return netif_ip_addr6(netif, i); } } } /* Choose a global with best matching prefix. */ if (ip6_addr_isglobal(dest) || ip6_addr_ismulticast_global(dest)) { for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && ip6_addr_isglobal(netif_ip6_addr(netif, i))) { if (src == NULL) { src = netif_ip_addr6(netif, i); } else { /* Replace src only if we find a prefix match. */ /* TODO find longest matching prefix. */ if ((!(ip6_addr_netcmp(ip_2_ip6(src), dest))) && ip6_addr_netcmp(netif_ip6_addr(netif, i), dest)) { src = netif_ip_addr6(netif, i); } } } } if (src != NULL) { return src; } } /* Last resort: see if arbitrary prefix matches. */ for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && ip6_addr_netcmp(dest, netif_ip6_addr(netif, i))) { return netif_ip_addr6(netif, i); } } return NULL; }
/********************************************************************************************************* ** 函数名称: __netIfShow ** 功能描述: 显示指定的网络接口信息 (ip v4) ** 输 入 : pcIfName 网络接口名 ** netifShow 网络接口结构 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ static VOID __netIfShow (CPCHAR pcIfName, const struct netif *netifShow) { struct netif *netif; CHAR cSpeed[32]; ip_addr_t ipaddrBroadcast; INT i; if ((pcIfName == LW_NULL) && (netifShow == LW_NULL)) { return; } if (netifShow) { netif = (struct netif *)netifShow; } else { netif = netif_find((PCHAR)pcIfName); } if (netif == LW_NULL) { return; } /* * 打印网口基本信息 */ printf("%c%c%d ", netif->name[0], netif->name[1], netif->num); printf("enable: %s ", (netif_is_up(netif) > 0) ? "true" : "false"); printf("linkup: %s ", (netif_is_link_up(netif) > 0) ? "true" : "false"); printf("MTU: %d ", netif->mtu); printf("multicast: %s\n", (netif->flags & NETIF_FLAG_IGMP) ? "true" : "false"); /* * 打印路由信息 */ if (netif == netif_default) { /* route interface */ printf(" metric: 1 "); } else { printf(" metric: 0 "); } /* * 打印网口硬件地址信息 */ if (netif->flags & NETIF_FLAG_ETHARP) { printf("type: Ethernet-Cap HWaddr: "); /* 以太网络 */ for (i = 0; i < netif->hwaddr_len - 1; i++) { printf("%02X:", netif->hwaddr[i]); } printf("%02X\n", netif->hwaddr[netif->hwaddr_len - 1]); } else if (netif->flags & NETIF_FLAG_POINTTOPOINT) { printf("type: WAN(PPP/SLIP)\n"); /* 点对点网络接口 */ } else { printf("type: General\n"); /* 通用网络接口 */ } __netIfSpeed(netif, cSpeed, sizeof(cSpeed)); #if LWIP_DHCP printf(" DHCP: %s(%s) speed: %s\n", (netif->flags2 & NETIF_FLAG2_DHCP) ? "Enable" : "Disable", (netif->dhcp) ? "On" : "Off", cSpeed); #else printf(" speed: %s\n", cSpeed); /* 打印链接速度 */ #endif /* LWIP_DHCP */ /* * 打印网口协议地址信息 */ printf(" inet addr: %d.%d.%d.%d ", ip4_addr1(&netif->ip_addr), ip4_addr2(&netif->ip_addr), ip4_addr3(&netif->ip_addr), ip4_addr4(&netif->ip_addr)); printf("netmask: %d.%d.%d.%d\n", ip4_addr1(&netif->netmask), ip4_addr2(&netif->netmask), ip4_addr3(&netif->netmask), ip4_addr4(&netif->netmask)); if (netif->flags & NETIF_FLAG_POINTTOPOINT) { printf(" P-to-P: %d.%d.%d.%d ", ip4_addr1(&netif->gw), ip4_addr2(&netif->gw), ip4_addr3(&netif->gw), ip4_addr4(&netif->gw)); } else { printf(" gateway: %d.%d.%d.%d ", ip4_addr1(&netif->gw), ip4_addr2(&netif->gw), ip4_addr3(&netif->gw), ip4_addr4(&netif->gw)); } if (netif->flags & NETIF_FLAG_BROADCAST) { /* 打印广播地址信息 */ ipaddrBroadcast.addr = (netif->ip_addr.addr | (~netif->netmask.addr)); printf("broadcast: %d.%d.%d.%d\n", ip4_addr1(&ipaddrBroadcast), ip4_addr2(&ipaddrBroadcast), ip4_addr3(&ipaddrBroadcast), ip4_addr4(&ipaddrBroadcast)); } else { printf("broadcast: Non\n"); } /* * 打印 ipv6 信息 */ for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { PCHAR pcAddrStat; PCHAR pcAddrType; CHAR cBuffer[64]; if (ip6_addr_istentative(netif->ip6_addr_state[i])) { pcAddrStat = "tentative"; } else if (ip6_addr_isvalid(netif->ip6_addr_state[i])) { pcAddrStat = "valid"; } else if (ip6_addr_ispreferred(netif->ip6_addr_state[i])) { pcAddrStat = "preferred"; } else { continue; } if (ip6_addr_isglobal(&netif->ip6_addr[i])) { pcAddrType = "global"; } else if (ip6_addr_islinklocal(&netif->ip6_addr[i])) { pcAddrType = "link"; } else if (ip6_addr_issitelocal(&netif->ip6_addr[i])) { pcAddrType = "site"; } else if (ip6_addr_isuniquelocal(&netif->ip6_addr[i])) { pcAddrType = "uniquelocal"; } else if (ip6_addr_isloopback(&netif->ip6_addr[i])) { pcAddrType = "loopback"; } else { pcAddrType = "unknown"; } printf(" inet6 addr: %s Scope:%s <%s>\n", ip6addr_ntoa_r(&netif->ip6_addr[i], cBuffer, sizeof(cBuffer)), pcAddrType, pcAddrStat); } /* * 打印网口收发数据信息 */ printf(" RX ucast packets:%u nucast packets:%u dropped:%u\n", netif->ifinucastpkts, netif->ifinnucastpkts, netif->ifindiscards); printf(" TX ucast packets:%u nucast packets:%u dropped:%u\n", netif->ifoutucastpkts, netif->ifoutnucastpkts, netif->ifoutdiscards); printf(" RX bytes:%u TX bytes:%u\n", netif->ifinoctets, netif->ifoutoctets); printf("\n"); }