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

/* -*- coding: utf-8 -*-
* ----------------------------------------------------------------------
* Copyright © 2009-2012, RedJack, LLC.
* All rights reserved.
*
* Please see the LICENSE.txt file in this distribution for license
* details.
* ----------------------------------------------------------------------
*/
#include <libcork/core.h>
#include "ipset/bdd/nodes.h"
#include "ipset/bits.h"
#include "ipset/errors.h"
#include "ipset/ipset.h"
/**
* Given a BDD variable number, return the index of the corresponding
* bit in an IP address. IPv4 addresses use variables 1-32; IPv6
* addresses use 1-128. (Variable 0 is used to identify the kind of
* address — TRUE for IPv4, FALSE for IPv6.)
*/
static unsigned int
IPMAP_NAME(bit_for_var)(ipset_variable var)
{
return (var - 1);
}
/**
* An assignment function that can be used to evaluate an IP map BDD.
*/
static bool
IPMAP_NAME(assignment)(const void *addr, ipset_variable var)
{
if (var == 0) {
return IP_DISCRIMINATOR_VALUE;
} else {
unsigned int bit = IPMAP_NAME(bit_for_var)(var);
return IPSET_BIT_GET(addr, bit);
}
}
int
IPMAP_NAME(get)(struct ip_map *map, CORK_IP *elem)
{
return ipset_node_evaluate
(map->cache, map->map_bdd, IPMAP_NAME(assignment), elem);
}
void
IPMAP_NAME(set_network)(struct ip_map *map, CORK_IP *elem,
unsigned int cidr_prefix, int value)
{
/* Special case — the BDD for a netmask that's out of range never
* evaluates to true. */
if (cidr_prefix > IP_BIT_SIZE) {
cork_error_set
(IPSET_ERROR, IPSET_PARSE_ERROR,
"CIDR block %u out of range [0..%u]", cidr_prefix, IP_BIT_SIZE);
return;
}
ipset_node_id new_bdd =
ipset_node_insert
(map->cache, map->map_bdd,
IPMAP_NAME(assignment), elem, cidr_prefix + 1, value);
ipset_node_decref(map->cache, map->map_bdd);
map->map_bdd = new_bdd;
}
void
IPMAP_NAME(set)(struct ip_map *map, CORK_IP *elem, int value)
{
ipset_node_id new_bdd =
ipset_node_insert
(map->cache, map->map_bdd,
IPMAP_NAME(assignment), elem, IP_BIT_SIZE + 1, value);
ipset_node_decref(map->cache, map->map_bdd);
map->map_bdd = new_bdd;
}