static G_GNUC_HOT int iprange_net4_cmp(const void *p, const void *q) { const struct iprange_net4 *a = p, *b = q; uint32 mask, a_key, b_key; mask = cidr_to_netmask(a->bits) & cidr_to_netmask(b->bits); a_key = a->ip & mask; b_key = b->ip & mask; return CMP(a_key, b_key); }
/** * Add CIDR IPv4 network to the database. * * @param db the IP range database * @param net the IPv4 network prefix * @param bits the amount of bits in the network prefix * @param value value associated to this IP network (must be non-zero) * * @return IPR_ERR_OK if successful, an error code otherwise. */ iprange_err_t iprange_add_cidr(struct iprange_db *idb, uint32 net, unsigned bits, uint16 value) { struct iprange_net4 item; uint32 mask; iprange_db_check(idb); g_assert(value != 0); g_return_val_if_fail(bits > 0, IPR_ERR_BAD_PREFIX); g_return_val_if_fail(bits <= 32, IPR_ERR_BAD_PREFIX); item.ip = net; item.value = value; item.bits = bits; mask = cidr_to_netmask(bits); if ((item.ip & mask) != item.ip) { return IPR_ERR_BAD_PREFIX; } else { sorted_array_add(idb->tab4, &item); idb->tab4_unsorted = TRUE; return IPR_ERR_OK; } }
/** * Retrieve value associated with an IPv4 address, i.e. that of the range * containing it. * * @param db the IP range database * @param ip the IPv4 address to lookup * @return The data associated with the IPv address or NULL if not found. */ void * iprange_get(const struct iprange_db *idb, guint32 ip) { struct iprange_net key, *item; iprange_db_check(idb); key.ip = ip; key.mask = cidr_to_netmask(32); item = sorted_array_lookup(idb->tab, &key); return item ? item->value : NULL; }
/** * Add CIDR network to the database. * * @param db the IP range database * @param net the network prefix * @param bits the amount of bits in the network prefix * @param value value associated to this IP network * * @return IPR_ERR_OK if successful, an error code otherwise. */ iprange_err_t iprange_add_cidr(struct iprange_db *idb, guint32 net, guint bits, void *value) { struct iprange_net item; iprange_db_check(idb); g_return_val_if_fail(bits > 0, IPR_ERR_BAD_PREFIX); g_return_val_if_fail(bits <= 32, IPR_ERR_BAD_PREFIX); item.ip = net; item.mask = cidr_to_netmask(bits); item.value = value; if ((item.ip & item.mask) != item.ip) { return IPR_ERR_BAD_PREFIX; } else { sorted_array_add(idb->tab, &item); return IPR_ERR_OK; } }