VirtualBox

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

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

NetworkServices/Dhcpd: getopt improvements.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.3 KB
Line 
1/* $Id: Config.cpp 71306 2018-03-13 01:25:43Z 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
195Config *Config::read(const char *pszFileName)
196{
197 RT_NOREF(pszFileName);
198 return NULL; /* not yet */
199}
200
201
202/*
203 * Set m_strBaseName to sanitized version of m_strNetwork that can be
204 * used in a path component.
205 */
206void Config::sanitizeBaseName()
207{
208 int rc;
209
210 char szBaseName[RTPATH_MAX];
211 rc = RTStrCopy(szBaseName, sizeof(szBaseName), m_strNetwork.c_str());
212 if (RT_FAILURE(rc))
213 return;
214
215 for (char *p = szBaseName; *p != '\0'; ++p)
216 {
217 if (RTPATH_IS_SEP(*p))
218 {
219 *p = '_';
220 }
221 }
222
223 m_strBaseName.assign(szBaseName);
224}
225
226
227optmap_t Config::getOptions(const OptParameterRequest &reqOpts,
228 const ClientId &id,
229 const OptVendorClassId &vendor) const
230{
231 optmap_t optmap;
232
233 fillDefaultOptions(optmap, reqOpts);
234 fillVendorOptions(optmap, reqOpts, vendor);
235 fillHostOptions(optmap, reqOpts, id);
236
237 return optmap;
238}
239
240
241void Config::fillDefaultOptions(optmap_t &optmap,
242 const OptParameterRequest &reqOpts) const
243{
244 RT_NOREF(reqOpts);
245
246 optmap << new OptSubnetMask(m_IPv4Netmask);
247}
248
249
250void Config::fillHostOptions(optmap_t &optmap,
251 const OptParameterRequest &reqOpts,
252 const ClientId &id) const
253{
254 /* not yet */
255 RT_NOREF(optmap, reqOpts, id);
256}
257
258
259void Config::fillVendorOptions(optmap_t &optmap,
260 const OptParameterRequest &reqOpts,
261 const OptVendorClassId &vendor) const
262{
263 if (!vendor.present())
264 return;
265
266 /* may be some day... */
267 RT_NOREF(optmap, reqOpts);
268}
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