pkt_transform.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. // Copyright (C) 2012-2015 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_TRANSFORM_H
  7. #define PKT_TRANSFORM_H
  8. #include <dhcp/option.h>
  9. #include "localized_option.h"
  10. namespace isc {
  11. namespace perfdhcp {
  12. /// \brief Read and write raw data to DHCP packets.
  13. ///
  14. /// This class provides static functions to read/write raw data from/to the
  15. /// packet buffer. When reading data with the unpack() method, the
  16. /// corresponding options objects are updated. When writing to the packet
  17. /// buffer with pack(), options objects carry input data to be written.
  18. ///
  19. /// This class is used both by \ref PerfPkt4 and
  20. /// \ref PerfPkt6 classes in case DHCP packets are created
  21. /// from template files. In this case, some of the template
  22. /// packet's options are replaced before sending it to the
  23. /// server. Offset of specific options are provided from the
  24. /// command line by the perfdhcp tool user, and passed in an
  25. /// options collection.
  26. class PktTransform {
  27. public:
  28. /// \brief Prepares on-wire format from raw buffer.
  29. ///
  30. /// The method copies the input buffer and options contents
  31. /// to the output buffer. The input buffer must contain whole
  32. /// initial packet data. Parts of this data will be
  33. /// overriden by options data specified in an options
  34. /// collection. Such options must have their offsets within
  35. /// a packet specified (see \ref LocalizedOption to find out
  36. /// how to specify options offset).
  37. ///
  38. /// \note The specified options must fit into the size of the
  39. /// initial packet data. A call to this method will fail
  40. /// if the option's offset + its size is beyond the packet's size.
  41. ///
  42. /// \param universe Universe used, V4 or V6
  43. /// \param in_buffer Input buffer holding initial packet
  44. /// data, this can be directly read from template file
  45. /// \param options Options collection with offsets
  46. /// \param transid_offset offset of transaction id in a packet,
  47. /// transaction ID will be written to output buffer at this
  48. /// offset
  49. /// \param transid Transaction ID value
  50. /// \param out_buffer Output buffer holding "packed" data
  51. ///
  52. /// \return false, if pack operation failed.
  53. static bool pack(const dhcp::Option::Universe universe,
  54. const dhcp::OptionBuffer& in_buffer,
  55. const dhcp::OptionCollection& options,
  56. const size_t transid_offset,
  57. const uint32_t transid,
  58. util::OutputBuffer& out_buffer);
  59. /// \brief Handles selective binary packet parsing.
  60. ///
  61. /// This method handles the parsing of packets that have non-default
  62. /// options or transaction ID offsets. The client class has to use
  63. /// \ref isc::dhcp::Pkt6::addOption to specify which options to parse.
  64. /// Each option should be of the \ref isc::perfdhcp::LocalizedOption
  65. /// type with the offset value specified.
  66. ///
  67. /// \param universe universe used, V4 or V6
  68. /// \param in_buffer input buffer to be parsed
  69. /// \param options options collection with options offsets
  70. /// \param transid_offset offset of transaction id in input buffer
  71. /// \param transid transaction id value read from input buffer
  72. ///
  73. /// \return false, if unpack operation failed.
  74. static bool unpack(const dhcp::Option::Universe universe,
  75. const dhcp::OptionBuffer& in_buffer,
  76. const dhcp::OptionCollection& options,
  77. const size_t transid_offset,
  78. uint32_t& transid);
  79. /// \brief Replace contents of buffer with vector.
  80. ///
  81. /// Function replaces data of the buffer with data from vector.
  82. ///
  83. /// \param in_buffer destination buffer.
  84. /// \param dest_pos position in destination buffer.
  85. /// \param first beginning of data range in source vector.
  86. /// \param last end of data range in source vector.
  87. static void writeAt(dhcp::OptionBuffer& in_buffer, size_t dest_pos,
  88. std::vector<uint8_t>::iterator first,
  89. std::vector<uint8_t>::iterator last);
  90. /// \brief Replace contents of one vector with uint16 value.
  91. ///
  92. /// Function replaces data inside one vector with uint16_t value.
  93. ///
  94. /// \param in_buffer destination buffer.
  95. /// \param dest_pos position in destination buffer.
  96. /// \param val value to be written.
  97. template<typename T>
  98. static void writeValueAt(dhcp::OptionBuffer& in_buffer, size_t dest_pos,
  99. T val) {
  100. // @todo consider replacing the loop with switch statement
  101. // checking sizeof(T).
  102. for (int i = 0; i < sizeof(T); ++i) {
  103. in_buffer[dest_pos + i] = (val >> 8 * (sizeof(T) - i - 1)) & 0xFF;
  104. }
  105. }
  106. private:
  107. /// \brief Replaces contents of options in a buffer.
  108. ///
  109. /// The method uses a localized options collection to
  110. /// replace parts of packet data (e.g. data read
  111. /// from template file).
  112. /// This private method is called from \ref PktTransform::pack
  113. ///
  114. /// \param in_buffer input buffer holding initial packet data.
  115. /// \param out_buffer output buffer with "packed" options.
  116. /// \param options options collection with actual data and offsets.
  117. ///
  118. /// \throw isc::Unexpected if options update failed.
  119. static void packOptions(const dhcp::OptionBuffer& in_buffer,
  120. const dhcp::OptionCollection& options,
  121. util::OutputBuffer& out_buffer);
  122. /// \brief Reads contents of specified options from buffer.
  123. ///
  124. /// The method reads options data from the input buffer
  125. /// and stores it in options objects. Offsets of the options
  126. /// must be specified (see \ref LocalizedOption to find out how to specify
  127. /// the option offset).
  128. /// This private method is called by \ref PktTransform::unpack.
  129. ///
  130. /// \note This method iterates through all options in an
  131. /// options collection, checks the offset of the option
  132. /// in input buffer and reads data from the buffer to
  133. /// update the option's buffer. If the provided options collection
  134. /// is empty, a call to this method will have no effect.
  135. ///
  136. /// \param universe universe used, V4 or V6
  137. /// \param in_buffer input buffer to be parsed.
  138. /// \param options options collection with their offsets
  139. /// in input buffer specified.
  140. ///
  141. /// \throw isc::Unexpected if options unpack failed.
  142. static void unpackOptions(const dhcp::OptionBuffer& in_buffer,
  143. const dhcp::OptionCollection& options);
  144. };
  145. } // namespace perfdhcp
  146. } // namespace isc
  147. #endif // PKT_TRANSFORM_H