pkt_transform.h 7.3 KB

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