/** * Determine if an address is a broadcast address on a network interface * * @param addr address to be checked * @param netif the network interface against which the address is checked * @return returns non-zero if the address is a broadcast address */ u8_t ip4_addr_isbroadcast(u32_t addr, const struct netif *netif) { ip_addr_t ipaddr; ip4_addr_set_u32(&ipaddr, addr); /* all ones (broadcast) or all zeroes (old skool broadcast) */ if ((~addr == IPADDR_ANY) || (addr == IPADDR_ANY)) { return 1; /* no broadcast support on this network interface? */ } else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0) { /* the given address cannot be a broadcast address * nor can we check against any broadcast addresses */ return 0; /* address matches network interface address exactly? => no broadcast */ } else if (addr == ip4_addr_get_u32(&netif->ip_addr)) { return 0; /* on the same (sub) network... */ } else if (ip_addr_netcmp(&ipaddr, &(netif->ip_addr), &(netif->netmask)) /* ...and host identifier bits are all ones? =>... */ && ((addr & ~ip4_addr_get_u32(&netif->netmask)) == (IPADDR_BROADCAST & ~ip4_addr_get_u32(&netif->netmask)))) { /* => network broadcast address */ return 1; } else { return 0; } }
/** * Create an IP-Address out of range 169.254.1.0 to 169.254.254.255 * * @param netif network interface on which create the IP-Address * @param ipaddr ip address to initialize */ static void autoip_create_addr(struct netif *netif, ip4_addr_t *ipaddr) { /* Here we create an IP-Address out of range 169.254.1.0 to 169.254.254.255 * compliant to RFC 3927 Section 2.1 * We have 254 * 256 possibilities */ u32_t addr = ntohl(LWIP_AUTOIP_CREATE_SEED_ADDR(netif)); addr += netif->autoip->tried_llipaddr; addr = AUTOIP_NET | (addr & 0xffff); /* Now, 169.254.0.0 <= addr <= 169.254.255.255 */ if (addr < AUTOIP_RANGE_START) { addr += AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1; } if (addr > AUTOIP_RANGE_END) { addr -= AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1; } LWIP_ASSERT("AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) && (addr <= AUTOIP_RANGE_END)); ip4_addr_set_u32(ipaddr, htonl(addr)); LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("autoip_create_addr(): tried_llipaddr=%"U16_F", %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", (u16_t)(netif->autoip->tried_llipaddr), ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr))); }
// Lua: s = net.dns.setdnsserver(ip_addr, [index]) static int net_setdnsserver( lua_State* L ) { size_t l; u32_t ip32; const char *server = luaL_checklstring( L, 1, &l ); if (l>16 || server == NULL || (ip32 = ipaddr_addr(server)) == IPADDR_NONE || ip32 == IPADDR_ANY) return luaL_error( L, "invalid dns server ip" ); int numdns = luaL_optint(L, 2, 0); if (numdns >= DNS_MAX_SERVERS) return luaL_error( L, "server index out of range [0-%d]", DNS_MAX_SERVERS - 1); ip_addr_t ipaddr; ip4_addr_set_u32(&ipaddr, ip32); dns_setserver(numdns,&ipaddr); return 0; }
/** * Mapping from loopback to local network for inbound (port-forwarded) * connections. * * Copy "src" to "dst" with ip_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_ip4(ip_addr_t *dst, ip_addr_t *src) { struct netif *netif; const struct ip4_lomap *lomap; unsigned int i; if (ip4_addr1(src) != IP_LOOPBACKNET) { ip_addr_set(dst, src); return PXREMAP_ASIS; } if (g_proxy_options->lomap_desc == NULL) { return PXREMAP_FAILED; } #if 0 /* ?TODO: with multiple interfaces we need to consider fwspec::dst */ netif = ip_route(target); if (netif == NULL) { return PXREMAP_FAILED; } #else netif = netif_list; LWIP_ASSERT1(netif != NULL); LWIP_ASSERT1(netif->next == NULL); #endif lomap = g_proxy_options->lomap_desc->lomap; for (i = 0; i < g_proxy_options->lomap_desc->num_lomap; ++i) { if (ip_addr_cmp(src, &lomap[i].loaddr)) { ip_addr_t net; ip_addr_get_network(&net, &netif->ip_addr, &netif->netmask); ip4_addr_set_u32(dst, htonl(ntohl(ip4_addr_get_u32(&net)) + lomap[i].off)); return PXREMAP_MAPPED; } } return PXREMAP_FAILED; }
static void ping_host_thread(void *arg) { int s,i=0; int timeout = PING_RCV_TIMEO; ip_addr_t ping_target; char *host = (char *)arg; //LWIP_UNUSED_ARG(arg); if ((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0) { return; } lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); while (1) { //ping_target = PING_TARGET; if (i>4) break; i++; (ip4_addr_set_u32(&ping_target, ipaddr_addr(host))); if (ping_send(s, &ping_target) == ERR_OK) { //LWIP_DEBUGF( PING_DEBUG, ("ping: send ")); //ip_addr_debug_print(PING_DEBUG, &ping_target); //LWIP_DEBUGF( PING_DEBUG, ("\n")); rt_kprintf("ping: send "); ip_addr_debug_print1(&ping_target); rt_kprintf("\n"); ping_time = sys_now(); ping_recv(s); } else { //LWIP_DEBUGF( PING_DEBUG, ("ping: send ")); //ip_addr_debug_print(PING_DEBUG, &ping_target); //LWIP_DEBUGF( PING_DEBUG, (" - error\n")); rt_kprintf("ping: send "); ip_addr_debug_print1(&ping_target); rt_kprintf(" - error\n"); } sys_msleep(PING_DELAY); } }
static void ping_host(char * host) { int s,i=0; int timeout = PING_RCV_TIMEO; ip_addr_t ping_target; if ((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0) { return; } lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); while (1) { if (i>4) break; i++; //ping_target = netif_default->gw; //IP4_ADDR(&ping_target,210,82,5,1); (ip4_addr_set_u32(&ping_target, ipaddr_addr(host))); if (ping_send(s, &ping_target) == ERR_OK) { //LWIP_DEBUGF( PING_DEBUG, ("ping: send ")); rt_kprintf("ping: send "); ip_addr_debug_print1(&ping_target); rt_kprintf("\n"); ping_time = sys_now(); ping_recv(s); } else { //LWIP_DEBUGF( PING_DEBUG, ("ping: send ")); rt_kprintf("ping: send "); ip_addr_debug_print1(&ping_target); rt_kprintf(" - error\n"); //LWIP_DEBUGF( PING_DEBUG, (" - error\n")); } sys_msleep(PING_DELAY); } }
/** * Create an IP-Address out of range 169.254.1.0 to 169.254.254.255 * * @param netif network interface on which create the IP-Address * @param ipaddr ip address to initialize */ static void autoip_create_addr(struct netif *netif, ip_addr_t *ipaddr) { /* Here we create an IP-Address out of range 169.254.1.0 to 169.254.254.255 * compliant to RFC 3927 Section 2.1 * We have 254 * 256 possibilities */ u32_t addr; if (prev_llipaddr.addr) { /* Use previously announced IP address, if any. * Previously announced IP doesn't persist across device reboot. * Its useful only in case of network hot-plugging/link-loss. */ addr = ntohl(prev_llipaddr.addr); } else { addr = ntohl(LWIP_AUTOIP_CREATE_SEED_ADDR(netif)); } addr += netif->autoip->tried_llipaddr; addr = AUTOIP_NET | (addr & 0xffff); /* Now, 169.254.0.0 <= addr <= 169.254.255.255 */ if (addr < AUTOIP_RANGE_START) { addr += AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1; } if (addr > AUTOIP_RANGE_END) { addr -= AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1; } LWIP_ASSERT("AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) && (addr <= AUTOIP_RANGE_END)); ip4_addr_set_u32(ipaddr, htonl(addr)); LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("autoip_create_addr(): tried_llipaddr=%"U16_F", %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", (u16_t)(netif->autoip->tried_llipaddr), ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr))); }
/** * Check whether "cp" is a valid ascii representation * of an Internet address and convert to a binary address. * Returns 1 if the address is valid, 0 if not. * This replaces inet_addr, the return value from which * cannot distinguish between failure and a local broadcast address. * * @param cp IP address in ascii represenation (e.g. "127.0.0.1") * @param addr pointer to which to save the ip address in network order * @return 1 if cp could be converted to addr, 0 on failure */ int ipaddr_aton(const char *cp, ip_addr_t *addr) { u32_t val; u8_t base; char c; u32_t parts[4]; u32_t *pp = parts; c = *cp; for (;;) { /* * Collect number up to ``.''. * Values are specified as for C: * 0x=hex, 0=octal, 1-9=decimal. */ if (!isdigit(c)) return (0); val = 0; base = 10; if (c == '0') { c = *++cp; if (c == 'x' || c == 'X') { base = 16; c = *++cp; } else base = 8; } for (;;) { if (isdigit(c)) { val = (val * base) + (int)(c - '0'); c = *++cp; } else if (base == 16 && isxdigit(c)) { val = (val << 4) | (int)(c + 10 - (islower(c) ? 'a' : 'A')); c = *++cp; } else break; } if (c == '.') { /* * Internet format: * a.b.c.d * a.b.c (with c treated as 16 bits) * a.b (with b treated as 24 bits) */ if (pp >= parts + 3) { return (0); } *pp++ = val; c = *++cp; } else break; } /* * Check for trailing characters. */ if (c != '\0' && !isspace(c)) { return (0); } /* * Concoct the address according to * the number of parts specified. */ switch (pp - parts + 1) { case 0: return (0); /* initial nondigit */ case 1: /* a -- 32 bits */ break; case 2: /* a.b -- 8.24 bits */ if (val > 0xffffffUL) { return (0); } val |= parts[0] << 24; break; case 3: /* a.b.c -- 8.8.16 bits */ if (val > 0xffff) { return (0); } val |= (parts[0] << 24) | (parts[1] << 16); break; case 4: /* a.b.c.d -- 8.8.8.8 bits */ if (val > 0xff) { return (0); } val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); break; default: LWIP_ASSERT("unhandled", 0); break; } if (addr) { ip4_addr_set_u32(addr, htonl(val)); } return (1); }
/** * Main thread. Starts also the LWIP thread. */ int VBoxNetLwipNAT::init() { LogFlowFuncEnter(); /* virtualbox initialized in super class */ int rc = ::VBoxNetBaseService::init(); AssertRCReturn(rc, rc); std::string networkName = getNetworkName(); rc = findNatNetwork(virtualbox, networkName, m_net); AssertRCReturn(rc, rc); ComEventTypeArray aNetEvents; aNetEvents.push_back(VBoxEventType_OnNATNetworkPortForward); aNetEvents.push_back(VBoxEventType_OnNATNetworkSetting); rc = createNatListener(m_listener, virtualbox, this, aNetEvents); AssertRCReturn(rc, rc); // resolver changes are reported on vbox but are retrieved from // host so stash a pointer for future lookups HRESULT hrc = virtualbox->COMGETTER(Host)(m_host.asOutParam()); AssertComRCReturn(hrc, VERR_INTERNAL_ERROR); ComEventTypeArray aVBoxEvents; aVBoxEvents.push_back(VBoxEventType_OnHostNameResolutionConfigurationChange); aVBoxEvents.push_back(VBoxEventType_OnNATNetworkStartStop); rc = createNatListener(m_vboxListener, virtualbox, this, aVBoxEvents); AssertRCReturn(rc, rc); BOOL fIPv6Enabled = FALSE; hrc = m_net->COMGETTER(IPv6Enabled)(&fIPv6Enabled); AssertComRCReturn(hrc, VERR_NOT_FOUND); BOOL fIPv6DefaultRoute = FALSE; if (fIPv6Enabled) { hrc = m_net->COMGETTER(AdvertiseDefaultIPv6RouteEnabled)(&fIPv6DefaultRoute); AssertComRCReturn(hrc, VERR_NOT_FOUND); } m_ProxyOptions.ipv6_enabled = fIPv6Enabled; m_ProxyOptions.ipv6_defroute = fIPv6DefaultRoute; com::Bstr bstrSourceIp4Key = com::BstrFmt("NAT/%s/SourceIp4", networkName.c_str()); com::Bstr bstrSourceIpX; hrc = virtualbox->GetExtraData(bstrSourceIp4Key.raw(), bstrSourceIpX.asOutParam()); if (SUCCEEDED(hrc)) { RTNETADDRIPV4 addr; rc = RTNetStrToIPv4Addr(com::Utf8Str(bstrSourceIpX).c_str(), &addr); if (RT_SUCCESS(rc)) { RT_ZERO(m_src4); m_src4.sin_addr.s_addr = addr.u; m_ProxyOptions.src4 = &m_src4; bstrSourceIpX.setNull(); } } if (!fDontLoadRulesOnStartup) { fetchNatPortForwardRules(m_net, false, m_vecPortForwardRule4); fetchNatPortForwardRules(m_net, true, m_vecPortForwardRule6); } /* if (!fDontLoadRulesOnStartup) */ AddressToOffsetMapping tmp; rc = localMappings(m_net, tmp); if (RT_SUCCESS(rc) && tmp.size() != 0) { unsigned long i = 0; for (AddressToOffsetMapping::iterator it = tmp.begin(); it != tmp.end() && i < RT_ELEMENTS(m_lo2off); ++it, ++i) { ip4_addr_set_u32(&m_lo2off[i].loaddr, it->first.u); m_lo2off[i].off = it->second; } m_loOptDescriptor.lomap = m_lo2off; m_loOptDescriptor.num_lomap = i; m_ProxyOptions.lomap_desc = &m_loOptDescriptor; } com::Bstr bstr; hrc = virtualbox->COMGETTER(HomeFolder)(bstr.asOutParam()); AssertComRCReturn(hrc, VERR_NOT_FOUND); if (!bstr.isEmpty()) { com::Utf8Str strTftpRoot(com::Utf8StrFmt("%ls%c%s", bstr.raw(), RTPATH_DELIMITER, "TFTP")); char *pszStrTemp; // avoid const char ** vs char ** rc = RTStrUtf8ToCurrentCP(&pszStrTemp, strTftpRoot.c_str()); AssertRC(rc); m_ProxyOptions.tftp_root = pszStrTemp; } m_ProxyOptions.nameservers = getHostNameservers(); /* end of COM initialization */ rc = g_pLwipNat->tryGoOnline(); if (RT_FAILURE(rc)) return rc; /* this starts LWIP thread */ vboxLwipCoreInitialize(VBoxNetLwipNAT::onLwipTcpIpInit, this); LogFlowFuncLeaveRC(rc); return rc; }
/** * Convert the Simba inet ip address to a lwip ip address. */ static inline void inet_ip_to_lwip_ip(ip_addr_t *dst_p, const struct inet_ip_addr_t *src_p) { ip4_addr_set_u32(ip_2_ip4(dst_p), src_p->number); IP_SET_TYPE_VAL(*dst_p, IPADDR_TYPE_V4); }
NDIS_STATUS WAN_AddRasLink ( IN PKIP_NDIS_ADAPTER pAdapter, IN PNDIS_WAN_LINE_UP pWanLineUp ) { NDIS_STATUS nStatus = NDIS_STATUS_SUCCESS; PKIP_RAS_LINK RasLink = NULL; ULONG OsVersion = OsGetMajorVersion(); DBGLOG(( LTrace, "Local MAC: %.2X%.2X%.2X%.2X%.2X%.2X Remote MAC: %.2X%.2X%.2X%.2X%.2X%.2X\n", pWanLineUp->LocalAddress[0], pWanLineUp->LocalAddress[1], pWanLineUp->LocalAddress[2], pWanLineUp->LocalAddress[3], pWanLineUp->LocalAddress[4], pWanLineUp->LocalAddress[5], pWanLineUp->RemoteAddress[0], pWanLineUp->RemoteAddress[1], pWanLineUp->RemoteAddress[2], pWanLineUp->RemoteAddress[3], pWanLineUp->RemoteAddress[4], pWanLineUp->RemoteAddress[5] )); if ( pWanLineUp->ProtocolType != ETHTYPE_IP ){ return NDIS_STATUS_SUCCESS; } if ( OsVersion < 5 ){ if ( pWanLineUp->ProtocolBufferLength < sizeof(WAN_IP_INFO_NT)){ return NDIS_STATUS_SUCCESS; } }else if ( OsVersion < 6 ){ if ( pWanLineUp->ProtocolBufferLength < sizeof(WAN_IP_INFO_W2K)){ return NDIS_STATUS_SUCCESS; } }else if ( OsVersion < 7 ){ if ( pWanLineUp->ProtocolBufferLength < sizeof(WAN_IP_INFO_VISTA)){ return NDIS_STATUS_SUCCESS; } } // To avoid RAS entries duplications if (WAN_CheckForContext(pAdapter, &pWanLineUp->LocalAddress[2]) == FALSE ) { RasLink = NDIS_AllocateRasLink( pAdapter, pWanLineUp ); if ( RasLink == NULL ) { nStatus = NDIS_STATUS_RESOURCES; }else{ if ( OsVersion < 5 ){ PWAN_IP_INFO_NT WanIpInfo = (PWAN_IP_INFO_NT)pWanLineUp->ProtocolBuffer; ip4_addr_set_u32(&RasLink->IpAddr,WanIpInfo->IpAddress); ip4_addr_set_u32(&RasLink->IpMask,IPADDR_BROADCAST); }else if ( OsVersion < 6 ){ PWAN_IP_INFO_W2K WanIpInfo = (PWAN_IP_INFO_W2K)pWanLineUp->ProtocolBuffer; ip4_addr_set_u32(&RasLink->IpAddr,WanIpInfo->LocalIpAddress); ip4_addr_set_u32(&RasLink->IpMask,WanIpInfo->IpSubnetMask); ip4_addr_set_u32(&RasLink->RemoteIpAddr,WanIpInfo->RemoteIpAddress); }else if ( OsVersion < 7 ){ PWAN_IP_INFO_VISTA WanIpInfo = (PWAN_IP_INFO_VISTA)pWanLineUp->ProtocolBuffer; ip4_addr_set_u32(&RasLink->IpAddr,WanIpInfo->LocalIpAddress); ip4_addr_set_u32(&RasLink->IpMask,WanIpInfo->IpSubnetMask); ip4_addr_set_u32(&RasLink->RemoteIpAddr,WanIpInfo->RemoteIpAddress); } ProtocolBindAdapter( (PKIP_NDIS_INTERFACE)RasLink, RasLink->IpAddr.addr, RasLink->IpMask.addr, RasLink->IpAddr.addr, TRUE ); // update arp table update_arp_entry( &RasLink->Interface.Protocol.IIF, &RasLink->RemoteIpAddr, (struct eth_addr*)RasLink->RemoteAddress, ETHARP_FLAG_STATIC_ENTRY ); update_arp_entry( &RasLink->Interface.Protocol.IIF, &RasLink->IpAddr, (struct eth_addr*)RasLink->RemoteAddress, ETHARP_FLAG_STATIC_ENTRY ); } } return nStatus; }