Kea 2.2.0
pkt4.cc
Go to the documentation of this file.
1// Copyright (C) 2011-2022 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
9#include <dhcp/dhcp4.h>
10#include <dhcp/libdhcp++.h>
11#include <dhcp/option_int.h>
12#include <dhcp/pkt4.h>
14
15#include <algorithm>
16#include <iostream>
17#include <sstream>
18
19using namespace std;
20using namespace isc::dhcp;
21using namespace isc::asiolink;
22
23namespace {
24
26const IOAddress DEFAULT_ADDRESS("0.0.0.0");
27}
28
29namespace isc {
30namespace dhcp {
31
32Pkt4::Pkt4(uint8_t msg_type, uint32_t transid)
33 : Pkt(transid, DEFAULT_ADDRESS, DEFAULT_ADDRESS, DHCP4_SERVER_PORT, DHCP4_CLIENT_PORT),
34 op_(DHCPTypeToBootpType(msg_type)), hwaddr_(new HWAddr()), hops_(0), secs_(0), flags_(0),
35 ciaddr_(DEFAULT_ADDRESS), yiaddr_(DEFAULT_ADDRESS), siaddr_(DEFAULT_ADDRESS),
36 giaddr_(DEFAULT_ADDRESS) {
37 memset(sname_, 0, MAX_SNAME_LEN);
38 memset(file_, 0, MAX_FILE_LEN);
39
40 setType(msg_type);
41}
42
43Pkt4::Pkt4(const uint8_t* data, size_t len)
44 : Pkt(data, len, DEFAULT_ADDRESS, DEFAULT_ADDRESS, DHCP4_SERVER_PORT, DHCP4_CLIENT_PORT),
45 op_(BOOTREQUEST), hwaddr_(new HWAddr()), hops_(0), secs_(0), flags_(0),
46 ciaddr_(DEFAULT_ADDRESS), yiaddr_(DEFAULT_ADDRESS), siaddr_(DEFAULT_ADDRESS),
47 giaddr_(DEFAULT_ADDRESS) {
48
49 if (len < DHCPV4_PKT_HDR_LEN) {
50 isc_throw(OutOfRange, "Truncated DHCPv4 packet (len=" << len
51 << ") received, at least " << DHCPV4_PKT_HDR_LEN
52 << " is expected.");
53 }
54 memset(sname_, 0, MAX_SNAME_LEN);
55 memset(file_, 0, MAX_FILE_LEN);
56}
57
58size_t
60 size_t length = DHCPV4_PKT_HDR_LEN; // DHCPv4 header
61
62 // ... and sum of lengths of all options
63 for (const auto& it : options_) {
64 length += it.second->len();
65 }
66
67 return (length);
68}
69
70void
72 ScopedPkt4OptionsCopy scoped_options(*this);
73 if (!hwaddr_) {
74 isc_throw(InvalidOperation, "Can't build Pkt4 packet. HWAddr not set.");
75 }
76
77 // Clear the output buffer to make sure that consecutive calls to pack()
78 // will not result in concatenation of multiple packet copies.
80
81 try {
82 size_t hw_len = hwaddr_->hwaddr_.size();
83
87 hw_len : MAX_CHADDR_LEN);
96
97
98 if ((hw_len > 0) && (hw_len <= MAX_CHADDR_LEN)) {
99 // write up to 16 bytes of the hardware address (CHADDR field is 16
100 // bytes long in DHCPv4 message).
101 buffer_out_.writeData(&hwaddr_->hwaddr_[0],
102 (hw_len < MAX_CHADDR_LEN ?
103 hw_len : MAX_CHADDR_LEN) );
104 hw_len = MAX_CHADDR_LEN - hw_len;
105 } else {
106 hw_len = MAX_CHADDR_LEN;
107 }
108
109 // write (len) bytes of padding
110 if (hw_len > 0) {
111 vector<uint8_t> zeros(hw_len, 0);
112 buffer_out_.writeData(&zeros[0], hw_len);
113 }
114
117
118 // write DHCP magic cookie
119 buffer_out_.writeUint32(DHCP_OPTIONS_COOKIE);
120
124
125 // The RFC3396 adds support for long options split over multiple options
126 // using the same code.
127 // The long options are split in multiple CustomOption instances which
128 // hold the data. As a result, the option type of the newly created
129 // options will differ from the ones instantiated by the
130 // @ref OptionDefinition::optionFactory. At this stage the server should
131 // not do anything useful with the options beside packing.
133
134 // Call packOptions4() with parameter,"top", true. This invokes
135 // logic to emit the message type option first.
137
138 // add END option that indicates end of options
139 // (End option is very simple, just a 255 octet)
141 } catch(const Exception& e) {
142 // An exception is thrown and message will be written to Logger
144 }
145}
146
147void
149 // input buffer (used during message reception)
150 isc::util::InputBuffer buffer_in(&data_[0], data_.size());
151
152 if (buffer_in.getLength() < DHCPV4_PKT_HDR_LEN) {
153 isc_throw(OutOfRange, "Received truncated DHCPv4 packet (len="
154 << buffer_in.getLength() << " received, at least "
155 << DHCPV4_PKT_HDR_LEN << "is expected");
156 }
157
158 op_ = buffer_in.readUint8();
159 uint8_t htype = buffer_in.readUint8();
160 uint8_t hlen = buffer_in.readUint8();
161 hops_ = buffer_in.readUint8();
162 transid_ = buffer_in.readUint32();
163 secs_ = buffer_in.readUint16();
164 flags_ = buffer_in.readUint16();
165 ciaddr_ = IOAddress(buffer_in.readUint32());
166 yiaddr_ = IOAddress(buffer_in.readUint32());
167 siaddr_ = IOAddress(buffer_in.readUint32());
168 giaddr_ = IOAddress(buffer_in.readUint32());
169
170 vector<uint8_t> hw_addr(MAX_CHADDR_LEN, 0);
171 buffer_in.readVector(hw_addr, MAX_CHADDR_LEN);
172 buffer_in.readData(sname_, MAX_SNAME_LEN);
173 buffer_in.readData(file_, MAX_FILE_LEN);
174
175 hw_addr.resize(hlen);
176
177 hwaddr_ = HWAddrPtr(new HWAddr(hw_addr, htype));
178
179 if (buffer_in.getLength() == buffer_in.getPosition()) {
180 // this is *NOT* DHCP packet. It does not have any DHCPv4 options. In
181 // particular, it does not have magic cookie, a 4 byte sequence that
182 // differentiates between DHCP and RFC 951 BOOTP packets.
183 isc_throw(InvalidOperation, "Received BOOTP packet without vendor information extensions.");
184 }
185
186 if (buffer_in.getLength() - buffer_in.getPosition() < 4) {
187 // there is not enough data to hold magic DHCP cookie
188 isc_throw(Unexpected, "Truncated or no DHCP packet.");
189 }
190
191 uint32_t magic = buffer_in.readUint32();
192 if (magic != DHCP_OPTIONS_COOKIE) {
193 isc_throw(Unexpected, "Invalid or missing DHCP magic cookie");
194 }
195
196 size_t opts_len = buffer_in.getLength() - buffer_in.getPosition();
197 vector<uint8_t> opts_buffer;
198
199 // Use readVector because a function which parses option requires
200 // a vector as an input.
201 buffer_in.readVector(opts_buffer, opts_len);
202
203 size_t offset = LibDHCP::unpackOptions4(opts_buffer, DHCP4_OPTION_SPACE, options_, deferred_options_, false);
204
205 // If offset is not equal to the size and there is no DHO_END,
206 // then something is wrong here. We either parsed past input
207 // buffer (bug in our code) or we haven't parsed everything
208 // (received trailing garbage or truncated option).
209 //
210 // Invoking Jon Postel's law here: be conservative in what you send, and be
211 // liberal in what you accept. There's no easy way to log something from
212 // libdhcp++ library, so we just choose to be silent about remaining
213 // bytes. We also need to quell compiler warning about unused offset
214 // variable.
215 //
216 // if ((offset != size) && (opts_buffer[offset] != DHO_END)) {
217 // isc_throw(BadValue, "Received DHCPv6 buffer of size " << size
218 // << ", were able to parse " << offset << " bytes.");
219 // }
220 (void)offset;
221
222 // The RFC3396 adds support for multiple options using the same code fused
223 // into long options.
224 // All instances of the same option are fused together, including merging
225 // the suboption lists and fusing suboptions. As a result, the options will
226 // store more than 255 bytes of data and the regex parsers can effectively
227 // access the entire data.
229
230 // No need to call check() here. There are thorough tests for this
231 // later (see Dhcp4Srv::accept()). We want to drop the packet later,
232 // so we'll be able to log more detailed drop reason.
233}
234
235uint8_t Pkt4::getType() const {
237 if (!generic) {
238 return (DHCP_NOTYPE);
239 }
240
241 // Check if Message Type is specified as OptionInt<uint8_t>
242 boost::shared_ptr<OptionInt<uint8_t> > type_opt =
243 boost::dynamic_pointer_cast<OptionInt<uint8_t> >(generic);
244 if (type_opt) {
245 return (type_opt->getValue());
246 }
247
248 // Try to use it as generic option
249 return (generic->getUint8());
250}
251
252void Pkt4::setType(uint8_t dhcp_type) {
254 if (opt) {
255
256 // There is message type option already, update it. It seems that
257 // we do have two types of objects representing message-type option.
258 // It would be more preferable to use only one type, but there's no
259 // easy way to enforce it.
260 //
261 // One is an instance of the Option class. It stores type in
262 // Option::data_, so Option::setUint8() and Option::getUint8() can be
263 // used. The other one is an instance of OptionInt<uint8_t> and
264 // it stores message type as integer, hence
265 // OptionInt<uint8_t>::getValue() and OptionInt<uint8_t>::setValue()
266 // should be used.
267 boost::shared_ptr<OptionInt<uint8_t> > type_opt =
268 boost::dynamic_pointer_cast<OptionInt<uint8_t> >(opt);
269 if (type_opt) {
270 type_opt->setValue(dhcp_type);
271 } else {
272 opt->setUint8(dhcp_type);
273 }
274 } else {
275 // There is no message type option yet, add it
277 dhcp_type));
278 addOption(opt);
279 }
280}
281
282const char*
283Pkt4::getName(const uint8_t type) {
284 static const char* DHCPDISCOVER_NAME = "DHCPDISCOVER";
285 static const char* DHCPOFFER_NAME = "DHCPOFFER";
286 static const char* DHCPREQUEST_NAME = "DHCPREQUEST";
287 static const char* DHCPDECLINE_NAME = "DHCPDECLINE";
288 static const char* DHCPACK_NAME = "DHCPACK";
289 static const char* DHCPNAK_NAME = "DHCPNAK";
290 static const char* DHCPRELEASE_NAME = "DHCPRELEASE";
291 static const char* DHCPINFORM_NAME = "DHCPINFORM";
292 static const char* DHCPLEASEQUERY_NAME = "DHCPLEASEQUERY";
293 static const char* DHCPLEASEUNASSIGNED_NAME = "DHCPLEASEUNASSIGNED";
294 static const char* DHCPLEASEUNKNOWN_NAME = "DHCPLEASEUNKNOWN";
295 static const char* DHCPLEASEACTIVE_NAME = "DHCPLEASEACTIVE";
296 static const char* DHCPBULKLEASEQUERY_NAME = "DHCPBULKLEASEQUERY";
297 static const char* DHCPLEASEQUERYDONE_NAME = "DHCPLEASEQUERYDONE";
298 static const char* DHCPLEASEQUERYSTATUS_NAME = "DHCPLEASEQUERYSTATUS";
299 static const char* DHCPTLS_NAME = "DHCPTLS";
300 static const char* UNKNOWN_NAME = "UNKNOWN";
301
302 switch (type) {
303 case DHCPDISCOVER:
304 return (DHCPDISCOVER_NAME);
305
306 case DHCPOFFER:
307 return (DHCPOFFER_NAME);
308
309 case DHCPREQUEST:
310 return (DHCPREQUEST_NAME);
311
312 case DHCPDECLINE:
313 return (DHCPDECLINE_NAME);
314
315 case DHCPACK:
316 return (DHCPACK_NAME);
317
318 case DHCPNAK:
319 return (DHCPNAK_NAME);
320
321 case DHCPRELEASE:
322 return (DHCPRELEASE_NAME);
323
324 case DHCPINFORM:
325 return (DHCPINFORM_NAME);
326
327 case DHCPLEASEQUERY:
328 return (DHCPLEASEQUERY_NAME);
329
331 return (DHCPLEASEUNASSIGNED_NAME);
332
333 case DHCPLEASEUNKNOWN:
334 return (DHCPLEASEUNKNOWN_NAME);
335
336 case DHCPLEASEACTIVE:
337 return (DHCPLEASEACTIVE_NAME);
338
340 return (DHCPBULKLEASEQUERY_NAME);
341
343 return (DHCPLEASEQUERYDONE_NAME);
344
346 return (DHCPLEASEQUERYSTATUS_NAME);
347
348 case DHCPTLS:
349 return (DHCPTLS_NAME);
350
351 default:
352 ;
353 }
354 return (UNKNOWN_NAME);
355}
356
357const char*
359 // getType() is now exception safe. Even if there's no option 53 (message
360 // type), it now returns 0 rather than throw. getName() is able to handle
361 // 0 and unknown message types.
362 return (Pkt4::getName(getType()));
363}
364
365std::string
367
370 std::string suffix;
371 ClientIdPtr client_id;
373 if (client_opt) {
374 try {
375 client_id = ClientIdPtr(new ClientId(client_opt->getData()));
376 } catch (...) {
377 // ClientId may throw if the client-id is too short.
378 suffix = " (malformed client-id)";
379 }
380 }
381
382 std::ostringstream label;
383 try {
384 label << makeLabel(hwaddr_, client_id, transid_);
385 } catch (...) {
386 // This should not happen with the current code, but we may add extra
387 // sanity checks in the future that would possibly throw if
388 // the hwaddr length is 0.
389 label << " (malformed hw address)";
390 }
391
392 label << suffix;
393 return (label.str());
394}
395
396std::string
397Pkt4::makeLabel(const HWAddrPtr& hwaddr, const ClientIdPtr& client_id,
398 const uint32_t transid) {
399 // Create label with HW address and client identifier.
400 stringstream label;
401 label << makeLabel(hwaddr, client_id);
402
403 // Append transaction id.
404 label << ", tid=0x" << hex << transid << dec;
405
406 return label.str();
407}
408
409std::string
410Pkt4::makeLabel(const HWAddrPtr& hwaddr, const ClientIdPtr& client_id) {
411 stringstream label;
412 label << "[" << (hwaddr ? hwaddr->toText() : "no hwaddr info")
413 << "], cid=[" << (client_id ? client_id->toText() : "no info")
414 << "]";
415
416 return label.str();
417}
418
419std::string
421 stringstream output;
422 output << "local_address=" << local_addr_ << ":" << local_port_
423 << ", remote_address=" << remote_addr_
424 << ":" << remote_port_ << ", msg_type=";
425
426 // Try to obtain message type.
427 uint8_t msg_type = getType();
428 if (msg_type != DHCP_NOTYPE) {
429 output << getName(msg_type) << " (" << static_cast<int>(msg_type) << ")";
430 } else {
431 // Message Type option is missing.
432 output << "(missing)";
433 }
434
435 output << ", transid=0x" << hex << transid_ << dec;
436
437 if (!options_.empty()) {
438 output << "," << std::endl << "options:";
439 for (const auto& opt : options_) {
440 try {
441 output << std::endl << opt.second->toText(2);
442 } catch (...) {
443 output << "(unknown)" << std::endl;
444 }
445 }
446
447 } else {
448 output << ", message contains no options";
449 }
450
451 return (output.str());
452}
453
454void
455Pkt4::setHWAddr(uint8_t htype, uint8_t hlen,
456 const std::vector<uint8_t>& mac_addr) {
457 setHWAddrMember(htype, hlen, mac_addr, hwaddr_);
458}
459
460void
462 if (!addr) {
463 isc_throw(BadValue, "Setting DHCPv4 chaddr field to NULL"
464 << " is forbidden");
465 }
466 hwaddr_ = addr;
467}
468
469void
470Pkt4::setHWAddrMember(const uint8_t htype, const uint8_t hlen,
471 const std::vector<uint8_t>& mac_addr,
472 HWAddrPtr& hw_addr) {
475 if (hlen > MAX_CHADDR_LEN) {
476 isc_throw(OutOfRange, "Hardware address (len=" << hlen
477 << " too long. Max " << MAX_CHADDR_LEN << " supported.");
478
479 } else if (mac_addr.empty() && (hlen > 0) ) {
480 isc_throw(OutOfRange, "Invalid HW Address specified");
481 }
482
486 hw_addr.reset(new HWAddr(mac_addr, htype));
487}
488
489void
490Pkt4::setLocalHWAddr(const uint8_t htype, const uint8_t hlen,
491 const std::vector<uint8_t>& mac_addr) {
492 setHWAddrMember(htype, hlen, mac_addr, local_hwaddr_);
493}
494
495void
497 if (!addr) {
498 isc_throw(BadValue, "Setting local HW address to NULL is"
499 << " forbidden.");
500 }
501 local_hwaddr_ = addr;
502}
503
504void
505Pkt4::setSname(const uint8_t* sname, size_t snameLen /*= MAX_SNAME_LEN*/) {
506 if (snameLen > MAX_SNAME_LEN) {
507 isc_throw(OutOfRange, "sname field (len=" << snameLen
508 << ") too long, Max " << MAX_SNAME_LEN << " supported.");
509
510 } else if (sname == NULL) {
511 isc_throw(InvalidParameter, "Invalid sname specified");
512 }
513
514 std::copy(sname, (sname + snameLen), sname_);
515 if (snameLen < MAX_SNAME_LEN) {
516 std::fill((sname_ + snameLen), (sname_ + MAX_SNAME_LEN), 0);
517 }
518
519 // No need to store snameLen as any empty space is filled with 0s
520}
521
522void
523Pkt4::setFile(const uint8_t* file, size_t fileLen /*= MAX_FILE_LEN*/) {
524 if (fileLen > MAX_FILE_LEN) {
525 isc_throw(OutOfRange, "file field (len=" << fileLen
526 << ") too long, Max " << MAX_FILE_LEN << " supported.");
527
528 } else if (file == NULL) {
529 isc_throw(InvalidParameter, "Invalid file name specified");
530 }
531
532 std::copy(file, (file + fileLen), file_);
533 if (fileLen < MAX_FILE_LEN) {
534 std::fill((file_ + fileLen), (file_ + MAX_FILE_LEN), 0);
535 }
536
537 // No need to store fileLen as any empty space is filled with 0s
538}
539
540uint8_t
541// cppcheck-suppress unusedFunction
542Pkt4::DHCPTypeToBootpType(uint8_t dhcpType) {
543 switch (dhcpType) {
544 case DHCPDISCOVER:
545 case DHCPREQUEST:
546 case DHCPDECLINE:
547 case DHCPRELEASE:
548 case DHCPINFORM:
549 case DHCPLEASEQUERY:
551 return (BOOTREQUEST);
552
553 case DHCPACK:
554 case DHCPNAK:
555 case DHCPOFFER:
557 case DHCPLEASEUNKNOWN:
558 case DHCPLEASEACTIVE:
560 return (BOOTREPLY);
561
562 default:
563 isc_throw(OutOfRange, "Invalid message type: "
564 << static_cast<int>(dhcpType) );
565 }
566}
567
568uint8_t
570 if (!hwaddr_) {
571 return (HTYPE_UNDEFINED);
572 }
573 return (hwaddr_->htype_);
574}
575
576uint8_t
578 if (!hwaddr_) {
579 return (0);
580 }
581 uint8_t len = hwaddr_->hwaddr_.size();
582 return (len <= MAX_CHADDR_LEN ? len : MAX_CHADDR_LEN);
583}
584
585void
587 // Check for uniqueness (DHCPv4 options must be unique)
588 if (getNonCopiedOption(opt->getType())) {
589 isc_throw(BadValue, "Option " << opt->getType()
590 << " already present in this message.");
591 }
592
593 Pkt::addOption(opt);
594}
595
596bool
598 return (!giaddr_.isV4Zero() && !giaddr_.isV4Bcast());
599}
600
601} // end of namespace isc::dhcp
602} // end of namespace isc
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
This is a base class for exceptions thrown from the DNS library module.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown if a function is called in a prohibited way.
A generic exception that is thrown if a parameter given to a method or function is considered invalid...
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
A generic exception that is thrown when an unexpected error condition occurs.
Holds Client identifier or client IPv4 address.
Definition: duid.h:111
static size_t unpackOptions4(const OptionBuffer &buf, const std::string &option_space, isc::dhcp::OptionCollection &options, std::list< uint16_t > &deferred, bool flexible_pad_end=false)
Parses provided buffer as DHCPv4 options and creates Option objects.
Definition: libdhcp++.cc:457
static void packOptions4(isc::util::OutputBuffer &buf, const isc::dhcp::OptionCollection &options, bool top=false, bool check=true)
Stores DHCPv4 options in a buffer.
Definition: libdhcp++.cc:888
static bool splitOptions4(isc::dhcp::OptionCollection &options, ScopedOptionsCopyContainer &scopedOptions, uint32_t used=0)
Split long options in multiple options with the same option code (RFC3396).
Definition: libdhcp++.cc:934
static bool fuseOptions4(isc::dhcp::OptionCollection &options)
Fuse multiple options with the same option code in long options (RFC3396).
Definition: libdhcp++.cc:619
Forward declaration to OptionInt.
Definition: option_int.h:49
virtual void addOption(const OptionPtr &opt)
Add an option.
Definition: pkt4.cc:586
std::string toText() const
Returns text representation of the packet.
Definition: pkt4.cc:420
virtual void unpack()
Parses on-wire form of DHCPv4 packet.
Definition: pkt4.cc:148
std::list< uint16_t > deferred_options_
Definition: pkt4.h:496
HWAddrPtr hwaddr_
link-layer address and hardware information represents 3 fields: htype (hardware type,...
Definition: pkt4.h:511
const char * getName() const
Returns name of the DHCP message.
Definition: pkt4.cc:358
HWAddrPtr local_hwaddr_
local HW address (dst if receiving packet, src if sending packet)
Definition: pkt4.h:493
static const size_t MAX_CHADDR_LEN
length of the CHADDR field in DHCPv4 message
Definition: pkt4.h:41
void setLocalHWAddr(const uint8_t htype, const uint8_t hlen, const std::vector< uint8_t > &mac_addr)
Sets local HW address.
Definition: pkt4.cc:490
uint8_t DHCPTypeToBootpType(uint8_t dhcpType)
converts DHCP message type to BOOTP op type
Definition: pkt4.cc:542
std::string getLabel() const
Returns text representation of the primary packet identifiers.
Definition: pkt4.cc:366
virtual void pack()
Prepares on-wire format of DHCPv4 packet.
Definition: pkt4.cc:71
isc::asiolink::IOAddress giaddr_
giaddr field (32 bits): Gateway IP address
Definition: pkt4.h:532
uint8_t file_[MAX_FILE_LEN]
file field (128 bytes)
Definition: pkt4.h:538
uint8_t op_
message operation code
Definition: pkt4.h:505
uint8_t hops_
Number of relay agents traversed.
Definition: pkt4.h:514
void setSname(const uint8_t *sname, size_t sname_len)
Sets sname field.
Definition: pkt4.cc:505
Pkt4(uint8_t msg_type, uint32_t transid)
Constructor, used in replying to a message.
Definition: pkt4.cc:32
uint8_t getHlen() const
Returns hlen field.
Definition: pkt4.cc:577
static const size_t DHCPV4_PKT_HDR_LEN
specifies DHCPv4 packet header length (fixed part)
Definition: pkt4.h:50
bool isRelayed() const
Checks if a DHCPv4 message has been relayed.
Definition: pkt4.cc:597
void setFile(const uint8_t *file, size_t file_len)
Sets file field.
Definition: pkt4.cc:523
static const size_t MAX_SNAME_LEN
length of the SNAME field in DHCPv4 message
Definition: pkt4.h:44
static std::string makeLabel(const HWAddrPtr &hwaddr, const ClientIdPtr &client_id, const uint32_t transid)
Returns text representation of the given packet identifiers.
Definition: pkt4.cc:397
uint8_t getType() const
Returns DHCP message type (e.g.
Definition: pkt4.cc:235
void setType(uint8_t type)
Sets DHCP message type (e.g.
Definition: pkt4.cc:252
isc::asiolink::IOAddress siaddr_
siaddr field (32 bits): next server IP address in boot process(e.g.TFTP)
Definition: pkt4.h:529
size_t len()
Returns the size of the required buffer to build the packet.
Definition: pkt4.cc:59
uint16_t secs_
elapsed (number of seconds since beginning of transmission)
Definition: pkt4.h:517
isc::asiolink::IOAddress ciaddr_
ciaddr field (32 bits): Client's IP address
Definition: pkt4.h:523
isc::asiolink::IOAddress yiaddr_
yiaddr field (32 bits): Client's IP address ("your"), set by server
Definition: pkt4.h:526
uint8_t sname_[MAX_SNAME_LEN]
sname field (64 bytes)
Definition: pkt4.h:535
void setHWAddr(uint8_t htype, uint8_t hlen, const std::vector< uint8_t > &mac_addr)
Sets hardware address.
Definition: pkt4.cc:455
uint8_t getHtype() const
Returns htype field.
Definition: pkt4.cc:569
uint16_t flags_
flags
Definition: pkt4.h:520
static const size_t MAX_FILE_LEN
length of the FILE field in DHCPv4 message
Definition: pkt4.h:47
Base class for classes representing DHCP messages.
Definition: pkt.h:90
isc::asiolink::IOAddress remote_addr_
Remote IP address.
Definition: pkt.h:748
uint16_t local_port_
local TDP or UDP port
Definition: pkt.h:751
uint32_t transid_
Transaction-id (32 bits for v4, 24 bits for v6)
Definition: pkt.h:726
isc::asiolink::IOAddress local_addr_
Local IP (v4 or v6) address.
Definition: pkt.h:742
OptionBuffer data_
Unparsed data (in received packets).
Definition: pkt.h:312
uint16_t remote_port_
remote TCP or UDP port
Definition: pkt.h:754
isc::dhcp::OptionCollection options_
Collection of options present in this message.
Definition: pkt.h:614
isc::util::OutputBuffer buffer_out_
Output buffer (used during message transmission)
Definition: pkt.h:764
OptionPtr getNonCopiedOption(const uint16_t type) const
Returns the first option of specified type without copying.
Definition: pkt.cc:46
virtual void addOption(const OptionPtr &opt)
Adds an option to this packet.
Definition: pkt.cc:41
RAII object enabling duplication of the stored options and restoring the original options on destruct...
Definition: pkt.h:856
The InputBuffer class is a buffer abstraction for manipulating read-only data.
Definition: buffer.h:81
void readVector(std::vector< uint8_t > &data, size_t len)
Read specified number of bytes as a vector.
Definition: buffer.h:204
uint32_t readUint32()
Read an unsigned 32-bit integer in network byte order from the buffer, convert it to host byte order,...
Definition: buffer.h:162
size_t getPosition() const
Return the current read position.
Definition: buffer.h:102
uint8_t readUint8()
Read an unsigned 8-bit integer from the buffer and return it.
Definition: buffer.h:130
size_t getLength() const
Return the length of the data stored in the buffer.
Definition: buffer.h:100
void readData(void *data, size_t len)
Read data of the specified length from the buffer and copy it to the caller supplied buffer.
Definition: buffer.h:186
uint16_t readUint16()
Read an unsigned 16-bit integer in network byte order from the buffer, convert it to host byte order,...
Definition: buffer.h:142
void writeUint8(uint8_t data)
Write an unsigned 8-bit integer into the buffer.
Definition: buffer.h:466
void writeUint16(uint16_t data)
Write an unsigned 16-bit integer in host byte order into the buffer in network byte order.
Definition: buffer.h:490
void writeData(const void *data, size_t len)
Copy an arbitrary length of data into the buffer.
Definition: buffer.h:550
void writeUint32(uint32_t data)
Write an unsigned 32-bit integer in host byte order into the buffer in network byte order.
Definition: buffer.h:520
void clear()
Clear buffer content.
Definition: buffer.h:451
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
ElementPtr copy(ConstElementPtr from, int level)
Copy the data up to a nesting level.
Definition: data.cc:1360
@ DHO_DHCP_MESSAGE_TYPE
Definition: dhcp4.h:122
@ DHO_DHCP_CLIENT_IDENTIFIER
Definition: dhcp4.h:130
@ DHO_END
Definition: dhcp4.h:228
@ BOOTREQUEST
Definition: dhcp4.h:46
@ BOOTREPLY
Definition: dhcp4.h:47
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
Definition: hwaddr.h:154
boost::shared_ptr< ClientId > ClientIdPtr
Shared pointer to a Client ID.
Definition: duid.h:103
@ DHCPLEASEQUERYSTATUS
Definition: dhcp4.h:250
@ DHCPTLS
Definition: dhcp4.h:251
@ DHCPREQUEST
Definition: dhcp4.h:236
@ DHCPLEASEQUERYDONE
Definition: dhcp4.h:248
@ DHCPLEASEUNKNOWN
Definition: dhcp4.h:245
@ DHCPOFFER
Definition: dhcp4.h:235
@ DHCPLEASEACTIVE
Definition: dhcp4.h:246
@ DHCPLEASEQUERY
Definition: dhcp4.h:243
@ DHCPDECLINE
Definition: dhcp4.h:237
@ DHCPNAK
Definition: dhcp4.h:239
@ DHCPRELEASE
Definition: dhcp4.h:240
@ DHCPLEASEUNASSIGNED
Definition: dhcp4.h:244
@ DHCPDISCOVER
Definition: dhcp4.h:234
@ DHCPBULKLEASEQUERY
Definition: dhcp4.h:247
@ DHCP_NOTYPE
Message Type option missing.
Definition: dhcp4.h:233
@ DHCPINFORM
Definition: dhcp4.h:241
@ DHCPACK
Definition: dhcp4.h:238
@ HTYPE_UNDEFINED
not specified or undefined
Definition: dhcp4.h:55
boost::shared_ptr< Option > OptionPtr
Definition: option.h:36
Defines the logger used by the top-level component of kea-lfc.
#define DHCP4_OPTION_SPACE
global std option spaces
Hardware type that represents information from DHCPv4 packet.
Definition: hwaddr.h:20
ScopedOptionsCopyContainer scoped_options_
The container.
Definition: libdhcp++.h:49