VirtualBox

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

Last change on this file since 79787 was 79763, checked in by vboxsync, 6 years ago

Main/DHCPServer,Dhcpd,VBoxManage: Added --log option to the DHCP server so we can start logging early. Added log rotation and limits. Put the config file next to the log and leases file. Validate DHCP options by reusing the parser code from the server, adding a bunch more DHCP options to the parser. Removed legacy and hardcoded configuration options from the dhcp server, it's all config file now. Fixed a bug in the option parsing of the VBoxManage dhcpserver add/modify commands. [build fix] bugref:9288

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.1 KB
Line 
1/* $Id: DhcpOptions.h 79763 2019-07-14 03:59:56Z 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> OptMaxDatagramReassemblySize;
759typedef OptValue<23, uint16_t> OptDefaultIPTTL;
760typedef OptValue<24, uint32_t> OptDefaultPathMTUAgingTimeout;
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> OptTFTPServer; /**< 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 */
818/** @} */
819
820#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