int add_detection_option(option_type_t type, void *option_data, void **existing_data)
{
    SnortConfig *sc = snort_conf_for_parsing;
    detection_option_key_t key;

    if (sc == NULL)
    {
        FatalError("%s(%d) Snort config is NULL.\n",
                   __FILE__, __LINE__);
    }

    if (sc->detection_option_hash_table == NULL)
        sc->detection_option_hash_table = DetectionHashTableNew();

    if (!option_data)
    {
        /* No option data, no conflict to resolve. */
        return DETECTION_OPTION_EQUAL;
    }

    key.option_type = type;
    key.option_data = option_data;

    *existing_data = sfxhash_find(sc->detection_option_hash_table, &key);
    if (*existing_data)
    {
        return DETECTION_OPTION_EQUAL;
    }

    sfxhash_add(sc->detection_option_hash_table, &key, option_data);
    return DETECTION_OPTION_NOT_EQUAL;
}
Beispiel #2
0
/** *
 * @param sip - source IP address
 * @param dip - destination IP address
 * @param sport - server sport number
 * @param file_sig - file signature
 * @param expiry - session expiry in seconds.
 */
int file_resume_block_add_file(void *pkt, uint32_t file_sig, uint32_t timeout,
        File_Verdict verdict, uint32_t file_type_id, uint8_t *signature)
{
    FileHashKey hashKey;
    SFXHASH_NODE *hash_node = NULL;
    FileNode *node;
    FileNode new_node;
    snort_ip_p srcIP;
    snort_ip_p dstIP;
    Packet *p = (Packet *)pkt;
    time_t now = p->pkth->ts.tv_sec;

    srcIP = GET_SRC_IP(p);
    dstIP = GET_DST_IP(p);
    IP_COPY_VALUE(hashKey.dip, dstIP);
    IP_COPY_VALUE(hashKey.sip, srcIP);
    hashKey.file_sig = file_sig;

    hash_node = sfxhash_find_node(fileHash, &hashKey);
    if (hash_node)
    {
        if (!(node = hash_node->data))
            sfxhash_free_node(fileHash, hash_node);
    }
    else
        node = NULL;
    if (node)
    {
        node->expires = now + timeout;
        updateFileNode(node, verdict, file_type_id, signature);
    }
    else
    {

        DEBUG_WRAP(DebugMessage(DEBUG_FILE, "Adding file node\n"););

        updateFileNode(&new_node, verdict, file_type_id, signature);

        /*
         * use the time that we keep files around
         * since this info would effectively be invalid
         * after that anyway because the file that
         * caused this will be gone.
         */
        new_node.expires = now + timeout;

        /* Add it to the table */
        if (sfxhash_add(fileHash, &hashKey, &new_node) != SFXHASH_OK)
        {
            /* Uh, shouldn't get here...
             * There is already a node or couldn't alloc space
             * for key.  This means bigger problems, but fail
             * gracefully.
             */
            DEBUG_WRAP(DebugMessage(DEBUG_FILE,
                    "Failed to add file node to hash table\n"););
Beispiel #3
0
int server_stats_add_ipv4(SERVER_STATS *ssp, u_int8_t ip_proto, u_int32_t address, u_int16_t port,
                          u_int32_t *retcount)
{
    SERVER_KEY *kp = &s_key;
    u_int32_t one = 1;
    u_int32_t *hitcountp = NULL;
    int ret;
#ifdef DEBUG
    u_int32_t hostaddress = ntohl(address);
#endif /* DEBUG */
    
    if(ssp == NULL || retcount == NULL)
        return FLOW_ENULL;

    /* calls to this subsystem should only be made if we are really watching this. */
    FLOWASSERT(ipset_contains(ssp->ipv4_watch, &hostaddress, IPV4_FAMILY));
    
    /* make the key */
    kp->address  = address;
    kp->port     = port;
    kp->protocol = ip_proto;
    
    /* find the key, add 1 to it or add a new node to the table */
    ret = sfxhash_add(ssp->ipv4_table, kp, &one);
    
    switch(ret)
    {
    case SFXHASH_NOMEM:
        /* NOMEM means that we would add it if we could but we're
         *  hard-core out of space.  So, just assume we added it.
         */
    case SFXHASH_OK:
        *retcount = 1;        
        break;
    case SFXHASH_INTABLE:
        hitcountp = (u_int32_t *) sfxhash_mru(ssp->ipv4_table);
        
        /* never let us wrap around to less hits */
        if(!hitcountp)
        {
            /* this is an odd error! */
            return FLOW_BADJUJU;
        }
        else
        {
            if((*hitcountp) < SERVER_STATS_MAX_HITCOUNT)
            {
                (*hitcountp)++;
            }            
        }
        break;
    }
    
    return FLOW_SUCCESS;
}
Beispiel #4
0
int scoreboard_add(SCOREBOARD *sbp, u_int32_t *address, SCORE_ENTRY **sepp)
{
    int ret;
    int hash_add_ret;
    
    if(!sbp)
    {
        return FLOW_ENULL;
    }

    hash_add_ret = sfxhash_add(sbp->ipv4_table, address, &s_init_entry);

    switch(hash_add_ret)
    {
        case SFXHASH_OK:
            if(scoreboard_mru(sbp,sepp) != FLOW_SUCCESS)
            {
                /* something's wrong because we just added this thing!\n */
                flow_printf("sba: Unable to find a key I just added!\n");
                ret = FLOW_BADJUJU;
            }
            else
            {
                ret = FLOW_SUCCESS;
            }

            break;

        case SFXHASH_NOMEM:
            ret = FLOW_ENOMEM;
            break;

        case SFXHASH_INTABLE:
        default:
            ret = FLOW_EINVALID;
            break;
    }

    return ret;    
}
Beispiel #5
0
void checkSessionForAFIndicator(SFSnortPacket *p, int dir, const tAppIdConfig *pConfig, tAppId indicator)
{
    AFElement *ind_element;
    if (!(ind_element = (AFElement*)sfxhash_find(pConfig->AF_indicators, &indicator)))
        return;

    rekeyMasterAFActKey(p, dir, ind_element->forecast);

    AFActVal *test_active_value;
    if ((test_active_value = (AFActVal*)sfxhash_find(pConfig->AF_actives, &master_key)))
    {
        test_active_value->last = GetPacketRealTime;
        test_active_value->target = ind_element->target;
        return;
    }

    AFActVal new_active_value;
    new_active_value.target = ind_element->target;
    new_active_value.last = GetPacketRealTime;

    sfxhash_add(pConfig->AF_actives, &master_key, &new_active_value);
}
Beispiel #6
0
/**
**  Get a tracker node by either finding one or starting a new one.  We may
**  return NULL, in which case we wait till the next packet.
*/
static int ps_tracker_get(PS_TRACKER **ht, PS_HASH_KEY *key)
{
    int iRet;

    *ht = (PS_TRACKER *)sfxhash_find(portscan_hash, (void *)key);
    if(!(*ht))
    {
        iRet = sfxhash_add(portscan_hash, (void *)key, NULL);
        if(iRet == SFXHASH_OK)
        {
            *ht = (PS_TRACKER *)sfxhash_mru(portscan_hash);
            if(!(*ht))
                return -1;

            ps_tracker_init(*ht);
        }
        else
        {
            return -1;
        }
    }

    return 0;
}
Beispiel #7
0
/*
 *   Test a global thresholding object
 */
static inline int sfthd_test_global(
    SFXHASH *global_hash,
    THD_NODE   * sfthd_node,
    unsigned     gen_id,     /* from current event */
    unsigned     sig_id,     /* from current event */
    snort_ip_p   sip,        /* " */
    snort_ip_p   dip,        /* " */
    time_t       curtime )
{
    THD_IP_GNODE_KEY key;
    THD_IP_NODE      data, *sfthd_ip_node;
    int              status=0;
    snort_ip_p       ip;
    tSfPolicyId policy_id = getRuntimePolicy();

#ifdef THD_DEBUG
    printf("THD_DEBUG-GLOBAL:  gen_id=%u, sig_id=%u\n",gen_id,sig_id);
    printf("THD_DEBUG: Global THD_NODE IP=%s,",printIP((unsigned)sfthd_node->ip_address) );
    printf(" MASK=%s\n",printIP((unsigned)sfthd_node->ip_mask) );
    printf("THD_DEBUG:        PKT  SIP=%s\n",printIP((unsigned)sip) );
    printf("THD_DEBUG:        PKT  DIP=%s\n",printIP((unsigned)dip) );
    fflush(stdout);
#endif

    /* -1 means don't do any limit or thresholding */
    if ( sfthd_node->count == THD_NO_THRESHOLD)
    {
#ifdef THD_DEBUG
        printf("\n...No Threshold applied for this object\n");
        fflush(stdout);
#endif
        return 0;
    }

    /* Get The correct IP */
    if (sfthd_node->tracking == THD_TRK_SRC)
       ip = sip;
    else
       ip = dip;

    /* Check for and test Suppression of this event to this IP */
    if( sfthd_node->type == THD_TYPE_SUPPRESS )
    {
#ifdef THD_DEBUG
        printf("THD_DEBUG: G-SUPPRESS NODE Testing...\n");fflush(stdout);
#endif
        return sfthd_test_suppress(sfthd_node, ip);
    }

    /*
    *  Go on and do standard thresholding
    */

    /* Set up the key */
    key.ip     = IP_VAL(ip);
    key.gen_id = sfthd_node->gen_id;
    key.sig_id = sig_id;
    key.policyId = policy_id;

    /* Set up a new data element */
    data.count  = 1;
    data.prev  = 0;
    data.tstart = data.tlast = curtime; /* Event time */

    /* Check for any Permanent sig_id objects for this gen_id  or add this one ...  */
    status = sfxhash_add(global_hash, (void*)&key, &data);
    if (status == SFXHASH_INTABLE)
    {
        /* Already in the table */
        sfthd_ip_node = global_hash->cnode->data;

        /* Increment the event count */
        sfthd_ip_node->count++;
    }
    else if (status != SFXHASH_OK)
    {
        /* hash error */
        return 1; /*  check the next threshold object */
    }
    else
    {
        /* Was not in the table - it was added - work with our copy of the data */
        sfthd_ip_node = &data;
    }

    return sfthd_test_non_suppress(sfthd_node, sfthd_ip_node, curtime);
}
Beispiel #8
0
int flowcache_newflow(FLOWCACHE *flowcachep, FLOWKEY *keyp, FLOW **flowpp)
{
    static int run_once = 1;
#ifdef FLOW_PERF_FIX
    FLOW *newflow = NULL;
    SFXHASH_NODE *new_node = NULL;
#else
    static FLOW zeroflow;
#endif
    static FLOWKEY searchkey;
    int ret;
    
    if(!flowcachep || !keyp || !flowpp)
    {
        return FLOW_ENULL;
    }

    FCS_new(flowcachep, keyp);
    
    if(run_once)
    {
        /* all the time that we're running this, we're actually going
           to be filling in the key, and having zero'd out counters */ 
#ifndef FLOW_PERF_FIX
        memset(&zeroflow, 0, sizeof(FLOW));
#endif
        memset(&searchkey, 0, sizeof(FLOWKEY));        
        run_once = 0;
    }

    flowkey_normalize(&searchkey, keyp);
   
#ifdef FLOW_PERF_FIX
    /* This just eliminates a memcpy. */
    /* Since we're using auto node recovery, we should get a node back
     * here that has a data pointer. */
    /* flow_init resets the internal key & stats to zero. */
    new_node = sfxhash_get_node(flowcachep->ipv4_table, &searchkey);
    if (new_node && new_node->data)
    {
        newflow = new_node->data;
    
        if(flow_init(newflow, keyp->protocol,
                     keyp->init_address, keyp->init_port,
                     keyp->resp_address, keyp->resp_port))
        {
            return FLOW_ENULL;
        }
        ret = SFXHASH_OK;
    }
    else
    {
        ret = SFXHASH_NOMEM;
    }
#else
    if(flow_init(&zeroflow, keyp->protocol,
                 keyp->init_address, keyp->init_port,
                 keyp->resp_address, keyp->resp_port))
    {
        return FLOW_ENULL;
    }

    ret = sfxhash_add(flowcachep->ipv4_table, &searchkey, &zeroflow);
#endif

    switch(ret)
    {
    case SFXHASH_OK:
        if(flowcache_mru(flowcachep,flowpp) != FLOW_SUCCESS)
        {
            /* something's wrong because we just added this thing!\n */
            flow_printf("Unable to find a key I just added!\n");
            return FLOW_BADJUJU;
        }

        if(init_flowdata(flowcachep, *flowpp))
        {
            return FLOW_BADJUJU;
        }

        return FLOW_SUCCESS;
        
    case SFXHASH_NOMEM:
        return FLOW_ENOMEM;

    case SFXHASH_INTABLE:
    default:
        return FLOW_EINVALID;
    }
}
Beispiel #9
0
/** 
 * load a server stats file
 *
 * fmt:
 *
 * 1 char for the family
 * hex network representation of the IP  (8 chars)
 * hex network representation of the port (2 chars)
 * 1 char for the ip_proto                (1 char)
 * hex network representation of the hit count (4 chars)
 *
 * yes this record format is hard to use but it's easy to parse! :>
 * 
 * @param ssp server stats pointer
 * @param filename filename to load
 * 
 * @return FLOW_SUCCESS on sucess
 */
int server_stats_load(SERVER_STATS *ssp, char *filename)
{
    SERVER_KEY *kp = &s_key;
    size_t rsize;
    unsigned char buf[STATSREC_SIZE];
    int fd;
    
    if(!filename || !ssp)
        return FLOW_ENULL;


    fd = open(filename, O_RDONLY);

    if(fd < 0)
    {
        return FLOW_NOTFOUND;
    }

    /* this is a crappy parser... that's par for the course */
    while((rsize = read(fd, &buf, STATSREC_SIZE) == STATSREC_SIZE) > 0)
    {
        u_int8_t  family;
        u_int32_t ipv4_address;
        u_int16_t port;
        u_int8_t  protocol;
        u_int32_t count;
        
        if(rsize != STATSREC_SIZE)
        {
            /* this record was truncated */
            close(fd);
            return FLOW_EINVALID;
        }

        memcpy(&family,       buf + FAMILY_OFFSET,   FAMILY_SIZE);
        memcpy(&ipv4_address, buf + IPV4_OFFSET,     IPV4_SIZE);       
        memcpy(&port,         buf + PORT_OFFSET,     PORT_SIZE);
        memcpy(&protocol,     buf + IP_PROTO_OFFSET, IP_PROTO_SIZE);
        memcpy(&count,        buf + COUNT_OFFSET,    COUNT_SIZE);

        /* make sure that we're reading a format we understand */
        
        if(family != '4')
        {
            close(fd);
            return FLOW_EINVALID;
        }

        kp->protocol = ntohs(protocol);
        kp->address  = ntohl(ipv4_address);
        kp->port     = ntohs(port);
        count        = ntohl(count);
        
        if(sfxhash_add(ssp->ipv4_table, kp, &count) != 0)
        {
            close(fd);
            return FLOW_BADJUJU;
        }
    }

    close(fd);
    return FLOW_SUCCESS;
}
Beispiel #10
0
/*
 *       Hash test program : use 'sfxhash 1000 50000' to stress the Auto_NodeRecover feature
 */
int main ( int argc, char ** argv )
{
    int             i;
    SFXHASH      * t;
    SFXHASH_NODE * n;
    char            strkey[256], strdata[256], * p;
    int             num = 100;
    int             mem = 0;

    memset(strkey,0,20);
    memset(strdata,0,20);

    if( argc > 1 )
    {
        num = atoi(argv[1]);
    }

    if( argc > 2 )
    {
        mem = atoi(argv[2]);
    }

    /* Create a Hash Table */
    t = sfxhash_new( 100,        /* one row per element in table, when possible */
                     20,        /* key size :  padded with zeros */ 
                     20,        /* data size:  padded with zeros */ 
                     mem,       /* max bytes,  0=no max */  
                     1,         /* enable AutoNodeRecovery */
                     anrfree,   /* provide a function to let user know we want to kill a node */
                     usrfree, /* provide a function to release user memory */
                     1);      /* Recycle nodes */
    if(!t)
    {
        printf("Low Memory!\n");
        exit(0);
    }
    /* Add Nodes to the Hash Table */
    for(i=0;i<num;i++) 
    {
        snprintf(strkey, sizeof(strkey), "KeyWord%5.5d",i+1);
        strkey[sizeof(strkey) - 1] = '\0';
        snprintf(strdata, sizeof(strdata), "KeyWord%5.5d",i+1);
        strdata[sizeof(strdata) - 1] = '\0';
        //strupr(strdata);
        sfxhash_add( t, strkey  /* user key */ ,  strdata /* user data */ );
    }  

    /* Find and Display Nodes in the Hash Table */
    printf("\n** FIND KEY TEST\n");
    for(i=0;i<num;i++) 
    {
        snprintf(strkey, sizeof(strkey) - 1, "KeyWord%5.5d",i+1);
        strkey[sizeof(strkey) - 1] = '\0';

        p = (char*) sfxhash_find( t, strkey );

        if(p)printf("Hash-key=%*s, data=%*s\n", strlen(strkey),strkey, strlen(strkey), p );
    }  

    /* Show memcap memory */
    printf("\n...******\n");
    sfmemcap_showmem(&t->mc);
    printf("...******\n");

    /* Display All Nodes in the Hash Table findfirst/findnext */
    printf("\n...FINDFIRST / FINDNEXT TEST\n");
    for( n  = sfxhash_findfirst(t); 
         n != 0; 
         n  = sfxhash_findnext(t) )
    {
        printf("hash-findfirst/next: n=%x, key=%s, data=%s\n", n, n->key, n->data );

        /*
          remove node we are looking at, this is first/next safe.
        */
        if( sfxhash_remove(t,n->key) ) 
        {
            printf("...ERROR: Could not remove the key node!\n");
        }
        else  
        {
            printf("...key node removed\n");
        }
    }

    printf("...Auto-Node-Recovery: %d recycle attempts, %d completions.\n",t->anr_tries,t->anr_count);

    /* Free the table and it's user data */
    printf("...sfxhash_delete\n");

    sfxhash_delete( t );
   
    printf("\nnormal pgm finish\n\n");

    return 0;
}
Beispiel #11
0
/** *
 * @param sip - source IP address
 * @param dip - destination IP address
 * @param sport - server sport number
 * @param file_sig - file signature
 * @param expiry - session expiry in seconds.
 */
int file_resume_block_add_file(void *pkt, uint32_t file_sig, uint32_t timeout,
        File_Verdict verdict, uint32_t file_type_id, uint8_t *signature)
{
    FileHashKey hashKey;
    SFXHASH_NODE *hash_node = NULL;
    FileNode *node;
    FileNode new_node;
    sfaddr_t* srcIP;
    sfaddr_t* dstIP;
    Packet *p = (Packet*)pkt;
    time_t now = p->pkth->ts.tv_sec;

    srcIP = GET_SRC_IP(p);
    dstIP = GET_DST_IP(p);
    sfaddr_copy_to_raw(&hashKey.dip, dstIP);
    sfaddr_copy_to_raw(&hashKey.sip, srcIP);
    hashKey.file_sig = file_sig;

#ifdef HAVE_DAQ_DP_ADD_DC
    {
        DAQ_DC_Params params;

        memset(&params, 0, sizeof(params));
        params.flags = DAQ_DC_ALLOW_MULTIPLE | DAQ_DC_PERSIST;
        params.timeout_ms = 5 * 60 * 1000; /* 5 minutes */
        if (p->packet_flags & PKT_FROM_CLIENT)
            DAQ_Add_Dynamic_Protocol_Channel(p, srcIP, 0, dstIP, p->dp, GET_IPH_PROTO(p),
                                             &params);
        else if (p->packet_flags & PKT_FROM_SERVER)
            DAQ_Add_Dynamic_Protocol_Channel(p, dstIP, 0, srcIP, p->sp, GET_IPH_PROTO(p),
                                             &params);
    }
#endif

    hash_node = sfxhash_find_node(fileHash, &hashKey);
    if (hash_node)
    {
        if (!(node = hash_node->data))
            sfxhash_free_node(fileHash, hash_node);
    }
    else
        node = NULL;
    if (node)
    {
        node->expires = now + timeout;
        updateFileNode(node, verdict, file_type_id, signature);
    }
    else
    {

        DEBUG_WRAP(DebugMessage(DEBUG_FILE, "Adding file node\n"););

        updateFileNode(&new_node, verdict, file_type_id, signature);

        /*
         * use the time that we keep files around
         * since this info would effectively be invalid
         * after that anyway because the file that
         * caused this will be gone.
         */
        new_node.expires = now + timeout;

        /* Add it to the table */
        if (sfxhash_add(fileHash, &hashKey, &new_node) != SFXHASH_OK)
        {
            /* Uh, shouldn't get here...
             * There is already a node or couldn't alloc space
             * for key.  This means bigger problems, but fail
             * gracefully.
             */
            DEBUG_WRAP(DebugMessage(DEBUG_FILE,
                    "Failed to add file node to hash table\n"););