Ejemplo n.º 1
0
inline void cx_track_simd_ipv4(packetinfo *pi)
{
    connection *cxt = NULL;
    connection *head = NULL;
    uint32_t hash;

    // add to packetinfo ? dont through int32 around :)
    hash = make_hash(pi);
    cxt = bucket[hash];
    head = cxt;

    ip6v incoming;
    ip6v compare;
    VEC_FILL(incoming,
        pi->ip_src.__u6_addr.__u6_addr32[0],
        pi->ip_dst.__u6_addr.__u6_addr32[0],
        pi->s_port,
        pi->d_port);
    while (cxt != NULL) {
        VEC_FILL(compare,
        cxt->s_ip.__u6_addr.__u6_addr32[0],
        cxt->d_ip.__u6_addr.__u6_addr32[0],
        cxt->s_port,
        cxt->d_port);

        // single-instruction compare -msse2
        compare.v = __builtin_ia32_pcmpeqd128(incoming.v,compare.v);
        // same thing, really. c == v iff c ^ v == 0
        //compare.v = compare.v ^ incoming.v;

        // 64-bit compare reduce
        if(!(compare.i[0] & compare.i[1])){
            //ok
            dlog("[*] Updating src connection: %lu\n",cxt->cxid);
            cxt_update_src(cxt,pi);
            return;
        }

        // compare the other direction
        VEC_FILL(compare,
        cxt->d_ip.__u6_addr.__u6_addr32[0],
        cxt->s_ip.__u6_addr.__u6_addr32[0],
        cxt->d_port,
        cxt->s_port);

        compare.v = __builtin_ia32_pcmpeqd128(incoming.v,compare.v);
        if(!(compare.i[0] & compare.i[1])){
            dlog("[*] Updating dst connection: %lu\n",cxt->cxid);
            cxt_update_dst(cxt,pi);
            return;
        }
        cxt = cxt->next;
    }
    if (cxt == NULL) {
        cxt = (connection *) connection_alloc();
        //cxt = (connection *) calloc(1, sizeof(connection));
        if (head != NULL) {
            head->prev = cxt;
        }
        cxt = cxt_new(pi);
        dlog("[*] New connection: %lu\n",cxt->cxid);
        cxt->next = head;
        bucket[hash] = cxt;
        return;
    }
    printf("[*] Error in session tracking...\n");
    exit (1);
}
Ejemplo n.º 2
0
inline void cxt_update (packetinfo *pi, uint32_t hash)
{
    connection *cxt = NULL;
    int ret = 0;
    /* get our hash bucket and lock it */
    cxtbucket *cb = &cxt_hash[hash];

    /* see if the bucket already has a connection */
    if (cb->cxt == NULL) {
        /* no, so get a new one */
        cxt = cb->cxt = cxt_dequeue(&cxt_spare_q);
        if (cxt == NULL) {
            cxt = cb->cxt = connection_alloc();
            if (cxt == NULL) {
                return;
            }
        }
        /* these are protected by the bucket lock */
        cxt->hnext = NULL;
        cxt->hprev = NULL;

        /* got one, initialize and return */
        cxt_new(cxt,pi);
        cxt_requeue(cxt, NULL, &cxt_est_q);
        cxt->cb = cb;
        cxt_update_src(cxt, pi);
        pi->cxt = cxt;
        return;
    }

    /* ok, we have a flow in the bucket. Let's find out if it is our flow */
    cxt = cb->cxt;

    /* see if this is the flow we are looking for */
    if (pi->af == AF_INET) {
        if (CMP_CXT4(cxt, PI_IP4SRC(pi), pi->s_port, PI_IP4DST(pi), pi->d_port)) {
            cxt_update_src(cxt, pi);
            ret = 1;
        } else if (CMP_CXT4(cxt, PI_IP4DST(pi), pi->d_port, PI_IP4SRC(pi), pi->s_port)) {
            cxt_update_dst(cxt, pi);
            ret = 1;
        }
    } else if (pi->af == AF_INET6){
        if (CMP_CXT6(cxt, &PI_IP6SRC(pi), pi->s_port, &PI_IP6DST(pi), pi->d_port)) {
            cxt_update_src(cxt, pi);
            ret = 1;
        } else if (CMP_CXT6(cxt, &PI_IP6DST(pi), pi->d_port, &PI_IP6SRC(pi), pi->s_port)) {
            cxt_update_dst(cxt, pi);
            ret = 1;
        }
    }

    if (ret == 0) {
        connection *pcxt = NULL; /* previous connection */

        while (cxt != NULL) {
            pcxt = cxt; /* pf is not locked at this point */
            cxt = cxt->hnext;

            if (cxt == NULL) {
                /* get us a new one and put it and the list tail */
                cxt = pcxt->hnext = cxt_dequeue(&cxt_spare_q);
                if (cxt == NULL) {

                    cxt = cb->cxt = connection_alloc();
                    if (cxt == NULL) {
                        return;
                    }
                }

                cxt->hnext = NULL;
                cxt->hprev = pcxt;

                /* initialize and return */
                cxt_new(cxt,pi);
                cxt_requeue(cxt, NULL, &cxt_est_q);

                cxt->cb = cb;
                cxt_update_src(cxt, pi);
                pi->cxt = cxt;
                return;
            }

            if (pi->af == AF_INET) {
                if (CMP_CXT4(cxt, PI_IP4SRC(pi), pi->s_port, PI_IP4DST(pi), pi->d_port)) {
                    cxt_update_src(cxt, pi);
                    ret = 1;
                } else if (CMP_CXT4(cxt, PI_IP4DST(pi), pi->d_port, PI_IP4SRC(pi), pi->s_port)) {
                    cxt_update_dst(cxt, pi);
                    ret = 1;
                }
            } else if (pi->af == AF_INET6) {
                if (CMP_CXT6(cxt, &PI_IP6SRC(pi), pi->s_port, &PI_IP6DST(pi), pi->d_port)) {
                    cxt_update_src(cxt, pi);
                    ret = 1;
                } else if (CMP_CXT6(cxt, &PI_IP6DST(pi), pi->d_port, &PI_IP6SRC(pi), pi->s_port)) {
                    cxt_update_dst(cxt, pi);
                    ret = 1;
                }
            }
            if ( ret != 0) {
                /* we found our flow, lets put it on top of the
                 * hash list -- this rewards active flows */
                if (cxt->hnext) cxt->hnext->hprev = cxt->hprev;
                if (cxt->hprev) cxt->hprev->hnext = cxt->hnext;

                cxt->hnext = cb->cxt;
                cxt->hprev = NULL;
                cb->cxt->hprev = cxt;
                cb->cxt = cxt;

                /* found our connection */
                pi->cxt = cxt;
                return;
            }

            /* not found, try the next... */
        }
    }
    pi->cxt = cxt;
    /* The 'root' connection was our connection, return it. */
    return;
}