VirtualBox

source: vbox/trunk/src/VBox/NetworkServices/Dhcpd/Config.h@ 95851

Last change on this file since 95851 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.7 KB
Line 
1/* $Id: Config.h 93115 2022-01-01 11:31:46Z vboxsync $ */
2/** @file
3 * DHCP server - server configuration
4 */
5
6/*
7 * Copyright (C) 2017-2022 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#ifndef VBOX_INCLUDED_SRC_Dhcpd_Config_h
19#define VBOX_INCLUDED_SRC_Dhcpd_Config_h
20#ifndef RT_WITHOUT_PRAGMA_ONCE
21# pragma once
22#endif
23
24#include "DhcpdInternal.h"
25#include <iprt/types.h>
26#include <iprt/net.h>
27#include <iprt/cpp/xml.h>
28#include <iprt/cpp/ministring.h>
29
30#include <VBox/intnet.h>
31
32#include "DhcpOptions.h"
33#include "ClientId.h"
34
35
36class Config;
37
38/**
39 * Base configuration
40 *
41 * @author bird (2019-07-15)
42 */
43class ConfigLevelBase
44{
45private:
46 /** DHCP options. */
47 optmap_t m_Options;
48protected:
49 /** Minimum lease time, zero means try next level up. */
50 uint32_t m_secMinLeaseTime;
51 /** Default lease time, zero means try next level up. */
52 uint32_t m_secDefaultLeaseTime;
53 /** Maximum lease time, zero means try next level up. */
54 uint32_t m_secMaxLeaseTime;
55
56 /** Options forced unsolicited upon the client. */
57 octets_t m_vecForcedOptions;
58 /** Options (typcially from higher up) that should be hidden from the client. */
59 octets_t m_vecSuppressedOptions;
60
61public:
62 ConfigLevelBase()
63 : m_Options()
64 , m_secMinLeaseTime(0)
65 , m_secDefaultLeaseTime(0)
66 , m_secMaxLeaseTime(0)
67 , m_vecForcedOptions()
68 , m_vecSuppressedOptions()
69 { }
70
71 virtual ~ConfigLevelBase()
72 { }
73
74 virtual void initFromXml(xml::ElementNode const *pElmConfig, bool fStrict, Config const *pConfig);
75 virtual const char *getType() const RT_NOEXCEPT = 0;
76 virtual const char *getName() const RT_NOEXCEPT = 0;
77
78 /**
79 * Tries to find DHCP option @a bOpt, returning an success indicator and
80 * iterator to the result.
81 */
82 bool findOption(uint8_t bOpt, optmap_t::const_iterator &a_rItRet) const RT_NOEXCEPT
83 {
84 a_rItRet = m_Options.find(bOpt);
85 return a_rItRet != m_Options.end();
86 }
87
88 /** Checks if @a bOpt is suppressed or not. */
89 bool isOptionSuppressed(uint8_t bOpt) const RT_NOEXCEPT
90 {
91 return m_vecSuppressedOptions.size() > 0
92 && memchr(&m_vecSuppressedOptions.front(), bOpt, m_vecSuppressedOptions.size()) != NULL;
93 }
94
95 /** @name Accessors
96 * @{ */
97 uint32_t getMinLeaseTime() const RT_NOEXCEPT { return m_secMinLeaseTime; }
98 uint32_t getDefaultLeaseTime() const RT_NOEXCEPT { return m_secDefaultLeaseTime; }
99 uint32_t getMaxLeaseTime() const RT_NOEXCEPT { return m_secMaxLeaseTime; }
100 octets_t const &getForcedOptions() const RT_NOEXCEPT { return m_vecForcedOptions; }
101 octets_t const &getSuppressedOptions() const RT_NOEXCEPT { return m_vecSuppressedOptions; }
102 optmap_t const &getOptions() const RT_NOEXCEPT { return m_Options; }
103 /** @} */
104
105protected:
106 void i_parseOption(const xml::ElementNode *pElmOption);
107 void i_parseForcedOrSuppressedOption(const xml::ElementNode *pElmOption, bool fForced);
108 virtual void i_parseChild(const xml::ElementNode *pElmChild, bool fStrict, Config const *pConfig);
109};
110
111
112/**
113 * Global config
114 */
115class GlobalConfig : public ConfigLevelBase
116{
117public:
118 GlobalConfig()
119 : ConfigLevelBase()
120 { }
121 void initFromXml(xml::ElementNode const *pElmOptions, bool fStrict, Config const *pConfig) RT_OVERRIDE;
122 const char *getType() const RT_NOEXCEPT RT_OVERRIDE { return "global"; }
123 const char *getName() const RT_NOEXCEPT RT_OVERRIDE { return "GlobalConfig"; }
124};
125
126
127/**
128 * Group membership condition.
129 */
130class GroupCondition
131{
132protected:
133 /** The value. */
134 RTCString m_strValue;
135 /** Inclusive (true) or exclusive (false), latter takes precedency. */
136 bool m_fInclusive;
137
138public:
139 virtual ~GroupCondition()
140 {}
141
142 virtual int initCondition(const char *a_pszValue, bool a_fInclusive);
143 virtual bool match(const ClientId &a_ridClient, const OptVendorClassId &a_ridVendorClass,
144 const OptUserClassId &a_ridUserClass) const RT_NOEXCEPT = 0;
145
146 /** @name accessors
147 * @{ */
148 RTCString const &getValue() const RT_NOEXCEPT { return m_strValue; }
149 bool getInclusive() const RT_NOEXCEPT { return m_fInclusive; }
150 /** @} */
151
152protected:
153 bool matchClassId(bool a_fPresent, std::vector<uint8_t> const &a_rBytes, bool fWildcard = false) const RT_NOEXCEPT;
154};
155
156/** MAC condition. */
157class GroupConditionMAC : public GroupCondition
158{
159private:
160 RTMAC m_MACAddress;
161public:
162 int initCondition(const char *a_pszValue, bool a_fInclusive) RT_OVERRIDE;
163 bool match(const ClientId &a_ridClient, const OptVendorClassId &a_ridVendorClass,
164 const OptUserClassId &a_ridUserClass) const RT_NOEXCEPT RT_OVERRIDE;
165};
166
167/** MAC wildcard condition. */
168class GroupConditionMACWildcard : public GroupCondition
169{
170public:
171 bool match(const ClientId &a_ridClient, const OptVendorClassId &a_ridVendorClass,
172 const OptUserClassId &a_ridUserClass) const RT_NOEXCEPT RT_OVERRIDE;
173};
174
175/** Vendor class ID condition. */
176class GroupConditionVendorClassID : public GroupCondition
177{
178public:
179 bool match(const ClientId &a_ridClient, const OptVendorClassId &a_ridVendorClass,
180 const OptUserClassId &a_ridUserClass) const RT_NOEXCEPT RT_OVERRIDE;
181};
182
183/** Vendor class ID wildcard condition. */
184class GroupConditionVendorClassIDWildcard : public GroupCondition
185{
186public:
187 bool match(const ClientId &a_ridClient, const OptVendorClassId &a_ridVendorClass,
188 const OptUserClassId &a_ridUserClass) const RT_NOEXCEPT RT_OVERRIDE;
189};
190
191/** User class ID condition. */
192class GroupConditionUserClassID : public GroupCondition
193{
194public:
195 bool match(const ClientId &a_ridClient, const OptVendorClassId &a_ridVendorClass,
196 const OptUserClassId &a_ridUserClass) const RT_NOEXCEPT RT_OVERRIDE;
197};
198
199/** User class ID wildcard condition. */
200class GroupConditionUserClassIDWildcard : public GroupCondition
201{
202public:
203 bool match(const ClientId &a_ridClient, const OptVendorClassId &a_ridVendorClass,
204 const OptUserClassId &a_ridUserClass) const RT_NOEXCEPT RT_OVERRIDE;
205};
206
207
208/**
209 * Group config
210 */
211class GroupConfig : public ConfigLevelBase
212{
213private:
214 typedef std::vector<GroupCondition *> GroupConditionVec;
215
216 /** The group name. */
217 RTCString m_strName;
218 /** Vector containing the inclusive membership conditions (must match one). */
219 GroupConditionVec m_Inclusive;
220 /** Vector containing the exclusive membership conditions (must match none). */
221 GroupConditionVec m_Exclusive;
222
223public:
224 GroupConfig()
225 : ConfigLevelBase()
226 {
227 }
228
229 void initFromXml(xml::ElementNode const *pElmGroup, bool fStrict, Config const *pConfig) RT_OVERRIDE;
230 bool match(const ClientId &a_ridClient, const OptVendorClassId &a_ridVendorClass, const OptUserClassId &a_ridUserClass) const;
231
232 /** @name Accessors
233 * @{ */
234 const char *getType() const RT_NOEXCEPT RT_OVERRIDE { return "group"; }
235 const char *getName() const RT_NOEXCEPT RT_OVERRIDE { return m_strName.c_str(); }
236 RTCString const &getGroupName() const RT_NOEXCEPT { return m_strName; }
237 /** @} */
238
239protected:
240 void i_parseChild(const xml::ElementNode *pElmChild, bool fStrict, Config const *pConfig) RT_OVERRIDE;
241 /** Used to name unnamed groups. */
242 static uint32_t s_uGroupNo;
243};
244
245
246/**
247 * Host (MAC address) specific configuration.
248 */
249class HostConfig : public ConfigLevelBase
250{
251protected:
252 /** The MAC address. */
253 RTMAC m_MACAddress;
254 /** Name annotating the entry. */
255 RTCString m_strName;
256 /** Fixed address assignment when m_fHaveFixedAddress is true. */
257 RTNETADDRIPV4 m_FixedAddress;
258 /** Set if we have a fixed address asignment. */
259 bool m_fHaveFixedAddress;
260
261public:
262 HostConfig()
263 : ConfigLevelBase()
264 , m_fHaveFixedAddress(false)
265 {
266 RT_ZERO(m_MACAddress);
267 RT_ZERO(m_FixedAddress);
268 }
269
270 void initFromXml(xml::ElementNode const *pElmConfig, bool fStrict, Config const *pConfig) RT_OVERRIDE;
271 const char *getType() const RT_NOEXCEPT RT_OVERRIDE { return "host"; }
272 const char *getName() const RT_NOEXCEPT RT_OVERRIDE { return m_strName.c_str(); }
273
274 /** @name Accessors
275 * @{ */
276 RTMAC const &getMACAddress() const RT_NOEXCEPT { return m_MACAddress; }
277 bool haveFixedAddress() const RT_NOEXCEPT { return m_fHaveFixedAddress; }
278 RTNETADDRIPV4 const & getFixedAddress() const RT_NOEXCEPT { return m_FixedAddress; }
279 /** @} */
280};
281
282
283/**
284 * DHCP server configuration.
285 */
286class Config
287{
288 /** Group configuration map. */
289 typedef std::map<RTCString, GroupConfig const * > GroupConfigMap;
290 /** Host configuration map. */
291 typedef std::map<RTMAC, HostConfig const * > HostConfigMap;
292
293
294 RTCString m_strHome; /**< path of ~/.VirtualBox or equivalent, */
295
296 RTCString m_strNetwork; /**< The name of the internal network the DHCP server is connected to. */
297 RTCString m_strLeasesFilename;/**< The lease DB filename. */
298
299 RTCString m_strTrunk; /**< The trunk name of the internal network. */
300 INTNETTRUNKTYPE m_enmTrunkType; /**< The trunk type of the internal network. */
301
302 RTMAC m_MacAddress; /**< The MAC address for the DHCP server. */
303
304 RTNETADDRIPV4 m_IPv4Address; /**< The IPv4 address of the DHCP server. */
305 RTNETADDRIPV4 m_IPv4Netmask; /**< The IPv4 netmask for the DHCP server. */
306
307 RTNETADDRIPV4 m_IPv4PoolFirst; /**< The first IPv4 address in the pool. */
308 RTNETADDRIPV4 m_IPv4PoolLast; /**< The last IPV4 address in the pool (inclusive like all other 'last' variables). */
309
310
311 /** The global configuration. */
312 GlobalConfig m_GlobalConfig;
313 /** The group configurations, indexed by group name. */
314 GroupConfigMap m_GroupConfigs;
315 /** The host configurations, indexed by MAC address. */
316 HostConfigMap m_HostConfigs;
317
318 /** Set if we've initialized the log already (via command line). */
319 static bool g_fInitializedLog;
320
321private:
322 Config();
323
324 int i_init() RT_NOEXCEPT;
325 int i_homeInit() RT_NOEXCEPT;
326 static Config *i_createInstanceAndCallInit() RT_NOEXCEPT;
327 int i_logInit() RT_NOEXCEPT;
328 static int i_logInitWithFilename(const char *pszFilename) RT_NOEXCEPT;
329 int i_complete() RT_NOEXCEPT;
330
331public:
332 /** @name Factory methods
333 * @{ */
334 static Config *hardcoded() RT_NOEXCEPT; /**< For testing. */
335 static Config *create(int argc, char **argv) RT_NOEXCEPT; /**< --config */
336 static Config *compat(int argc, char **argv);
337 /** @} */
338
339 /** @name Accessors
340 * @{ */
341 const RTCString &getHome() const RT_NOEXCEPT { return m_strHome; }
342
343 const RTCString &getNetwork() const RT_NOEXCEPT { return m_strNetwork; }
344 const RTCString &getLeasesFilename() const RT_NOEXCEPT { return m_strLeasesFilename; }
345
346 const RTCString &getTrunk() const RT_NOEXCEPT { return m_strTrunk; }
347 INTNETTRUNKTYPE getTrunkType() const RT_NOEXCEPT { return m_enmTrunkType; }
348
349 const RTMAC &getMacAddress() const RT_NOEXCEPT { return m_MacAddress; }
350
351 RTNETADDRIPV4 getIPv4Address() const RT_NOEXCEPT { return m_IPv4Address; }
352 RTNETADDRIPV4 getIPv4Netmask() const RT_NOEXCEPT { return m_IPv4Netmask; }
353 RTNETADDRIPV4 getIPv4PoolFirst() const RT_NOEXCEPT { return m_IPv4PoolFirst; }
354 RTNETADDRIPV4 getIPv4PoolLast() const RT_NOEXCEPT { return m_IPv4PoolLast; }
355 /** @} */
356
357 /** Gets the network (IP masked by network mask). */
358 RTNETADDRIPV4 getIPv4Network() const RT_NOEXCEPT
359 {
360 RTNETADDRIPV4 Network;
361 Network.u = m_IPv4Netmask.u & m_IPv4Address.u;
362 return Network;
363 }
364 /** Checks if the given IPv4 address is in the DHCP server network. */
365 bool isInIPv4Network(RTNETADDRIPV4 a_rAddress) const RT_NOEXCEPT
366 {
367 return (a_rAddress.u & getIPv4Netmask().u) == getIPv4Network().u;
368 }
369
370 /** Host configuration vector. */
371 typedef std::vector<HostConfig const *> HostConfigVec;
372 int getFixedAddressConfigs(HostConfigVec &a_rRetConfigs) const;
373
374 /** Configuration vector. */
375 typedef std::vector<ConfigLevelBase const *> ConfigVec;
376 ConfigVec &getConfigsForClient(ConfigVec &a_rRetConfigs, const ClientId &a_ridClient,
377 const OptVendorClassId &a_ridVendorClass,
378 const OptUserClassId &a_ridUserClass) const;
379 optmap_t &getOptionsForClient(optmap_t &a_rRetOpts, const OptParameterRequest &a_rReqOpts,
380 ConfigVec &a_rConfigs) const;
381
382private:
383 /** @name Configuration file reading and parsing
384 * @{ */
385 static Config *i_read(const char *pszFilename, bool fStrict) RT_NOEXCEPT;
386 void i_parseConfig(const xml::ElementNode *pElmRoot, bool fStrict);
387 void i_parseServer(const xml::ElementNode *pElmServer, bool fStrict);
388 /** @} */
389};
390
391#endif /* !VBOX_INCLUDED_SRC_Dhcpd_Config_h */
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