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; }
/** * Initialize DHCP6 server. * * Join DHCP6 multicast groups. * Create and bind server pcb. * Prebuild fixed parts of reply. */ err_t dhcp6ds_init(struct netif *proxy_netif) { ip6_addr_t *pxaddr, *pxaddr_nonlocal; int i; err_t error; LWIP_ASSERT1(proxy_netif != NULL); LWIP_ASSERT1(proxy_netif->hwaddr_len == 6); /* ethernet */ pxaddr = netif_ip6_addr(proxy_netif, 0); /* link local */ /* * XXX: TODO: This is a leftover from testing with IPv6 mapped * loopback with a special IPv6->IPv4 mapping hack in pxudp.c */ /* advertise ourself as DNS resolver - will be proxied to host */ pxaddr_nonlocal = NULL; for (i = 1; i < LWIP_IPV6_NUM_ADDRESSES; ++i) { if (ip6_addr_ispreferred(netif_ip6_addr_state(proxy_netif, i)) && !ip6_addr_islinklocal(netif_ip6_addr(proxy_netif, i))) { pxaddr_nonlocal = netif_ip6_addr(proxy_netif, i); break; } } LWIP_ASSERT1(pxaddr_nonlocal != NULL); /* must be configured on the netif */ error = mld6_joingroup(pxaddr, &all_dhcp_relays_and_servers); if (error != ERR_OK) { DPRINTF0(("%s: failed to join All_DHCP_Relay_Agents_and_Servers: %s\n", __func__, proxy_lwip_strerr(error))); goto err; } error = mld6_joingroup(pxaddr, &all_dhcp_servers); if (error != ERR_OK) { DPRINTF0(("%s: failed to join All_DHCP_Servers: %s\n", __func__, proxy_lwip_strerr(error))); goto err1; } dhcp6ds_pcb = udp_new_ip6(); if (dhcp6ds_pcb == NULL) { DPRINTF0(("%s: failed to allocate PCB\n", __func__)); error = ERR_MEM; goto err2; } udp_recv_ip6(dhcp6ds_pcb, dhcp6ds_recv, NULL); error = udp_bind_ip6(dhcp6ds_pcb, pxaddr, DHCP6_SERVER_PORT); if (error != ERR_OK) { DPRINTF0(("%s: failed to bind PCB\n", __func__)); goto err3; } #define OPT_SET(buf, off, c) do { \ u16_t _s = PP_HTONS(c); \ memcpy(&(buf)[off], &_s, sizeof(u16_t)); \ } while (0) #define SERVERID_SET(off, c) OPT_SET(dhcp6ds_serverid, (off), (c)) #define DNSSRV_SET(off, c) OPT_SET(dhcp6ds_dns, (off), (c)) SERVERID_SET(0, DHCP6_OPTION_SERVERID); SERVERID_SET(2, DUID_LL_LEN); SERVERID_SET(4, DHCP6_DUID_LL); SERVERID_SET(6, ARES_HRD_ETHERNET); memcpy(&dhcp6ds_serverid[8], proxy_netif->hwaddr, 6); DNSSRV_SET(0, DHCP6_OPTION_DNS_SERVERS); DNSSRV_SET(2, 16); /* one IPv6 address */ /* * XXX: TODO: This is a leftover from testing with IPv6 mapped * loopback with a special IPv6->IPv4 mapping hack in pxudp.c */ memcpy(&dhcp6ds_dns[4], pxaddr_nonlocal, sizeof(ip6_addr_t)); #undef SERVERID_SET #undef DNSSRV_SET return ERR_OK; err3: udp_remove(dhcp6ds_pcb); dhcp6ds_pcb = NULL; err2: mld6_leavegroup(pxaddr, &all_dhcp_servers); err1: mld6_leavegroup(pxaddr, &all_dhcp_relays_and_servers); err: return error; }
/********************************************************************************************************* ** 函数名称: __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"); }