/** * \brief Converts the binary network address of a tcpr_cidr_t to a string */ const char * get_cidr2name(const tcpr_cidr_t *cidr_ptr, bool dnslookup) { if (cidr_ptr->family == AF_INET) { return get_addr2name4(cidr_ptr->u.network, dnslookup); } else if (cidr_ptr->family == AF_INET6) { return get_addr2name6(&cidr_ptr->u.network6, dnslookup); } else { return NULL; } }
void add_tree_ipv6(const struct tcpr_in6_addr * addr, const u_char * data) { tcpr_tree_t *newnode = NULL; assert(data); newnode = packet2tree(data); assert(ipv6_cmp(addr, &newnode->u.ip6) == 0); if (newnode->type == DIR_UNKNOWN) { /* couldn't figure out if packet was client or server */ dbgx(2, "%s unknown client/server", get_addr2name6(&newnode->u.ip6, RESOLVE)); } add_tree_node(newnode); }
/** * 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); } } } }
tcpr_dir_t check_ip6_tree(const int mode, const struct tcpr_in6_addr *addr) { tcpr_tree_t *node = NULL, *finder = NULL; finder = new_tree(); finder->family = AF_INET6; finder->u.ip6 = *addr; node = RB_FIND(tcpr_data_tree_s, &treeroot, finder); if (node == NULL && mode == DIR_UNKNOWN) errx(-1, "%s is an unknown system... aborting.!\n" "Try a different auto mode (-n router|client|server)", get_addr2name6(addr, RESOLVE)); #ifdef DEBUG switch (node->type) { case DIR_SERVER: dbgx(1, "DIR_SERVER: %s", get_addr2name6(addr, RESOLVE)); break; case DIR_CLIENT: dbgx(1, "DIR_CLIENT: %s", get_addr2name6(addr, RESOLVE)); break; case DIR_UNKNOWN: dbgx(1, "DIR_UNKNOWN: %s", get_addr2name6(addr, RESOLVE)); break; case DIR_ANY: dbgx(1, "DIR_ANY: %s", get_addr2name6(addr, RESOLVE)); break; } #endif /* * FIXME: Is this logic correct? I think this might be backwards :( */ /* return node type if we found the node, else return the default (mode) */ if (node != NULL) { switch (node->type) { case DIR_SERVER: return TCPR_DIR_C2S; break; case DIR_CLIENT: return TCPR_DIR_S2C; break; case DIR_UNKNOWN: case DIR_ANY: /* use our current mode to determine return code */ goto return_unknown; default: errx(-1, "Node for %s has invalid type: %d", get_addr2name6(addr, RESOLVE), node->type); } } return_unknown: switch (mode) { case DIR_SERVER: return TCPR_DIR_C2S; break; case DIR_CLIENT: return TCPR_DIR_S2C; break; default: return -1; } }