The functions in this section allow you to work with sets of IP addresses. IP sets work seamlessly with both IPv4 and IPv6 addresses.
Note
Before using any of the IP set functions, you must initialize this library using the following function.
Initializes the IP set library. This function must be called before any other function in the library. It is safe to call this function multiple times, and from multiple threads.
A set of IP addresses. The fields of this struct are opaque; you should only use the public library functions to access the contents of the set.
There are two ways that you can work with IP sets. The first is that you can allocate the space for the ip_set instance yourself — for instance, directly on the stack. The second is to let the IP set library allocate the space for you. Your choice determines which of the following functions you will use to create and free your IP sets.
Creates a new IP set. The init variant should be used if you’ve allocated space for the set yourself. The new variant should be used if you want the library to allocate the space for you. (The new variant never returns NULL; it will abort the program if the allocation fails.) In both cases, the set starts off empty.
Finalizes an IP set. The done variant must be used if you created the set using ipset_init(); the free variant must be used if you created the set using ipset_new().
We provide a variety of functions for adding and removing addresses from an IP set.
Adds a single IP address to set. If the IP address was not already in the set, we return true; otherwise we return false. (In other words, we return whether the set changed as a result of this operation.)
Removes a single IP removeress from set. If the IP address was previously in the set, we return true; otherwise we return false. (In other words, we return whether the set changed as a result of this operation.)
Adds an entire CIDR network of IP addresses to set. ip is one of the addresses in the set; 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.
We return whether the set changed as a result of this operation; if we return true, than at least one of the address in the CIDR network was not already present in set. We cannot currently distinguish whether all of the addresses were missing (and therefore added).
Removes an entire CIDR network of IP addresses from set. ip is one of the addresses in the set; 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.
We return whether the set changed as a result of this operation; if we return true, than at least one of the address in the CIDR network was present in set. We cannot currently distinguish whether all of the addresses were present (and therefore removed).
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 set to 0. We do not enforce this, however.
Returns whether set contains ip.
In addition to querying individual addresses, you can iterate through the entire contents of an IP set. There are two iterator functions; one that provides every individual IP address, and one that collapses addresses into CIDR networks as much as possible, and returns those networks.
Note
You should not modify an IP set while you’re actively iterating through its contents; if you do this, you’ll get undefined behavior.
An iterator object that lets you query all of the addresses in an IP set.
If iterating through individual addresses, this contains the address that the iterator currently points at. If iterating through CIDR networks, this is the representative address of the current network.
If iterating through CIDR networks, this is the CIDR prefix of the current network. If iterating through individual IP addresses, this will always be 32 or 128, depending on whether addr contains an IPv4 or IPv6 address.
If desired_value is true, then we return an iterator that will produce the IP addresses that are present in set. If it’s false, then the iterator will produce the IP addresses that are not in set.
The _networks variant will summarize the IP addresses into CIDR networks, to reduce the number of items that are reported by the iterator. (This can be especially useful (necessary?) if your set contains any /8 or /16 IPv4 networks, for instance; or even worse, a /64 IPv6 network.)
Advance iterator to the next IP address or network in its underlying set.
Frees an IP set iterator.
The functions in this section allow you to store IP sets 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 sets 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; sets 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.)
Saves an IP set into stream. You’re responsible for opening stream before calling this function, and for closing stream afterwards. If there are any errors writing the set, we return -1 and fill in a libcork error condition.
Saves an IP set into a libcork stream consumer. If there are any errors writing the set, we return -1 and fill in a libcork error condition.
Loads an IP set from stream. You’re responsible for opening stream before calling this function, and for closing stream afterwards. If there are any errors reading the set, we return NULL and fill in a libcork error condition. You must use ipset_free() to free the set when you’re done with it.
Produces a GraphViz dot representation of the BDD graph used to store set, and writes this graph representation to stream. You’re responsible for opening stream before calling this function, and for closing stream afterwards. If there are any errors writing the set, we return -1 and fill in a libcork error condition.