VirtualBox

source: vbox/trunk/src/VBox/NetworkServices/Dhcpd/Config.cpp@ 71516

Last change on this file since 71516 was 71353, checked in by vboxsync, 7 years ago

NetworkServices/Dhcpd: stub for reading the config from a file.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.8 KB
Line 
1/* $Id: Config.cpp 71353 2018-03-15 14:11:55Z vboxsync $ */
2/** @file
3 * DHCP server - server configuration
4 */
5
6/*
7 * Copyright (C) 2017-2018 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#include <iprt/types.h>
19#include <iprt/net.h> /* NB: must come before getopt.h */
20#include <iprt/getopt.h>
21#include <iprt/path.h>
22#include <iprt/message.h>
23#include <iprt/string.h>
24
25#include "Config.h"
26
27
28bool Config::isSane()
29{
30 int rc;
31
32 /* unicast MAC address */
33 if (m_MacAddress.au8[0] & 0x01)
34 return false;
35
36 /* unicast IP address */
37 if ((m_IPv4Address.au8[0] & 0xe0) == 0xe0)
38 return false;
39
40 /* valid netmask */
41 int iPrefixLengh;
42 rc = RTNetMaskToPrefixIPv4(&m_IPv4Netmask, &iPrefixLengh);
43 if (RT_FAILURE(rc) || iPrefixLengh == 0)
44 return false;
45
46 /* first IP is from the same network */
47 if ((m_IPv4PoolFirst.u & m_IPv4Netmask.u) != (m_IPv4Address.u & m_IPv4Netmask.u))
48 return false;
49
50 /* last IP is from the same network */
51 if ((m_IPv4PoolLast.u & m_IPv4Netmask.u) != (m_IPv4Address.u & m_IPv4Netmask.u))
52 return false;
53
54 /* the pool is valid */
55 if (RT_N2H_U32(m_IPv4PoolLast.u) < RT_N2H_U32(m_IPv4PoolFirst.u))
56 return false;
57
58 return true;
59}
60
61
62Config *Config::hardcoded()
63{
64 std::unique_ptr<Config> config(new Config());
65
66 config->m_strNetwork.assign("HostInterfaceNetworking-vboxnet0");
67 config->sanitizeBaseName(); /* nop, but be explicit */
68
69 config->m_strTrunk.assign("vboxnet0");
70 config->m_enmTrunkType = kIntNetTrunkType_NetFlt;
71
72 config->m_MacAddress.au8[0] = 0x08;
73 config->m_MacAddress.au8[1] = 0x00;
74 config->m_MacAddress.au8[2] = 0x27;
75 config->m_MacAddress.au8[3] = 0xa9;
76 config->m_MacAddress.au8[4] = 0xcf;
77 config->m_MacAddress.au8[5] = 0xef;
78
79
80 config->m_IPv4Address.u = RT_H2N_U32_C(0xc0a838fe); /* 192.168.56.254 */
81 config->m_IPv4Netmask.u = RT_H2N_U32_C(0xffffff00); /* 255.255.255.0 */
82
83 /* flip to test naks */
84#if 1
85 config->m_IPv4PoolFirst.u = RT_H2N_U32_C(0xc0a8385a); /* 192.168.56.90 */
86 config->m_IPv4PoolLast.u = RT_H2N_U32_C(0xc0a83863); /* 192.168.56.99 */
87#else
88 config->m_IPv4PoolFirst.u = RT_H2N_U32_C(0xc0a838c9); /* 192.168.56.201 */
89 config->m_IPv4PoolLast.u = RT_H2N_U32_C(0xc0a838dc); /* 192.168.56.220 */
90#endif
91
92 AssertReturn(config->isSane(), NULL);
93 return config.release();
94}
95
96
97/* compatibility with old VBoxNetDHCP */
98static const RTGETOPTDEF g_aCompatOptions[] =
99{
100 { "--ip-address", 'i', RTGETOPT_REQ_IPV4ADDR },
101 { "--lower-ip", 'l', RTGETOPT_REQ_IPV4ADDR },
102 { "--mac-address", 'a', RTGETOPT_REQ_MACADDR },
103 { "--netmask", 'm', RTGETOPT_REQ_IPV4ADDR },
104 { "--network", 'n', RTGETOPT_REQ_STRING },
105 { "--trunk-name", 't', RTGETOPT_REQ_STRING },
106 { "--trunk-type", 'T', RTGETOPT_REQ_STRING },
107 { "--upper-ip", 'u', RTGETOPT_REQ_IPV4ADDR },
108};
109
110
111Config *Config::compat(int argc, char **argv)
112{
113 RTGETOPTSTATE State;
114 int rc;
115
116 rc = RTGetOptInit(&State, argc, argv,
117 g_aCompatOptions, RT_ELEMENTS(g_aCompatOptions), 1,
118 RTGETOPTINIT_FLAGS_NO_STD_OPTS);
119 AssertRCReturn(rc, NULL);
120
121 std::unique_ptr<Config> config(new Config());
122 for (;;)
123 {
124 RTGETOPTUNION Val;
125
126 rc = RTGetOpt(&State, &Val);
127 if (rc == 0) /* done */
128 break;
129
130 switch (rc)
131 {
132 case 'a': /* --mac-address */
133 config->m_MacAddress = Val.MacAddr;
134 break;
135
136 case 'i': /* --ip-address */
137 config->m_IPv4Address = Val.IPv4Addr;
138 break;
139
140 case 'l': /* --lower-ip */
141 config->m_IPv4PoolFirst = Val.IPv4Addr;
142 break;
143
144 case 'm': /* --netmask */
145 config->m_IPv4Netmask = Val.IPv4Addr;
146 break;
147
148 case 'n': /* --network */
149 config->m_strNetwork.assign(Val.psz);
150 break;
151
152 case 't': /* --trunk-name */
153 config->m_strTrunk.assign(Val.psz);
154 break;
155
156 case 'T': /* --trunk-type */
157 if (strcmp(Val.psz, "none") == 0)
158 config->m_enmTrunkType = kIntNetTrunkType_None;
159 else if (strcmp(Val.psz, "whatever") == 0)
160 config->m_enmTrunkType = kIntNetTrunkType_WhateverNone;
161 else if (strcmp(Val.psz, "netflt") == 0)
162 config->m_enmTrunkType = kIntNetTrunkType_NetFlt;
163 else if (strcmp(Val.psz, "netadp") == 0)
164 config->m_enmTrunkType = kIntNetTrunkType_NetAdp;
165 else
166 {
167 RTMsgError("Unknown trunk type '%s'", Val.psz);
168 return NULL;
169 }
170 break;
171
172 case 'u': /* --upper-ip */
173 config->m_IPv4PoolLast = Val.IPv4Addr;
174 break;
175
176 case VINF_GETOPT_NOT_OPTION:
177 RTMsgError("%s: Unexpected command line argument", Val.psz);
178 return NULL;
179
180 default:
181 RTGetOptPrintError(rc, &Val);
182 return NULL;
183 }
184 }
185
186 config->sanitizeBaseName();
187
188 if (!config->isSane())
189 return NULL;
190
191 return config.release();
192}
193
194
195static const RTGETOPTDEF g_aOptions[] =
196{
197 { "--config", 'c', RTGETOPT_REQ_STRING },
198};
199
200
201Config *Config::create(int argc, char **argv)
202{
203 RTGETOPTSTATE State;
204 int rc;
205
206 rc = RTGetOptInit(&State, argc, argv,
207 g_aOptions, RT_ELEMENTS(g_aOptions), 1,
208 RTGETOPTINIT_FLAGS_NO_STD_OPTS);
209 AssertRCReturn(rc, NULL);
210
211 std::unique_ptr<Config> config;
212 for (;;)
213 {
214 RTGETOPTUNION Val;
215
216 rc = RTGetOpt(&State, &Val);
217 if (rc == 0) /* done */
218 break;
219
220 switch (rc)
221 {
222 case 'c': /* --config */
223 if (config.get() != NULL)
224 {
225 printf("Duplicate option: --config '%s'\n", Val.psz);
226 return NULL;
227 }
228
229 printf("reading config from %s\n", Val.psz);
230 config.reset(Config::read(Val.psz));
231 if (config.get() == NULL)
232 return NULL;
233
234 break;
235
236 case VINF_GETOPT_NOT_OPTION:
237 RTMsgError("Unexpected command line argument: '%s'", Val.psz);
238 return NULL;
239
240 default:
241 RTGetOptPrintError(rc, &Val);
242 return NULL;
243 }
244 }
245
246 if (config.get() == NULL)
247 return NULL;
248
249 if (!config->isSane())
250 return NULL;
251
252 config->sanitizeBaseName();
253
254 return config.release();
255}
256
257
258Config *Config::read(const char *pszFileName)
259{
260 std::unique_ptr<Config> config(new Config());
261
262 RT_NOREF(pszFileName);
263 return config.release();
264}
265
266
267/*
268 * Set m_strBaseName to sanitized version of m_strNetwork that can be
269 * used in a path component.
270 */
271void Config::sanitizeBaseName()
272{
273 int rc;
274
275 char szBaseName[RTPATH_MAX];
276 rc = RTStrCopy(szBaseName, sizeof(szBaseName), m_strNetwork.c_str());
277 if (RT_FAILURE(rc))
278 return;
279
280 for (char *p = szBaseName; *p != '\0'; ++p)
281 {
282 if (RTPATH_IS_SEP(*p))
283 {
284 *p = '_';
285 }
286 }
287
288 m_strBaseName.assign(szBaseName);
289}
290
291
292optmap_t Config::getOptions(const OptParameterRequest &reqOpts,
293 const ClientId &id,
294 const OptVendorClassId &vendor) const
295{
296 optmap_t optmap;
297
298 fillDefaultOptions(optmap, reqOpts);
299 fillVendorOptions(optmap, reqOpts, vendor);
300 fillHostOptions(optmap, reqOpts, id);
301
302 return optmap;
303}
304
305
306void Config::fillDefaultOptions(optmap_t &optmap,
307 const OptParameterRequest &reqOpts) const
308{
309 RT_NOREF(reqOpts);
310
311 optmap << new OptSubnetMask(m_IPv4Netmask);
312}
313
314
315void Config::fillHostOptions(optmap_t &optmap,
316 const OptParameterRequest &reqOpts,
317 const ClientId &id) const
318{
319 /* not yet */
320 RT_NOREF(optmap, reqOpts, id);
321}
322
323
324void Config::fillVendorOptions(optmap_t &optmap,
325 const OptParameterRequest &reqOpts,
326 const OptVendorClassId &vendor) const
327{
328 if (!vendor.present())
329 return;
330
331 /* may be some day... */
332 RT_NOREF(optmap, reqOpts);
333}
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