VirtualBox

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

Last change on this file since 17321 was 17321, checked in by vboxsync, 16 years ago

VBoxNetDHCP: Connect and run code.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.5 KB
Line 
1
2
3/*******************************************************************************
4* Header Files *
5*******************************************************************************/
6#include <iprt/initterm.h>
7#include <iprt/net.h>
8#include <iprt/err.h>
9#include <iprt/time.h>
10#include <iprt/stream.h>
11#include <iprt/path.h>
12#include <iprt/param.h>
13#include <iprt/getopt.h>
14
15#include <VBox/sup.h>
16#include <VBox/intnet.h>
17#include <VBox/vmm.h>
18#include <VBox/version.h>
19
20#include <vector>
21#include <string>
22
23
24/*******************************************************************************
25* Structures and Typedefs *
26*******************************************************************************/
27
28/**
29 * DHCP configuration item.
30 *
31 * This is all public data because I'm too lazy to do it propertly right now.
32 */
33class VBoxNetDhcpCfg
34{
35public:
36 /** The etheret addresses this matches config applies to.
37 * An empty vector means 'ANY'. */
38 std::vector<RTMAC> m_MacAddresses;
39 /** The upper address in the range. */
40 RTNETADDRIPV4 m_UpperAddr;
41 /** The lower address in the range. */
42 RTNETADDRIPV4 m_LowerAddr;
43
44 /** Option 1: The net mask. */
45 RTNETADDRIPV4 m_SubnetMask;
46 /* * Option 2: The time offset. */
47 /** Option 3: Routers for the subnet. */
48 std::vector<RTNETADDRIPV4> m_Routers;
49 /* * Option 4: Time server. */
50 /* * Option 5: Name server. */
51 /** Option 6: Domain Name Server (DNS) */
52 std::vector<RTNETADDRIPV4> m_DNSes;
53 /* * Option 7: Log server. */
54 /* * Option 8: Cookie server. */
55 /* * Option 9: LPR server. */
56 /* * Option 10: Impress server. */
57 /* * Option 11: Resource location server. */
58 /* * Option 12: Host name. */
59 //std::string<char> m_HostName;
60 /* * Option 13: Boot file size option. */
61 /* * Option 14: Merit dump file. */
62 /** Option 15: Domain name. */
63 std::string m_DomainName;
64 /* * Option 16: Swap server. */
65 /* * Option 17: Root path. */
66 /* * Option 18: Extension path. */
67 /* * Option 19: IP forwarding enable/disable. */
68 /* * Option 20: Non-local routing enable/disable. */
69 /* * Option 21: Policy filter. */
70 /* * Option 22: Maximum datagram reassembly size (MRS). */
71 /* * Option 23: Default IP time-to-live. */
72 /* * Option 24: Path MTU aging timeout. */
73 /* * Option 25: Path MTU plateau table. */
74 /* * Option 26: Interface MTU. */
75 /* * Option 27: All subnets are local. */
76 /* * Option 28: Broadcast address. */
77 /* * Option 29: Perform maximum discovery. */
78 /* * Option 30: Mask supplier. */
79 /* * Option 31: Perform route discovery. */
80 /* * Option 32: Router solicitation address. */
81 /* * Option 33: Static route. */
82 /* * Option 34: Trailer encapsulation. */
83 /* * Option 35: ARP cache timeout. */
84 /* * Option 36: Ethernet encapsulation. */
85 /* * Option 37: TCP Default TTL. */
86 /* * Option 38: TCP Keepalive Interval. */
87 /* * Option 39: TCP Keepalive Garbage. */
88 /* * Option 40: Network Information Service (NIS) Domain. */
89 /* * Option 41: Network Information Servers. */
90 /* * Option 42: Network Time Protocol Servers. */
91 /* * Option 43: Vendor Specific Information. */
92 /* * Option 44: NetBIOS over TCP/IP Name Server (NBNS). */
93 /* * Option 45: NetBIOS over TCP/IP Datagram distribution Server (NBDD). */
94 /* * Option 46: NetBIOS over TCP/IP Node Type. */
95 /* * Option 47: NetBIOS over TCP/IP Scope. */
96 /* * Option 48: X Window System Font Server. */
97 /* * Option 49: X Window System Display Manager. */
98
99 /** Option 51: IP Address Lease Time. */
100 uint32_t m_cSecLease;
101
102 /* * Option 64: Network Information Service+ Domain. */
103 /* * Option 65: Network Information Service+ Servers. */
104 /** Option 66: TFTP server name. */
105 std::string m_TftpServer;
106 /** Option 67: Bootfile name. */
107 std::string m_BootfileName;
108
109 /* * Option 68: Mobile IP Home Agent. */
110 /* * Option 69: Simple Mail Transport Protocol (SMPT) Server. */
111 /* * Option 70: Post Office Protocol (POP3) Server. */
112 /* * Option 71: Network News Transport Protocol (NNTP) Server. */
113 /* * Option 72: Default World Wide Web (WWW) Server. */
114 /* * Option 73: Default Finger Server. */
115 /* * Option 74: Default Internet Relay Chat (IRC) Server. */
116 /* * Option 75: StreetTalk Server. */
117
118 /* * Option 119: Domain Search. */
119
120
121 VBoxNetDhcpCfg()
122 {
123 m_UpperAddr.u = UINT32_MAX;
124 m_LowerAddr.u = UINT32_MAX;
125 m_SubnetMask.u = UINT32_MAX;
126 m_cSecLease = 60*60; /* 1 hour */
127 }
128
129 /** Validates the configuration.
130 * @returns 0 on success, exit code + error message to stderr on failure. */
131 int validate(void)
132 {
133 if ( m_UpperAddr.u == UINT32_MAX
134 || m_LowerAddr.u == UINT32_MAX
135 || m_SubnetMask.u == UINT32_MAX)
136 {
137 RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: Config is missing:");
138 if (m_UpperAddr.u == UINT32_MAX)
139 RTStrmPrintf(g_pStdErr, " --upper-ip");
140 if (m_LowerAddr.u == UINT32_MAX)
141 RTStrmPrintf(g_pStdErr, " --lower-ip");
142 if (m_SubnetMask.u == UINT32_MAX)
143 RTStrmPrintf(g_pStdErr, " --netmask");
144 return 2;
145 }
146 return 0;
147 }
148
149};
150
151/**
152 * DHCP lease.
153 */
154class VBoxNetDhcpLease
155{
156public:
157 /** The client MAC address. */
158 RTMAC m_MacAddress;
159 /** The lease expiration time. */
160 RTTIMESPEC m_ExpireTime;
161};
162
163/**
164 * DHCP server instance.
165 */
166class VBoxNetDhcp
167{
168public:
169 VBoxNetDhcp();
170 virtual ~VBoxNetDhcp();
171
172 int parseArgs(int argc, char **argv);
173 int tryGoOnline(void);
174 int run(void);
175
176protected:
177 int addConfig(VBoxNetDhcpCfg *pCfg);
178
179protected:
180 /** @name The server configuration data members.
181 * @{ */
182 std::string m_Name;
183 std::string m_Network;
184 RTMAC m_MacAddress;
185 RTNETADDRIPV4 m_IpAddress;
186 int32_t m_cVerbosity;
187 /** @} */
188
189 /** The current configs. */
190 std::vector<VBoxNetDhcpCfg> m_Cfgs;
191
192 /** The current leases. */
193 std::vector<VBoxNetDhcpLease> m_Leases;
194
195 /** @name The network interface
196 * @{ */
197 PSUPDRVSESSION m_pSession;
198 uint32_t m_cbSendBuf;
199 uint32_t m_cbRecvBuf;
200 INTNETIFHANDLE m_hIf; /**< The handle to the network interface. */
201 PINTNETBUF m_pIfBuf; /**< Interface buffer. */
202 /** @} */
203};
204
205
206/*******************************************************************************
207* Global Variables *
208*******************************************************************************/
209/** Pointer to the DHCP server. */
210static VBoxNetDhcp *g_pDhcp;
211
212
213
214/**
215 * Construct a DHCP server with a default configuration.
216 */
217VBoxNetDhcp::VBoxNetDhcp()
218{
219 m_Name = "VBoxNetDhcp";
220 m_Network = "VBoxNetDhcp";
221 m_MacAddress.au8[0] = 0x08;
222 m_MacAddress.au8[1] = 0x00;
223 m_MacAddress.au8[2] = 0x27;
224 m_MacAddress.au8[3] = 0x40;
225 m_MacAddress.au8[4] = 0x41;
226 m_MacAddress.au8[5] = 0x42;
227 m_IpAddress.u = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10, 0, 2, 5)));
228
229 m_pSession = NULL;
230 m_cbSendBuf = 8192;
231 m_cbRecvBuf = 51200; /** @todo tune to 64 KB with help from SrvIntR0 */
232 m_hIf = INTNET_HANDLE_INVALID;
233 m_pIfBuf = NULL;
234
235
236#if 1 /* while hacking. */
237 VBoxNetDhcpCfg DefCfg;
238 DefCfg.m_LowerAddr.u = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10, 0, 2,100)));
239 DefCfg.m_UpperAddr.u = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10, 0, 2,250)));
240 DefCfg.m_SubnetMask.u = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8(255,255,255, 0)));
241 RTNETADDRIPV4 Addr;
242 Addr.u = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10, 0, 2, 1)));
243 DefCfg.m_Routers.push_back(Addr);
244 Addr.u = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10, 0, 2, 2)));
245 DefCfg.m_DNSes.push_back(Addr);
246 DefCfg.m_DomainName = "vboxnetdhcp.org";
247 DefCfg.m_cSecLease = 60*60; /* 1 hour */
248 DefCfg.m_TftpServer = "10.0.2.3"; //??
249#endif
250}
251
252
253/**
254 * Destruct a DHCP server.
255 */
256VBoxNetDhcp::~VBoxNetDhcp()
257{
258 /*
259 * Close the interface connection.
260 */
261 if (m_hIf != INTNET_HANDLE_INVALID)
262 {
263 INTNETIFCLOSEREQ CloseReq;
264 CloseReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
265 CloseReq.Hdr.cbReq = sizeof(CloseReq);
266 CloseReq.pSession = m_pSession;
267 CloseReq.hIf = m_hIf;
268 m_hIf = INTNET_HANDLE_INVALID;
269 int rc = SUPCallVMMR0Ex(NIL_RTR0PTR, VMMR0_DO_INTNET_IF_CLOSE, 0, &CloseReq.Hdr);
270 AssertRC(rc);
271 }
272
273 if (m_pSession)
274 {
275 SUPTerm(false /* not forced */);
276 m_pSession = NULL;
277 }
278}
279
280
281/**
282 * Adds a config to the tail.
283 *
284 * @returns See VBoxNetDHCP::validate().
285 * @param pCfg The config too add.
286 * This object will be consumed by this call!
287 */
288int VBoxNetDhcp::addConfig(VBoxNetDhcpCfg *pCfg)
289{
290 int rc = 0;
291 if (pCfg)
292 {
293 rc = pCfg->validate();
294 if (!rc)
295 m_Cfgs.push_back(*pCfg);
296 delete pCfg;
297 }
298 return rc;
299}
300
301
302/**
303 * Parse the arguments.
304 *
305 * @returns 0 on success, fully bitched exit code on failure.
306 *
307 * @param argc Argument count.
308 * @param argv Argument vector.
309 */
310int VBoxNetDhcp::parseArgs(int argc, char **argv)
311{
312 static const RTGETOPTDEF s_aOptionDefs[] =
313 {
314 { "--name", 'N', RTGETOPT_REQ_STRING },
315 { "--network", 'n', RTGETOPT_REQ_STRING },
316/// @todo { "--mac-address", 'a', RTGETOPT_REQ_MACADDR },
317 { "--ip-address", 'i', RTGETOPT_REQ_IPV4ADDR },
318 { "--verbose", 'v', RTGETOPT_REQ_NOTHING },
319
320 { "--begin-config", 'b', RTGETOPT_REQ_NOTHING },
321 { "--gateway", 'g', RTGETOPT_REQ_IPV4ADDR },
322 { "--lower-ip", 'l', RTGETOPT_REQ_IPV4ADDR },
323 { "--upper-ip", 'u', RTGETOPT_REQ_IPV4ADDR },
324 { "--netmask", 'm', RTGETOPT_REQ_IPV4ADDR },
325
326 { "--help", 'h', RTGETOPT_REQ_NOTHING },
327 { "--version ", 'V', RTGETOPT_REQ_NOTHING },
328 };
329
330 RTGETOPTSTATE State;
331 int rc = RTGetOptInit(&State, argc, argv, &s_aOptionDefs[0], RT_ELEMENTS(s_aOptionDefs), 0, 0);
332 AssertReturn(rc, 49);
333
334 VBoxNetDhcpCfg *pCurCfg = NULL;
335 for (;;)
336 {
337 RTGETOPTUNION Val;
338 rc = RTGetOpt(&State, &Val);
339 if (!rc)
340 break;
341 switch (rc)
342 {
343 case 'N':
344 m_Name = Val.psz;
345 break;
346 case 'n':
347 m_Network = Val.psz;
348 break;
349 case 'a':
350AssertFailed();
351// m_MacAddress = Val.Mac;
352 break;
353 case 'i':
354 m_IpAddress = Val.IPv4Addr;
355 break;
356
357 case 'v':
358 m_cVerbosity++;
359 break;
360
361 /* Begin config. */
362 case 'b':
363 rc = addConfig(pCurCfg);
364 if (rc)
365 break;
366 pCurCfg = NULL;
367 /* fall thru */
368
369 /* config specific ones. */
370 case 'g':
371 case 'l':
372 case 'u':
373 case 'm':
374 if (!pCurCfg)
375 {
376 pCurCfg = new VBoxNetDhcpCfg();
377 if (!pCurCfg)
378 {
379 RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: new VBoxDhcpCfg failed\n");
380 rc = 1;
381 break;
382 }
383 }
384
385 switch (rc)
386 {
387 case 'g':
388 pCurCfg->m_Routers.push_back(Val.IPv4Addr);
389 break;
390
391 case 'l':
392 pCurCfg->m_LowerAddr = Val.IPv4Addr;
393 break;
394
395 case 'u':
396 pCurCfg->m_UpperAddr = Val.IPv4Addr;
397 break;
398
399 case 'm':
400 pCurCfg->m_SubnetMask = Val.IPv4Addr;
401 break;
402
403 case 0: /* ignore */ break;
404 default:
405 AssertMsgFailed(("%d", rc));
406 rc = 1;
407 break;
408 }
409 break;
410
411 case 'V':
412 RTPrintf("%sr%d\n", VBOX_VERSION_STRING, VBOX_SVN_REV);
413 rc = 0;
414 break;
415
416 case 'h':
417 RTPrintf("VBoxNetDHCP Version %s\n"
418 "(C) 2009 Sun Microsystems, Inc.\n"
419 "All rights reserved\n"
420 "\n"
421 "Usage:\n"
422 " TODO\n",
423 VBOX_VERSION_STRING);
424 rc = 1;
425 break;
426
427 default:
428 break;
429 }
430 }
431
432 return rc;
433}
434
435
436/**
437 * Tries to connect to the internal network.
438 *
439 * @returns 0 on success, exit code + error message to stderr on failure.
440 */
441int VBoxNetDhcp::tryGoOnline(void)
442{
443 /*
444 * Open the session, load ring-0 and issue the request.
445 */
446 int rc = SUPR3Init(&m_pSession);
447 if (RT_FAILURE(rc))
448 {
449 m_pSession = NULL;
450 RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: SUPR3Init -> %Rrc\n", rc);
451 return 1;
452 }
453
454 char szPath[RTPATH_MAX];
455 rc = RTPathProgram(szPath, sizeof(szPath) - sizeof("/VMMR0.r0"));
456 if (RT_FAILURE(rc))
457 {
458 RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: RTPathProgram -> %Rrc\n", rc);
459 return 1;
460 }
461
462 rc = SUPLoadVMM(strcat(szPath, "/VMMR0.r0"));
463 if (RT_FAILURE(rc))
464 {
465 RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: SUPLoadVMM(\"%s\") -> %Rrc\n", szPath, rc);
466 return 1;
467 }
468
469 /*
470 * Create the open request.
471 */
472 INTNETOPENREQ OpenReq;
473 OpenReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
474 OpenReq.Hdr.cbReq = sizeof(OpenReq);
475 OpenReq.pSession = m_pSession;
476 strncpy(OpenReq.szNetwork, m_Network.c_str(), sizeof(OpenReq.szNetwork));
477 OpenReq.szTrunk[0] = '\0';
478 OpenReq.enmTrunkType = kIntNetTrunkType_WhateverNone;
479 OpenReq.fFlags = 0; /** @todo check this */
480 OpenReq.cbSend = m_cbSendBuf;
481 OpenReq.cbRecv = m_cbRecvBuf;
482 OpenReq.hIf = INTNET_HANDLE_INVALID;
483
484 /*
485 * Issue the request.
486 */
487 if (m_cVerbosity >= 2)
488 RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: attempting to open/create network \"%s\"...\n", OpenReq.szNetwork);
489 rc = SUPCallVMMR0Ex(NIL_RTR0PTR, VMMR0_DO_INTNET_OPEN, 0, &OpenReq.Hdr);
490 if (RT_SUCCESS(rc))
491 {
492 m_hIf = OpenReq.hIf;
493 if (m_cVerbosity >= 1)
494 RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: successfully opened/created \"%s\" - hIf=%#x\n",
495 OpenReq.szNetwork, m_hIf);
496
497 /*
498 * Get the ring-3 address of the shared interface buffer.
499 */
500 INTNETIFGETRING3BUFFERREQ GetRing3BufferReq;
501 GetRing3BufferReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
502 GetRing3BufferReq.Hdr.cbReq = sizeof(GetRing3BufferReq);
503 GetRing3BufferReq.pSession = m_pSession;
504 GetRing3BufferReq.hIf = m_hIf;
505 GetRing3BufferReq.pRing3Buf = NULL;
506 rc = SUPCallVMMR0Ex(NIL_RTR0PTR, VMMR0_DO_INTNET_IF_GET_RING3_BUFFER, 0, &GetRing3BufferReq.Hdr);
507 if (RT_SUCCESS(rc))
508 {
509 PINTNETBUF pBuf = GetRing3BufferReq.pRing3Buf;
510 if (m_cVerbosity >= 1)
511 RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: pBuf=%p cbBuf=%d cbSend=%d cbRecv=%d\n",
512 pBuf, pBuf->cbBuf, pBuf->cbSend, pBuf->cbRecv);
513 m_pIfBuf = pBuf;
514
515 /*
516 * Activate the interface.
517 */
518 INTNETIFSETACTIVEREQ ActiveReq;
519 ActiveReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
520 ActiveReq.Hdr.cbReq = sizeof(ActiveReq);
521 ActiveReq.pSession = m_pSession;
522 ActiveReq.hIf = m_hIf;
523 ActiveReq.fActive = true;
524 rc = SUPCallVMMR0Ex(NIL_RTR0PTR, VMMR0_DO_INTNET_IF_SET_ACTIVE, 0, &ActiveReq.Hdr);
525 if (RT_SUCCESS(rc))
526 return 0;
527
528 /* bail out */
529 RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: SUPCallVMMR0Ex(,VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE,) failed, rc=%Rrc\n", rc);
530 }
531 else
532 RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: SUPCallVMMR0Ex(,VMMR0_DO_INTNET_IF_GET_RING3_BUFFER,) failed, rc=%Rrc\n", rc);
533 }
534 else
535 RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: SUPCallVMMR0Ex(,VMMR0_DO_INTNET_OPEN,) failed, rc=%Rrc\n", rc);
536
537 return RT_SUCCESS(rc) ? 0 : 1;
538}
539
540
541/**
542 * Runs the DHCP server.
543 *
544 * @returns exit code + error message to stderr on failure, won't return on
545 * success (you must kill this process).
546 */
547int VBoxNetDhcp::run(void)
548{
549/** @todo The idea is that run() to use VBoxNetUDP here to mimic sockets and not
550 * do all the parsing here... */
551
552
553 /*
554 * The loop.
555 */
556 PINTNETRINGBUF pRingBuf = &m_pIfBuf->Recv;
557 for (;;)
558 {
559 /*
560 * Wait for a packet to become available.
561 */
562 INTNETIFWAITREQ WaitReq;
563 WaitReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
564 WaitReq.Hdr.cbReq = sizeof(WaitReq);
565 WaitReq.pSession = m_pSession;
566 WaitReq.hIf = m_hIf;
567 WaitReq.cMillies = RT_INDEFINITE_WAIT;
568 int rc = SUPCallVMMR0Ex(NIL_RTR0PTR, VMMR0_DO_INTNET_IF_WAIT, 0, &WaitReq.Hdr);
569 if (RT_FAILURE(rc))
570 {
571 RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: VMMR0_DO_INTNET_IF_WAIT returned %Rrc\n", rc);
572 return 1;
573 }
574
575 /*
576 * Process the receive buffer.
577 */
578 while (INTNETRingGetReadable(pRingBuf) > 0)
579 {
580 PINTNETHDR pHdr = (PINTNETHDR)((uintptr_t)m_pIfBuf + pRingBuf->offRead);
581 if (pHdr->u16Type == INTNETHDR_TYPE_FRAME)
582 {
583 size_t cbFrame = pHdr->cbFrame;
584 const void *pvFrame = INTNETHdrGetFramePtr(pHdr, m_pIfBuf);
585
586 PCRTNETETHERHDR pEthHdr = (PCRTNETETHERHDR)pvFrame;
587 if (m_cVerbosity >= 2)
588 RTStrmPrintf(g_pStdErr, "frame: cb=%04x dst=%.6Rhxs src=%.6Rhxs type=%04x%s\n",
589 cbFrame, &pEthHdr->DstMac, &pEthHdr->SrcMac, RT_BE2H_U16(pEthHdr->EtherType),
590 !memcmp(&pEthHdr->DstMac, &m_MacAddress, sizeof(m_MacAddress)) ? " Mine!" : "");
591
592 /* Look for the DHCP messages. */
593 if ( cbFrame > 64
594 && RT_BE2H_U16(pEthHdr->EtherType) == 0x0800 /* EtherType == IP */)
595 {
596 PCRTNETIPV4 pIpHdr = (PCRTNETIPV4)(pEthHdr + 1);
597 PCRTNETUDP pUdpHdr = (PCRTNETUDP)((uint32_t *)pIpHdr + pIpHdr->ip_hl);
598 if ( pIpHdr->ip_p == 0x11 /*UDP*/
599 && RT_BE2H_U16(pUdpHdr->uh_dport) == 68 /* bootp */
600 && RT_BE2H_U16(pUdpHdr->uh_sport) == 67 /* bootps */)
601 {
602
603// PCRTNETDHCP pDhcpMsg = (PCRTNETDHCP)(pUdpHdr + 1);
604
605 }
606 }
607 }
608
609 /* Advance to the next frame. */
610 INTNETRingSkipFrame(m_pIfBuf, pRingBuf);
611 }
612 }
613
614 return 0;
615}
616
617
618
619/**
620 * Entry point.
621 */
622extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
623{
624 /*
625 * Instantiate the DHCP server and hand it the options.
626 */
627 VBoxNetDhcp *pDhcp = new VBoxNetDhcp();
628 if (!pDhcp)
629 {
630 RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: new VBoxNetDhcp failed!\n");
631 return 1;
632 }
633 int rc = pDhcp->parseArgs(argc - 1, argv + 1);
634 if (rc)
635 return rc;
636
637 /*
638 * Try connect the server to the network.
639 */
640 rc = pDhcp->tryGoOnline();
641 if (rc)
642 {
643 delete pDhcp;
644 return rc;
645 }
646
647 /*
648 * Process requests.
649 */
650 g_pDhcp = pDhcp;
651 rc = pDhcp->run();
652 g_pDhcp = NULL;
653 delete pDhcp;
654
655 return rc;
656}
657
658
659
660#ifndef VBOX_WITH_HARDENING
661
662int main(int argc, char **argv, char **envp)
663{
664 int rc = RTR3InitAndSUPLib();
665 if (RT_FAILURE(rc))
666 {
667 RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: RTR3InitAndSupLib failed, rc=%Rrc\n", rc);
668 return 1;
669 }
670
671 return TrustedMain(argc, argv, envp);
672}
673
674#endif /* !VBOX_WITH_HARDENING */
675
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