VirtualBox

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

Last change on this file since 107044 was 106061, checked in by vboxsync, 2 months ago

Copyright year updates by scm.

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