Exemple #1
0
/**
 * calculates wether each node in the tree is a client, server, or unknown for each node in the tree
 */
void
tree_calculate(tcpr_data_tree_t *treeroot)
{
    tcpr_tree_t *node;
    tcpprep_opt_t *options = tcpprep->options;

    dbg(1, "Running tree_calculate()");

    RB_FOREACH(node, tcpr_data_tree_s, treeroot) {
        dbgx(4, "Processing %s", get_addr2name4(node->u.ip, RESOLVE));
        if ((node->server_cnt > 0) || (node->client_cnt > 0)) {
            /* type based on: server >= (client*ratio) */
            if ((double)node->server_cnt >= (double)node->client_cnt * options->ratio) {
                node->type = DIR_SERVER;
                dbgx(3, "Setting %s to server", 
                        get_addr2name4(node->u.ip, RESOLVE));
            }
            else {
                node->type = DIR_CLIENT;
                dbgx(3, "Setting %s to client", 
                        get_addr2name4(node->u.ip, RESOLVE));
            }
        }
        else {                  /* IP had no client or server connections */
            node->type = DIR_UNKNOWN;
            dbgx(3, "Setting %s to unknown", 
                    get_addr2name4(node->u.ip, RESOLVE));
        }
    }
Exemple #2
0
/**
 * \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;
    }
}
Exemple #3
0
/**
 * adds an entry to the tree (phase 1 of auto mode).  We add each host
 * to the tree if it doesn't yet exist.  We go through and track:
 * - number of times each host acts as a client or server
 * - the way the host acted the first time we saw it (client or server)
 */
void
add_tree_ipv4(const unsigned long ip, const u_char * data)
{
    tcpr_tree_t *newnode = NULL;
    assert(data);

    newnode = packet2tree(data);

    assert(ip == newnode->u.ip);

    if (newnode->type == DIR_UNKNOWN) {
        /* couldn't figure out if packet was client or server */

        dbgx(2, "%s (%lu) unknown client/server",
            get_addr2name4(newnode->u.ip, RESOLVE), newnode->u.ip);

    }
    add_tree_node(newnode);
}
Exemple #4
0
/**
 * takes in an IP and masklen, and returns a string in
 * cidr format: x.x.x.x/y.  This malloc's memory.
 */
u_char *
ip2cidr(const unsigned long ip, const int masklen)
{
    u_char *network;
    char mask[3];

    network = (u_char *)safe_malloc(20);

    strlcpy((char *)network, (char *)get_addr2name4(ip, RESOLVE), 20);

    strcat((char *)network, "/");
    if (masklen < 10) {
        snprintf(mask, 1, "%d", masklen);
        strncat((char *)network, mask, 1);
    } else {
        snprintf(mask, 2, "%d", masklen);
        strncat((char *)network, mask, 2);
    }

    return (network);
}
Exemple #5
0
/**
 * 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);
            }
        }
    }
}
Exemple #6
0
/**
 * Checks to see if an IP is client or server by finding it in the tree
 * returns TCPR_DIR_C2S or TCPR_DIR_S2C or -1 on error
 * if mode = UNKNOWN, then abort on unknowns
 * if mode = CLIENT, then unknowns become clients
 * if mode = SERVER, then unknowns become servers
 */
tcpr_dir_t
check_ip_tree(const int mode, const unsigned long ip)
{
    tcpr_tree_t *node = NULL, *finder = NULL;

    finder = new_tree();
    finder->family = AF_INET;
    finder->u.ip = ip;

    node = RB_FIND(tcpr_data_tree_s, &treeroot, finder);

    if (node == NULL && mode == DIR_UNKNOWN)
        errx(-1, "%s (%lu) is an unknown system... aborting.!\n"
             "Try a different auto mode (-n router|client|server)",
             get_addr2name4(ip, RESOLVE), ip);

#ifdef DEBUG
    switch (node->type) {
    case DIR_SERVER:
        dbgx(1, "DIR_SERVER: %s", get_addr2name4(ip, RESOLVE));
        break;
    case DIR_CLIENT:
        dbgx(1, "DIR_CLIENT: %s", get_addr2name4(ip, RESOLVE));
        break;
    case DIR_UNKNOWN:
        dbgx(1, "DIR_UNKNOWN: %s", get_addr2name4(ip, RESOLVE));
        break;
    case DIR_ANY:
        dbgx(1, "DIR_ANY: %s", get_addr2name4(ip, RESOLVE));
        break;
    }
#endif

    /* 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_S2C;
            break;
        case DIR_CLIENT:
            return TCPR_DIR_C2S;
            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_addr2name4(ip, RESOLVE), node->type);
        }
    }
    
    return_unknown:
    switch (mode) {
    case DIR_SERVER:
        return TCPR_DIR_S2C;
        break;
    case DIR_CLIENT:
        return TCPR_DIR_C2S;
        break;
    default:
        return -1;
    }
}