Beispiel #1
0
/**
 * uses rbwalk to check to see if a given ip address of a given type in the
 * tree is inside any of the cidrdata
 */
static int
tree_checkincidr(tcpr_data_tree_t *treeroot, tcpr_buildcidr_t * bcdata)
{
    tcpr_tree_t *node = NULL;
    tcpprep_opt_t *options = tcpprep->options;


    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 0;

        /*
         * in cases of leaves and last visit add to cidrdata if
         * necessary
         */
        if (node->family == AF_INET && check_ip_cidr(options->cidrdata, node->u.ip))    /* if we exist, abort */
            return 1;
        if (node->family == AF_INET6 && check_ip6_cidr(options->cidrdata, &node->u.ip6))
            return 1;

    }
    return 0;
}
Beispiel #2
0
/**
 * compare the source/destination IP address according to the mode
 * and return 1 if we should send the packet or 0 if not
 */
int
process_xX_by_cidr_ipv4(int mode, tcpr_cidr_t * cidr, ipv4_hdr_t * ip_hdr)
{

    if (mode & xXExclude) {
        /* Exclude mode */
        switch (mode ^ xXExclude) {
        case xXSource:
            /* note: check_ip_cidr() returns TCPR_DIR_C2S for true, TCPR_DIR_S2C for false 
             * and NOT true/false or 1/0, etc!
             */
            return check_ip_cidr(cidr, ip_hdr->ip_src.s_addr) ? DONT_SEND : SEND;
            break;

        case xXDest:
            return check_ip_cidr(cidr, ip_hdr->ip_dst.s_addr)  ? DONT_SEND : SEND;

        case xXBoth:
            return (check_ip_cidr(cidr, ip_hdr->ip_dst.s_addr)  &&
                    check_ip_cidr(cidr, ip_hdr->ip_src.s_addr) ) ? DONT_SEND : SEND;
            break;

        case xXEither:
            return (check_ip_cidr(cidr, ip_hdr->ip_dst.s_addr)  ||
                    check_ip_cidr(cidr, ip_hdr->ip_src.s_addr) ) ? DONT_SEND : SEND;
            break;
        }
    }
    else {
        /* Include Mode */
        switch (mode) {
        case xXSource:
            return check_ip_cidr(cidr, ip_hdr->ip_src.s_addr)  ? SEND : DONT_SEND;
            break;

        case xXDest:
            return check_ip_cidr(cidr, ip_hdr->ip_dst.s_addr)  ? SEND : DONT_SEND;
            break;

        case xXBoth:
            return (check_ip_cidr(cidr, ip_hdr->ip_dst.s_addr)  &&
                    check_ip_cidr(cidr, ip_hdr->ip_src.s_addr) ) ? SEND : DONT_SEND;
            break;

        case xXEither:
            return (check_ip_cidr(cidr, ip_hdr->ip_dst.s_addr)  ||
                    check_ip_cidr(cidr, ip_hdr->ip_src.s_addr) ) ? SEND : DONT_SEND;
            break;
        }
    }

    /* total failure */
    if (mode &xXExclude) {
        warn("Unable to determine action in CIDR filter mode.  Default: Don't Send.");
        return DONT_SEND;
    } else {
        warn("Unable to determine action in CIDR filter mode.  Default: Send.");
        return SEND;
    }

}
Beispiel #3
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);
            }
        }
    }
}