VirtualBox

source: vbox/trunk/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp@ 49564

Last change on this file since 49564 was 49564, checked in by vboxsync, 12 years ago

DHCP/VBoxNetDHCP.cpp: G/c unused declarations.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 25.4 KB
Line 
1/* $Id: VBoxNetDHCP.cpp 49564 2013-11-20 07:26:02Z vboxsync $ */
2/** @file
3 * VBoxNetDHCP - DHCP Service for connecting to IntNet.
4 */
5
6/*
7 * Copyright (C) 2009-2011 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.215389.xyz. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18/** @page pg_net_dhcp VBoxNetDHCP
19 *
20 * Write a few words...
21 *
22 */
23
24/*******************************************************************************
25* Header Files *
26*******************************************************************************/
27#include <VBox/com/com.h>
28#include <VBox/com/listeners.h>
29#include <VBox/com/string.h>
30#include <VBox/com/Guid.h>
31#include <VBox/com/array.h>
32#include <VBox/com/ErrorInfo.h>
33#include <VBox/com/errorprint.h>
34#include <VBox/com/EventQueue.h>
35#include <VBox/com/VirtualBox.h>
36
37#include <iprt/alloca.h>
38#include <iprt/buildconfig.h>
39#include <iprt/err.h>
40#include <iprt/net.h> /* must come before getopt */
41#include <iprt/getopt.h>
42#include <iprt/initterm.h>
43#include <iprt/message.h>
44#include <iprt/param.h>
45#include <iprt/path.h>
46#include <iprt/stream.h>
47#include <iprt/time.h>
48#include <iprt/string.h>
49
50#include <VBox/sup.h>
51#include <VBox/intnet.h>
52#include <VBox/intnetinline.h>
53#include <VBox/vmm/vmm.h>
54#include <VBox/version.h>
55
56
57#include "../NetLib/VBoxNetLib.h"
58#include "../NetLib/shared_ptr.h"
59
60#include <vector>
61#include <list>
62#include <string>
63#include <map>
64
65#include "../NetLib/VBoxNetBaseService.h"
66
67#ifdef RT_OS_WINDOWS /* WinMain */
68# include <Windows.h>
69# include <stdlib.h>
70# ifdef INET_ADDRSTRLEN
71/* On Windows INET_ADDRSTRLEN defined as 22 Ws2ipdef.h, because it include port number */
72# undef INET_ADDRSTRLEN
73# endif
74# define INET_ADDRSTRLEN 16
75#else
76# include <netinet/in.h>
77#endif
78
79
80#include "Config.h"
81/*******************************************************************************
82* Structures and Typedefs *
83*******************************************************************************/
84/**
85 * DHCP server instance.
86 */
87class VBoxNetDhcp: public VBoxNetBaseService
88{
89public:
90 VBoxNetDhcp();
91 virtual ~VBoxNetDhcp();
92
93 int init();
94 int run(void);
95 void usage(void) { /* XXX: document options */ };
96 int parseOpt(int rc, const RTGETOPTUNION& getOptVal);
97
98protected:
99 bool handleDhcpMsg(uint8_t uMsgType, PCRTNETBOOTP pDhcpMsg, size_t cb);
100
101 void debugPrintV(int32_t iMinLevel, bool fMsg, const char *pszFmt, va_list va) const;
102 static const char *debugDhcpName(uint8_t uMsgType);
103
104private:
105 int initNoMain();
106 int initWithMain();
107
108protected:
109 /** @name The DHCP server specific configuration data members.
110 * @{ */
111 /*
112 * XXX: what was the plan? SQL3 or plain text file?
113 * How it will coexists with managment from VBoxManagement, who should manage db
114 * in that case (VBoxManage, VBoxSVC ???)
115 */
116 std::string m_LeaseDBName;
117
118 /** @} */
119
120 /* corresponding dhcp server description in Main */
121 ComPtr<IDHCPServer> m_DhcpServer;
122
123 ComPtr<INATNetwork> m_NATNetwork;
124
125 /*
126 * We will ignore cmd line parameters IFF there will be some DHCP specific arguments
127 * otherwise all paramters will come from Main.
128 */
129 bool m_fIgnoreCmdLineParameters;
130
131 /*
132 * -b -n 10.0.1.2 -m 255.255.255.0 -> to the list processing in
133 */
134 typedef struct
135 {
136 char Key;
137 std::string strValue;
138 } CMDLNPRM;
139 std::list<CMDLNPRM> CmdParameterll;
140 typedef std::list<CMDLNPRM>::iterator CmdParameterIterator;
141
142 /** @name Debug stuff
143 * @{ */
144 int32_t m_cVerbosity;
145 uint8_t m_uCurMsgType;
146 size_t m_cbCurMsg;
147 PCRTNETBOOTP m_pCurMsg;
148 VBOXNETUDPHDRS m_CurHdrs;
149 /** @} */
150};
151
152/*******************************************************************************
153* Global Variables *
154*******************************************************************************/
155/** Pointer to the DHCP server. */
156static VBoxNetDhcp *g_pDhcp;
157
158/* DHCP server specific options */
159static RTGETOPTDEF g_aOptionDefs[] =
160{
161 { "--lease-db", 'D', RTGETOPT_REQ_STRING },
162 { "--begin-config", 'b', RTGETOPT_REQ_NOTHING },
163 { "--gateway", 'g', RTGETOPT_REQ_IPV4ADDR },
164 { "--lower-ip", 'l', RTGETOPT_REQ_IPV4ADDR },
165 { "--upper-ip", 'u', RTGETOPT_REQ_IPV4ADDR },
166};
167
168/**
169 * Construct a DHCP server with a default configuration.
170 */
171VBoxNetDhcp::VBoxNetDhcp()
172{
173 m_Name = "VBoxNetDhcp";
174 m_Network = "VBoxNetDhcp";
175 m_TrunkName = "";
176 m_enmTrunkType = kIntNetTrunkType_WhateverNone;
177 m_MacAddress.au8[0] = 0x08;
178 m_MacAddress.au8[1] = 0x00;
179 m_MacAddress.au8[2] = 0x27;
180 m_MacAddress.au8[3] = 0x40;
181 m_MacAddress.au8[4] = 0x41;
182 m_MacAddress.au8[5] = 0x42;
183 m_Ipv4Address.u = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10, 0, 2, 5)));
184
185 m_pSession = NIL_RTR0PTR;
186 m_cbSendBuf = 8192;
187 m_cbRecvBuf = 51200; /** @todo tune to 64 KB with help from SrvIntR0 */
188 m_hIf = INTNET_HANDLE_INVALID;
189 m_pIfBuf = NULL;
190
191 m_cVerbosity = 0;
192 m_uCurMsgType = UINT8_MAX;
193 m_cbCurMsg = 0;
194 m_pCurMsg = NULL;
195 memset(&m_CurHdrs, '\0', sizeof(m_CurHdrs));
196
197 m_fIgnoreCmdLineParameters = true;
198
199 for(unsigned int i = 0; i < RT_ELEMENTS(g_aOptionDefs); ++i)
200 m_vecOptionDefs.push_back(&g_aOptionDefs[i]);
201
202#if 0 /* enable to hack the code without a mile long argument list. */
203 VBoxNetDhcpCfg *pDefCfg = new VBoxNetDhcpCfg();
204 pDefCfg->m_LowerAddr.u = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10, 0, 2,100)));
205 pDefCfg->m_UpperAddr.u = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10, 0, 2,250)));
206 pDefCfg->m_SubnetMask.u = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8(255,255,255, 0)));
207 RTNETADDRIPV4 Addr;
208 Addr.u = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10, 0, 2, 1)));
209 pDefCfg->m_Routers.push_back(Addr);
210 Addr.u = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10, 0, 2, 2)));
211 pDefCfg->m_DNSes.push_back(Addr);
212 pDefCfg->m_DomainName = "vboxnetdhcp.org";
213# if 0
214 pDefCfg->m_cSecLease = 60*60; /* 1 hour */
215# else
216 pDefCfg->m_cSecLease = 30; /* sec */
217# endif
218 pDefCfg->m_TftpServer = "10.0.2.3"; //??
219 this->addConfig(pDefCfg);
220#endif
221}
222
223
224/**
225 * Destruct a DHCP server.
226 */
227VBoxNetDhcp::~VBoxNetDhcp()
228{
229}
230
231
232
233
234/**
235 * Parse the DHCP specific arguments.
236 *
237 * This callback caled for each paramenter so
238 * ....
239 * we nee post analisys of the parameters, at least
240 * for -b, -g, -l, -u, -m
241 */
242int VBoxNetDhcp::parseOpt(int rc, const RTGETOPTUNION& Val)
243{
244 CMDLNPRM prm;
245
246 /* Ok, we've entered here, thus we can't ignore cmd line parameters anymore */
247 m_fIgnoreCmdLineParameters = false;
248
249 prm.Key = rc;
250
251 switch (rc)
252 {
253 case 'l':
254 case 'u':
255 case 'g':
256 {
257 char buf[17];
258 RTStrPrintf(buf, 17, "%RTnaipv4", Val.IPv4Addr.u);
259 prm.strValue = buf;
260 CmdParameterll.push_back(prm);
261 }
262 break;
263
264 case 'b': // ignore
265 case 'D': // ignore
266 break;
267
268 default:
269 rc = RTGetOptPrintError(rc, &Val);
270 RTPrintf("Use --help for more information.\n");
271 return rc;
272 }
273
274 return VINF_SUCCESS;
275}
276
277int VBoxNetDhcp::init()
278{
279 int rc = this->VBoxNetBaseService::init();
280 AssertRCReturn(rc, rc);
281
282 NetworkManager *netManager = NetworkManager::getNetworkManager();
283
284 netManager->setOurAddress(m_Ipv4Address);
285 netManager->setOurNetmask(m_Ipv4Netmask);
286 netManager->setOurMac(m_MacAddress);
287
288 if (isMainNeeded())
289 rc = initWithMain();
290 else
291 rc = initNoMain();
292
293 AssertRCReturn(rc, rc);
294
295 return VINF_SUCCESS;
296}
297
298/**
299 * Runs the DHCP server.
300 *
301 * @returns exit code + error message to stderr on failure, won't return on
302 * success (you must kill this process).
303 */
304int VBoxNetDhcp::run(void)
305{
306
307 /* XXX: shortcut should be hidden from network manager */
308 NetworkManager *netManager = NetworkManager::getNetworkManager();
309 netManager->setSession(m_pSession);
310 netManager->setInterface(m_hIf);
311 netManager->setRingBuffer(m_pIfBuf);
312
313 /*
314 * The loop.
315 */
316 PINTNETRINGBUF pRingBuf = &m_pIfBuf->Recv;
317 for (;;)
318 {
319 /*
320 * Wait for a packet to become available.
321 */
322 INTNETIFWAITREQ WaitReq;
323 WaitReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
324 WaitReq.Hdr.cbReq = sizeof(WaitReq);
325 WaitReq.pSession = m_pSession;
326 WaitReq.hIf = m_hIf;
327 WaitReq.cMillies = 2000; /* 2 secs - the sleep is for some reason uninterruptible... */ /** @todo fix interruptability in SrvIntNet! */
328 int rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_WAIT, 0, &WaitReq.Hdr);
329 if (RT_FAILURE(rc))
330 {
331 if (rc == VERR_TIMEOUT || rc == VERR_INTERRUPTED)
332 continue;
333 RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: VMMR0_DO_INTNET_IF_WAIT returned %Rrc\n", rc);
334 return 1;
335 }
336
337 /*
338 * Process the receive buffer.
339 */
340 while (IntNetRingHasMoreToRead(pRingBuf))
341 {
342 size_t cb;
343 void *pv = VBoxNetUDPMatch(m_pIfBuf, RTNETIPV4_PORT_BOOTPS, &m_MacAddress,
344 VBOXNETUDP_MATCH_UNICAST | VBOXNETUDP_MATCH_BROADCAST | VBOXNETUDP_MATCH_CHECKSUM
345 | (m_cVerbosity > 2 ? VBOXNETUDP_MATCH_PRINT_STDERR : 0),
346 &m_CurHdrs, &cb);
347 if (pv && cb)
348 {
349 PCRTNETBOOTP pDhcpMsg = (PCRTNETBOOTP)pv;
350 m_pCurMsg = pDhcpMsg;
351 m_cbCurMsg = cb;
352
353 uint8_t uMsgType;
354 if (RTNetIPv4IsDHCPValid(NULL /* why is this here? */, pDhcpMsg, cb, &uMsgType))
355 {
356 m_uCurMsgType = uMsgType;
357 handleDhcpMsg(uMsgType, pDhcpMsg, cb);
358 m_uCurMsgType = UINT8_MAX;
359 }
360 else
361 debugPrint(1, true, "VBoxNetDHCP: Skipping invalid DHCP packet.\n"); /** @todo handle pure bootp clients too? */
362
363 m_pCurMsg = NULL;
364 m_cbCurMsg = 0;
365 }
366 else if (VBoxNetArpHandleIt(m_pSession, m_hIf, m_pIfBuf, &m_MacAddress, m_Ipv4Address))
367 {
368 /* nothing */
369 }
370
371 /* Advance to the next frame. */
372 IntNetRingSkipFrame(pRingBuf);
373 }
374 }
375
376 return 0;
377}
378
379
380/**
381 * Handles a DHCP message.
382 *
383 * @returns true if handled, false if not.
384 * @param uMsgType The message type.
385 * @param pDhcpMsg The DHCP message.
386 * @param cb The size of the DHCP message.
387 */
388bool VBoxNetDhcp::handleDhcpMsg(uint8_t uMsgType, PCRTNETBOOTP pDhcpMsg, size_t cb)
389{
390 if (pDhcpMsg->bp_op == RTNETBOOTP_OP_REQUEST)
391 {
392 NetworkManager *networkManager = NetworkManager::getNetworkManager();
393
394 switch (uMsgType)
395 {
396 case RTNET_DHCP_MT_DISCOVER:
397 return networkManager->handleDhcpReqDiscover(pDhcpMsg, cb);
398
399 case RTNET_DHCP_MT_REQUEST:
400 return networkManager->handleDhcpReqRequest(pDhcpMsg, cb);
401
402 case RTNET_DHCP_MT_DECLINE:
403 return networkManager->handleDhcpReqDecline(pDhcpMsg, cb);
404
405 case RTNET_DHCP_MT_RELEASE:
406 return networkManager->handleDhcpReqRelease(pDhcpMsg, cb);
407
408 case RTNET_DHCP_MT_INFORM:
409 debugPrint(0, true, "Should we handle this?");
410 break;
411
412 default:
413 debugPrint(0, true, "Unexpected.");
414 break;
415 }
416 }
417 return false;
418}
419
420/**
421 * Print debug message depending on the m_cVerbosity level.
422 *
423 * @param iMinLevel The minimum m_cVerbosity level for this message.
424 * @param fMsg Whether to dump parts for the current DHCP message.
425 * @param pszFmt The message format string.
426 * @param va Optional arguments.
427 */
428void VBoxNetDhcp::debugPrintV(int iMinLevel, bool fMsg, const char *pszFmt, va_list va) const
429{
430 if (iMinLevel <= m_cVerbosity)
431 {
432 va_list vaCopy; /* This dude is *very* special, thus the copy. */
433 va_copy(vaCopy, va);
434 RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: %s: %N\n", iMinLevel >= 2 ? "debug" : "info", pszFmt, &vaCopy);
435 va_end(vaCopy);
436
437 if ( fMsg
438 && m_cVerbosity >= 2
439 && m_pCurMsg)
440 {
441 /* XXX: export this to debugPrinfDhcpMsg or variant and other method export
442 * to base class
443 */
444 const char *pszMsg = m_uCurMsgType != UINT8_MAX ? debugDhcpName(m_uCurMsgType) : "";
445 RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: debug: %8s chaddr=%.6Rhxs ciaddr=%d.%d.%d.%d yiaddr=%d.%d.%d.%d siaddr=%d.%d.%d.%d xid=%#x\n",
446 pszMsg,
447 &m_pCurMsg->bp_chaddr,
448 m_pCurMsg->bp_ciaddr.au8[0], m_pCurMsg->bp_ciaddr.au8[1], m_pCurMsg->bp_ciaddr.au8[2], m_pCurMsg->bp_ciaddr.au8[3],
449 m_pCurMsg->bp_yiaddr.au8[0], m_pCurMsg->bp_yiaddr.au8[1], m_pCurMsg->bp_yiaddr.au8[2], m_pCurMsg->bp_yiaddr.au8[3],
450 m_pCurMsg->bp_siaddr.au8[0], m_pCurMsg->bp_siaddr.au8[1], m_pCurMsg->bp_siaddr.au8[2], m_pCurMsg->bp_siaddr.au8[3],
451 m_pCurMsg->bp_xid);
452 }
453 }
454}
455
456
457/**
458 * Gets the name of given DHCP message type.
459 *
460 * @returns Readonly name.
461 * @param uMsgType The message number.
462 */
463/* static */ const char *VBoxNetDhcp::debugDhcpName(uint8_t uMsgType)
464{
465 switch (uMsgType)
466 {
467 case 0: return "MT_00";
468 case RTNET_DHCP_MT_DISCOVER: return "DISCOVER";
469 case RTNET_DHCP_MT_OFFER: return "OFFER";
470 case RTNET_DHCP_MT_REQUEST: return "REQUEST";
471 case RTNET_DHCP_MT_DECLINE: return "DECLINE";
472 case RTNET_DHCP_MT_ACK: return "ACK";
473 case RTNET_DHCP_MT_NAC: return "NAC";
474 case RTNET_DHCP_MT_RELEASE: return "RELEASE";
475 case RTNET_DHCP_MT_INFORM: return "INFORM";
476 case 9: return "MT_09";
477 case 10: return "MT_0a";
478 case 11: return "MT_0b";
479 case 12: return "MT_0c";
480 case 13: return "MT_0d";
481 case 14: return "MT_0e";
482 case 15: return "MT_0f";
483 case 16: return "MT_10";
484 case 17: return "MT_11";
485 case 18: return "MT_12";
486 case 19: return "MT_13";
487 case UINT8_MAX: return "MT_ff";
488 default: return "UNKNOWN";
489 }
490}
491
492
493int VBoxNetDhcp::initNoMain()
494{
495 CmdParameterIterator it;
496
497 RTNETADDRIPV4 networkId;
498 networkId.u = m_Ipv4Address.u & m_Ipv4Netmask.u;
499 RTNETADDRIPV4 netmask = m_Ipv4Netmask;
500
501 RTNETADDRIPV4 UpperAddress;
502 RTNETADDRIPV4 LowerAddress = networkId;
503 UpperAddress.u = RT_H2N_U32(RT_N2H_U32(LowerAddress.u) | RT_N2H_U32(netmask.u));
504
505 for (it = CmdParameterll.begin(); it != CmdParameterll.end(); ++it)
506 {
507 switch(it->Key)
508 {
509 case 'l':
510 RTNetStrToIPv4Addr(it->strValue.c_str(), &LowerAddress);
511 break;
512
513 case 'u':
514 RTNetStrToIPv4Addr(it->strValue.c_str(), &UpperAddress);
515 break;
516 case 'b':
517 break;
518
519 }
520 }
521
522 ConfigurationManager *confManager = ConfigurationManager::getConfigurationManager();
523 AssertPtrReturn(confManager, VERR_INTERNAL_ERROR);
524 confManager->addNetwork(unconst(g_RootConfig),
525 networkId,
526 m_Ipv4Netmask,
527 LowerAddress,
528 UpperAddress);
529
530 return VINF_SUCCESS;
531}
532
533
534int VBoxNetDhcp::initWithMain()
535{
536 /* ok, here we should initiate instance of dhcp server
537 * and listener for Dhcp configuration events
538 */
539 AssertRCReturn(virtualbox.isNull(), VERR_INTERNAL_ERROR);
540
541 HRESULT hrc = virtualbox->FindDHCPServerByNetworkName(com::Bstr(m_Network.c_str()).raw(),
542 m_DhcpServer.asOutParam());
543 AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
544
545 hrc = virtualbox->FindNATNetworkByName(com::Bstr(m_Network.c_str()).raw(),
546 m_NATNetwork.asOutParam());
547
548 BOOL fNeedDhcpServer = false;
549 if (FAILED(m_NATNetwork->COMGETTER(NeedDhcpServer)(&fNeedDhcpServer)))
550 return VERR_INTERNAL_ERROR;
551
552 if (!fNeedDhcpServer)
553 return VERR_CANCELLED;
554
555 RTNETADDRIPV4 gateway;
556 com::Bstr strGateway;
557
558 hrc = m_NATNetwork->COMGETTER(Gateway)(strGateway.asOutParam());
559 AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
560 RTNetStrToIPv4Addr(com::Utf8Str(strGateway).c_str(), &gateway);
561
562 ConfigurationManager *confManager = ConfigurationManager::getConfigurationManager();
563 AssertPtrReturn(confManager, VERR_INTERNAL_ERROR);
564 confManager->addToAddressList(RTNET_DHCP_OPT_ROUTERS, gateway);
565
566 unsigned int i;
567 unsigned int count_strs;
568 com::SafeArray<BSTR> strs;
569 std::map<RTNETADDRIPV4, uint32_t> MapIp4Addr2Off;
570
571 hrc = m_NATNetwork->COMGETTER(LocalMappings)(ComSafeArrayAsOutParam(strs));
572 if ( SUCCEEDED(hrc)
573 && (count_strs = strs.size()))
574 {
575 for (i = 0; i < count_strs; ++i)
576 {
577 char szAddr[17];
578 RTNETADDRIPV4 ip4addr;
579 char *pszTerm;
580 uint32_t u32Off;
581 com::Utf8Str strLo2Off(strs[i]);
582 const char *pszLo2Off = strLo2Off.c_str();
583
584 RT_ZERO(szAddr);
585
586 pszTerm = RTStrStr(pszLo2Off, "=");
587
588 if ( pszTerm
589 && (pszTerm - pszLo2Off) <= INET_ADDRSTRLEN)
590 {
591 memcpy(szAddr, pszLo2Off, (pszTerm - pszLo2Off));
592 int rc = RTNetStrToIPv4Addr(szAddr, &ip4addr);
593 if (RT_SUCCESS(rc))
594 {
595 u32Off = RTStrToUInt32(pszTerm + 1);
596 if (u32Off != 0)
597 MapIp4Addr2Off.insert(
598 std::map<RTNETADDRIPV4,uint32_t>::value_type(ip4addr, u32Off));
599 }
600 }
601 }
602 }
603
604 strs.setNull();
605 ComPtr<IHost> host;
606 if (SUCCEEDED(virtualbox->COMGETTER(Host)(host.asOutParam())))
607 {
608 if (SUCCEEDED(host->COMGETTER(NameServers)(ComSafeArrayAsOutParam(strs))))
609 {
610 RTNETADDRIPV4 addr;
611
612 confManager->flushAddressList(RTNET_DHCP_OPT_DNS);
613 int rc;
614 for (i = 0; i < strs.size(); ++i)
615 {
616 rc = RTNetStrToIPv4Addr(com::Utf8Str(strs[i]).c_str(), &addr);
617 if (RT_SUCCESS(rc))
618 {
619 if (addr.au8[0] == 127)
620 {
621 if (MapIp4Addr2Off[addr] != 0)
622 {
623 addr.u = RT_H2N_U32(RT_N2H_U32(m_Ipv4Address.u & m_Ipv4Netmask.u)
624 + MapIp4Addr2Off[addr]);
625 }
626 else
627 continue;
628 }
629
630 confManager->addToAddressList(RTNET_DHCP_OPT_DNS, addr);
631 }
632 }
633 }
634
635 strs.setNull();
636#if 0
637 if (SUCCEEDED(host->COMGETTER(SearchStrings)(ComSafeArrayAsOutParam(strs))))
638 {
639 /* XXX: todo. */;
640 }
641 strs.setNull();
642#endif
643 com::Bstr domain;
644 if (SUCCEEDED(host->COMGETTER(DomainName)(domain.asOutParam())))
645 confManager->setString(RTNET_DHCP_OPT_DOMAIN_NAME, std::string(com::Utf8Str(domain).c_str()));
646 }
647
648 com::Bstr strUpperIp, strLowerIp;
649
650 RTNETADDRIPV4 LowerAddress;
651 RTNETADDRIPV4 UpperAddress;
652
653 hrc = m_DhcpServer->COMGETTER(UpperIP)(strUpperIp.asOutParam());
654 AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
655 RTNetStrToIPv4Addr(com::Utf8Str(strUpperIp).c_str(), &UpperAddress);
656
657
658 hrc = m_DhcpServer->COMGETTER(LowerIP)(strLowerIp.asOutParam());
659 AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
660 RTNetStrToIPv4Addr(com::Utf8Str(strLowerIp).c_str(), &LowerAddress);
661
662 RTNETADDRIPV4 networkId;
663 networkId.u = m_Ipv4Address.u & m_Ipv4Netmask.u;
664 std::string name = std::string("default");
665
666 confManager->addNetwork(unconst(g_RootConfig),
667 networkId,
668 m_Ipv4Netmask,
669 LowerAddress,
670 UpperAddress);
671
672 com::Bstr bstr;
673 hrc = virtualbox->COMGETTER(HomeFolder)(bstr.asOutParam());
674 std::string strXmlLeaseFile(com::Utf8StrFmt("%ls%c%s.leases",
675 bstr.raw(), RTPATH_DELIMITER, m_Network.c_str()).c_str());
676 confManager->loadFromFile(strXmlLeaseFile);
677
678 return VINF_SUCCESS;
679}
680
681/**
682 * Entry point.
683 */
684extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv)
685{
686 /*
687 * Instantiate the DHCP server and hand it the options.
688 */
689
690 VBoxNetDhcp *pDhcp = new VBoxNetDhcp();
691 if (!pDhcp)
692 {
693 RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: new VBoxNetDhcp failed!\n");
694 return 1;
695 }
696 int rc = pDhcp->parseArgs(argc - 1, argv + 1);
697 if (rc)
698 return rc;
699
700 pDhcp->init();
701
702 /*
703 * Try connect the server to the network.
704 */
705 rc = pDhcp->tryGoOnline();
706 if (RT_FAILURE(rc))
707 {
708 delete pDhcp;
709 return 1;
710 }
711
712 /*
713 * Process requests.
714 */
715 g_pDhcp = pDhcp;
716 rc = pDhcp->run();
717 g_pDhcp = NULL;
718 delete pDhcp;
719
720 return 0;
721}
722
723
724#ifndef VBOX_WITH_HARDENING
725
726int main(int argc, char **argv)
727{
728 int rc = RTR3InitExe(argc, &argv, RTR3INIT_FLAGS_SUPLIB);
729 if (RT_FAILURE(rc))
730 return RTMsgInitFailure(rc);
731
732 return TrustedMain(argc, argv);
733}
734
735# ifdef RT_OS_WINDOWS
736
737static LRESULT CALLBACK WindowProc(HWND hwnd,
738 UINT uMsg,
739 WPARAM wParam,
740 LPARAM lParam
741)
742{
743 if(uMsg == WM_DESTROY)
744 {
745 PostQuitMessage(0);
746 return 0;
747 }
748 return DefWindowProc (hwnd, uMsg, wParam, lParam);
749}
750
751static LPCWSTR g_WndClassName = L"VBoxNetDHCPClass";
752
753static DWORD WINAPI MsgThreadProc(__in LPVOID lpParameter)
754{
755 HWND hwnd = 0;
756 HINSTANCE hInstance = (HINSTANCE)GetModuleHandle (NULL);
757 bool bExit = false;
758
759 /* Register the Window Class. */
760 WNDCLASS wc;
761 wc.style = 0;
762 wc.lpfnWndProc = WindowProc;
763 wc.cbClsExtra = 0;
764 wc.cbWndExtra = sizeof(void *);
765 wc.hInstance = hInstance;
766 wc.hIcon = NULL;
767 wc.hCursor = NULL;
768 wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
769 wc.lpszMenuName = NULL;
770 wc.lpszClassName = g_WndClassName;
771
772 ATOM atomWindowClass = RegisterClass(&wc);
773
774 if (atomWindowClass != 0)
775 {
776 /* Create the window. */
777 hwnd = CreateWindowEx (WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST,
778 g_WndClassName, g_WndClassName,
779 WS_POPUPWINDOW,
780 -200, -200, 100, 100, NULL, NULL, hInstance, NULL);
781
782 if (hwnd)
783 {
784 SetWindowPos(hwnd, HWND_TOPMOST, -200, -200, 0, 0,
785 SWP_NOACTIVATE | SWP_HIDEWINDOW | SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_NOSIZE);
786
787 MSG msg;
788 while (GetMessage(&msg, NULL, 0, 0))
789 {
790 TranslateMessage(&msg);
791 DispatchMessage(&msg);
792 }
793
794 DestroyWindow (hwnd);
795
796 bExit = true;
797 }
798
799 UnregisterClass (g_WndClassName, hInstance);
800 }
801
802 if(bExit)
803 {
804 /* no need any accuracy here, in anyway the DHCP server usually gets terminated with TerminateProcess */
805 exit(0);
806 }
807
808 return 0;
809}
810
811
812/** (We don't want a console usually.) */
813int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
814{
815 NOREF(hInstance); NOREF(hPrevInstance); NOREF(lpCmdLine); NOREF(nCmdShow);
816
817 HANDLE hThread = CreateThread(
818 NULL, /*__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, */
819 0, /*__in SIZE_T dwStackSize, */
820 MsgThreadProc, /*__in LPTHREAD_START_ROUTINE lpStartAddress,*/
821 NULL, /*__in_opt LPVOID lpParameter,*/
822 0, /*__in DWORD dwCreationFlags,*/
823 NULL /*__out_opt LPDWORD lpThreadId*/
824 );
825
826 if(hThread != NULL)
827 CloseHandle(hThread);
828
829 return main(__argc, __argv);
830}
831# endif /* RT_OS_WINDOWS */
832
833#endif /* !VBOX_WITH_HARDENING */
834
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette