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