VirtualBox

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

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

Main/DHCPServer,VBoxManage,Dhcpd: Created a new DHCPOption enum that replaced the incorrectly cased DhcpOpt enum in new APIs. Adjusted and documented each and every option and its format as best as I could. Also added two new attributes to IDHCPConfig, one for supressing options (from higher up the configuration scope) and one for forcing unsolicited options on a client. These attributes have not yet been pushed down to Dhcpd. bugref:9288

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