pkt.h 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775
  1. // Copyright (C) 2014-2016 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. #ifndef PKT_H
  7. #define PKT_H
  8. #include <asiolink/io_address.h>
  9. #include <util/buffer.h>
  10. #include <dhcp/option.h>
  11. #include <dhcp/hwaddr.h>
  12. #include <dhcp/classify.h>
  13. #include <boost/date_time/posix_time/posix_time.hpp>
  14. #include <boost/shared_ptr.hpp>
  15. #include <utility>
  16. namespace isc {
  17. namespace dhcp {
  18. /// @brief RAII object enabling copying options retrieved from the
  19. /// packet.
  20. ///
  21. /// This object enables copying retrieved options from a packet within
  22. /// a scope in which this object exists. When the object goes out of scope
  23. /// copying options is disabled. This is applicable in cases when the
  24. /// server is going to invoke a callout (hook library) where copying options
  25. /// must be enabled by default. When the callouts return copying options
  26. /// should be disabled. The use of RAII object eliminates the need for
  27. /// explicitly re-disabling options copying and is safer in case of
  28. /// exceptions thrown by callouts and a presence of multiple exit points.
  29. ///
  30. /// @tparam PktType Type of the packet, e.g. Pkt4, Pkt6, Pkt4o6.
  31. template<typename PktType>
  32. class ScopedEnableOptionsCopy {
  33. public:
  34. /// @brief Pointer to an encapsulated packet.
  35. typedef boost::shared_ptr<PktType> PktTypePtr;
  36. /// @brief Constructor.
  37. ///
  38. /// Enables options copying on a packet(s).
  39. ///
  40. /// @param pkt1 Pointer to first packet.
  41. /// @param pkt2 Optional pointer to the second packet.
  42. ScopedEnableOptionsCopy(const PktTypePtr& pkt1,
  43. const PktTypePtr& pkt2 = PktTypePtr())
  44. : pkts_(pkt1, pkt2) {
  45. if (pkt1) {
  46. pkt1->setCopyRetrievedOptions(true);
  47. }
  48. if (pkt2) {
  49. pkt2->setCopyRetrievedOptions(true);
  50. }
  51. }
  52. /// @brief Destructor.
  53. ///
  54. /// Disables options copying on a packets.
  55. ~ScopedEnableOptionsCopy() {
  56. if (pkts_.first) {
  57. pkts_.first->setCopyRetrievedOptions(false);
  58. }
  59. if (pkts_.second) {
  60. pkts_.second->setCopyRetrievedOptions(false);
  61. }
  62. }
  63. private:
  64. /// @brief Holds a pointers to the packets.
  65. std::pair<PktTypePtr, PktTypePtr> pkts_;
  66. };
  67. /// @brief Base class for classes representing DHCP messages.
  68. ///
  69. /// This is a base class that holds common information (e.g. source
  70. /// and destination ports) and operations (e.g. add, get, delete options)
  71. /// for derived classes representing both DHCPv4 and DHCPv6 messages.
  72. /// The @c Pkt4 and @c Pkt6 classes derive from it.
  73. ///
  74. /// @note This is abstract class. Please instantiate derived classes
  75. /// such as @c Pkt4 or @c Pkt6.
  76. class Pkt {
  77. protected:
  78. /// @brief Constructor.
  79. ///
  80. /// This constructor is typically used for transmitted messages as it
  81. /// creates an empty (no options) packet. The constructor is protected,
  82. /// so only derived classes can call it. Pkt class cannot be instantiated
  83. /// anyway, because it is an abstract class.
  84. ///
  85. /// @param transid transaction-id
  86. /// @param local_addr local IPv4 or IPv6 address
  87. /// @param remote_addr remote IPv4 or IPv6 address
  88. /// @param local_port local UDP (one day also TCP) port
  89. /// @param remote_port remote UDP (one day also TCP) port
  90. Pkt(uint32_t transid, const isc::asiolink::IOAddress& local_addr,
  91. const isc::asiolink::IOAddress& remote_addr, uint16_t local_port,
  92. uint16_t remote_port);
  93. /// @brief Constructor.
  94. ///
  95. /// This constructor is typically used for received messages as it takes
  96. /// a buffer that's going to be parsed as one of arguments. The constructor
  97. /// is protected, so only derived classes can call it. Pkt class cannot be
  98. /// instantiated anyway, because it is an abstract class.
  99. ///
  100. /// @param buf pointer to a buffer that contains on-wire data
  101. /// @param len length of the pointer specified in buf
  102. /// @param local_addr local IPv4 or IPv6 address
  103. /// @param remote_addr remote IPv4 or IPv6 address
  104. /// @param local_port local UDP (one day also TCP) port
  105. /// @param remote_port remote UDP (one day also TCP) port
  106. Pkt(const uint8_t* buf, uint32_t len,
  107. const isc::asiolink::IOAddress& local_addr,
  108. const isc::asiolink::IOAddress& remote_addr, uint16_t local_port,
  109. uint16_t remote_port);
  110. public:
  111. /// @brief Prepares on-wire format of DHCP (either v4 or v6) packet.
  112. ///
  113. /// Prepares on-wire format of message and all its options.
  114. /// A caller must ensure that options are stored in options_ field
  115. /// prior to calling this method.
  116. ///
  117. /// Output buffer will be stored in buffer_out_.
  118. /// The buffer_out_ should be cleared before writing to the buffer
  119. /// in the derived classes.
  120. ///
  121. /// @note This is a pure virtual method and must be implemented in
  122. /// the derived classes. The @c Pkt4 and @c Pkt6 class have respective
  123. /// implementations of this method.
  124. ///
  125. /// @throw InvalidOperation if packing fails
  126. virtual void pack() = 0;
  127. /// @brief Parses on-wire form of DHCP (either v4 or v6) packet.
  128. ///
  129. /// Parses received packet, stored in on-wire format in data_.
  130. ///
  131. /// Will create a collection of option objects that will
  132. /// be stored in options_ container.
  133. ///
  134. /// @note This is a pure virtual method and must be implemented in
  135. /// the derived classes. The @c Pkt4 and @c Pkt6 class have respective
  136. /// implementations of this method.
  137. ///
  138. /// Method will throw exception if packet parsing fails.
  139. ///
  140. /// @throw tbd
  141. virtual void unpack() = 0;
  142. /// @brief Returns reference to output buffer.
  143. ///
  144. /// Returned buffer will contain reasonable data only for
  145. /// output (TX) packet and after pack() was called.
  146. ///
  147. /// RX packet or TX packet before pack() will return buffer with
  148. /// zero length. This buffer is returned as non-const, so hooks
  149. /// framework (and user's callouts) can modify them if needed
  150. ///
  151. /// @note This buffer is only valid till object that returned it exists.
  152. ///
  153. /// @return reference to output buffer
  154. isc::util::OutputBuffer& getBuffer() { return (buffer_out_); };
  155. /// @brief Adds an option to this packet.
  156. ///
  157. /// Derived classes may provide more specialized implementations.
  158. /// In particular @c Pkt4 provides one that checks if option is
  159. /// unique.
  160. ///
  161. /// @param opt option to be added.
  162. virtual void addOption(const OptionPtr& opt);
  163. /// @brief Attempts to delete first suboption of requested type.
  164. ///
  165. /// If there are several options of the same type present, only
  166. /// the first option will be deleted.
  167. ///
  168. /// @param type Type of option to be deleted.
  169. ///
  170. /// @return true if option was deleted, false if no such option existed
  171. bool delOption(uint16_t type);
  172. /// @brief Returns text representation primary packet identifiers
  173. ///
  174. /// This method is intended to be used to provide as a consistent way to
  175. /// identify packets within log statements. Derivations should supply
  176. /// there own implementation.
  177. ///
  178. /// @return string with text representation
  179. virtual std::string getLabel() const {
  180. isc_throw(NotImplemented, "Pkt::getLabel()");
  181. }
  182. /// @brief Returns text representation of the packet.
  183. ///
  184. /// This function is useful mainly for debugging.
  185. ///
  186. /// @note This is a pure virtual method and must be implemented in
  187. /// the derived classes. The @c Pkt4 and @c Pkt6 class have respective
  188. /// implementations of this method.
  189. ///
  190. /// @return string with text representation
  191. virtual std::string toText() const = 0;
  192. /// @brief Returns packet size in binary format.
  193. ///
  194. /// Returns size of the packet in on-wire format or size needed to store
  195. /// it in on-wire format.
  196. ///
  197. /// @note This is a pure virtual method and must be implemented in
  198. /// the derived classes. The @c Pkt4 and @c Pkt6 class have respective
  199. /// implementations of this method.
  200. ///
  201. /// @return packet size in bytes
  202. virtual size_t len() = 0;
  203. /// @brief Returns message type (e.g. 1 = SOLICIT).
  204. ///
  205. /// @note This is a pure virtual method and must be implemented in
  206. /// the derived classes. The @c Pkt4 and @c Pkt6 class have respective
  207. /// implementations of this method.
  208. ///
  209. /// @return message type
  210. virtual uint8_t getType() const = 0;
  211. /// @brief Sets message type (e.g. 1 = SOLICIT).
  212. ///
  213. /// @note This is a pure virtual method and must be implemented in
  214. /// the derived classes. The @c Pkt4 and @c Pkt6 class have respective
  215. /// implementations of this method.
  216. ///
  217. /// @param type message type to be set
  218. virtual void setType(uint8_t type) = 0;
  219. /// @brief Returns name of the DHCP message.
  220. ///
  221. /// For all unsupported messages the derived classes must return
  222. /// "UNKNOWN".
  223. ///
  224. /// @return Pointer to "const" string containing DHCP message name.
  225. /// The implementations in the derived classes should statically
  226. /// allocate returned strings and the caller must not release the
  227. /// returned pointer.
  228. virtual const char* getName() const = 0;
  229. /// @brief Sets transaction-id value.
  230. ///
  231. /// @param transid transaction-id to be set.
  232. void setTransid(uint32_t transid) { transid_ = transid; }
  233. /// @brief Returns value of transaction-id field.
  234. ///
  235. /// @return transaction-id
  236. uint32_t getTransid() const { return (transid_); };
  237. /// @brief Checks whether a client belongs to a given class.
  238. ///
  239. /// @param client_class name of the class
  240. /// @return true if belongs
  241. bool inClass(const isc::dhcp::ClientClass& client_class);
  242. /// @brief Adds packet to a specified class.
  243. ///
  244. /// A packet can be added to the same class repeatedly. Any additional
  245. /// attempts to add to a class the packet already belongs to, will be
  246. /// ignored silently.
  247. ///
  248. /// @note It is a matter of naming convention. Conceptually, the server
  249. /// processes a stream of packets, with some packets belonging to given
  250. /// classes. From that perspective, this method adds a packet to specified
  251. /// class. Implementation wise, it looks the opposite - the class name
  252. /// is added to the packet. Perhaps the most appropriate name for this
  253. /// method would be associateWithClass()? But that seems overly long,
  254. /// so I decided to stick with addClass().
  255. ///
  256. /// @param client_class name of the class to be added
  257. void addClass(const isc::dhcp::ClientClass& client_class);
  258. /// @brief Returns the class set
  259. ///
  260. /// @note This should be used only to iterate over the class set.
  261. /// @return
  262. const ClientClasses& getClasses() const { return (classes_); }
  263. /// @brief Unparsed data (in received packets).
  264. ///
  265. /// @warning This public member is accessed by derived
  266. /// classes directly. One of such derived classes is
  267. /// @ref perfdhcp::PerfPkt6. The impact on derived classes'
  268. /// behavior must be taken into consideration before making
  269. /// changes to this member such as access scope restriction or
  270. /// data format change etc.
  271. OptionBuffer data_;
  272. protected:
  273. /// @brief Returns the first option of specified type without copying.
  274. ///
  275. /// This method is internally used by the @ref Pkt class and derived
  276. /// classes to retrieve a pointer to the specified option. This
  277. /// method doesn't copy the option before returning it to the
  278. /// caller.
  279. ///
  280. /// @param type Option type.
  281. ///
  282. /// @return Pointer to the option of specified type or NULL pointer
  283. /// if such option is not present.
  284. OptionPtr getNonCopiedOption(const uint16_t type) const;
  285. public:
  286. /// @brief Returns the first option of specified type.
  287. ///
  288. /// Returns the first option of specified type. Note that in DHCPv6 several
  289. /// instances of the same option are allowed (and frequently used).
  290. /// Also see @ref Pkt6::getOptions().
  291. ///
  292. /// The options will be only returned after unpack() is called.
  293. ///
  294. /// @param type option type we are looking for
  295. ///
  296. /// @return pointer to found option (or NULL)
  297. OptionPtr getOption(const uint16_t type);
  298. /// @brief Controls whether the option retrieved by the @ref Pkt::getOption
  299. /// should be copied before being returned.
  300. ///
  301. /// Setting this value to true enables the mechanism of copying options
  302. /// retrieved from the packet to prevent accidental modifications of
  303. /// options that shouldn't be modified. The typical use case for this
  304. /// mechanism is to prevent hook library from modifying instance of
  305. /// an option within the packet that would also affect the value for
  306. /// this option within the Kea configuration structures.
  307. ///
  308. /// Kea doesn't copy option instances which it stores in the packet.
  309. /// It merely copy pointers into the packets. Thus, any modification
  310. /// to an option would change the value of this option in the
  311. /// Kea configuration. To prevent this, option copying should be
  312. /// enabled prior to passing the pointer to a packet to a hook library.
  313. ///
  314. /// Note that only only does this method causes the server to copy
  315. /// an option, but the copied option also replaces the original
  316. /// option within the packet. The option can be then freely modified
  317. /// and the modifications will only affect the instance of this
  318. /// option within the packet but not within the server configuration.
  319. ///
  320. /// @param copy Indicates if the options should be copied when
  321. /// retrieved (if true), or not copied (if false).
  322. virtual void setCopyRetrievedOptions(const bool copy) {
  323. copy_retrieved_options_ = copy;
  324. }
  325. /// @brief Returns whether the copying of retrieved options is enabled.
  326. ///
  327. /// Also see @ref setCopyRetrievedOptions.
  328. ///
  329. /// @return true if retrieved options are copied.
  330. bool isCopyRetrievedOptions() const {
  331. return (copy_retrieved_options_);
  332. }
  333. /// @brief Update packet timestamp.
  334. ///
  335. /// Updates packet timestamp. This method is invoked
  336. /// by interface manager just before sending or
  337. /// just after receiving it.
  338. /// @throw isc::Unexpected if timestamp update failed
  339. void updateTimestamp();
  340. /// @brief Returns packet timestamp.
  341. ///
  342. /// Returns packet timestamp value updated when
  343. /// packet is received or send.
  344. ///
  345. /// @return packet timestamp.
  346. const boost::posix_time::ptime& getTimestamp() const {
  347. return timestamp_;
  348. }
  349. /// @brief Copies content of input buffer to output buffer.
  350. ///
  351. /// This is mostly a diagnostic function. It is being used for sending
  352. /// received packet. Received packet is stored in data_, but
  353. /// transmitted data is stored in buffer_out_. If we want to send packet
  354. /// that we just received, a copy between those two buffers is necessary.
  355. void repack();
  356. /// @brief Sets remote IP address.
  357. ///
  358. /// @param remote specifies remote address
  359. void setRemoteAddr(const isc::asiolink::IOAddress& remote) {
  360. remote_addr_ = remote;
  361. }
  362. /// @brief Returns remote IP address.
  363. ///
  364. /// @return remote address
  365. const isc::asiolink::IOAddress& getRemoteAddr() const {
  366. return (remote_addr_);
  367. }
  368. /// @brief Sets local IP address.
  369. ///
  370. /// @param local specifies local address
  371. void setLocalAddr(const isc::asiolink::IOAddress& local) {
  372. local_addr_ = local;
  373. }
  374. /// @brief Returns local IP address.
  375. ///
  376. /// @return local address
  377. const isc::asiolink::IOAddress& getLocalAddr() const {
  378. return (local_addr_);
  379. }
  380. /// @brief Sets local UDP (and soon TCP) port.
  381. ///
  382. /// This sets a local port, i.e. destination port for recently received
  383. /// packet or a source port for to be transmitted packet.
  384. ///
  385. /// @param local specifies local port
  386. void setLocalPort(uint16_t local) {
  387. local_port_ = local;
  388. }
  389. /// @brief Returns local UDP (and soon TCP) port.
  390. ///
  391. /// This sets a local port, i.e. destination port for recently received
  392. /// packet or a source port for to be transmitted packet.
  393. ///
  394. /// @return local port
  395. uint16_t getLocalPort() const {
  396. return (local_port_);
  397. }
  398. /// @brief Sets remote UDP (and soon TCP) port.
  399. ///
  400. /// This sets a remote port, i.e. source port for recently received
  401. /// packet or a destination port for to be transmitted packet.
  402. ///
  403. /// @param remote specifies remote port
  404. void setRemotePort(uint16_t remote) {
  405. remote_port_ = remote;
  406. }
  407. /// @brief Returns remote port.
  408. ///
  409. /// @return remote port
  410. uint16_t getRemotePort() const {
  411. return (remote_port_);
  412. }
  413. /// @brief Sets interface index.
  414. ///
  415. /// @param ifindex specifies interface index.
  416. void setIndex(uint32_t ifindex) {
  417. ifindex_ = ifindex;
  418. };
  419. /// @brief Resets interface index to negative value.
  420. void resetIndex() {
  421. ifindex_ = -1;
  422. }
  423. /// @brief Returns interface index.
  424. ///
  425. /// @return interface index
  426. uint32_t getIndex() const {
  427. return (ifindex_);
  428. };
  429. /// @brief Checks if interface index has been set.
  430. ///
  431. /// @return true if interface index set, false otherwise.
  432. bool indexSet() const {
  433. return (ifindex_ >= 0);
  434. }
  435. /// @brief Returns interface name.
  436. ///
  437. /// Returns interface name over which packet was received or is
  438. /// going to be transmitted.
  439. ///
  440. /// @return interface name
  441. std::string getIface() const { return (iface_); };
  442. /// @brief Sets interface name.
  443. ///
  444. /// Sets interface name over which packet was received or is
  445. /// going to be transmitted.
  446. ///
  447. /// @return interface name
  448. void setIface(const std::string& iface ) { iface_ = iface; };
  449. /// @brief Sets remote hardware address.
  450. ///
  451. /// Sets hardware address (MAC) from an existing HWAddr structure.
  452. /// The remote address is a destination address for outgoing
  453. /// packet and source address for incoming packet. When this
  454. /// is an outgoing packet, this address will be used to
  455. /// construct the link layer header.
  456. ///
  457. /// @param hw_addr structure representing HW address.
  458. ///
  459. /// @throw BadValue if addr is null
  460. void setRemoteHWAddr(const HWAddrPtr& hw_addr);
  461. /// @brief Sets remote hardware address.
  462. ///
  463. /// Sets the destination hardware (MAC) address for the outgoing packet
  464. /// or source HW address for the incoming packet. When this
  465. /// is an outgoing packet this address will be used to construct
  466. /// the link layer header.
  467. ///
  468. /// @note mac_addr must be a buffer of at least hlen bytes.
  469. ///
  470. /// In a typical case, hlen field would be redundant, as it could
  471. /// be extracted from mac_addr.size(). However, the difference is
  472. /// when running on exotic hardware, like Infiniband, that had
  473. /// MAC addresses 20 bytes long. In that case, hlen is set to zero
  474. /// in DHCPv4.
  475. ///
  476. /// @param htype hardware type (will be sent in htype field)
  477. /// @param hlen hardware length (will be sent in hlen field)
  478. /// @param hw_addr pointer to hardware address
  479. void setRemoteHWAddr(const uint8_t htype, const uint8_t hlen,
  480. const std::vector<uint8_t>& hw_addr);
  481. /// @brief Returns the remote HW address obtained from raw sockets.
  482. ///
  483. /// @return remote HW address.
  484. HWAddrPtr getRemoteHWAddr() const {
  485. return (remote_hwaddr_);
  486. }
  487. /// @brief Returns MAC address.
  488. ///
  489. /// The difference between this method and getRemoteHWAddr() is that
  490. /// getRemoteHWAddr() returns only what was obtained from raw sockets.
  491. /// This method is more generic and can attempt to obtain MAC from
  492. /// varied sources: raw sockets, client-id, link-local IPv6 address,
  493. /// and various relay options.
  494. ///
  495. /// @note Technically the proper term for this information is a link layer
  496. /// address, but it is frequently referred to MAC or hardware address.
  497. /// Since we're calling the feature "MAC addresses in DHCPv6", we decided
  498. /// to keep the name of getMAC().
  499. ///
  500. /// hw_addr_src takes a combination of bit values specified in
  501. /// HWADDR_SOURCE_* constants.
  502. ///
  503. /// @param hw_addr_src a bitmask that specifies hardware address source
  504. HWAddrPtr getMAC(uint32_t hw_addr_src);
  505. /// @brief Virtual destructor.
  506. ///
  507. /// There is nothing to clean up here, but since there are virtual methods,
  508. /// we define virtual destructor to ensure that derived classes will have
  509. /// a virtual one, too.
  510. virtual ~Pkt() {
  511. }
  512. /// @brief Classes this packet belongs to.
  513. ///
  514. /// This field is public, so the code outside of Pkt4 or Pkt6 class can
  515. /// iterate over existing classes. Having it public also solves the problem
  516. /// of returned reference lifetime. It is preferred to use @ref inClass and
  517. /// @ref addClass should be used to operate on this field.
  518. ClientClasses classes_;
  519. /// @brief Collection of options present in this message.
  520. ///
  521. /// @warning This public member is accessed by derived
  522. /// classes directly. One of such derived classes is
  523. /// @ref perfdhcp::PerfPkt6. The impact on derived classes'
  524. /// behavior must be taken into consideration before making
  525. /// changes to this member such as access scope restriction or
  526. /// data format change etc.
  527. isc::dhcp::OptionCollection options_;
  528. protected:
  529. /// @brief Attempts to obtain MAC address from source link-local
  530. /// IPv6 address
  531. ///
  532. /// This method is called from getMAC(HWADDR_SOURCE_IPV6_LINK_LOCAL)
  533. /// and should not be called directly. It is not 100% reliable.
  534. /// The source IPv6 address does not necessarily have to be link-local
  535. /// (may be global or ULA) and even if it's link-local, it doesn't
  536. /// necessarily be based on EUI-64. For example, Windows supports
  537. /// RFC4941, which randomized IID part of the link-local address.
  538. /// If this method fails, it will return NULL.
  539. ///
  540. /// For direct message, it attempts to use remote_addr_ field. For relayed
  541. /// message, it uses peer-addr of the first relay.
  542. ///
  543. /// @note This is a pure virtual method and must be implemented in
  544. /// the derived classes. The @c Pkt6 class have respective implementation.
  545. /// This method is not applicable to DHCPv4.
  546. ///
  547. /// @return hardware address (or NULL)
  548. virtual HWAddrPtr getMACFromSrcLinkLocalAddr() = 0;
  549. /// @brief Attempts to obtain MAC address from relay option
  550. /// client-linklayer-addr
  551. ///
  552. /// This method is called from getMAC(HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION)
  553. /// and should not be called directly. It will extract the client's
  554. /// MAC/Hardware address from option client_linklayer_addr (RFC6939)
  555. /// inserted by the relay agent closest to the client.
  556. /// If this method fails, it will return NULL.
  557. ///
  558. /// @note This is a pure virtual method and must be implemented in
  559. /// the derived classes. The @c Pkt6 class have respective implementation.
  560. /// This method is not applicable to DHCPv4.
  561. ///
  562. /// @return hardware address (or NULL)
  563. virtual HWAddrPtr getMACFromIPv6RelayOpt() = 0;
  564. /// @brief Attempts to obtain MAC address from DUID-LL or DUID-LLT.
  565. ///
  566. /// This method is called from getMAC(HWADDR_SOURCE_DUID) and should not be
  567. /// called directly. It will attempt to extract MAC address information
  568. /// from DUID if its type is LLT or LL. If this method fails, it will
  569. /// return NULL.
  570. ///
  571. /// @note This is a pure virtual method and must be implemented in
  572. /// the derived classes. The @c Pkt6 class have respective implementation.
  573. /// This method is not applicable to DHCPv4.
  574. ///
  575. /// @return hardware address (or NULL)
  576. virtual HWAddrPtr getMACFromDUID() = 0;
  577. /// @brief Attempts to obtain MAC address from remote-id relay option.
  578. ///
  579. /// This method is called from getMAC(HWADDR_SOURCE_REMOTE_ID) and should not be
  580. /// called directly. It will attempt to extract MAC address information
  581. /// from remote-id option inserted by a relay agent closest to the client.
  582. /// If this method fails, it will return NULL.
  583. ///
  584. /// @note This is a pure virtual method and must be implemented in
  585. /// the derived classes. The @c Pkt6 class have respective implementation.
  586. /// This method is not applicable to DHCPv4.
  587. ///
  588. /// @return hardware address (or NULL)
  589. virtual HWAddrPtr getMACFromRemoteIdRelayOption() = 0;
  590. /// @brief Attempts to convert IPv6 address into MAC.
  591. ///
  592. /// Utility method that attempts to convert link-local IPv6 address to the
  593. /// MAC address. That works only for link-local IPv6 addresses that are
  594. /// based on EUI-64.
  595. ///
  596. /// @note This method uses hardware type of the interface the packet was
  597. /// received on. If you have multiple access technologies in your network
  598. /// (e.g. client connected to WiFi that relayed the traffic to the server
  599. /// over Ethernet), hardware type may be invalid.
  600. ///
  601. /// @param addr IPv6 address to be converted
  602. /// @return hardware address (or NULL)
  603. HWAddrPtr
  604. getMACFromIPv6(const isc::asiolink::IOAddress& addr);
  605. /// @brief Attempts to extract MAC/Hardware address from DOCSIS options
  606. /// inserted by the modem itself.
  607. ///
  608. /// This is a generic mechanism for extracting hardware address from the
  609. /// DOCSIS options.
  610. ///
  611. /// @note This is a pure virtual method and must be implemented in
  612. /// the derived classes. The @c Pkt6 class have respective implementation.
  613. /// This method is currently not implemented in DHCPv4.
  614. ///
  615. /// @return hardware address (if necessary DOCSIS suboptions are present)
  616. virtual HWAddrPtr getMACFromDocsisModem() = 0;
  617. /// @brief Attempts to extract MAC/Hardware address from DOCSIS options
  618. /// inserted by the CMTS (the relay agent)
  619. ///
  620. /// This is a generic mechanism for extracting hardware address from the
  621. /// DOCSIS options.
  622. ///
  623. /// @note This is a pure virtual method and must be implemented in
  624. /// the derived classes. The @c Pkt6 class have respective implementation.
  625. /// This method is currently not implemented in DHCPv4.
  626. ///
  627. /// @return hardware address (if necessary DOCSIS suboptions are present)
  628. virtual HWAddrPtr getMACFromDocsisCMTS() = 0;
  629. /// Transaction-id (32 bits for v4, 24 bits for v6)
  630. uint32_t transid_;
  631. /// Name of the network interface the packet was received/to be sent over.
  632. std::string iface_;
  633. /// @brief Interface index.
  634. ///
  635. /// Each network interface has assigned an unique ifindex.
  636. /// It is a functional equivalent of a name, but sometimes more useful, e.g.
  637. /// when using odd systems that allow spaces in interface names.
  638. int64_t ifindex_;
  639. /// @brief Local IP (v4 or v6) address.
  640. ///
  641. /// Specifies local IPv4 or IPv6 address. It is a destination address for
  642. /// received packet, and a source address if it packet is being transmitted.
  643. isc::asiolink::IOAddress local_addr_;
  644. /// @brief Remote IP address.
  645. ///
  646. /// Specifies local IPv4 or IPv6 address. It is source address for received
  647. /// packet and a destination address for packet being transmitted.
  648. isc::asiolink::IOAddress remote_addr_;
  649. /// local TDP or UDP port
  650. uint16_t local_port_;
  651. /// remote TCP or UDP port
  652. uint16_t remote_port_;
  653. /// Output buffer (used during message transmission)
  654. ///
  655. /// @warning This protected member is accessed by derived
  656. /// classes directly. One of such derived classes is
  657. /// @ref perfdhcp::PerfPkt6. The impact on derived classes'
  658. /// behavior must be taken into consideration before making
  659. /// changes to this member such as access scope restriction or
  660. /// data format change etc.
  661. isc::util::OutputBuffer buffer_out_;
  662. /// @brief Indicates if a copy of the retrieved option should be
  663. /// returned when @ref Pkt::getOption is called.
  664. ///
  665. /// @see the documentation for @ref Pkt::setCopyRetrievedOptions.
  666. bool copy_retrieved_options_;
  667. /// packet timestamp
  668. boost::posix_time::ptime timestamp_;
  669. // remote HW address (src if receiving packet, dst if sending packet)
  670. HWAddrPtr remote_hwaddr_;
  671. private:
  672. /// @brief Generic method that validates and sets HW address.
  673. ///
  674. /// This is a generic method used by all modifiers of this class
  675. /// which set class members representing HW address.
  676. ///
  677. /// @param htype hardware type.
  678. /// @param hlen hardware length.
  679. /// @param hw_addr pointer to actual hardware address.
  680. /// @param [out] storage pointer to a class member to be modified.
  681. ///
  682. /// @throw isc::OutOfRange if invalid HW address specified.
  683. virtual void setHWAddrMember(const uint8_t htype, const uint8_t hlen,
  684. const std::vector<uint8_t>& hw_addr,
  685. HWAddrPtr& storage);
  686. };
  687. }; // namespace isc::dhcp
  688. }; // namespace isc
  689. #endif