pkt4.h 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. // Copyright (C) 2011 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 PKT4_H
  15. #define PKT4_H
  16. #include <iostream>
  17. #include <boost/shared_ptr.hpp>
  18. #include <boost/shared_array.hpp>
  19. #include "asiolink/io_address.h"
  20. #include "util/buffer.h"
  21. #include "dhcp/option.h"
  22. namespace isc {
  23. namespace dhcp {
  24. class Pkt4 {
  25. public:
  26. // length of the CHADDR field in DHCPv4 message
  27. const static size_t MAX_CHADDR_LEN = 16;
  28. // length of the SNAME field in DHCPv4 message
  29. const static size_t MAX_SNAME_LEN = 64;
  30. // length of the FILE field in DHCPv4 message
  31. const static size_t MAX_FILE_LEN = 128;
  32. /// specifes DHCPv4 packet header length (fixed part)
  33. const static size_t DHCPV4_PKT_HDR_LEN = 236;
  34. /// Constructor, used in replying to a message
  35. ///
  36. /// @param msg_type type of message (e.g. DHCPDISOVER=1)
  37. /// @param transid transaction-id
  38. Pkt4(uint8_t msg_type, uint32_t transid);
  39. /// Constructor, used in message transmission
  40. ///
  41. /// Creates new message. Transaction-id will randomized.
  42. ///
  43. /// @param data pointer to received data
  44. /// @param len size of buffer to be allocated for this packet.
  45. Pkt4(const uint8_t* data, size_t len);
  46. /// @brief Prepares on-wire format.
  47. ///
  48. /// Prepares on-wire format of message and all its options.
  49. /// Options must be stored in options_ field.
  50. /// Output buffer will be stored in data_. Length
  51. /// will be set in data_len_.
  52. ///
  53. /// @return true if packing procedure was successful
  54. bool
  55. pack();
  56. /// @brief Parses on-wire form of UDP DHCPv6 packet.
  57. ///
  58. /// Parses received packet, stored in on-wire format in data_.
  59. /// data_len_ must be set to indicate data length.
  60. /// Will create a collection of option objects that will
  61. /// be stored in options_ container.
  62. ///
  63. /// @return true, if build was successful
  64. bool
  65. unpack();
  66. /// @brief Returns text representation of the packet.
  67. ///
  68. /// This function is useful mainly for debugging.
  69. ///
  70. /// @return string with text representation
  71. std::string
  72. toText();
  73. /// @brief Returns calculated length of the packet.
  74. ///
  75. /// This function returns size of required buffer to buld this packet.
  76. /// To use that function, options_ field must be set.
  77. ///
  78. /// @return number of bytes required to build this packet
  79. size_t
  80. len();
  81. /// Sets hops field
  82. ///
  83. /// @param hops value to be set
  84. void
  85. setHops(uint8_t hops) { hops_ = hops; };
  86. /// Returns hops field
  87. ///
  88. /// @return hops field
  89. uint8_t
  90. getHops() { return (hops_); };
  91. // Note: There's no need to manipulate OP field directly,
  92. // thus no setOp() method. See op_ comment.
  93. /// Returns op field
  94. ///
  95. /// @return op field
  96. uint8_t
  97. getOp() { return (op_); };
  98. /// Sets secs field
  99. ///
  100. /// @param secs value to be set
  101. void
  102. setSecs(uint16_t secs) { secs_ = secs; };
  103. /// Returns secs field
  104. ///
  105. /// @return secs field
  106. uint16_t
  107. getSecs() { return (secs_); };
  108. /// Sets flags field
  109. ///
  110. /// @param flags value to be set
  111. void
  112. setFlags(uint16_t flags) { flags_ = flags; };
  113. /// Returns flags field
  114. ///
  115. /// @return flags field
  116. uint16_t
  117. getFlags() { return (flags_); };
  118. /// Returns ciaddr field
  119. ///
  120. /// @return ciaddr field
  121. isc::asiolink::IOAddress&
  122. getCiaddr() { return (ciaddr_); };
  123. /// Sets ciaddr field
  124. ///
  125. /// @param ciaddr value to be set
  126. void
  127. setCiaddr(const isc::asiolink::IOAddress& ciaddr) { ciaddr_ = ciaddr; };
  128. /// Returns siaddr field
  129. ///
  130. /// @return siaddr field
  131. isc::asiolink::IOAddress&
  132. getSiaddr() { return (siaddr_); };
  133. /// Sets siaddr field
  134. ///
  135. /// @param siaddr value to be set
  136. void
  137. setSiaddr(const isc::asiolink::IOAddress& siaddr) { siaddr_ = siaddr; };
  138. /// Returns yiaddr field
  139. ///
  140. /// @return yiaddr field
  141. isc::asiolink::IOAddress&
  142. getYiaddr() { return (yiaddr_); };
  143. /// Sets yiaddr field
  144. ///
  145. /// @param yiaddr value to be set
  146. void
  147. setYiaddr(const isc::asiolink::IOAddress& yiaddr) { yiaddr_ = yiaddr; };
  148. /// Returns giaddr field
  149. ///
  150. /// @return giaddr field
  151. isc::asiolink::IOAddress&
  152. getGiaddr() { return (giaddr_); };
  153. /// Sets giaddr field
  154. ///
  155. /// @param giaddr value to be set
  156. void
  157. setGiaddr(const isc::asiolink::IOAddress& giaddr) { giaddr_ = giaddr; };
  158. /// Returns value of transaction-id field
  159. ///
  160. /// @return transaction-id
  161. uint32_t getTransid() { return (transid_); };
  162. /// Returns message type (e.g. 1 = DHCPDISCOVER)
  163. ///
  164. /// @return message type
  165. uint8_t
  166. getType() { return (msg_type_); }
  167. /// Sets message type (e.g. 1 = DHCPDISCOVER)
  168. ///
  169. /// @param type message type to be set
  170. void setType(uint8_t type) { msg_type_=type; };
  171. /// @brief Returns sname field
  172. ///
  173. /// Note: This is 64 bytes long field. It doesn't have to be
  174. /// null-terminated. Do no use strlen() or similar on it.
  175. ///
  176. /// @return sname field
  177. const uint8_t*
  178. getSname() { return (sname_); };
  179. /// Sets sname field
  180. ///
  181. /// @param sname value to be set
  182. void
  183. setSname(const uint8_t* sname, size_t snameLen = MAX_SNAME_LEN);
  184. /// @brief Returns file field
  185. ///
  186. /// Note: This is 128 bytes long field. It doesn't have to be
  187. /// null-terminated. Do no use strlen() or similar on it.
  188. ///
  189. /// @return pointer to file field
  190. const uint8_t*
  191. getFile() { return (file_); };
  192. /// Sets file field
  193. ///
  194. /// @param file value to be set
  195. void
  196. setFile(const uint8_t* file, size_t fileLen = MAX_FILE_LEN);
  197. /// Sets hardware address
  198. ///
  199. /// @param hwType hardware type (will be sent in htype field)
  200. /// @param hlen hardware length (will be sent in hlen field)
  201. /// @param macAddr pointer to hardware address
  202. void setHWAddr(uint8_t hType, uint8_t hlen,
  203. const uint8_t* macAddr);
  204. /// Returns htype field
  205. ///
  206. /// @return hardware type
  207. uint8_t
  208. getHtype() { return (htype_); };
  209. /// Returns hlen field
  210. ///
  211. /// @return hardware address length
  212. uint8_t
  213. getHlen() { return (hlen_); };
  214. /// @brief Returns chaddr field
  215. ///
  216. /// Note: This is 16 bytes long field. It doesn't have to be
  217. /// null-terminated. Do no use strlen() or similar on it.
  218. ///
  219. /// @return pointer to hardware address
  220. const uint8_t*
  221. getChaddr() { return (chaddr_); };
  222. protected:
  223. /// converts DHCP message type to BOOTP op type
  224. ///
  225. /// @param dhcpType DHCP message type (e.g. DHCPDISCOVER)
  226. ///
  227. /// @return BOOTP type (BOOTREQUEST or BOOTREPLY)
  228. uint8_t
  229. DHCPTypeToBootpType(uint8_t dhcpType);
  230. /// local address (dst if receiving packet, src if sending packet)
  231. isc::asiolink::IOAddress local_addr_;
  232. /// remote address (src if receiving packet, dst if sending packet)
  233. isc::asiolink::IOAddress remote_addr_;
  234. /// name of the network interface the packet was received/to be sent over
  235. std::string iface_;
  236. /// @brief interface index
  237. ///
  238. /// interface index (each network interface has assigned unique ifindex
  239. /// it is functional equvalent of name, but sometimes more useful, e.g.
  240. /// when using crazy systems that allow spaces in interface names
  241. /// e.g. windows
  242. int ifindex_;
  243. /// local UDP port
  244. int local_port_;
  245. /// remote UDP port
  246. int remote_port_;
  247. /// message operation code (kept due to BOOTP format, this is NOT DHCPv4 type)
  248. ///
  249. /// Note: This is legacy BOOTP field. There's no need to manipulate it
  250. /// directly. Its value is set based on DHCP message type.
  251. uint8_t op_;
  252. /// link-layer address type
  253. uint8_t htype_;
  254. /// link-layer address length
  255. uint8_t hlen_;
  256. /// Number of relay agents traversed
  257. uint8_t hops_;
  258. /// DHCPv4 transaction-id (32 bits, not 24 bits as in DHCPv6)
  259. uint32_t transid_;
  260. /// elapsed (number of seconds since beginning of transmission)
  261. uint16_t secs_;
  262. /// flags
  263. uint16_t flags_;
  264. // ciaddr field (32 bits): Client's IP address
  265. isc::asiolink::IOAddress ciaddr_;
  266. // yiaddr field (32 bits): Client's IP address ("your"), set by server
  267. isc::asiolink::IOAddress yiaddr_;
  268. // siaddr field (32 bits): next server IP address in boot process(e.g.TFTP)
  269. isc::asiolink::IOAddress siaddr_;
  270. // giaddr field (32 bits): Gateway IP address
  271. isc::asiolink::IOAddress giaddr_;
  272. // ciaddr field (32 bits): Client's IP address
  273. uint8_t chaddr_[16];
  274. // sname 64 bytes
  275. uint8_t sname_[64];
  276. // file
  277. uint8_t file_[128];
  278. // end of real DHCPv4 fields
  279. /// input buffer (used during message reception)
  280. /// Note that it must be modifiable as hooks can modify incoming buffer),
  281. /// thus OutputBuffer, not InputBuffer
  282. isc::util::OutputBuffer bufferIn_;
  283. /// output buffer (used during message
  284. isc::util::OutputBuffer bufferOut_;
  285. /// message type (e.g. 1=DHCPDISCOVER)
  286. /// TODO: this will eventually be replaced with DHCP Message Type
  287. /// option (option 53)
  288. uint8_t msg_type_;
  289. /// collection of options present in this message
  290. isc::dhcp::Option::Option4Collection options_;
  291. }; // Pkt4 class
  292. } // isc::dhcp namespace
  293. } // isc namespace
  294. #endif