You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

88 lines
2.2 KiB

10 years ago
  1. /* -*- coding: utf-8 -*-
  2. * ----------------------------------------------------------------------
  3. * Copyright © 2009-2012, RedJack, LLC.
  4. * All rights reserved.
  5. *
  6. * Please see the LICENSE.txt file in this distribution for license
  7. * details.
  8. * ----------------------------------------------------------------------
  9. */
  10. #include <libcork/core.h>
  11. #include "ipset/bdd/nodes.h"
  12. #include "ipset/bits.h"
  13. #include "ipset/errors.h"
  14. #include "ipset/ipset.h"
  15. /**
  16. * Given a BDD variable number, return the index of the corresponding
  17. * bit in an IP address. IPv4 addresses use variables 1-32; IPv6
  18. * addresses use 1-128. (Variable 0 is used to identify the kind of
  19. * address — TRUE for IPv4, FALSE for IPv6.)
  20. */
  21. static unsigned int
  22. IPMAP_NAME(bit_for_var)(ipset_variable var)
  23. {
  24. return (var - 1);
  25. }
  26. /**
  27. * An assignment function that can be used to evaluate an IP map BDD.
  28. */
  29. static bool
  30. IPMAP_NAME(assignment)(const void *addr, ipset_variable var)
  31. {
  32. if (var == 0) {
  33. return IP_DISCRIMINATOR_VALUE;
  34. } else {
  35. unsigned int bit = IPMAP_NAME(bit_for_var)(var);
  36. return IPSET_BIT_GET(addr, bit);
  37. }
  38. }
  39. int
  40. IPMAP_NAME(get)(struct ip_map *map, CORK_IP *elem)
  41. {
  42. return ipset_node_evaluate
  43. (map->cache, map->map_bdd, IPMAP_NAME(assignment), elem);
  44. }
  45. void
  46. IPMAP_NAME(set_network)(struct ip_map *map, CORK_IP *elem,
  47. unsigned int cidr_prefix, int value)
  48. {
  49. /* Special case — the BDD for a netmask that's out of range never
  50. * evaluates to true. */
  51. if (cidr_prefix > IP_BIT_SIZE) {
  52. cork_error_set
  53. (IPSET_ERROR, IPSET_PARSE_ERROR,
  54. "CIDR block %u out of range [0..%u]", cidr_prefix, IP_BIT_SIZE);
  55. return;
  56. }
  57. ipset_node_id new_bdd =
  58. ipset_node_insert
  59. (map->cache, map->map_bdd,
  60. IPMAP_NAME(assignment), elem, cidr_prefix + 1, value);
  61. ipset_node_decref(map->cache, map->map_bdd);
  62. map->map_bdd = new_bdd;
  63. }
  64. void
  65. IPMAP_NAME(set)(struct ip_map *map, CORK_IP *elem, int value)
  66. {
  67. ipset_node_id new_bdd =
  68. ipset_node_insert
  69. (map->cache, map->map_bdd,
  70. IPMAP_NAME(assignment), elem, IP_BIT_SIZE + 1, value);
  71. ipset_node_decref(map->cache, map->map_bdd);
  72. map->map_bdd = new_bdd;
  73. }