addr_utilities.cc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. // Copyright (C) 2012-2017 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. #include <dhcpsrv/addr_utilities.h>
  7. #include <exceptions/exceptions.h>
  8. #include <vector>
  9. #include <limits>
  10. #include <string.h>
  11. using namespace isc;
  12. using namespace isc::asiolink;
  13. namespace {
  14. /// @brief mask used for first/last address calculation in a IPv4 prefix
  15. ///
  16. /// Using a static mask is faster than calculating it dynamically every time.
  17. const uint32_t bitMask4[] = { 0xffffffff, 0x7fffffff, 0x3fffffff, 0x1fffffff,
  18. 0x0fffffff, 0x07ffffff, 0x03ffffff, 0x01ffffff,
  19. 0x00ffffff, 0x007fffff, 0x003fffff, 0x001fffff,
  20. 0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff,
  21. 0x0000ffff, 0x00007fff, 0x00003fff, 0x00001fff,
  22. 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff,
  23. 0x000000ff, 0x0000007f, 0x0000003f, 0x0000001f,
  24. 0x0000000f, 0x00000007, 0x00000003, 0x00000001,
  25. 0x00000000 };
  26. /// @brief mask used for first/last address calculation in a IPv6 prefix
  27. const uint8_t bitMask6[]= { 0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
  28. /// @brief mask used for IPv6 prefix calculation
  29. const uint8_t revMask6[]= { 0xff, 0x7f, 0x3f, 0x1f, 0xf, 0x7, 0x3, 0x1 };
  30. /// @brief calculates the first IPv6 address in a IPv6 prefix
  31. ///
  32. /// Note: This is a private function. Do not use it directly.
  33. /// Please use firstAddrInPrefix() instead.
  34. ///
  35. /// @param prefix IPv6 prefix
  36. /// @param len prefix length
  37. isc::asiolink::IOAddress firstAddrInPrefix6(const isc::asiolink::IOAddress& prefix,
  38. uint8_t len) {
  39. if (len > 128) {
  40. isc_throw(isc::BadValue,
  41. "Too large netmask. 0..128 is allowed in IPv6");
  42. }
  43. // First we copy the whole address as 16 bytes.
  44. // We don't check that it is a valid IPv6 address and thus has
  45. // the required length because it is already checked by
  46. // the calling function.
  47. uint8_t packed[V6ADDRESS_LEN];
  48. memcpy(packed, &prefix.toBytes()[0], V6ADDRESS_LEN);
  49. // If the length is divisible by 8, it is simple. We just zero out the host
  50. // part. Otherwise we need to handle the byte that has to be partially
  51. // zeroed.
  52. if (len % 8 != 0) {
  53. // Get the appropriate mask. It has relevant bits (those that should
  54. // stay) set and irrelevant (those that should be wiped) cleared.
  55. uint8_t mask = bitMask6[len % 8];
  56. // Let's leave only whatever the mask says should not be cleared.
  57. packed[len / 8] = packed[len / 8] & mask;
  58. // Since we have just dealt with this byte, let's move the prefix length
  59. // to the beginning of the next byte (len is expressed in bits).
  60. len = (len / 8 + 1) * 8;
  61. }
  62. // Clear out the remaining bits.
  63. for (int i = len / 8; i < sizeof(packed); ++i) {
  64. packed[i] = 0x0;
  65. }
  66. // Finally, let's wrap this into nice and easy IOAddress object.
  67. return (isc::asiolink::IOAddress::fromBytes(AF_INET6, packed));
  68. }
  69. /// @brief calculates the first IPv4 address in a IPv4 prefix
  70. ///
  71. /// Note: This is a private function. Do not use it directly.
  72. /// Please use firstAddrInPrefix() instead.
  73. ///
  74. /// @param prefix IPv4 prefix
  75. /// @param len netmask length (0-32)
  76. isc::asiolink::IOAddress firstAddrInPrefix4(const isc::asiolink::IOAddress& prefix,
  77. uint8_t len) {
  78. if (len > 32) {
  79. isc_throw(isc::BadValue, "Too large netmask. 0..32 is allowed in IPv4");
  80. }
  81. // We don't check that it is a valid IPv4 address and thus has
  82. // a required length of 4 bytes because it has been already
  83. // checked by the calling function.
  84. uint32_t addr = prefix.toUint32();
  85. return (IOAddress(addr & (~bitMask4[len])));
  86. }
  87. /// @brief calculates the last IPv4 address in a IPv4 prefix
  88. ///
  89. /// Note: This is a private function. Do not use it directly.
  90. /// Please use firstAddrInPrefix() instead.
  91. ///
  92. /// @param prefix IPv4 prefix that we calculate first address for
  93. /// @param len netmask length (0-32)
  94. isc::asiolink::IOAddress lastAddrInPrefix4(const isc::asiolink::IOAddress& prefix,
  95. uint8_t len) {
  96. if (len > 32) {
  97. isc_throw(isc::BadValue, "Too large netmask. 0..32 is allowed in IPv4");
  98. }
  99. uint32_t addr = prefix.toUint32();
  100. return (IOAddress(addr | bitMask4[len]));
  101. }
  102. /// @brief calculates the last IPv6 address in a IPv6 prefix
  103. ///
  104. /// Note: This is a private function. Do not use it directly.
  105. /// Please use lastAddrInPrefix() instead.
  106. ///
  107. /// @param prefix IPv6 prefix that we calculate first address for
  108. /// @param len netmask length (0-128)
  109. isc::asiolink::IOAddress lastAddrInPrefix6(const isc::asiolink::IOAddress& prefix,
  110. uint8_t len) {
  111. if (len > 128) {
  112. isc_throw(isc::BadValue,
  113. "Too large netmask. 0..128 is allowed in IPv6");
  114. }
  115. // First we copy the whole address as 16 bytes.
  116. uint8_t packed[V6ADDRESS_LEN];
  117. memcpy(packed, &prefix.toBytes()[0], 16);
  118. // if the length is divisible by 8, it is simple. We just fill the host part
  119. // with ones. Otherwise we need to handle the byte that has to be partially
  120. // zeroed.
  121. if (len % 8 != 0) {
  122. // Get the appropriate mask. It has relevant bits (those that should
  123. // stay) set and irrelevant (those that should be set to 1) cleared.
  124. uint8_t mask = bitMask6[len % 8];
  125. // Let's set those irrelevant bits with 1. It would be perhaps
  126. // easier to not use negation here and invert bitMask6 content. However,
  127. // with this approach, we can use the same mask in first and last
  128. // address calculations.
  129. packed[len / 8] = packed[len / 8] | ~mask;
  130. // Since we have just dealt with this byte, let's move the prefix length
  131. // to the beginning of the next byte (len is expressed in bits).
  132. len = (len / 8 + 1) * 8;
  133. }
  134. // Finally set remaining bits to 1.
  135. for (int i = len / 8; i < sizeof(packed); ++i) {
  136. packed[i] = 0xff;
  137. }
  138. // Finally, let's wrap this into nice and easy IOAddress object.
  139. return (isc::asiolink::IOAddress::fromBytes(AF_INET6, packed));
  140. }
  141. }; // end of anonymous namespace
  142. namespace isc {
  143. namespace dhcp {
  144. isc::asiolink::IOAddress firstAddrInPrefix(const isc::asiolink::IOAddress& prefix,
  145. uint8_t len) {
  146. if (prefix.isV4()) {
  147. return (firstAddrInPrefix4(prefix, len));
  148. } else {
  149. return (firstAddrInPrefix6(prefix, len));
  150. }
  151. }
  152. isc::asiolink::IOAddress lastAddrInPrefix(const isc::asiolink::IOAddress& prefix,
  153. uint8_t len) {
  154. if (prefix.isV4()) {
  155. return (lastAddrInPrefix4(prefix, len));
  156. } else {
  157. return (lastAddrInPrefix6(prefix, len));
  158. }
  159. }
  160. isc::asiolink::IOAddress getNetmask4(uint8_t len) {
  161. if (len > 32) {
  162. isc_throw(BadValue, "Invalid netmask size "
  163. << static_cast<unsigned>(len) << ", allowed range is 0..32");
  164. }
  165. uint32_t x = ~bitMask4[len];
  166. return (IOAddress(x));
  167. }
  168. uint64_t
  169. addrsInRange(const isc::asiolink::IOAddress& min,
  170. const isc::asiolink::IOAddress& max) {
  171. if (min.getFamily() != max.getFamily()) {
  172. isc_throw(BadValue, "Both addresses have to be the same family");
  173. }
  174. if (max < min) {
  175. isc_throw(BadValue, min.toText() << " must not be greater than "
  176. << max.toText());
  177. }
  178. if (min.isV4()) {
  179. // Let's explicitly cast last_ and first_ (IOAddress). This conversion is
  180. // automatic, but let's explicitly cast it show that we moved to integer
  181. // domain and addresses are now substractable.
  182. uint64_t max_numeric = static_cast<uint64_t>(max.toUint32());
  183. uint64_t min_numeric = static_cast<uint64_t>(min.toUint32());
  184. // We can simply subtract the values. We need to increase the result
  185. // by one, as both min and max are included in the range. So even if
  186. // min == max, there's one address.
  187. return (max_numeric - min_numeric + 1);
  188. } else {
  189. // Calculating the difference in v6 is more involved. Let's subtract
  190. // one from the other. By subtracting min from max, we move the
  191. // [a, b] range to the [0, (b-a)] range. We don't care about the beginning
  192. // of the new range (it's always zero). The upper bound now specifies
  193. // the number of addresses minus one.
  194. IOAddress count = IOAddress::subtract(max, min);
  195. // There's one very special case. Someone is trying to check how many
  196. // IPv6 addresses are in IPv6 address space. He called this method
  197. // with ::, ffff:ffff:ffff:fffff:ffff:ffff:ffff:ffff. The diff is also
  198. // all 1s. Had we increased it by one, the address would flip to all 0s.
  199. // This will not happen in a real world. Apparently, unit-tests are
  200. // sometimes nastier then a real world.
  201. static IOAddress max6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
  202. if (count == max6) {
  203. return (std::numeric_limits<uint64_t>::max());
  204. }
  205. // Increase it by one (a..a range still contains one address, even though
  206. // a subtracted from a is zero).
  207. count = IOAddress::increase(count);
  208. // We don't have uint128, so for anything greater than 2^64, we'll just
  209. // assume numeric_limits<uint64_t>::max. Let's do it the manual way.
  210. const std::vector<uint8_t>& bin(count.toBytes());
  211. // If any of the most significant 64 bits is set, we have more than
  212. // 2^64 addresses and can't represent it even on uint64_t.
  213. for (int i = 0 ; i < 8; i++) {
  214. if (bin[i]) {
  215. return (std::numeric_limits<uint64_t>::max());
  216. }
  217. }
  218. // Ok, we're good. The pool is sanely sized. It may be huge, but at least
  219. // that's something we can represent on uint64_t.
  220. uint64_t numeric = 0;
  221. for (int i = 8; i < 16; i++) {
  222. numeric <<= 8;
  223. numeric += bin[i];
  224. }
  225. return (numeric);
  226. }
  227. }
  228. int
  229. prefixLengthFromRange(const isc::asiolink::IOAddress& min,
  230. const isc::asiolink::IOAddress& max) {
  231. if (min.getFamily() != max.getFamily()) {
  232. isc_throw(BadValue, "Both addresses have to be the same family");
  233. }
  234. if (max < min) {
  235. isc_throw(BadValue, min.toText() << " must not be greater than "
  236. << max.toText());
  237. }
  238. if (min.isV4()) {
  239. // Get addresses as integers
  240. uint32_t max_numeric = max.toUint32();
  241. uint32_t min_numeric = min.toUint32();
  242. // Get the exclusive or which must be one of the bit masks
  243. uint32_t xor_numeric = max_numeric ^ min_numeric;
  244. for (uint8_t prefix_len = 0; prefix_len <= 32; ++prefix_len) {
  245. if (xor_numeric == bitMask4[prefix_len]) {
  246. // Got it: the wanted value is also the index
  247. return (static_cast<int>(prefix_len));
  248. }
  249. }
  250. // If it was not found the range is not from a prefix / prefix_len
  251. return (-1);
  252. } else {
  253. // Get addresses as 16 bytes
  254. uint8_t min_packed[V6ADDRESS_LEN];
  255. memcpy(min_packed, &min.toBytes()[0], 16);
  256. uint8_t max_packed[V6ADDRESS_LEN];
  257. memcpy(max_packed, &max.toBytes()[0], 16);
  258. // Scan the exclusive or of addresses to find a difference
  259. int candidate = 128;
  260. bool zeroes = true;
  261. for (uint8_t i = 0; i < 16; ++i) {
  262. uint8_t xor_byte = min_packed[i] ^ max_packed[i];
  263. if (zeroes) {
  264. // Skipping zero bits searching for one bits
  265. if (xor_byte == 0) {
  266. continue;
  267. }
  268. // Found a one bit: note the fact
  269. zeroes = false;
  270. // Compare the exclusive or to masks
  271. for (uint8_t j = 0; j < 8; ++j) {
  272. if (xor_byte == revMask6[j]) {
  273. // Got it the prefix length: note it
  274. candidate = static_cast<int>((i * 8) + j);
  275. }
  276. }
  277. if (candidate == 128) {
  278. // Not found? The range is not from a prefix / prefix_len
  279. return (-1);
  280. }
  281. } else {
  282. // Checking that trailing bits are on bits
  283. if (xor_byte == 0xff) {
  284. continue;
  285. }
  286. // Not all ones is bad
  287. return (-1);
  288. }
  289. }
  290. return (candidate);
  291. }
  292. }
  293. uint64_t prefixesInRange(const uint8_t pool_len, const uint8_t delegated_len) {
  294. if (delegated_len < pool_len) {
  295. return (0);
  296. }
  297. uint64_t count = delegated_len - pool_len;
  298. if (count == 0) {
  299. // If we want to delegate /64 out of /64 pool, we have only
  300. // one prefix.
  301. return (1);
  302. } else if (count >= 64) {
  303. // If the difference is greater than or equal 64, e.g. we want to
  304. // delegate /96 out of /16 pool, the number is bigger than we can
  305. // express, so we'll stick with maximum value of uint64_t.
  306. return (std::numeric_limits<uint64_t>::max());
  307. } else {
  308. // Now count specifies the exponent (e.g. if the difference between the
  309. // delegated and pool length is 4, we have 16 prefixes), so we need
  310. // to calculate 2^(count - 1)
  311. return ((static_cast<uint64_t>(2)) << (count - 1));
  312. }
  313. }
  314. };
  315. };