pkt4.cc 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  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. #include <dhcp/pkt4.h>
  15. #include <dhcp/libdhcp.h>
  16. #include <dhcp/dhcp4.h>
  17. #include <exceptions/exceptions.h>
  18. #include <asiolink/io_address.h>
  19. #include <iostream>
  20. #include <sstream>
  21. using namespace std;
  22. using namespace isc::dhcp;
  23. using namespace isc::asiolink;
  24. namespace isc {
  25. const IOAddress DEFAULT_ADDRESS("0.0.0.0");
  26. Pkt4::Pkt4(uint8_t msg_type, uint32_t transid)
  27. :local_addr_(IOAddress("0.0.0.0")),
  28. remote_addr_(IOAddress("0.0.0.0")),
  29. iface_(""),
  30. ifindex_(0),
  31. local_port_(DHCP4_SERVER_PORT),
  32. remote_port_(DHCP4_CLIENT_PORT),
  33. op_(DHCPTypeToBootpType(msg_type)),
  34. htype_(HTYPE_ETHER),
  35. hlen_(0),
  36. hops_(0),
  37. transid_(transid),
  38. secs_(0),
  39. flags_(0),
  40. ciaddr_(DEFAULT_ADDRESS),
  41. yiaddr_(DEFAULT_ADDRESS),
  42. siaddr_(DEFAULT_ADDRESS),
  43. giaddr_(DEFAULT_ADDRESS),
  44. bufferIn_(0), // not used, this is TX packet
  45. bufferOut_(DHCPV4_PKT_HDR_LEN),
  46. msg_type_(msg_type)
  47. {
  48. /// TODO: fixed fields, uncomment in ticket #1224
  49. memset(chaddr_, 0, MAX_CHADDR_LEN);
  50. memset(sname_, 0, MAX_SNAME_LEN);
  51. memset(file_, 0, MAX_FILE_LEN);
  52. }
  53. Pkt4::Pkt4(const uint8_t* data, size_t len)
  54. :local_addr_(IOAddress("0.0.0.0")),
  55. remote_addr_(IOAddress("0.0.0.0")),
  56. iface_(""),
  57. ifindex_(-1),
  58. local_port_(DHCP4_SERVER_PORT),
  59. remote_port_(DHCP4_CLIENT_PORT),
  60. /// TODO Fixed fields, uncomment in ticket #1224
  61. op_(BOOTREQUEST),
  62. transid_(transid_),
  63. secs_(0),
  64. flags_(0),
  65. ciaddr_(DEFAULT_ADDRESS),
  66. yiaddr_(DEFAULT_ADDRESS),
  67. siaddr_(DEFAULT_ADDRESS),
  68. giaddr_(DEFAULT_ADDRESS),
  69. bufferIn_(0), // not used, this is TX packet
  70. bufferOut_(DHCPV4_PKT_HDR_LEN),
  71. msg_type_(DHCPDISCOVER)
  72. {
  73. if (len < DHCPV4_PKT_HDR_LEN) {
  74. isc_throw(OutOfRange, "Truncated DHCPv4 packet (len=" << len
  75. << " received, at least 236 bytes expected.");
  76. }
  77. bufferIn_.writeData(data, len);
  78. }
  79. size_t
  80. Pkt4::len() {
  81. size_t length = DHCPV4_PKT_HDR_LEN; // DHCPv4 header
  82. /// TODO: Include options here (ticket #1228)
  83. return (length);
  84. }
  85. bool
  86. Pkt4::pack() {
  87. /// TODO: Implement this (ticket #1227)
  88. return (false);
  89. }
  90. bool
  91. Pkt4::unpack() {
  92. /// TODO: Implement this (ticket #1226)
  93. return (false);
  94. }
  95. std::string
  96. Pkt4::toText() {
  97. stringstream tmp;
  98. tmp << "localAddr=[" << local_addr_.toText() << "]:" << local_port_
  99. << " remoteAddr=[" << remote_addr_.toText()
  100. << "]:" << remote_port_ << endl;
  101. tmp << "msgtype=" << msg_type_
  102. << ", transid=0x" << hex << transid_ << dec
  103. << endl;
  104. return tmp.str();
  105. }
  106. void
  107. Pkt4::setHWAddr(uint8_t hType, uint8_t hlen, const uint8_t* macAddr) {
  108. /// TODO Rewrite this once support for client-identifier option
  109. /// is implemented (ticket 1228?)
  110. if (hlen>MAX_CHADDR_LEN) {
  111. isc_throw(OutOfRange, "Hardware address (len=" << hlen
  112. << " too long. Max " << MAX_CHADDR_LEN << " supported.");
  113. }
  114. if ( (!macAddr) && (hlen > 0) ) {
  115. isc_throw(OutOfRange, "Invalid HW Address specified");
  116. }
  117. htype_ = hType;
  118. hlen_ = hlen;
  119. memset(chaddr_, 0, MAX_CHADDR_LEN);
  120. memcpy(chaddr_, macAddr, hlen);
  121. }
  122. void
  123. Pkt4::setSname(const uint8_t* sname, size_t snameLen /*= MAX_SNAME_LEN*/) {
  124. if (snameLen > MAX_SNAME_LEN) {
  125. isc_throw(OutOfRange, "sname field (len=" << snameLen
  126. << ") too long, Max " << MAX_SNAME_LEN << " supported.");
  127. }
  128. memset(sname_, 0, MAX_SNAME_LEN);
  129. memcpy(sname_, sname, snameLen);
  130. // no need to store snameLen as any empty space is filled with 0s
  131. }
  132. void
  133. Pkt4::setFile(const uint8_t* file, size_t fileLen /*= MAX_FILE_LEN*/) {
  134. if (fileLen > MAX_FILE_LEN) {
  135. isc_throw(OutOfRange, "file field (len=" << fileLen
  136. << ") too long, Max " << MAX_FILE_LEN << " supported.");
  137. }
  138. memset(file_, 0, MAX_FILE_LEN);
  139. memcpy(file_, file, fileLen);
  140. // no need to store fileLen as any empty space is filled with 0s
  141. }
  142. uint8_t
  143. Pkt4::DHCPTypeToBootpType(uint8_t dhcpType) {
  144. switch (dhcpType) {
  145. case DHCPDISCOVER:
  146. case DHCPREQUEST:
  147. case DHCPDECLINE:
  148. case DHCPRELEASE:
  149. case DHCPINFORM:
  150. case DHCPLEASEQUERY:
  151. return (BOOTREQUEST);
  152. case DHCPACK:
  153. case DHCPNAK:
  154. case DHCPOFFER:
  155. case DHCPLEASEUNASSIGNED:
  156. case DHCPLEASEUNKNOWN:
  157. case DHCPLEASEACTIVE:
  158. return (BOOTREPLY);
  159. default:
  160. isc_throw(OutOfRange, "Invalid message type: "
  161. << static_cast<int>(dhcpType) );
  162. }
  163. }
  164. };