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