VirtualBox

source: vbox/trunk/src/VBox/NetworkServices/Dhcpd/DhcpOptions.h

Last change on this file was 106517, checked in by vboxsync, 7 weeks ago

NetworkServices/Dhcpd: DhcpOption needs a copy assignment operator too as it urns it and the rest of DhcpOptions.h is in Main while appearing to be an internal DHCP server file. Stupid mess. jiraref:VBP-1171

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.9 KB
Line 
1/* $Id: DhcpOptions.h 106517 2024-10-20 02:27:17Z vboxsync $ */
2/** @file
3 * DHCP server - DHCP options
4 *
5 * @note This file is also used by Main!
6 * @todo r=bird: Move to global include directory.
7 */
8
9/*
10 * Copyright (C) 2017-2024 Oracle and/or its affiliates.
11 *
12 * This file is part of VirtualBox base platform packages, as
13 * available from https://www.virtualbox.org.
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation, in version 3 of the
18 * License.
19 *
20 * This program is distributed in the hope that it will be useful, but
21 * WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see <https://www.gnu.org/licenses>.
27 *
28 * SPDX-License-Identifier: GPL-3.0-only
29 */
30
31#ifndef VBOX_INCLUDED_SRC_Dhcpd_DhcpOptions_h
32#define VBOX_INCLUDED_SRC_Dhcpd_DhcpOptions_h
33#ifndef RT_WITHOUT_PRAGMA_ONCE
34# pragma once
35#endif
36
37#include "DhcpdInternal.h"
38
39#include <iprt/asm.h>
40#include <iprt/err.h>
41#include <iprt/net.h>
42#include <iprt/string.h>
43#include <iprt/cpp/ministring.h>
44
45
46class DhcpClientMessage;
47
48typedef struct DhcpIpv4AddrAndMask
49{
50 RTNETADDRIPV4 Ipv4;
51 RTNETADDRIPV4 Mask;
52} DhcpIpv4AddrAndMask;
53
54
55class DhcpOption
56{
57protected:
58 uint8_t m_OptCode;
59 bool m_fPresent;
60
61public:
62 explicit DhcpOption(uint8_t aOptCode)
63 : m_OptCode(aOptCode), m_fPresent(true)
64 {}
65
66 DhcpOption(uint8_t aOptCode, bool fPresent)
67 : m_OptCode(aOptCode), m_fPresent(fPresent)
68 {}
69
70 virtual DhcpOption *clone() const = 0;
71
72 virtual ~DhcpOption()
73 {}
74
75#if RT_CPLUSPLUS_PREREQ(201100) /* VC2022: Excplit default copy constructor and copy assignment operator to avoid warnings. */
76 DhcpOption(DhcpOption const &) = default;
77 DhcpOption &operator=(DhcpOption const &) = default;
78#endif
79
80public:
81 static DhcpOption *parse(uint8_t aOptCode, int aEnc, const char *pcszValue, int *prc = NULL);
82 static const char *name(uint8_t bOptcode);
83
84public:
85 uint8_t optcode() const RT_NOEXCEPT { return m_OptCode; }
86 bool present() const RT_NOEXCEPT { return m_fPresent; }
87
88public:
89 int encode(octets_t &dst) const;
90
91 int decode(const rawopts_t &map);
92 int decode(const DhcpClientMessage &req);
93
94protected:
95 virtual ssize_t encodeValue(octets_t &dst) const = 0;
96 virtual int decodeValue(const octets_t &src, size_t cb) = 0;
97
98protected:
99 static const octets_t *findOption(const rawopts_t &aOptMap, uint8_t aOptCode);
100
101protected:
102 /** @name Serialization
103 * @{ */
104 static void append(octets_t &aDst, bool aValue)
105 {
106 uint8_t b = aValue ? 1 : 0;
107 aDst.push_back(b);
108 }
109
110 static void append(octets_t &aDst, uint8_t aValue)
111 {
112 aDst.push_back(aValue);
113 }
114
115 static void append(octets_t &aDst, uint16_t aValue)
116 {
117 RTUINT16U u16 = { RT_H2N_U16(aValue) };
118 aDst.insert(aDst.end(), u16.au8, u16.au8 + sizeof(aValue));
119 }
120
121 static void append(octets_t &aDst, uint32_t aValue)
122 {
123 RTUINT32U u32 = { RT_H2N_U32(aValue) };
124 aDst.insert(aDst.end(), u32.au8, u32.au8 + sizeof(aValue));
125 }
126
127 static void append(octets_t &aDst, RTNETADDRIPV4 aIPv4)
128 {
129 aDst.insert(aDst.end(), aIPv4.au8, aIPv4.au8 + sizeof(aIPv4));
130 }
131
132 static void append(octets_t &aDst, DhcpIpv4AddrAndMask aIPv4)
133 {
134 aDst.insert(aDst.end(), (uint8_t *)&aIPv4, (uint8_t *)&aIPv4 + sizeof(aIPv4));
135 }
136
137 static void append(octets_t &aDst, const char *pszString, size_t cb)
138 {
139 aDst.insert(aDst.end(), pszString, pszString + cb);
140 }
141
142 static void append(octets_t &aDst, const RTCString &str)
143 {
144 append(aDst, str.c_str(), str.length());
145 }
146
147 /* non-overloaded name to avoid ambiguity */
148 static void appendLength(octets_t &aDst, size_t cb)
149 {
150 append(aDst, static_cast<uint8_t>(cb));
151 }
152
153 /** @} */
154
155
156 /** @name Deserialization
157 * @{ */
158 static void extract(bool &aValue, octets_t::const_iterator &pos)
159 {
160 aValue = *pos != 0;
161 pos += sizeof(uint8_t);
162 }
163
164 static void extract(uint8_t &aValue, octets_t::const_iterator &pos)
165 {
166 aValue = *pos;
167 pos += sizeof(uint8_t);
168 }
169
170 static void extract(uint16_t &aValue, octets_t::const_iterator &pos)
171 {
172 RTUINT16U u16;
173 memcpy(u16.au8, &pos[0], sizeof(uint16_t));
174 aValue = RT_N2H_U16(u16.u);
175 pos += sizeof(uint16_t);
176 }
177
178 static void extract(uint32_t &aValue, octets_t::const_iterator &pos)
179 {
180 RTUINT32U u32;
181 memcpy(u32.au8, &pos[0], sizeof(uint32_t));
182 aValue = RT_N2H_U32(u32.u);
183 pos += sizeof(uint32_t);
184 }
185
186 static void extract(RTNETADDRIPV4 &aValue, octets_t::const_iterator &pos)
187 {
188 memcpy(aValue.au8, &pos[0], sizeof(RTNETADDRIPV4));
189 pos += sizeof(RTNETADDRIPV4);
190 }
191
192 static void extract(DhcpIpv4AddrAndMask &aValue, octets_t::const_iterator &pos)
193 {
194 memcpy(&aValue, &pos[0], sizeof(aValue));
195 pos += sizeof(aValue);
196 }
197
198#if 0 /** @todo fix me */
199 static void extract(RTCString &aString, octets_t::const_iterator &pos, size_t cb)
200 {
201 aString.replace(aString.begin(), aString.end(), &pos[0], &pos[cb]);
202 pos += cb;
203 }
204#endif
205
206 /** @} */
207
208 /** @name Parse textual representation (e.g. in config file)
209 * @{ */
210 static int parse1(bool &aValue, const char *pcszValue);
211 static int parse1(uint8_t &aValue, const char *pcszValue);
212 static int parse1(uint16_t &aValue, const char *pcszValue);
213 static int parse1(uint32_t &aValue, const char *pcszValue);
214 static int parse1(RTNETADDRIPV4 &aValue, const char *pcszValue);
215 static int parse1(DhcpIpv4AddrAndMask &aValue, const char *pcszValue);
216
217 template <typename a_Type> static int parseList(std::vector<a_Type> &aList, const char *pcszValue);
218
219 static int parseHex(octets_t &aRawValue, const char *pcszValue);
220
221 /** @} */
222};
223
224
225inline octets_t &operator<<(octets_t &dst, const DhcpOption &option)
226{
227 option.encode(dst);
228 return dst;
229}
230
231
232#ifndef IN_VBOXSVC
233optmap_t &operator<<(optmap_t &optmap, DhcpOption *option);
234optmap_t &operator<<(optmap_t &optmap, const std::shared_ptr<DhcpOption> &option);
235#endif
236
237
238
239/**
240 * Only for << OptEnd() syntactic sugar...
241 */
242struct OptEnd {};
243inline octets_t &operator<<(octets_t &dst, const OptEnd &end)
244{
245 RT_NOREF(end);
246
247 dst.push_back(RTNET_DHCP_OPT_END);
248 return dst;
249}
250
251
252
253/**
254 * Option that has no value
255 */
256class OptNoValueBase
257 : public DhcpOption
258{
259public:
260 explicit OptNoValueBase(uint8_t aOptCode)
261 : DhcpOption(aOptCode, false)
262 {}
263
264 OptNoValueBase(uint8_t aOptCode, bool fPresent)
265 : DhcpOption(aOptCode, fPresent)
266 {}
267
268 OptNoValueBase(uint8_t aOptCode, const DhcpClientMessage &req)
269 : DhcpOption(aOptCode, false)
270 {
271 decode(req);
272 }
273
274 virtual OptNoValueBase *clone() const
275 {
276 return new OptNoValueBase(*this);
277 }
278
279protected:
280 virtual ssize_t encodeValue(octets_t &dst) const
281 {
282 RT_NOREF(dst);
283 return 0;
284 }
285
286public:
287 static bool isLengthValid(size_t cb)
288 {
289 return cb == 0;
290 }
291
292 virtual int decodeValue(const octets_t &src, size_t cb)
293 {
294 RT_NOREF(src);
295
296 if (!isLengthValid(cb))
297 return VERR_INVALID_PARAMETER;
298
299 m_fPresent = true;
300 return VINF_SUCCESS;
301 }
302};
303
304template <uint8_t _OptCode>
305class OptNoValue
306 : public OptNoValueBase
307{
308public:
309 static const uint8_t optcode = _OptCode;
310
311 OptNoValue()
312 : OptNoValueBase(optcode)
313 {}
314
315 explicit OptNoValue(bool fPresent) /* there's no overloaded ctor with value */
316 : OptNoValueBase(optcode, fPresent)
317 {}
318
319 explicit OptNoValue(const DhcpClientMessage &req)
320 : OptNoValueBase(optcode, req)
321 {}
322};
323
324
325
326/*
327 * Option that contains single value of fixed-size type T
328 */
329template <typename T>
330class OptValueBase
331 : public DhcpOption
332{
333public:
334 typedef T value_t;
335
336protected:
337 T m_Value;
338
339 explicit OptValueBase(uint8_t aOptCode)
340 : DhcpOption(aOptCode, false), m_Value()
341 {}
342
343 OptValueBase(uint8_t aOptCode, const T &aOptValue)
344 : DhcpOption(aOptCode), m_Value(aOptValue)
345 {}
346
347 OptValueBase(uint8_t aOptCode, const DhcpClientMessage &req)
348 : DhcpOption(aOptCode, false), m_Value()
349 {
350 decode(req);
351 }
352
353public:
354 virtual OptValueBase *clone() const
355 {
356 return new OptValueBase(*this);
357 }
358
359public:
360 T &value() { return m_Value; }
361 const T &value() const { return m_Value; }
362
363protected:
364 virtual ssize_t encodeValue(octets_t &dst) const
365 {
366 append(dst, m_Value);
367 return sizeof(T);
368 }
369
370public:
371 static bool isLengthValid(size_t cb)
372 {
373 return cb == sizeof(T);
374 }
375
376 virtual int decodeValue(const octets_t &src, size_t cb)
377 {
378 if (!isLengthValid(cb))
379 return VERR_INVALID_PARAMETER;
380
381 octets_t::const_iterator pos(src.begin());
382 extract(m_Value, pos);
383
384 m_fPresent = true;
385 return VINF_SUCCESS;
386 }
387};
388
389template<uint8_t _OptCode, typename T>
390class OptValue
391 : public OptValueBase<T>
392{
393public:
394 using typename OptValueBase<T>::value_t;
395
396public:
397 static const uint8_t optcode = _OptCode;
398
399 OptValue()
400 : OptValueBase<T>(optcode)
401 {}
402
403 explicit OptValue(const T &aOptValue)
404 : OptValueBase<T>(optcode, aOptValue)
405 {}
406
407 explicit OptValue(const DhcpClientMessage &req)
408 : OptValueBase<T>(optcode, req)
409 {}
410
411 static OptValue *parse(const char *pcszValue, int *prc)
412 {
413 typename OptValueBase<T>::value_t v;
414 int rc = DhcpOption::parse1(v, pcszValue);
415 *prc = rc;
416 if (RT_SUCCESS(rc))
417 return new OptValue(v);
418 return NULL;
419 }
420};
421
422
423
424/**
425 * Option that contains a string.
426 */
427class OptStringBase
428 : public DhcpOption
429{
430public:
431 typedef RTCString value_t;
432
433protected:
434 RTCString m_String;
435
436 explicit OptStringBase(uint8_t aOptCode)
437 : DhcpOption(aOptCode, false), m_String()
438 {}
439
440 OptStringBase(uint8_t aOptCode, const RTCString &aOptString)
441 : DhcpOption(aOptCode), m_String(aOptString)
442 {}
443
444 OptStringBase(uint8_t aOptCode, const DhcpClientMessage &req)
445 : DhcpOption(aOptCode, false), m_String()
446 {
447 decode(req);
448 }
449
450public:
451 virtual OptStringBase *clone() const
452 {
453 return new OptStringBase(*this);
454 }
455
456public:
457 RTCString &value() { return m_String; }
458 const RTCString &value() const { return m_String; }
459
460protected:
461 virtual ssize_t encodeValue(octets_t &dst) const
462 {
463 if (!isLengthValid(m_String.length()))
464 return -1;
465
466 append(dst, m_String);
467 return (ssize_t)m_String.length();
468 }
469
470public:
471 static bool isLengthValid(size_t cb)
472 {
473 return cb <= UINT8_MAX;
474 }
475
476 virtual int decodeValue(const octets_t &src, size_t cb)
477 {
478 if (!isLengthValid(cb))
479 return VERR_INVALID_PARAMETER;
480
481 int rc = m_String.assignNoThrow((char *)&src.front(), cb); /** @todo encoding. */
482 m_fPresent = true;
483 return rc;
484 }
485};
486
487template<uint8_t _OptCode>
488class OptString
489 : public OptStringBase
490{
491public:
492 static const uint8_t optcode = _OptCode;
493
494 OptString()
495 : OptStringBase(optcode)
496 {}
497
498 explicit OptString(const RTCString &aOptString)
499 : OptStringBase(optcode, aOptString)
500 {}
501
502 explicit OptString(const DhcpClientMessage &req)
503 : OptStringBase(optcode, req)
504 {}
505
506 static OptString *parse(const char *pcszValue, int *prc)
507 {
508 *prc = VINF_SUCCESS;
509 return new OptString(pcszValue);
510 }
511};
512
513
514
515/*
516 * Option that contains a list of values of type T
517 */
518template <typename T>
519class OptListBase
520 : public DhcpOption
521{
522public:
523 typedef std::vector<T> value_t;
524
525protected:
526 std::vector<T> m_List;
527
528 explicit OptListBase(uint8_t aOptCode)
529 : DhcpOption(aOptCode, false), m_List()
530 {}
531
532 OptListBase(uint8_t aOptCode, const T &aOptSingle)
533 : DhcpOption(aOptCode), m_List(1, aOptSingle)
534 {}
535
536 OptListBase(uint8_t aOptCode, const std::vector<T> &aOptList)
537 : DhcpOption(aOptCode), m_List(aOptList)
538 {}
539
540 OptListBase(uint8_t aOptCode, const DhcpClientMessage &req)
541 : DhcpOption(aOptCode, false), m_List()
542 {
543 decode(req);
544 }
545
546public:
547 virtual OptListBase *clone() const
548 {
549 return new OptListBase(*this);
550 }
551
552public:
553 std::vector<T> &value() { return m_List; }
554 const std::vector<T> &value() const { return m_List; }
555
556protected:
557 virtual ssize_t encodeValue(octets_t &dst) const
558 {
559 const size_t cbItem = sizeof(T);
560 size_t cbValue = 0;
561
562 for (size_t i = 0; i < m_List.size(); ++i)
563 {
564 if (cbValue + cbItem > UINT8_MAX)
565 break;
566
567 append(dst, m_List[i]);
568 cbValue += cbItem;
569 }
570
571 return (ssize_t)cbValue;
572 }
573
574public:
575 static bool isLengthValid(size_t cb)
576 {
577 return cb % sizeof(T) == 0;
578 }
579
580 virtual int decodeValue(const octets_t &src, size_t cb)
581 {
582 if (!isLengthValid(cb))
583 return VERR_INVALID_PARAMETER;
584
585 m_List.erase(m_List.begin(), m_List.end());
586
587 octets_t::const_iterator pos(src.begin());
588 for (size_t i = 0; i < cb / sizeof(T); ++i)
589 {
590 T item;
591 extract(item, pos);
592 m_List.push_back(item);
593 }
594 m_fPresent = true;
595 return VINF_SUCCESS;
596 }
597};
598
599template<uint8_t _OptCode, typename T>
600class OptList
601 : public OptListBase<T>
602
603{
604public:
605 using typename OptListBase<T>::value_t;
606
607public:
608 static const uint8_t optcode = _OptCode;
609
610 OptList()
611 : OptListBase<T>(optcode)
612 {}
613
614 explicit OptList(const T &aOptSingle)
615 : OptListBase<T>(optcode, aOptSingle)
616 {}
617
618 explicit OptList(const std::vector<T> &aOptList)
619 : OptListBase<T>(optcode, aOptList)
620 {}
621
622 explicit OptList(const DhcpClientMessage &req)
623 : OptListBase<T>(optcode, req)
624 {}
625
626 static OptList *parse(const char *pcszValue, int *prc)
627 {
628 typename OptListBase<T>::value_t v;
629 int rc = DhcpOption::parseList<T>(v, pcszValue);
630 if (RT_SUCCESS(rc))
631 {
632 if (!v.empty())
633 {
634 *prc = rc;
635 return new OptList(v);
636 }
637 rc = VERR_NO_DATA;
638 }
639 *prc = rc;
640 return NULL;
641 }
642};
643
644
645template<uint8_t _OptCode, typename T>
646class OptPairList
647 : public OptListBase<T>
648
649{
650public:
651 using typename OptListBase<T>::value_t;
652
653public:
654 static const uint8_t optcode = _OptCode;
655
656 OptPairList()
657 : OptListBase<T>(optcode)
658 {}
659
660 explicit OptPairList(const T &aOptSingle)
661 : OptListBase<T>(optcode, aOptSingle)
662 {}
663
664 explicit OptPairList(const std::vector<T> &aOptList)
665 : OptListBase<T>(optcode, aOptList)
666 {}
667
668 explicit OptPairList(const DhcpClientMessage &req)
669 : OptListBase<T>(optcode, req)
670 {}
671
672 static OptPairList *parse(const char *pcszValue, int *prc)
673 {
674 typename OptListBase<T>::value_t v;
675 int rc = DhcpOption::parseList<T>(v, pcszValue);
676 if (RT_SUCCESS(rc))
677 {
678 if (!v.empty())
679 {
680 if ((v.size() & 1) == 0)
681 {
682 *prc = rc;
683 return new OptPairList(v);
684 }
685 rc = VERR_UNEVEN_INPUT;
686 }
687 else
688 rc = VERR_NO_DATA;
689 }
690 *prc = rc;
691 return NULL;
692 }
693};
694
695
696/*
697 * Options specified by raw binary data that we don't know how to
698 * interpret.
699 */
700class RawOption
701 : public DhcpOption
702{
703protected:
704 octets_t m_Data;
705
706public:
707 explicit RawOption(uint8_t aOptCode)
708 : DhcpOption(aOptCode, false), m_Data()
709 {}
710
711 RawOption(uint8_t aOptCode, const octets_t &aSrc)
712 : DhcpOption(aOptCode), m_Data(aSrc)
713 {}
714
715public:
716 virtual RawOption *clone() const
717 {
718 return new RawOption(*this);
719 }
720
721
722protected:
723 virtual ssize_t encodeValue(octets_t &dst) const
724 {
725 dst.insert(dst.end(), m_Data.begin(), m_Data.end());
726 return (ssize_t)m_Data.size();
727 }
728
729 virtual int decodeValue(const octets_t &src, size_t cb)
730 {
731 octets_t::const_iterator beg(src.begin());
732 octets_t data(beg, beg + (ssize_t)cb);
733 m_Data.swap(data);
734
735 m_fPresent = true;
736 return VINF_SUCCESS;
737 }
738
739public:
740 static RawOption *parse(uint8_t aOptCode, const char *pcszValue, int *prc)
741 {
742 octets_t data;
743 int rc = DhcpOption::parseHex(data, pcszValue);
744 *prc = rc;
745 if (RT_SUCCESS(rc))
746 return new RawOption(aOptCode, data);
747 return NULL;
748 }
749};
750
751
752
753/** @name The DHCP options types.
754 * @{
755 */
756typedef OptValue<1, RTNETADDRIPV4> OptSubnetMask;
757typedef OptValue<2, uint32_t> OptTimeOffset;
758typedef OptList<3, RTNETADDRIPV4> OptRouters;
759typedef OptList<4, RTNETADDRIPV4> OptTimeServers;
760typedef OptList<5, RTNETADDRIPV4> OptNameServers;
761typedef OptList<6, RTNETADDRIPV4> OptDNSes;
762typedef OptList<7, RTNETADDRIPV4> OptLogServers;
763typedef OptList<8, RTNETADDRIPV4> OptCookieServers;
764typedef OptList<9, RTNETADDRIPV4> OptLPRServers;
765typedef OptList<10, RTNETADDRIPV4> OptImpressServers;
766typedef OptList<11, RTNETADDRIPV4> OptResourceLocationServers;
767typedef OptString<12> OptHostName;
768typedef OptValue<13, uint16_t> OptBootFileSize;
769typedef OptString<14> OptMeritDumpFile;
770typedef OptString<15> OptDomainName;
771typedef OptValue<16, RTNETADDRIPV4> OptSwapServer;
772typedef OptString<17> OptRootPath;
773typedef OptString<18> OptExtensionPath;
774typedef OptValue<19, bool> OptIPForwarding;
775typedef OptValue<20, bool> OptNonLocalSourceRouting;
776typedef OptList<21, DhcpIpv4AddrAndMask> OptPolicyFilter;
777typedef OptValue<22, uint16_t> OptMaxDgramReassemblySize;
778typedef OptValue<23, uint16_t> OptDefaultIPTTL;
779typedef OptValue<24, uint32_t> OptPathMTUAgingTimeout;
780typedef OptList<25, uint16_t> OptPathMTUPlateauTable;
781typedef OptValue<26, uint16_t> OptInterfaceMTU;
782typedef OptValue<27, bool> OptAllSubnetsAreLocal;
783typedef OptValue<28, RTNETADDRIPV4> OptBroadcastAddress;
784typedef OptValue<29, bool> OptPerformMaskDiscovery;
785typedef OptValue<30, bool> OptMaskSupplier;
786typedef OptValue<31, bool> OptPerformRouterDiscovery;
787typedef OptValue<32, RTNETADDRIPV4> OptRouterSolicitationAddress;
788typedef OptPairList<33, RTNETADDRIPV4> OptStaticRoute;
789typedef OptValue<34, bool> OptTrailerEncapsulation;
790typedef OptValue<35, uint32_t> OptARPCacheTimeout;
791typedef OptValue<36, bool> OptEthernetEncapsulation;
792typedef OptValue<37, uint8_t> OptTCPDefaultTTL;
793typedef OptValue<38, uint32_t> OptTCPKeepaliveInterval;
794typedef OptValue<39, bool> OptTCPKeepaliveGarbage;
795typedef OptString<40> OptNISDomain;
796typedef OptList<41, RTNETADDRIPV4> OptNISServers;
797typedef OptList<42, RTNETADDRIPV4> OptNTPServers;
798/* DHCP related options: */
799typedef OptList<43, uint8_t> OptVendorSpecificInfo;
800typedef OptList<44, RTNETADDRIPV4> OptNetBIOSNameServers;
801typedef OptList<45, RTNETADDRIPV4> OptNetBIOSDatagramServers;
802typedef OptValue<46, uint8_t> OptNetBIOSNodeType;
803typedef OptList<47, uint8_t> OptNetBIOSScope; /**< uint8_t or string? */
804typedef OptList<48, RTNETADDRIPV4> OptXWindowsFontServers;
805typedef OptList<49, RTNETADDRIPV4> OptXWindowsDisplayManager;
806typedef OptValue<50, RTNETADDRIPV4> OptRequestedAddress;
807typedef OptValue<51, uint32_t> OptLeaseTime;
808/* 52 - option overload is syntactic and handled internally */
809typedef OptValue<53, uint8_t> OptMessageType;
810typedef OptValue<54, RTNETADDRIPV4> OptServerId;
811typedef OptList<55, uint8_t> OptParameterRequest;
812typedef OptString<56> OptMessage;
813typedef OptValue<57, uint16_t> OptMaxDHCPMessageSize;
814typedef OptValue<58, uint32_t> OptRenewalTime;
815typedef OptValue<59, uint32_t> OptRebindingTime;
816typedef OptList<60, uint8_t> OptVendorClassId;
817typedef OptList<61, uint8_t> OptClientId;
818typedef OptString<62> OptNetWareIPDomainName; /**< RFC2242 */
819typedef OptList<63, uint8_t> OptNetWareIPInformation; /**< complicated, so just byte list for now. RFC2242 */
820typedef OptString<64> OptNISPlusDomain;
821typedef OptString<65> OptNISPlusServers;
822typedef OptString<66> OptTFTPServerName; /**< when overloaded */
823typedef OptString<67> OptBootfileName; /**< when overloaded */
824typedef OptList<68, RTNETADDRIPV4> OptMobileIPHomeAgents;
825typedef OptList<69, RTNETADDRIPV4> OptSMTPServers;
826typedef OptList<70, RTNETADDRIPV4> OptPOP3Servers;
827typedef OptList<71, RTNETADDRIPV4> OptNNTPServers;
828typedef OptList<72, RTNETADDRIPV4> OptWWWServers;
829typedef OptList<73, RTNETADDRIPV4> OptFingerServers;
830typedef OptList<74, RTNETADDRIPV4> OptIRCServers;
831typedef OptList<75, RTNETADDRIPV4> OptStreetTalkServers;
832typedef OptList<76, RTNETADDRIPV4> OptSTDAServers;
833typedef OptList<77, uint8_t> OptUserClassId;
834typedef OptList<78, uint8_t> OptSLPDirectoryAgent; /**< complicated, so just byte list for now. RFC2610 */
835typedef OptList<79, uint8_t> OptSLPServiceScope; /**< complicated, so just byte list for now. RFC2610 */
836typedef OptNoValue<80> OptRapidCommit; /**< RFC4039 */
837typedef OptList<119, uint8_t> OptDomainSearch; /**< RFC3397 */
838/** @} */
839
840#endif /* !VBOX_INCLUDED_SRC_Dhcpd_DhcpOptions_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