/usr/include/kea/dhcp/pkt4.h is in kea-dev 1.0.0-1build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 | // Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#ifndef PKT4_H
#define PKT4_H
#include <asiolink/io_address.h>
#include <dhcp/option.h>
#include <dhcp/duid.h>
#include <util/buffer.h>
#include <dhcp/option.h>
#include <dhcp/classify.h>
#include <dhcp/pkt.h>
#include <boost/shared_ptr.hpp>
#include <iostream>
#include <vector>
#include <set>
#include <time.h>
namespace isc {
namespace dhcp {
/// @brief Represents DHCPv4 packet
///
/// This class represents a single DHCPv4 packet. It handles both incoming
/// and transmitted packets, parsing incoming options, options handling
/// (add, get, remove), on-wire assembly, sanity checks and other operations.
/// This specific class has several DHCPv4-specific methods, but it uses a lot
/// of common operations from its base @c Pkt class that is shared with Pkt6.
class Pkt4 : public Pkt {
public:
/// length of the CHADDR field in DHCPv4 message
const static size_t MAX_CHADDR_LEN = 16;
/// length of the SNAME field in DHCPv4 message
const static size_t MAX_SNAME_LEN = 64;
/// length of the FILE field in DHCPv4 message
const static size_t MAX_FILE_LEN = 128;
/// specifies DHCPv4 packet header length (fixed part)
const static size_t DHCPV4_PKT_HDR_LEN = 236;
/// Mask for the value of flags field in the DHCPv4 message
/// to check whether client requested broadcast response.
const static uint16_t FLAG_BROADCAST_MASK = 0x8000;
/// Constructor, used in replying to a message.
///
/// @param msg_type type of message (e.g. DHCPDISOVER=1)
/// @param transid transaction-id
Pkt4(uint8_t msg_type, uint32_t transid);
/// @brief Constructor, used in message reception.
///
/// Creates new message. Pkt4 will copy data to bufferIn_
/// buffer on creation.
///
/// @param data pointer to received data
/// @param len size of buffer to be allocated for this packet.
Pkt4(const uint8_t* data, size_t len);
/// @brief Prepares on-wire format of DHCPv4 packet.
///
/// Prepares on-wire format of message and all its options.
/// Options must be stored in options_ field.
/// Output buffer will be stored in buffer_out_.
/// The buffer_out_ is cleared before writting to the buffer.
///
/// @throw InvalidOperation if packing fails
virtual void pack();
/// @brief Parses on-wire form of DHCPv4 packet.
///
/// Parses received packet, stored in on-wire format in bufferIn_.
///
/// Will create a collection of option objects that will
/// be stored in options_ container.
///
/// Method with throw exception if packet parsing fails.
virtual void unpack();
/// @brief Returns text representation of the primary packet identifiers
///
/// This method is intended to be used to provide a consistent way to
/// identify packets within log statements. It is an instance-level
/// wrapper around static makeLabel(). See this method for string
/// content.
///
/// This method is exception safe.
///
/// @return string with text representation
std::string getLabel() const;
/// @brief Returns text representation of the given packet identifiers
///
/// @param hwaddr - hardware address to include in the string, it may be
/// NULL.
/// @param client_id - client id to include in the string, it may be NULL.
/// to include in the string
/// @param transid - numeric transaction id to include in the string
///
/// @return string with text representation
static std::string makeLabel(const HWAddrPtr& hwaddr,
const ClientIdPtr& client_id,
const uint32_t transid);
/// @brief Returns text representation of the given packet identifers.
///
/// This variant of the method does not include transaction id.
///
/// @param hwaddr hardware address to include in the string, it may be
/// NULL.
/// @param client_id client id to include in the string, it may be NULL.
static std::string makeLabel(const HWAddrPtr& hwaddr, const ClientIdPtr& client_id);
/// @brief Returns text representation of the packet.
///
/// This function is useful mainly for debugging.
///
/// @return string with text representation
std::string toText() const;
/// @brief Returns the size of the required buffer to build the packet.
///
/// Returns the size of the required buffer to build the packet with
/// the current set of packet options.
///
/// @return number of bytes required to build this packet
size_t len();
/// @brief Sets hops field.
///
/// @param hops value to be set
void setHops(uint8_t hops) { hops_ = hops; };
/// @brief Returns hops field.
///
/// @return hops field
uint8_t getHops() const { return (hops_); };
// Note: There's no need to manipulate OP field directly,
// thus no setOp() method. See op_ comment.
/// @brief Returns op field.
///
/// @return op field
uint8_t getOp() const { return (op_); };
/// @brief Sets secs field.
///
/// @param secs value to be set
void setSecs(uint16_t secs) { secs_ = secs; };
/// @brief Returns secs field.
///
/// @return secs field
uint16_t getSecs() const { return (secs_); };
/// @brief Sets flags field.
///
/// @param flags value to be set
void setFlags(uint16_t flags) { flags_ = flags; };
/// @brief Returns flags field.
///
/// @return flags field
uint16_t getFlags() const { return (flags_); };
/// @brief Returns ciaddr field.
///
/// @return ciaddr field
const isc::asiolink::IOAddress&
getCiaddr() const { return (ciaddr_); };
/// @brief Sets ciaddr field.
///
/// @param ciaddr value to be set
void
setCiaddr(const isc::asiolink::IOAddress& ciaddr) { ciaddr_ = ciaddr; };
/// @brief Returns siaddr field.
///
/// @return siaddr field
const isc::asiolink::IOAddress&
getSiaddr() const { return (siaddr_); };
/// @brief Sets siaddr field.
///
/// @param siaddr value to be set
void
setSiaddr(const isc::asiolink::IOAddress& siaddr) { siaddr_ = siaddr; };
/// @brief Returns yiaddr field.
///
/// @return yiaddr field
const isc::asiolink::IOAddress&
getYiaddr() const { return (yiaddr_); };
/// @brief Sets yiaddr field.
///
/// @param yiaddr value to be set
void
setYiaddr(const isc::asiolink::IOAddress& yiaddr) { yiaddr_ = yiaddr; };
/// @brief Returns giaddr field.
///
/// @return giaddr field
const isc::asiolink::IOAddress&
getGiaddr() const { return (giaddr_); };
/// @brief Sets giaddr field.
///
/// @param giaddr value to be set
void
setGiaddr(const isc::asiolink::IOAddress& giaddr) { giaddr_ = giaddr; };
/// @brief Returns DHCP message type (e.g. 1 = DHCPDISCOVER).
///
/// @return message type
uint8_t getType() const;
/// @brief Sets DHCP message type (e.g. 1 = DHCPDISCOVER).
///
/// @param type message type to be set
void setType(uint8_t type);
/// @brief Returns name of the DHCP message for a given type number.
///
/// @param type DHCPv4 message type which name should be returned.
///
/// @return Pointer to the "const" string containing DHCP message name.
/// If the message type is unsupported the "UNKNOWN" is returned.
/// The caller must not release the returned pointer.
static const char* getName(const uint8_t type);
/// @brief Returns name of the DHCP message.
///
/// @return Pointer to the "const" string containing DHCP message name.
/// If the message type is unsupported the "UNKNOWN" is returned.
/// The caller must not release the returned pointer.
const char* getName() const;
/// @brief Returns sname field
///
/// Note: This is 64 bytes long field. It doesn't have to be
/// null-terminated. Do not use strlen() or similar on it.
///
/// @return sname field
const OptionBuffer
getSname() const { return (std::vector<uint8_t>(sname_, &sname_[MAX_SNAME_LEN])); };
/// @brief Sets sname field.
///
/// @param sname value to be set
/// @param sname_len length of the sname buffer (up to MAX_SNAME_LEN)
void setSname(const uint8_t* sname, size_t sname_len = MAX_SNAME_LEN);
/// @brief Returns file field
///
/// Note: This is 128 bytes long field. It doesn't have to be
/// null-terminated. Do not use strlen() or similar on it.
///
/// @return pointer to file field
const OptionBuffer
getFile() const { return (std::vector<uint8_t>(file_, &file_[MAX_FILE_LEN])); };
/// Sets file field
///
/// @param file value to be set
/// @param file_len length of the file buffer (up to MAX_FILE_LEN)
void
setFile(const uint8_t* file, size_t file_len = MAX_FILE_LEN);
/// @brief Sets hardware address.
///
/// Sets parameters of hardware address. hlen specifies
/// length of mac_addr buffer. Content of mac_addr buffer
/// will be copied to appropriate field.
///
/// Note: mac_addr must be a buffer of at least hlen bytes.
///
/// @param htype hardware type (will be sent in htype field)
/// @param hlen hardware length (will be sent in hlen field)
/// @param mac_addr pointer to hardware address
void setHWAddr(uint8_t htype, uint8_t hlen,
const std::vector<uint8_t>& mac_addr);
/// @brief Sets hardware address
///
/// Sets hardware address, based on existing HWAddr structure
/// @param addr already filled in HWAddr structure
/// @throw BadValue if addr is null
void setHWAddr(const HWAddrPtr& addr);
/// Returns htype field
///
/// @return hardware type
uint8_t
getHtype() const;
/// Returns hlen field
///
/// @return hardware address length
uint8_t
getHlen() const;
/// @brief returns hardware address information
/// @return hardware address structure
HWAddrPtr getHWAddr() const { return (hwaddr_); }
/// @brief Add an option.
///
/// @throw BadValue if option with that type is already present.
///
/// @param opt option to be added
virtual void
addOption(const OptionPtr& opt);
/// @brief Sets local HW address.
///
/// Sets the source HW address for the outgoing packet or
/// destination HW address for the incoming packet.
///
/// @note mac_addr must be a buffer of at least hlen bytes.
///
/// @param htype hardware type (will be sent in htype field)
/// @param hlen hardware length (will be sent in hlen field)
/// @param mac_addr pointer to hardware address
void setLocalHWAddr(const uint8_t htype, const uint8_t hlen,
const std::vector<uint8_t>& mac_addr);
/// @brief Sets local HW address.
///
/// Sets hardware address from an existing HWAddr structure.
/// The local address is a source address for outgoing
/// packet and destination address for incoming packet.
///
/// @param addr structure representing HW address.
///
/// @throw BadValue if addr is null
void setLocalHWAddr(const HWAddrPtr& addr);
/// @brief Returns local HW address.
///
/// @return local HW addr.
HWAddrPtr getLocalHWAddr() const {
return (local_hwaddr_);
}
/// @brief Checks if a DHCPv4 message has been relayed.
///
/// This function returns a boolean value which indicates whether a DHCPv4
/// message has been relayed (if true is returned) or not (if false).
///
/// The message is considered relayed if the giaddr field is non-zero and
/// non-broadcast.
///
/// @return Boolean value which indicates whether the message is relayed
/// (true) or non-relayed (false).
bool isRelayed() const;
/// @brief Checks if a DHCPv4 message has beeb transported over DHCPv6
///
/// @return Boolean value which indicates whether the message is
/// transported over DHCPv6 (true) or native DHCPv4 (false)
virtual bool isDhcp4o6() const {
return (false);
}
private:
/// @brief Generic method that validates and sets HW address.
///
/// This is a generic method used by all modifiers of this class
/// which set class members representing HW address.
///
/// @param htype hardware type.
/// @param hlen hardware length.
/// @param mac_addr pointer to actual hardware address.
/// @param [out] hw_addr pointer to a class member to be modified.
///
/// @trow isc::OutOfRange if invalid HW address specified.
virtual void setHWAddrMember(const uint8_t htype, const uint8_t hlen,
const std::vector<uint8_t>& mac_addr,
HWAddrPtr& hw_addr);
protected:
/// converts DHCP message type to BOOTP op type
///
/// @param dhcpType DHCP message type (e.g. DHCPDISCOVER)
///
/// @return BOOTP type (BOOTREQUEST or BOOTREPLY)
uint8_t
DHCPTypeToBootpType(uint8_t dhcpType);
/// @brief No-op
///
/// This method returns hardware address generated from the IPv6 link-local
/// address. As there is no IPv4-equivalent, it always returns NULL.
/// We need this stub implementation here, to keep all the get hardware
/// address logic in the base class.
///
/// @return always NULL
virtual HWAddrPtr getMACFromSrcLinkLocalAddr() {
return (HWAddrPtr());
}
/// @brief No-op
///
/// This method returns hardware address extracted from an IPv6 relay agent.
/// option. As there is no IPv4-equivalent, it always returns NULL.
/// We need this stub implementation here, to keep all the get hardware
/// address logic in the base class.
///
/// @return always NULL
virtual HWAddrPtr getMACFromIPv6RelayOpt() {
return (HWAddrPtr());
}
/// @brief No-op
///
/// This is a DHCPv4 version of the function that attempts to extract
/// MAC address from the options inserted by a cable modem. It is currently
/// not implemented for v4.
///
/// @return always NULL
virtual HWAddrPtr getMACFromDocsisModem() {
return (HWAddrPtr());
}
/// @brief No-op
///
/// This method returns hardware address extracted from DUID.
/// Currently it is a no-op, even though there's RFC that defines how to
/// use DUID in DHCPv4 (see RFC4361). We may implement it one day.
///
/// @return always NULL
virtual HWAddrPtr getMACFromDUID(){
return (HWAddrPtr());
}
/// @brief No-op
///
/// This is a DHCPv4 version of the function that attempts to extract
/// MAC address from the options inserted by a CMTS. It is currently
/// not implemented for v4.
///
/// @return always NULL
virtual HWAddrPtr getMACFromDocsisCMTS() {
return (HWAddrPtr());
}
/// @brief No-op
///
/// This method returns hardware address extracted from remote-id relay option.
/// Currently it is a no-op, it always returns NULL.
///
/// @return always NULL
virtual HWAddrPtr getMACFromRemoteIdRelayOption(){
return(HWAddrPtr());
}
/// local HW address (dst if receiving packet, src if sending packet)
HWAddrPtr local_hwaddr_;
/// @brief message operation code
///
/// Note: This is legacy BOOTP field. There's no need to manipulate it
/// directly. Its value is set based on DHCP message type. Note that
/// DHCPv4 protocol reuses BOOTP message format, so this field is
/// kept due to BOOTP format. This is NOT DHCPv4 type (DHCPv4 message
/// type is kept in message type option).
uint8_t op_;
/// @brief 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)
HWAddrPtr hwaddr_;
/// Number of relay agents traversed
uint8_t hops_;
/// elapsed (number of seconds since beginning of transmission)
uint16_t secs_;
/// flags
uint16_t flags_;
/// ciaddr field (32 bits): Client's IP address
isc::asiolink::IOAddress ciaddr_;
/// yiaddr field (32 bits): Client's IP address ("your"), set by server
isc::asiolink::IOAddress yiaddr_;
/// siaddr field (32 bits): next server IP address in boot process(e.g.TFTP)
isc::asiolink::IOAddress siaddr_;
/// giaddr field (32 bits): Gateway IP address
isc::asiolink::IOAddress giaddr_;
/// sname field (64 bytes)
uint8_t sname_[MAX_SNAME_LEN];
/// file field (128 bytes)
uint8_t file_[MAX_FILE_LEN];
// end of real DHCPv4 fields
}; // Pkt4 class
/// @brief A pointer to Pkt4 object.
typedef boost::shared_ptr<Pkt4> Pkt4Ptr;
} // isc::dhcp namespace
} // isc namespace
#endif
|