+
+subnet_t *lookup_subnet(node_t *owner, subnet_t *subnet)
+{
+ cp();
+ return avl_search(owner->subnet_tree, subnet);
+}
+
+subnet_t *lookup_subnet_mac(mac_t *address)
+{
+ subnet_t subnet, *p;
+ cp();
+ subnet.type = SUBNET_MAC;
+ memcpy(&subnet.net.mac.address, address, sizeof(mac_t));
+ subnet.owner = NULL;
+
+ p = (subnet_t *)avl_search(subnet_tree, &subnet);
+ cp();
+ return p;
+}
+
+subnet_t *lookup_subnet_ipv4(ipv4_t *address)
+{
+ subnet_t subnet, *p;
+ cp();
+ subnet.type = SUBNET_IPV4;
+ memcpy(&subnet.net.ipv4.address, address, sizeof(ipv4_t));
+ subnet.net.ipv4.prefixlength = 32;
+ subnet.owner = NULL;
+
+ do
+ {
+ /* Go find subnet */
+
+ p = (subnet_t *)avl_search_closest_smaller(subnet_tree, &subnet);
+
+ /* Check if the found subnet REALLY matches */
+ cp();
+ if(p)
+ {
+ if(p->type != SUBNET_IPV4)
+ {
+ p = NULL;
+ break;
+ }
+
+ if (!maskcmp(address, &p->net.ipv4.address, p->net.ipv4.prefixlength, sizeof(ipv4_t)))
+ break;
+ else
+ {
+ /* Otherwise, see if there is a bigger enclosing subnet */
+
+ subnet.net.ipv4.prefixlength = p->net.ipv4.prefixlength - 1;
+ maskcpy(&subnet.net.ipv4.address, &p->net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof(ipv4_t));
+ }
+ }
+ } while (p);
+ cp();
+ return p;
+}
+
+subnet_t *lookup_subnet_ipv6(ipv6_t *address)
+{
+ subnet_t subnet, *p;
+ cp();
+ subnet.type = SUBNET_IPV6;
+ memcpy(&subnet.net.ipv6.address, address, sizeof(ipv6_t));
+ subnet.net.ipv6.prefixlength = 128;
+ subnet.owner = NULL;
+
+ do
+ {
+ /* Go find subnet */
+
+ p = (subnet_t *)avl_search_closest_smaller(subnet_tree, &subnet);
+
+ /* Check if the found subnet REALLY matches */
+
+ cp();
+ if(p)
+ {
+ if(p->type != SUBNET_IPV6)
+ return NULL;
+
+ if (!maskcmp(address, &p->net.ipv6.address, p->net.ipv6.prefixlength, sizeof(ipv6_t)))
+ break;
+ else
+ {
+ /* Otherwise, see if there is a bigger enclosing subnet */
+
+ subnet.net.ipv6.prefixlength = p->net.ipv6.prefixlength - 1;
+ maskcpy(&subnet.net.ipv6.address, &p->net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof(ipv6_t));
+ }
+ }
+ } while (p);
+ cp();
+ return p;
+}
+
+void dump_subnets(void)
+{
+ char *netstr;
+ subnet_t *subnet;
+ avl_node_t *node;
+ cp();
+ syslog(LOG_DEBUG, _("Subnet list:"));
+ for(node = subnet_tree->head; node; node = node->next)
+ {
+ subnet = (subnet_t *)node->data;
+ netstr = net2str(subnet);
+ syslog(LOG_DEBUG, _(" %s owner %s"), netstr, subnet->owner->name);
+ free(netstr);
+ }
+ syslog(LOG_DEBUG, _("End of subnet list."));
+ cp();
+}