int VBoxNetDhcp::hostDnsServers(const ComHostPtr& host, const RTNETADDRIPV4& networkid, const AddressToOffsetMapping& mapping, AddressList& servers) { ComBstrArray strs; HRESULT hrc = host->COMGETTER(NameServers)(ComSafeArrayAsOutParam(strs)); if (FAILED(hrc)) return VERR_NOT_FOUND; /* * Recent fashion is to run dnsmasq on 127.0.1.1 which we * currently can't map. If that's the only nameserver we've got, * we need to use DNS proxy for VMs to reach it. */ bool fUnmappedLoopback = false; for (size_t i = 0; i < strs.size(); ++i) { RTNETADDRIPV4 addr; int rc; rc = RTNetStrToIPv4Addr(com::Utf8Str(strs[i]).c_str(), &addr); if (RT_FAILURE(rc)) continue; if (addr.au8[0] == 127) { AddressToOffsetMapping::const_iterator remap(mapping.find(addr)); if (remap != mapping.end()) { int offset = remap->second; addr.u = RT_H2N_U32(RT_N2H_U32(networkid.u) + offset); } else { fUnmappedLoopback = true; continue; } } servers.push_back(addr); } if (servers.empty() && fUnmappedLoopback) { RTNETADDRIPV4 proxy; proxy.u = networkid.u | RT_H2N_U32_C(1U); servers.push_back(proxy); } return VINF_SUCCESS; }
int hostDnsDomain(const ComHostPtr& host, std::string& domainStr) { com::Bstr domain; if (SUCCEEDED(host->COMGETTER(DomainName)(domain.asOutParam()))) { domainStr = com::Utf8Str(domain).c_str(); return VINF_SUCCESS; } return VERR_NOT_FOUND; }
int VBoxNetDhcp::fetchAndUpdateDnsInfo() { ComHostPtr host; if (SUCCEEDED(virtualbox->COMGETTER(Host)(host.asOutParam()))) { AddressToOffsetMapping mapIp4Addr2Off; int rc = localMappings(m_NATNetwork, mapIp4Addr2Off); /* XXX: here could be several cases: 1. COM error, 2. not found (empty) 3. ? */ AssertMsgRCReturn(rc, ("Can't fetch local mappings"), rc); RTNETADDRIPV4 address = getIpv4Address(); RTNETADDRIPV4 netmask = getIpv4Netmask(); AddressList nameservers; rc = hostDnsServers(host, networkid(address, netmask), mapIp4Addr2Off, nameservers); AssertMsgRCReturn(rc, ("Debug me!!!"), rc); /* XXX: Search strings */ std::string domain; rc = hostDnsDomain(host, domain); AssertMsgRCReturn(rc, ("Debug me!!"), rc); { VBoxNetALock(this); ConfigurationManager *confManager = ConfigurationManager::getConfigurationManager(); confManager->flushAddressList(RTNET_DHCP_OPT_DNS); for (AddressList::iterator it = nameservers.begin(); it != nameservers.end(); ++it) confManager->addToAddressList(RTNET_DHCP_OPT_DNS, *it); confManager->setString(RTNET_DHCP_OPT_DOMAIN_NAME, domain); } } return VINF_SUCCESS; }
int hostDnsSearchList(const ComHostPtr& host, std::vector<std::string>& strings) { strings.clear(); ComBstrArray strs; if (SUCCEEDED(host->COMGETTER(SearchStrings)(ComSafeArrayAsOutParam(strs)))) { for (unsigned int i = 0; i < strs.size(); ++i) { strings.push_back(com::Utf8Str(strs[i]).c_str()); } } else return VERR_NOT_FOUND; return VINF_SUCCESS; }
/** * @note: const dropped here, because of map<K,V>::operator[] which isn't const, map<K,V>::at() has const * variant but it's C++11. */ int hostDnsServers(const ComHostPtr& host, const RTNETADDRIPV4& networkid, /*const*/ AddressToOffsetMapping& mapping, AddressList& servers) { servers.clear(); ComBstrArray strs; if (SUCCEEDED(host->COMGETTER(NameServers)(ComSafeArrayAsOutParam(strs)))) { RTNETADDRIPV4 addr; int rc; for (unsigned int i = 0; i < strs.size(); ++i) { rc = RTNetStrToIPv4Addr(com::Utf8Str(strs[i]).c_str(), &addr); if (RT_SUCCESS(rc)) { if (addr.au8[0] == 127) { /* XXX: here we want map<K,V>::at(const K& k) const */ if (mapping[addr] != 0) { addr.u = RT_H2N_U32(RT_N2H_U32(networkid.u) + mapping[addr]); } else continue; /* XXX: Warning here (local mapping wasn't registered) */ } servers.push_back(addr); } } } else return VERR_NOT_FOUND; return VINF_SUCCESS; }