VirtualBox

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

Last change on this file since 49735 was 49735, checked in by vboxsync, 11 years ago

VBoxNetBaseService hides all details of internal network implementation and become responsible for supporting receiving loop. Notification of children are done via introduced interface:

virtual int processFrame(void *, size_t) = 0;
virtual int processGSO(PCPDMNETWORKGSO, size_t) = 0;
virtual int processUDP(void *, size_t) = 0;

processFrame() and processGSO() might return VERR_IGNORED, to inform base service switch to processUDP() (e.g. for DHCP needs)

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