IP maps¶
The functions in this section allow you to work with IP maps, which map IP addresses to integer values. IP maps work seamlessly with both IPv4 and IPv6 addresses. Every IP address is mapped to some value; each IP map has a default value that will be used for any addresses that aren’t explicitly mapped to something else. (This is the map equivalent of an address not appearing in a set; “removing” an address from a map is the same as setting it to the map’s default value.)
Note
With this definition of a map, an IP set is just an IP map that is restricted to the values 0 and 1. This is actually how sets are implemented internally.
Note
Before using any of the IP map functions, you must initialize this library
using ipset_init_library()
.
Creating and freeing maps¶
-
struct
ip_map
¶ Maps IP addresses to integer values. The fields of this
struct
are opaque; you should only use the public library functions to access the contents of the map.
There are two ways that you can work with IP maps. The first is that you can
allocate the space for the ip_map
instance yourself — for instance,
directly on the stack. The second is to let the IP map library allocate the
space for you. Your choice determines which of the following functions you will
use to create and free your IP maps.
-
void
ipmap_init
(struct ip_map *map, int default_value)¶ -
struct ip_map *
ipmap_new
(int default_value)¶ Creates a new IP map. The map will use default_value as the default value for any addresses that aren’t explicitly mapped to something else.
The
init
variant should be used if you’ve allocated space for the map yourself. Thenew
variant should be used if you want the library to allocate the space for you. (Thenew
variant never returnsNULL
; it will abort the program if the allocation fails.) In both cases, the map starts off empty.
-
void
ipmap_done
(struct ip_map *map)¶ -
void
ipmap_free
(struct ip_map *map)¶ Finalizes an IP map. The
done
variant must be used if you created the map usingipmap_init()
; thefree
variant must be used if you created the map usingipmap_new()
.
Adding and removing elements¶
We provide a variety of functions for adding and removing addresses from an IP map.
-
void
ipmap_ipv4_set
(struct ip_map *map, struct cork_ipv4 *ip, int value)¶ -
void
ipmap_ipv6_set
(struct ip_map *map, struct cork_ipv6 *ip, int value)¶ -
void
ipmap_ip_set
(struct ip_map *map, struct cork_ip *ip, int value)¶ Updates map so that ip is mapped to value.
-
void
ipmap_ipv4_set_network
(struct ip_map *map, struct cork_ipv4 *ip, unsigned int cidr_prefix, int value)¶ -
void
ipmap_ipv6_set_network
(struct ip_map *map, struct cork_ipv6 *ip, unsigned int cidr_prefix, int value)¶ -
void
ipmap_ip_set_network
(struct ip_map *map, struct cork_ip *ip, unsigned int cidr_prefix, int value)¶ Updates map so that all of the addresses in a CIDR network are mapped to value. ip is one of the addresses in the CIDR network; cidr_prefix is the number of bits in the network portion of each IP address in the CIDR network, as defined in RFC 4632. cidr_prefix must be in the range 0-32 (inclusive) if ip is an IPv4 address, and in the range 0-128 (inclusive) if it’s an IPv6 address.
Note
In all of the _network
functions, if you want to strictly adhere to RFC
4632, ip can only have non-zero bits in its cidr_prefix uppermost bits.
All of the lower-order bits (i.e., in the host portion of the IP address)
must be map to 0. We do not enforce this, however.
Querying a map¶
-
int
ipmap_get_ipv4
(const struct ip_map *map, struct cork_ipv4 *ip)¶ -
int
ipmap_get_ipv6
(const struct ip_map *map, struct cork_ipv6 *ip)¶ -
int
ipmap_get_ip
(const struct ip_map *map, struct cork_ip *ip)¶ Returns the value that ip is mapped to in map.
-
bool
ipmap_is_empty
(const struct ip_map *map)¶ Returns whether map is empty. A map is considered empty is every IP address is mapped to the default value.
Storing maps in files¶
The functions in this section allow you to store IP maps on disk, and reload them into another program at a later time. You don’t have to know the details of the file format to be able to use these functions; we guarantee that maps written with previous versions of the library will be readable by later versions of the library (but not vice versa). And we guarantee that the file format is platform-independent; maps written on any machine will be readable on any other machine.
(That said, if you do want to know the details of the file format, that’s documented in another section.)
-
int
ipmap_save
(FILE *stream, const struct ip_map *map)¶ Saves an IP map into stream. You’re responsible for opening stream before calling this function, and for closing stream afterwards. If there are any errors writing the map, we return
-1
and fill in a libcork error condition.
-
int
ipmap_save_to_stream
(struct cork_stream_consumer *stream, const struct ip_map *map)¶ Saves an IP map into a libcork stream consumer. If there are any errors writing the map, we return
-1
and fill in a libcork error condition.
-
struct ip_map *
ipmap_load
(FILE *stream)¶ Loads an IP map from stream. You’re responsible for opening stream before calling this function, and for closing stream afterwards. If there are any errors reading the map, we return
NULL
and fill in a libcork error condition. You must useipmap_free()
to free the map when you’re done with it.