VirtualBox

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

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

VBoxNetDHCP: code in progress.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.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/getopt.h>
12
13#ifdef VBOX_WITH_HARDENING
14# include <VBox/sup.h>
15#endif
16#include <VBox/version.h>
17
18#include <vector>
19#include <string>
20
21
22/*******************************************************************************
23* Structures and Typedefs *
24*******************************************************************************/
25
26/**
27 * DHCP configuration item.
28 *
29 * This is all public data because I'm too lazy to do it propertly right now.
30 */
31class VBoxNetDhcpCfg
32{
33public:
34 /** The etheret addresses this matches config applies to.
35 * An empty vector means 'ANY'. */
36 std::vector<RTMAC> m_MacAddresses;
37 /** The upper address in the range. */
38 RTNETADDRIPV4 m_UpperAddr;
39 /** The lower address in the range. */
40 RTNETADDRIPV4 m_LowerAddr;
41
42 /** Option 1: The net mask. */
43 RTNETADDRIPV4 m_SubnetMask;
44 /* * Option 2: The time offset. */
45 /** Option 3: Routers for the subnet. */
46 std::vector<RTNETADDRIPV4> m_Routers;
47 /* * Option 4: Time server. */
48 /* * Option 5: Name server. */
49 /** Option 6: Domain Name Server (DNS) */
50 std::vector<RTNETADDRIPV4> m_DNSes;
51 /* * Option 7: Log server. */
52 /* * Option 8: Cookie server. */
53 /* * Option 9: LPR server. */
54 /* * Option 10: Impress server. */
55 /* * Option 11: Resource location server. */
56 /* * Option 12: Host name. */
57 //std::string<char> m_HostName;
58 /* * Option 13: Boot file size option. */
59 /* * Option 14: Merit dump file. */
60 /** Option 15: Domain name. */
61 std::string m_DomainName;
62 /* * Option 16: Swap server. */
63 /* * Option 17: Root path. */
64 /* * Option 18: Extension path. */
65 /* * Option 19: IP forwarding enable/disable. */
66 /* * Option 20: Non-local routing enable/disable. */
67 /* * Option 21: Policy filter. */
68 /* * Option 22: Maximum datagram reassembly size (MRS). */
69 /* * Option 23: Default IP time-to-live. */
70 /* * Option 24: Path MTU aging timeout. */
71 /* * Option 25: Path MTU plateau table. */
72 /* * Option 26: Interface MTU. */
73 /* * Option 27: All subnets are local. */
74 /* * Option 28: Broadcast address. */
75 /* * Option 29: Perform maximum discovery. */
76 /* * Option 30: Mask supplier. */
77 /* * Option 31: Perform route discovery. */
78 /* * Option 32: Router solicitation address. */
79 /* * Option 33: Static route. */
80 /* * Option 34: Trailer encapsulation. */
81 /* * Option 35: ARP cache timeout. */
82 /* * Option 36: Ethernet encapsulation. */
83 /* * Option 37: TCP Default TTL. */
84 /* * Option 38: TCP Keepalive Interval. */
85 /* * Option 39: TCP Keepalive Garbage. */
86 /* * Option 40: Network Information Service (NIS) Domain. */
87 /* * Option 41: Network Information Servers. */
88 /* * Option 42: Network Time Protocol Servers. */
89 /* * Option 43: Vendor Specific Information. */
90 /* * Option 44: NetBIOS over TCP/IP Name Server (NBNS). */
91 /* * Option 45: NetBIOS over TCP/IP Datagram distribution Server (NBDD). */
92 /* * Option 46: NetBIOS over TCP/IP Node Type. */
93 /* * Option 47: NetBIOS over TCP/IP Scope. */
94 /* * Option 48: X Window System Font Server. */
95 /* * Option 49: X Window System Display Manager. */
96
97 /** Option 51: IP Address Lease Time. */
98 uint32_t m_cSecLease;
99
100 /* * Option 64: Network Information Service+ Domain. */
101 /* * Option 65: Network Information Service+ Servers. */
102 /** Option 66: TFTP server name. */
103 std::string m_TftpServer;
104 /** Option 67: Bootfile name. */
105 std::string m_BootfileName;
106
107 /* * Option 68: Mobile IP Home Agent. */
108 /* * Option 69: Simple Mail Transport Protocol (SMPT) Server. */
109 /* * Option 70: Post Office Protocol (POP3) Server. */
110 /* * Option 71: Network News Transport Protocol (NNTP) Server. */
111 /* * Option 72: Default World Wide Web (WWW) Server. */
112 /* * Option 73: Default Finger Server. */
113 /* * Option 74: Default Internet Relay Chat (IRC) Server. */
114 /* * Option 75: StreetTalk Server. */
115
116 /* * Option 119: Domain Search. */
117
118
119 VBoxNetDhcpCfg()
120 {
121 m_UpperAddr.u = UINT32_MAX;
122 m_LowerAddr.u = UINT32_MAX;
123 m_SubnetMask.u = UINT32_MAX;
124 m_cSecLease = 60*60; /* 1 hour */
125 }
126
127 /** Validates the configuration.
128 * @returns 0 on success, exit code + error message to stderr on failure. */
129 int validate(void)
130 {
131 if ( m_UpperAddr.u == UINT32_MAX
132 || m_LowerAddr.u == UINT32_MAX
133 || m_SubnetMask.u == UINT32_MAX)
134 {
135 RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: Config is missing:");
136 if (m_UpperAddr.u == UINT32_MAX)
137 RTStrmPrintf(g_pStdErr, " --upper-ip");
138 if (m_LowerAddr.u == UINT32_MAX)
139 RTStrmPrintf(g_pStdErr, " --lower-ip");
140 if (m_SubnetMask.u == UINT32_MAX)
141 RTStrmPrintf(g_pStdErr, " --netmask");
142 return 2;
143 }
144 return 0;
145 }
146
147};
148
149/**
150 * DHCP lease.
151 */
152class VBoxNetDhcpLease
153{
154public:
155 /** The client MAC address. */
156 RTMAC m_MacAddress;
157 /** The lease expiration time. */
158 RTTIMESPEC m_ExpireTime;
159};
160
161/**
162 * DHCP server instance.
163 */
164class VBoxNetDhcp
165{
166public:
167 VBoxNetDhcp();
168 virtual ~VBoxNetDhcp();
169
170 int parseArgs(int argc, char **argv);
171 int tryGoOnline(void);
172 int run(void);
173
174protected:
175 int addConfig(VBoxNetDhcpCfg *pCfg);
176
177protected:
178 /** @name The server configuration data members.
179 * @{ */
180 std::string m_Name;
181 std::string m_Network;
182 RTMAC m_MacAddress;
183 RTNETADDRIPV4 m_IpAddress;
184 int32_t m_cVerbosity;
185 /** @} */
186
187 /** The current configs. */
188 std::vector<VBoxNetDhcpCfg> m_Cfgs;
189
190 /** The current leases. */
191 std::vector<VBoxNetDhcpLease> m_Leases;
192};
193
194
195/*******************************************************************************
196* Global Variables *
197*******************************************************************************/
198/** Pointer to the DHCP server. */
199static VBoxNetDhcp *g_pDhcp;
200
201
202
203/**
204 * Construct a DHCP server with a default configuration.
205 */
206VBoxNetDhcp::VBoxNetDhcp()
207{
208 m_Name = "VBoxNetDhcp";
209 m_Network = "VBoxNetDhcp";
210 m_MacAddress.au8[0] = 0x08;
211 m_MacAddress.au8[1] = 0x00;
212 m_MacAddress.au8[2] = 0x27;
213 m_MacAddress.au8[3] = 0x40;
214 m_MacAddress.au8[4] = 0x41;
215 m_MacAddress.au8[5] = 0x42;
216 m_IpAddress.u = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10, 0, 2, 5)));
217
218#if 1 /* while hacking. */
219 VBoxNetDhcpCfg DefCfg;
220 DefCfg.m_LowerAddr.u = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10, 0, 2,100)));
221 DefCfg.m_UpperAddr.u = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10, 0, 2,250)));
222 DefCfg.m_SubnetMask.u = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8(255,255,255, 0)));
223 RTNETADDRIPV4 Addr;
224 Addr.u = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10, 0, 2, 1)));
225 DefCfg.m_Routers.push_back(Addr);
226 Addr.u = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10, 0, 2, 2)));
227 DefCfg.m_DNSes.push_back(Addr);
228 DefCfg.m_DomainName = "vboxnetdhcp.org";
229 DefCfg.m_cSecLease = 60*60; /* 1 hour */
230 DefCfg.m_TftpServer = "10.0.2.3"; //??
231#endif
232}
233
234
235/**
236 * Destruct a DHCP server.
237 */
238VBoxNetDhcp::~VBoxNetDhcp()
239{
240 /*
241 * Close the interface connection.
242 */
243}
244
245
246/**
247 * Adds a config to the tail.
248 *
249 * @returns See VBoxNetDHCP::validate().
250 * @param pCfg The config too add.
251 * This object will be consumed by this call!
252 */
253int VBoxNetDhcp::addConfig(VBoxNetDhcpCfg *pCfg)
254{
255 int rc = 0;
256 if (pCfg)
257 {
258 rc = pCfg->validate();
259 if (!rc)
260 m_Cfgs.push_back(*pCfg);
261 delete pCfg;
262 }
263 return rc;
264}
265
266
267/**
268 * Parse the arguments.
269 *
270 * @returns 0 on success, fully bitched exit code on failure.
271 *
272 * @param argc Argument count.
273 * @param argv Argument vector.
274 */
275int VBoxNetDhcp::parseArgs(int argc, char **argv)
276{
277 static const RTGETOPTDEF s_aOptionDefs[] =
278 {
279 { "--name", 'N', RTGETOPT_REQ_STRING },
280 { "--network", 'n', RTGETOPT_REQ_STRING },
281/// @todo { "--mac-address", 'a', RTGETOPT_REQ_MACADDR },
282 { "--ip-address", 'i', RTGETOPT_REQ_IPV4ADDR },
283 { "--verbose", 'v', RTGETOPT_REQ_NOTHING },
284
285 { "--begin-config", 'b', RTGETOPT_REQ_NOTHING },
286 { "--gateway", 'g', RTGETOPT_REQ_IPV4ADDR },
287 { "--lower-ip", 'l', RTGETOPT_REQ_IPV4ADDR },
288 { "--upper-ip", 'u', RTGETOPT_REQ_IPV4ADDR },
289 { "--netmask", 'm', RTGETOPT_REQ_IPV4ADDR },
290
291 { "--help", 'h', RTGETOPT_REQ_NOTHING },
292 { "--version ", 'V', RTGETOPT_REQ_NOTHING },
293 };
294
295 RTGETOPTSTATE State;
296 int rc = RTGetOptInit(&State, argc, argv, &s_aOptionDefs[0], RT_ELEMENTS(s_aOptionDefs), 0, 0);
297 AssertReturn(rc, 49);
298
299 VBoxNetDhcpCfg *pCurCfg = NULL;
300 for (;;)
301 {
302 RTGETOPTUNION Val;
303 rc = RTGetOpt(&State, &Val);
304 if (!rc)
305 break;
306 switch (rc)
307 {
308 case 'N':
309 m_Name = Val.psz;
310 break;
311 case 'n':
312 m_Network = Val.psz;
313 break;
314 case 'a':
315AssertFailed();
316// m_MacAddress = Val.Mac;
317 break;
318 case 'i':
319 m_IpAddress = Val.IPv4Addr;
320 break;
321
322 case 'v':
323 m_cVerbosity++;
324 break;
325
326 /* Begin config. */
327 case 'b':
328 rc = addConfig(pCurCfg);
329 if (rc)
330 break;
331 pCurCfg = NULL;
332 /* fall thru */
333
334 /* config specific ones. */
335 case 'g':
336 case 'l':
337 case 'u':
338 case 'm':
339 if (!pCurCfg)
340 {
341 pCurCfg = new VBoxNetDhcpCfg();
342 if (!pCurCfg)
343 {
344 RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: new VBoxDhcpCfg failed\n");
345 rc = 1;
346 break;
347 }
348 }
349
350 switch (rc)
351 {
352 case 'g':
353 pCurCfg->m_Routers.push_back(Val.IPv4Addr);
354 break;
355
356 case 'l':
357 pCurCfg->m_LowerAddr = Val.IPv4Addr;
358 break;
359
360 case 'u':
361 pCurCfg->m_UpperAddr = Val.IPv4Addr;
362 break;
363
364 case 'm':
365 pCurCfg->m_SubnetMask = Val.IPv4Addr;
366 break;
367
368 case 0: /* ignore */ break;
369 default:
370 AssertMsgFailed(("%d", rc));
371 rc = 1;
372 break;
373 }
374 break;
375
376 case 'V':
377 RTPrintf("%sr%d\n", VBOX_VERSION_STRING, VBOX_SVN_REV);
378 rc = 0;
379 break;
380
381 case 'h':
382 RTPrintf("VBoxNetDHCP Version %s\n"
383 "(C) 2009 Sun Microsystems, Inc.\n"
384 "All rights reserved\n"
385 "\n"
386 "Usage:\n"
387 " TODO\n",
388 VBOX_VERSION_STRING);
389 rc = 1;
390 break;
391
392 default:
393 break;
394 }
395 }
396
397 return rc;
398}
399
400
401/**
402 * Tries to connect to the internal network.
403 *
404 * @returns 0 on success, exit code + error message to stderr on failure.
405 */
406int VBoxNetDhcp::tryGoOnline(void)
407{
408 return 0;
409}
410
411
412/**
413 * Runs the DHCP server.
414 *
415 * @returns 0 on success, exit code + error message to stderr on failure.
416 */
417int VBoxNetDhcp::run(void)
418{
419 return 0;
420}
421
422
423
424/**
425 * Entry point.
426 */
427extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
428{
429 /*
430 * Instantiate the DHCP server and hand it the options.
431 */
432 VBoxNetDhcp *pDhcp = new VBoxNetDhcp();
433 if (!pDhcp)
434 {
435 RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: new VBoxNetDhcp failed!\n");
436 return 1;
437 }
438 int rc = pDhcp->parseArgs(argc - 1, argv + 1);
439 if (rc)
440 return rc;
441
442 /*
443 * Try connect the server to the network.
444 */
445 rc = pDhcp->tryGoOnline();
446 if (rc)
447 {
448 delete pDhcp;
449 return rc;
450 }
451
452 /*
453 * Process requests.
454 */
455 g_pDhcp = pDhcp;
456 rc = pDhcp->run();
457 g_pDhcp = NULL;
458 delete pDhcp;
459
460 return rc;
461}
462
463
464
465#ifndef VBOX_WITH_HARDENING
466
467int main(int argc, char **argv, char **envp)
468{
469 int rc = RTR3InitAndSUPLib();
470 if (RT_FAILURE(rc))
471 {
472 RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: RTR3InitAndSupLib failed, rc=%Rrc\n", rc);
473 return 1;
474 }
475
476 return TrustedMain(argc, argv, envp);
477}
478
479#endif /* !VBOX_WITH_HARDENING */
480
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