int ConfigurationManager::commitLease4Client(Client& client) { Lease l = client.lease(); AssertReturn(l != Lease::NullLease, VERR_INTERNAL_ERROR); l.bindingPhase(false); const NetworkConfigEntity *pCfg = l.getConfig(); AssertPtr(pCfg); l.setExpiration(pCfg->expirationPeriod()); l.phaseStart(RTTimeMilliTS()); saveToFile(); return VINF_SUCCESS; }
int NetworkManager::processParameterReqList(const Client& client, const uint8_t *pu8ReqList, int cReqList, std::vector<RawOption>& extra) { int rc; const Lease l = client.lease(); const NetworkConfigEntity *pNetCfg = l.getConfig(); /* * XXX: Brute-force. Unfortunately, there's no notification event * for changes. Should at least cache the options for a short * time, enough to last discover/offer/request/ack cycle. */ typedef std::map< int, std::pair<std::string, int> > DhcpOptionMap; DhcpOptionMap OptMap; if (!m->m_DhcpServer.isNull()) { com::SafeArray<BSTR> strings; com::Bstr str; HRESULT hrc; int OptCode, OptEncoding; char *pszOptText; strings.setNull(); hrc = m->m_DhcpServer->COMGETTER(GlobalOptions)(ComSafeArrayAsOutParam(strings)); AssertComRC(hrc); for (size_t i = 0; i < strings.size(); ++i) { com::Utf8Str encoded(strings[i]); rc = parseDhcpOptionText(encoded.c_str(), &OptCode, &pszOptText, &OptEncoding); if (!RT_SUCCESS(rc)) continue; OptMap[OptCode] = std::make_pair(pszOptText, OptEncoding); } const RTMAC &mac = client.getMacAddress(); char strMac[6*2+1] = ""; RTStrPrintf(strMac, sizeof(strMac), "%02x%02x%02x%02x%02x%02x", mac.au8[0], mac.au8[1], mac.au8[2], mac.au8[3], mac.au8[4], mac.au8[5]); strings.setNull(); hrc = m->m_DhcpServer->GetMacOptions(com::Bstr(strMac).raw(), ComSafeArrayAsOutParam(strings)); AssertComRC(hrc); for (size_t i = 0; i < strings.size(); ++i) { com::Utf8Str text(strings[i]); rc = parseDhcpOptionText(text.c_str(), &OptCode, &pszOptText, &OptEncoding); if (!RT_SUCCESS(rc)) continue; OptMap[OptCode] = std::make_pair(pszOptText, OptEncoding); } } /* request parameter list */ RawOption opt; bool fIgnore; uint8_t u8Req; for (int idxParam = 0; idxParam < cReqList; ++idxParam) { fIgnore = false; RT_ZERO(opt); u8Req = opt.u8OptId = pu8ReqList[idxParam]; switch(u8Req) { case RTNET_DHCP_OPT_SUBNET_MASK: ((PRTNETADDRIPV4)opt.au8RawOpt)->u = pNetCfg->netmask().u; opt.cbRawOpt = sizeof(RTNETADDRIPV4); break; case RTNET_DHCP_OPT_ROUTERS: case RTNET_DHCP_OPT_DNS: { const Ipv4AddressContainer lst = g_ConfigurationManager->getAddressList(u8Req); PRTNETADDRIPV4 pAddresses = (PRTNETADDRIPV4)&opt.au8RawOpt[0]; for (Ipv4AddressConstIterator it = lst.begin(); it != lst.end(); ++it) { *pAddresses = (*it); pAddresses++; opt.cbRawOpt += sizeof(RTNETADDRIPV4); } if (lst.empty()) fIgnore = true; } break; case RTNET_DHCP_OPT_DOMAIN_NAME: { std::string domainName = g_ConfigurationManager->getString(u8Req); if (domainName == g_ConfigurationManager->m_noString) { fIgnore = true; break; } char *pszDomainName = (char *)&opt.au8RawOpt[0]; strcpy(pszDomainName, domainName.c_str()); opt.cbRawOpt = domainName.length(); } break; default: { DhcpOptionMap::const_iterator it = OptMap.find((int)u8Req); if (it == OptMap.end()) { Log(("opt: %d is ignored\n", u8Req)); fIgnore = true; } else { std::string OptText((*it).second.first); int OptEncoding((*it).second.second); rc = fillDhcpOption(opt, OptText, OptEncoding); if (!RT_SUCCESS(rc)) { fIgnore = true; break; } } } break; } if (!fIgnore) extra.push_back(opt); } return VINF_SUCCESS; }