VirtualBox

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

Last change on this file since 55264 was 54700, checked in by vboxsync, 10 years ago

VBoxNetNAT, VBoxNetDHCP: use the VirtualBoxClient interface

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.0 KB
Line 
1/* $Id: VBoxNetDHCP.cpp 54700 2015-03-09 16:14:52Z 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.virtualbox.org. 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#include "../NetLib/utils.h"
67
68#ifdef RT_OS_WINDOWS /* WinMain */
69# include <Windows.h>
70# include <stdlib.h>
71# ifdef INET_ADDRSTRLEN
72/* On Windows INET_ADDRSTRLEN defined as 22 Ws2ipdef.h, because it include port number */
73# undef INET_ADDRSTRLEN
74# endif
75# define INET_ADDRSTRLEN 16
76#else
77# include <netinet/in.h>
78#endif
79
80
81#include "Config.h"
82/*******************************************************************************
83* Structures and Typedefs *
84*******************************************************************************/
85/**
86 * DHCP server instance.
87 */
88class VBoxNetDhcp: public VBoxNetBaseService, public NATNetworkEventAdapter
89{
90public:
91 VBoxNetDhcp();
92 virtual ~VBoxNetDhcp();
93
94 int init();
95 void done();
96 void usage(void) { /* XXX: document options */ };
97 int parseOpt(int rc, const RTGETOPTUNION& getOptVal);
98 int processFrame(void *, size_t) {return VERR_IGNORED; };
99 int processGSO(PCPDMNETWORKGSO, size_t) {return VERR_IGNORED; };
100 int processUDP(void *, size_t);
101
102protected:
103 bool handleDhcpMsg(uint8_t uMsgType, PCRTNETBOOTP pDhcpMsg, size_t cb);
104
105 void debugPrintV(int32_t iMinLevel, bool fMsg, const char *pszFmt, va_list va) const;
106 static const char *debugDhcpName(uint8_t uMsgType);
107
108private:
109 int initNoMain();
110 int initWithMain();
111 HRESULT HandleEvent(VBoxEventType_T aEventType, IEvent *pEvent);
112 int fetchAndUpdateDnsInfo();
113
114protected:
115 /** @name The DHCP server specific configuration data members.
116 * @{ */
117 /*
118 * XXX: what was the plan? SQL3 or plain text file?
119 * How it will coexists with managment from VBoxManagement, who should manage db
120 * in that case (VBoxManage, VBoxSVC ???)
121 */
122 std::string m_LeaseDBName;
123
124 /** @} */
125
126 /* corresponding dhcp server description in Main */
127 ComPtr<IDHCPServer> m_DhcpServer;
128
129 ComPtr<INATNetwork> m_NATNetwork;
130
131 /** Listener for Host DNS changes */
132 ComNatListenerPtr m_VBoxListener;
133 ComNatListenerPtr m_VBoxClientListener;
134
135 NetworkManager *m_NetworkManager;
136
137 /*
138 * We will ignore cmd line parameters IFF there will be some DHCP specific arguments
139 * otherwise all paramters will come from Main.
140 */
141 bool m_fIgnoreCmdLineParameters;
142
143 /*
144 * -b -n 10.0.1.2 -m 255.255.255.0 -> to the list processing in
145 */
146 typedef struct
147 {
148 char Key;
149 std::string strValue;
150 } CMDLNPRM;
151 std::list<CMDLNPRM> CmdParameterll;
152 typedef std::list<CMDLNPRM>::iterator CmdParameterIterator;
153
154 /** @name Debug stuff
155 * @{ */
156 int32_t m_cVerbosity;
157 uint8_t m_uCurMsgType;
158 size_t m_cbCurMsg;
159 PCRTNETBOOTP m_pCurMsg;
160 VBOXNETUDPHDRS m_CurHdrs;
161 /** @} */
162};
163
164
165static inline int configGetBoundryAddress(const ComDhcpServerPtr& dhcp, bool fUpperBoundry, RTNETADDRIPV4& boundryAddress)
166{
167 boundryAddress.u = INADDR_ANY;
168
169 HRESULT hrc;
170 com::Bstr strAddress;
171 if (fUpperBoundry)
172 hrc = dhcp->COMGETTER(UpperIP)(strAddress.asOutParam());
173 else
174 hrc = dhcp->COMGETTER(LowerIP)(strAddress.asOutParam());
175 AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
176
177 return RTNetStrToIPv4Addr(com::Utf8Str(strAddress).c_str(), &boundryAddress);
178}
179
180/*******************************************************************************
181* Global Variables *
182*******************************************************************************/
183/** Pointer to the DHCP server. */
184static VBoxNetDhcp *g_pDhcp;
185
186/* DHCP server specific options */
187static RTGETOPTDEF g_aOptionDefs[] =
188{
189 { "--lease-db", 'D', RTGETOPT_REQ_STRING },
190 { "--begin-config", 'b', RTGETOPT_REQ_NOTHING },
191 { "--gateway", 'g', RTGETOPT_REQ_IPV4ADDR },
192 { "--lower-ip", 'l', RTGETOPT_REQ_IPV4ADDR },
193 { "--upper-ip", 'u', RTGETOPT_REQ_IPV4ADDR },
194};
195
196/**
197 * Construct a DHCP server with a default configuration.
198 */
199VBoxNetDhcp::VBoxNetDhcp()
200 : VBoxNetBaseService("VBoxNetDhcp", "VBoxNetDhcp"),
201 m_NetworkManager(NULL)
202{
203 /* m_enmTrunkType = kIntNetTrunkType_WhateverNone; */
204 RTMAC mac;
205 mac.au8[0] = 0x08;
206 mac.au8[1] = 0x00;
207 mac.au8[2] = 0x27;
208 mac.au8[3] = 0x40;
209 mac.au8[4] = 0x41;
210 mac.au8[5] = 0x42;
211 setMacAddress(mac);
212
213 RTNETADDRIPV4 address;
214 address.u = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10, 0, 2, 5)));
215 setIpv4Address(address);
216
217 setSendBufSize(8 * _1K);
218 setRecvBufSize(50 * _1K);
219
220 m_uCurMsgType = UINT8_MAX;
221 m_cbCurMsg = 0;
222 m_pCurMsg = NULL;
223 memset(&m_CurHdrs, '\0', sizeof(m_CurHdrs));
224
225 m_fIgnoreCmdLineParameters = true;
226
227 for(unsigned int i = 0; i < RT_ELEMENTS(g_aOptionDefs); ++i)
228 addCommandLineOption(&g_aOptionDefs[i]);
229}
230
231
232/**
233 * Destruct a DHCP server.
234 */
235VBoxNetDhcp::~VBoxNetDhcp()
236{
237}
238
239
240
241
242/**
243 * Parse the DHCP specific arguments.
244 *
245 * This callback caled for each paramenter so
246 * ....
247 * we nee post analisys of the parameters, at least
248 * for -b, -g, -l, -u, -m
249 */
250int VBoxNetDhcp::parseOpt(int rc, const RTGETOPTUNION& Val)
251{
252 CMDLNPRM prm;
253
254 /* Ok, we've entered here, thus we can't ignore cmd line parameters anymore */
255 m_fIgnoreCmdLineParameters = false;
256
257 prm.Key = rc;
258
259 switch (rc)
260 {
261 case 'l':
262 case 'u':
263 case 'g':
264 {
265 char buf[17];
266 RTStrPrintf(buf, 17, "%RTnaipv4", Val.IPv4Addr.u);
267 prm.strValue = buf;
268 CmdParameterll.push_back(prm);
269 }
270 break;
271
272 case 'b': // ignore
273 case 'D': // ignore
274 break;
275
276 default:
277 rc = RTGetOptPrintError(rc, &Val);
278 RTPrintf("Use --help for more information.\n");
279 return rc;
280 }
281
282 return VINF_SUCCESS;
283}
284
285int VBoxNetDhcp::init()
286{
287 int rc = this->VBoxNetBaseService::init();
288 AssertRCReturn(rc, rc);
289
290 if (isMainNeeded())
291 rc = initWithMain();
292 else
293 rc = initNoMain();
294 AssertRCReturn(rc, rc);
295
296 m_NetworkManager = NetworkManager::getNetworkManager(m_DhcpServer);
297 AssertPtrReturn(m_NetworkManager, VERR_INTERNAL_ERROR);
298
299 m_NetworkManager->setOurAddress(getIpv4Address());
300 m_NetworkManager->setOurNetmask(getIpv4Netmask());
301 m_NetworkManager->setOurMac(getMacAddress());
302 m_NetworkManager->setService(this);
303
304 return VINF_SUCCESS;
305}
306
307void VBoxNetDhcp::done()
308{
309 destroyNatListener(m_VBoxListener, virtualbox);
310 destroyClientListener(m_VBoxClientListener, virtualboxClient);
311}
312
313int VBoxNetDhcp::processUDP(void *pv, size_t cbPv)
314{
315 PCRTNETBOOTP pDhcpMsg = (PCRTNETBOOTP)pv;
316 m_pCurMsg = pDhcpMsg;
317 m_cbCurMsg = cbPv;
318
319 uint8_t uMsgType;
320 if (RTNetIPv4IsDHCPValid(NULL /* why is this here? */, pDhcpMsg, cbPv, &uMsgType))
321 {
322 m_uCurMsgType = uMsgType;
323 {
324 /* To avoid fight with event processing thread */
325 VBoxNetALock(this);
326 handleDhcpMsg(uMsgType, pDhcpMsg, cbPv);
327 }
328 m_uCurMsgType = UINT8_MAX;
329 }
330 else
331 debugPrint(1, true, "VBoxNetDHCP: Skipping invalid DHCP packet.\n"); /** @todo handle pure bootp clients too? */
332
333 m_pCurMsg = NULL;
334 m_cbCurMsg = 0;
335
336 return VINF_SUCCESS;
337}
338
339
340/**
341 * Handles a DHCP message.
342 *
343 * @returns true if handled, false if not.
344 * @param uMsgType The message type.
345 * @param pDhcpMsg The DHCP message.
346 * @param cb The size of the DHCP message.
347 */
348bool VBoxNetDhcp::handleDhcpMsg(uint8_t uMsgType, PCRTNETBOOTP pDhcpMsg, size_t cb)
349{
350 if (pDhcpMsg->bp_op == RTNETBOOTP_OP_REQUEST)
351 {
352 AssertPtrReturn(m_NetworkManager, false);
353
354 switch (uMsgType)
355 {
356 case RTNET_DHCP_MT_DISCOVER:
357 return m_NetworkManager->handleDhcpReqDiscover(pDhcpMsg, cb);
358
359 case RTNET_DHCP_MT_REQUEST:
360 return m_NetworkManager->handleDhcpReqRequest(pDhcpMsg, cb);
361
362 case RTNET_DHCP_MT_DECLINE:
363 return m_NetworkManager->handleDhcpReqDecline(pDhcpMsg, cb);
364
365 case RTNET_DHCP_MT_RELEASE:
366 return m_NetworkManager->handleDhcpReqRelease(pDhcpMsg, cb);
367
368 case RTNET_DHCP_MT_INFORM:
369 debugPrint(0, true, "Should we handle this?");
370 break;
371
372 default:
373 debugPrint(0, true, "Unexpected.");
374 break;
375 }
376 }
377 return false;
378}
379
380/**
381 * Print debug message depending on the m_cVerbosity level.
382 *
383 * @param iMinLevel The minimum m_cVerbosity level for this message.
384 * @param fMsg Whether to dump parts for the current DHCP message.
385 * @param pszFmt The message format string.
386 * @param va Optional arguments.
387 */
388void VBoxNetDhcp::debugPrintV(int iMinLevel, bool fMsg, const char *pszFmt, va_list va) const
389{
390 if (iMinLevel <= m_cVerbosity)
391 {
392 va_list vaCopy; /* This dude is *very* special, thus the copy. */
393 va_copy(vaCopy, va);
394 RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: %s: %N\n", iMinLevel >= 2 ? "debug" : "info", pszFmt, &vaCopy);
395 va_end(vaCopy);
396
397 if ( fMsg
398 && m_cVerbosity >= 2
399 && m_pCurMsg)
400 {
401 /* XXX: export this to debugPrinfDhcpMsg or variant and other method export
402 * to base class
403 */
404 const char *pszMsg = m_uCurMsgType != UINT8_MAX ? debugDhcpName(m_uCurMsgType) : "";
405 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",
406 pszMsg,
407 &m_pCurMsg->bp_chaddr,
408 m_pCurMsg->bp_ciaddr.au8[0], m_pCurMsg->bp_ciaddr.au8[1], m_pCurMsg->bp_ciaddr.au8[2], m_pCurMsg->bp_ciaddr.au8[3],
409 m_pCurMsg->bp_yiaddr.au8[0], m_pCurMsg->bp_yiaddr.au8[1], m_pCurMsg->bp_yiaddr.au8[2], m_pCurMsg->bp_yiaddr.au8[3],
410 m_pCurMsg->bp_siaddr.au8[0], m_pCurMsg->bp_siaddr.au8[1], m_pCurMsg->bp_siaddr.au8[2], m_pCurMsg->bp_siaddr.au8[3],
411 m_pCurMsg->bp_xid);
412 }
413 }
414}
415
416
417/**
418 * Gets the name of given DHCP message type.
419 *
420 * @returns Readonly name.
421 * @param uMsgType The message number.
422 */
423/* static */ const char *VBoxNetDhcp::debugDhcpName(uint8_t uMsgType)
424{
425 switch (uMsgType)
426 {
427 case 0: return "MT_00";
428 case RTNET_DHCP_MT_DISCOVER: return "DISCOVER";
429 case RTNET_DHCP_MT_OFFER: return "OFFER";
430 case RTNET_DHCP_MT_REQUEST: return "REQUEST";
431 case RTNET_DHCP_MT_DECLINE: return "DECLINE";
432 case RTNET_DHCP_MT_ACK: return "ACK";
433 case RTNET_DHCP_MT_NAC: return "NAC";
434 case RTNET_DHCP_MT_RELEASE: return "RELEASE";
435 case RTNET_DHCP_MT_INFORM: return "INFORM";
436 case 9: return "MT_09";
437 case 10: return "MT_0a";
438 case 11: return "MT_0b";
439 case 12: return "MT_0c";
440 case 13: return "MT_0d";
441 case 14: return "MT_0e";
442 case 15: return "MT_0f";
443 case 16: return "MT_10";
444 case 17: return "MT_11";
445 case 18: return "MT_12";
446 case 19: return "MT_13";
447 case UINT8_MAX: return "MT_ff";
448 default: return "UNKNOWN";
449 }
450}
451
452
453int VBoxNetDhcp::initNoMain()
454{
455 CmdParameterIterator it;
456
457 RTNETADDRIPV4 address = getIpv4Address();
458 RTNETADDRIPV4 netmask = getIpv4Netmask();
459 RTNETADDRIPV4 networkId;
460 networkId.u = address.u & netmask.u;
461
462 RTNETADDRIPV4 UpperAddress;
463 RTNETADDRIPV4 LowerAddress = networkId;
464 UpperAddress.u = RT_H2N_U32(RT_N2H_U32(LowerAddress.u) | RT_N2H_U32(netmask.u));
465
466 for (it = CmdParameterll.begin(); it != CmdParameterll.end(); ++it)
467 {
468 switch(it->Key)
469 {
470 case 'l':
471 RTNetStrToIPv4Addr(it->strValue.c_str(), &LowerAddress);
472 break;
473
474 case 'u':
475 RTNetStrToIPv4Addr(it->strValue.c_str(), &UpperAddress);
476 break;
477 case 'b':
478 break;
479
480 }
481 }
482
483 ConfigurationManager *confManager = ConfigurationManager::getConfigurationManager();
484 AssertPtrReturn(confManager, VERR_INTERNAL_ERROR);
485 confManager->addNetwork(unconst(g_RootConfig),
486 networkId,
487 netmask,
488 LowerAddress,
489 UpperAddress);
490
491 return VINF_SUCCESS;
492}
493
494
495int VBoxNetDhcp::initWithMain()
496{
497 /* ok, here we should initiate instance of dhcp server
498 * and listener for Dhcp configuration events
499 */
500 AssertRCReturn(virtualbox.isNull(), VERR_INTERNAL_ERROR);
501 std::string networkName = getNetwork();
502
503 int rc = findDhcpServer(virtualbox, networkName, m_DhcpServer);
504 AssertRCReturn(rc, rc);
505
506 rc = findNatNetwork(virtualbox, networkName, m_NATNetwork);
507 AssertRCReturn(rc, rc);
508
509 BOOL fNeedDhcpServer = isDhcpRequired(m_NATNetwork);
510 if (!fNeedDhcpServer)
511 return VERR_CANCELLED;
512
513 RTNETADDRIPV4 gateway;
514 com::Bstr strGateway;
515 HRESULT hrc = m_NATNetwork->COMGETTER(Gateway)(strGateway.asOutParam());
516 AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
517 RTNetStrToIPv4Addr(com::Utf8Str(strGateway).c_str(), &gateway);
518
519 ConfigurationManager *confManager = ConfigurationManager::getConfigurationManager();
520 AssertPtrReturn(confManager, VERR_INTERNAL_ERROR);
521 confManager->addToAddressList(RTNET_DHCP_OPT_ROUTERS, gateway);
522
523 rc = fetchAndUpdateDnsInfo();
524 AssertMsgRCReturn(rc, ("Wasn't able to fetch Dns info"), rc);
525
526 {
527 ComEventTypeArray eventTypes;
528 eventTypes.push_back(VBoxEventType_OnHostNameResolutionConfigurationChange);
529 eventTypes.push_back(VBoxEventType_OnNATNetworkStartStop);
530 rc = createNatListener(m_VBoxListener, virtualbox, this, eventTypes);
531 AssertRCReturn(rc, rc);
532 }
533
534 {
535 ComEventTypeArray eventTypes;
536 eventTypes.push_back(VBoxEventType_OnVBoxSVCAvailabilityChanged);
537 rc = createClientListener(m_VBoxClientListener, virtualboxClient, this, eventTypes);
538 AssertRCReturn(rc, rc);
539 }
540
541 RTNETADDRIPV4 LowerAddress;
542 rc = configGetBoundryAddress(m_DhcpServer, false, LowerAddress);
543 AssertMsgRCReturn(rc, ("can't get lower boundrary adderss'"),rc);
544
545 RTNETADDRIPV4 UpperAddress;
546 rc = configGetBoundryAddress(m_DhcpServer, true, UpperAddress);
547 AssertMsgRCReturn(rc, ("can't get upper boundrary adderss'"),rc);
548
549 RTNETADDRIPV4 address = getIpv4Address();
550 RTNETADDRIPV4 netmask = getIpv4Netmask();
551 RTNETADDRIPV4 networkId = networkid(address, netmask);
552 std::string name = std::string("default");
553
554 confManager->addNetwork(unconst(g_RootConfig),
555 networkId,
556 netmask,
557 LowerAddress,
558 UpperAddress);
559
560 com::Bstr bstr;
561 hrc = virtualbox->COMGETTER(HomeFolder)(bstr.asOutParam());
562 com::Utf8StrFmt strXmlLeaseFile("%ls%c%s.leases",
563 bstr.raw(), RTPATH_DELIMITER, networkName.c_str());
564 confManager->loadFromFile(strXmlLeaseFile);
565
566 return VINF_SUCCESS;
567}
568
569
570int VBoxNetDhcp::fetchAndUpdateDnsInfo()
571{
572 ComHostPtr host;
573 if (SUCCEEDED(virtualbox->COMGETTER(Host)(host.asOutParam())))
574 {
575 AddressToOffsetMapping mapIp4Addr2Off;
576 int rc = localMappings(m_NATNetwork, mapIp4Addr2Off);
577 /* XXX: here could be several cases: 1. COM error, 2. not found (empty) 3. ? */
578 AssertMsgRCReturn(rc, ("Can't fetch local mappings"), rc);
579
580 RTNETADDRIPV4 address = getIpv4Address();
581 RTNETADDRIPV4 netmask = getIpv4Netmask();
582
583 AddressList nameservers;
584 rc = hostDnsServers(host, networkid(address, netmask), mapIp4Addr2Off, nameservers);
585 AssertMsgRCReturn(rc, ("Debug me!!!"), rc);
586 /* XXX: Search strings */
587
588 std::string domain;
589 rc = hostDnsDomain(host, domain);
590 AssertMsgRCReturn(rc, ("Debug me!!"), rc);
591
592 {
593 VBoxNetALock(this);
594 ConfigurationManager *confManager = ConfigurationManager::getConfigurationManager();
595 confManager->flushAddressList(RTNET_DHCP_OPT_DNS);
596
597 for (AddressList::iterator it = nameservers.begin(); it != nameservers.end(); ++it)
598 confManager->addToAddressList(RTNET_DHCP_OPT_DNS, *it);
599
600 confManager->setString(RTNET_DHCP_OPT_DOMAIN_NAME, domain);
601 }
602 }
603
604 return VINF_SUCCESS;
605}
606
607HRESULT VBoxNetDhcp::HandleEvent(VBoxEventType_T aEventType, IEvent *pEvent)
608{
609 switch(aEventType)
610 {
611 case VBoxEventType_OnHostNameResolutionConfigurationChange:
612 fetchAndUpdateDnsInfo();
613 break;
614
615 case VBoxEventType_OnNATNetworkStartStop:
616 {
617 ComPtr <INATNetworkStartStopEvent> pStartStopEvent = pEvent;
618 BOOL fStart = TRUE;
619 HRESULT hrc = pStartStopEvent->COMGETTER(StartEvent)(&fStart);
620 if (!fStart)
621 shutdown();
622 break;
623 }
624
625 case VBoxEventType_OnVBoxSVCAvailabilityChanged:
626 {
627 shutdown();
628 break;
629 }
630 }
631
632 return S_OK;
633}
634
635/**
636 * Entry point.
637 */
638extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv)
639{
640 /*
641 * Instantiate the DHCP server and hand it the options.
642 */
643
644 VBoxNetDhcp *pDhcp = new VBoxNetDhcp();
645 if (!pDhcp)
646 {
647 RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: new VBoxNetDhcp failed!\n");
648 return 1;
649 }
650 int rc = pDhcp->parseArgs(argc - 1, argv + 1);
651 if (rc)
652 return rc;
653
654 pDhcp->init();
655
656 /*
657 * Try connect the server to the network.
658 */
659 rc = pDhcp->tryGoOnline();
660 if (RT_FAILURE(rc))
661 {
662 delete pDhcp;
663 return 1;
664 }
665
666 /*
667 * Process requests.
668 */
669 g_pDhcp = pDhcp;
670 rc = pDhcp->run();
671 pDhcp->done();
672
673 g_pDhcp = NULL;
674 delete pDhcp;
675
676 return 0;
677}
678
679
680#ifndef VBOX_WITH_HARDENING
681
682int main(int argc, char **argv)
683{
684 int rc = RTR3InitExe(argc, &argv, RTR3INIT_FLAGS_SUPLIB);
685 if (RT_FAILURE(rc))
686 return RTMsgInitFailure(rc);
687
688 return TrustedMain(argc, argv);
689}
690
691# ifdef RT_OS_WINDOWS
692
693static LRESULT CALLBACK WindowProc(HWND hwnd,
694 UINT uMsg,
695 WPARAM wParam,
696 LPARAM lParam
697)
698{
699 if(uMsg == WM_DESTROY)
700 {
701 PostQuitMessage(0);
702 return 0;
703 }
704 return DefWindowProc (hwnd, uMsg, wParam, lParam);
705}
706
707static LPCWSTR g_WndClassName = L"VBoxNetDHCPClass";
708
709static DWORD WINAPI MsgThreadProc(__in LPVOID lpParameter)
710{
711 HWND hwnd = 0;
712 HINSTANCE hInstance = (HINSTANCE)GetModuleHandle (NULL);
713 bool bExit = false;
714
715 /* Register the Window Class. */
716 WNDCLASS wc;
717 wc.style = 0;
718 wc.lpfnWndProc = WindowProc;
719 wc.cbClsExtra = 0;
720 wc.cbWndExtra = sizeof(void *);
721 wc.hInstance = hInstance;
722 wc.hIcon = NULL;
723 wc.hCursor = NULL;
724 wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
725 wc.lpszMenuName = NULL;
726 wc.lpszClassName = g_WndClassName;
727
728 ATOM atomWindowClass = RegisterClass(&wc);
729
730 if (atomWindowClass != 0)
731 {
732 /* Create the window. */
733 hwnd = CreateWindowEx (WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST,
734 g_WndClassName, g_WndClassName,
735 WS_POPUPWINDOW,
736 -200, -200, 100, 100, NULL, NULL, hInstance, NULL);
737
738 if (hwnd)
739 {
740 SetWindowPos(hwnd, HWND_TOPMOST, -200, -200, 0, 0,
741 SWP_NOACTIVATE | SWP_HIDEWINDOW | SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_NOSIZE);
742
743 MSG msg;
744 while (GetMessage(&msg, NULL, 0, 0))
745 {
746 TranslateMessage(&msg);
747 DispatchMessage(&msg);
748 }
749
750 DestroyWindow (hwnd);
751
752 bExit = true;
753 }
754
755 UnregisterClass (g_WndClassName, hInstance);
756 }
757
758 if(bExit)
759 {
760 /* no need any accuracy here, in anyway the DHCP server usually gets terminated with TerminateProcess */
761 exit(0);
762 }
763
764 return 0;
765}
766
767
768/** (We don't want a console usually.) */
769int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
770{
771 NOREF(hInstance); NOREF(hPrevInstance); NOREF(lpCmdLine); NOREF(nCmdShow);
772
773 HANDLE hThread = CreateThread(
774 NULL, /*__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, */
775 0, /*__in SIZE_T dwStackSize, */
776 MsgThreadProc, /*__in LPTHREAD_START_ROUTINE lpStartAddress,*/
777 NULL, /*__in_opt LPVOID lpParameter,*/
778 0, /*__in DWORD dwCreationFlags,*/
779 NULL /*__out_opt LPDWORD lpThreadId*/
780 );
781
782 if(hThread != NULL)
783 CloseHandle(hThread);
784
785 return main(__argc, __argv);
786}
787# endif /* RT_OS_WINDOWS */
788
789#endif /* !VBOX_WITH_HARDENING */
790
Note: See TracBrowser for help on using the repository browser.

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