/* * used with rbwalk to walk a tree and generate CIDR * cidrdata. * is smart enough to prevent dupes. void * arg is cast to bulidcidr_type */ void tree_buildcidr(struct data_tree *treeroot, BUILDCIDR * bcdata) { struct tree_type *node = NULL; CIDR *newcidr = NULL; unsigned long network = 0; unsigned long mask = ~0; /* turn on all bits */ RB_FOREACH(node, data_tree, treeroot) { /* we only check types that are vaild */ if (bcdata->type != ANY) /* don't check if we're adding ANY */ if (bcdata->type != node->type) /* no match, exit early */ return; /* * in cases of leaves and last visit add to cidrdata if * necessary */ if (!check_ip_CIDR(cidrdata, node->ip)) { /* if we exist, abort */ newcidr = new_cidr(); newcidr->masklen = bcdata->masklen; network = node->ip & (mask << (32 - bcdata->masklen)); newcidr->network = network; add_cidr(&cidrdata, &newcidr); } } }
/** * used with rbwalk to walk a tree and generate cidr_t * cidrdata. * is smart enough to prevent dupes. void * arg is cast to bulidcidr_t */ void tree_buildcidr(tcpr_data_tree_t *treeroot, tcpr_buildcidr_t * bcdata) { tcpr_tree_t *node = NULL; tcpr_cidr_t *newcidr = NULL; unsigned long network = 0; struct tcpr_in6_addr network6; unsigned long mask = ~0; /* turn on all bits */ tcpprep_opt_t *options = tcpprep->options; int i, j, k; dbg(1, "Running: tree_buildcidr()"); RB_FOREACH(node, tcpr_data_tree_s, treeroot) { /* we only check types that are valid */ if (bcdata->type != DIR_ANY) /* don't check if we're adding ANY */ if (bcdata->type != node->type) /* no match, exit early */ return; /* * in cases of leaves and last visit add to cidrdata if * necessary. First check IPv4 */ dbgx(4, "Checking if %s exists in cidrdata...", get_addr2name4(node->u.ip, RESOLVE)); if (node->family == AF_INET) { if (! check_ip_cidr(options->cidrdata, node->u.ip)) { /* if we exist, abort */ dbgx(3, "Node %s doesn't exist... creating.", get_addr2name4(node->u.ip, RESOLVE)); newcidr = new_cidr(); newcidr->masklen = bcdata->masklen; network = node->u.ip & (mask << (32 - bcdata->masklen)); dbgx(3, "Using network: %s", get_addr2name4(network, RESOLVE)); newcidr->u.network = network; add_cidr(&options->cidrdata, &newcidr); } } /* Check IPv6 Address */ else if (node->family == AF_INET6) { if (! check_ip6_cidr(options->cidrdata, &node->u.ip6)) { /* if we exist, abort */ dbgx(3, "Node %s doesn't exist... creating.", get_addr2name6(&node->u.ip6, RESOLVE)); newcidr = new_cidr(); newcidr->masklen = bcdata->masklen; /* init each 4 quads to zero */ for (i = 0; i < 4; i++) network6.tcpr_s6_addr32[i] = 0; /* Build our mask */ j = bcdata->masklen / 8; for (i = 0; i < j; i++) network6.tcpr_s6_addr[i] = node->u.ip6.tcpr_s6_addr[i]; if ((k = bcdata->masklen % 8) != 0) { k = ~0 << (8 - k); network6.tcpr_s6_addr[j] = node->u.ip6.tcpr_s6_addr[i] & k; } dbgx(3, "Using network: %s", get_addr2name6(&network6, RESOLVE)); newcidr->u.network6 = network6; add_cidr(&options->cidrdata, &newcidr); } } } }