VirtualBox

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

Last change on this file since 82968 was 82968, checked in by vboxsync, 5 years ago

Copyright year updates by scm.

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