pkt.h 25 KB

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