⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snort_stream5_session.c

📁 入侵检测SNORT.最近更新的基于网络检测的IDS.希望能给大家带来方便.
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (hnode && hnode->data)    {        /* This is a unique hnode, since the sfxhash finds the         * same key before returning this node.         */        returned = (Stream5LWSession *)hnode->data;    }    return returned;}void FreeLWApplicationData(Stream5LWSession *ssn){    Stream5AppData *tmpData, *appData = ssn->appDataList;    while (appData)    {        if (appData->freeFunc && appData->dataPointer)        {            appData->freeFunc(appData->dataPointer);        }        tmpData = appData->next;        free(appData);        appData = tmpData;    }    ssn->appDataList = NULL;}int RemoveLWSession(Stream5SessionCache *sessionCache, Stream5LWSession *ssn){    mempool_free(&s5FlowMempool, ssn->flowdata);    ssn->flowdata = NULL;    return sfxhash_remove(sessionCache->hashTable, &(ssn->key));}int DeleteLWSession(Stream5SessionCache *sessionCache,                   Stream5LWSession *ssn, char *delete_reason){    int ret;    /* Save the current mem in use before pruning */    u_int32_t old_mem_in_use = s5_global_config.mem_in_use;    /* And save some info on that session */#ifdef SUP_IP6    sfip_t client_ip;    sfip_t server_ip;#else    struct in_addr client_ip;    struct in_addr server_ip;#endif    u_int16_t client_port = ntohs(ssn->client_port);    u_int16_t server_port = ntohs(ssn->server_port);    u_int16_t lw_session_state = ssn->session_state;    u_int32_t lw_session_flags = ssn->session_flags;#ifdef TARGET_BASED    int16_t app_proto_id = ssn->application_protocol;#endif#ifdef SUP_IP6    sfip_set_ip(&client_ip, &ssn->client_ip);    sfip_set_ip(&server_ip, &ssn->server_ip);#else    client_ip.s_addr = ssn->client_ip;    server_ip.s_addr = ssn->server_ip;#endif    /*      * Call callback to cleanup the protocol (TCP/UDP/ICMP)     * specific session details     */    if (sessionCache->cleanup_fcn)        sessionCache->cleanup_fcn(ssn);    FreeLWApplicationData(ssn);    ret = RemoveLWSession(sessionCache, ssn);    /* If we're pruning and we clobbered some large amount, log a     * message about that session. */    if (s5_global_config.prune_log_max &&        ((old_mem_in_use - s5_global_config.mem_in_use ) >            s5_global_config.prune_log_max))    {        char *client_ip_str, *server_ip_str;#ifdef SUP_IP6        client_ip_str = SnortStrdup(inet_ntoa(&client_ip));        server_ip_str = SnortStrdup(inet_ntoa(&server_ip));#else        client_ip_str = SnortStrdup(inet_ntoa(client_ip));        server_ip_str = SnortStrdup(inet_ntoa(server_ip));#endif        LogMessage("S5: Pruned session from cache that was "                   "using %d bytes (%s). %s %d --> %s %d "#ifdef TARGET_BASED                   "(%d) "#endif                   ": LWstate 0x%x LWFlags 0x%x\n",                   old_mem_in_use - s5_global_config.mem_in_use,                   delete_reason,                   client_ip_str, client_port,                   server_ip_str, server_port,#ifdef TARGET_BASED                   app_proto_id,#endif                   lw_session_state, lw_session_flags);        free(client_ip_str);        free(server_ip_str);    }    return ret;}int PurgeLWSessionCache(Stream5SessionCache *sessionCache){    int retCount = 0;    Stream5LWSession *idx;    SFXHASH_NODE *hnode;    if (!sessionCache)        return 0;    /* Remove all sessions from the hash table. */    hnode = sfxhash_mru_node(sessionCache->hashTable);    while (hnode)    {        idx = (Stream5LWSession *)hnode->data;        if (!idx)        {            sfxhash_free_node(sessionCache->hashTable, hnode);        }        else        {            idx->session_flags |= SSNFLAG_PRUNED;            DeleteLWSession(sessionCache, idx, "purge whole cache");        }        hnode = sfxhash_mru_node(sessionCache->hashTable);        retCount++;    }    return retCount;}int DeleteLWSessionCache(Stream5SessionCache *sessionCache){    int retCount = 0;    if (!sessionCache)        return 0;    retCount = PurgeLWSessionCache(sessionCache);    sfxhash_delete(sessionCache->hashTable);    free(sessionCache);    return retCount;}int PruneLWSessionCache(Stream5SessionCache *sessionCache,                   u_int32_t thetime,                   Stream5LWSession *save_me,                   int memCheck){    Stream5LWSession *idx;    u_int32_t pruned = 0;    if (thetime != 0)    {        /* Pruning, look for sessions that have time'd out */        char got_one;        idx = (Stream5LWSession *) sfxhash_lru(sessionCache->hashTable);        if(idx == NULL)        {            return 0;        }        do        {            got_one = 0;                        if(idx == save_me)            {                SFXHASH_NODE *lastNode = sfxhash_lru_node(sessionCache->hashTable);                sfxhash_gmovetofront(sessionCache->hashTable, lastNode);                lastNode = sfxhash_lru_node(sessionCache->hashTable);                if ((lastNode) && (lastNode->data != idx))                {                    idx = (Stream5LWSession *)lastNode->data;                    continue;                }                else                {                    return pruned;                }            }            if((idx->last_data_seen+sessionCache->timeout) < thetime)            {                Stream5LWSession *savidx = idx;                if(sfxhash_count(sessionCache->hashTable) > 1)                {                    DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "pruning stale session\n"););                    savidx->session_flags |= SSNFLAG_TIMEDOUT;                    DeleteLWSession(sessionCache, savidx, "stale/timeout");                    idx = (Stream5LWSession *) sfxhash_lru(sessionCache->hashTable);                    pruned++;                    got_one = 1;                }                else                {                    savidx->session_flags |= SSNFLAG_TIMEDOUT;                    DeleteLWSession(sessionCache, savidx, "stale/timeout/last ssn");                    pruned++;                    return pruned;                }            }            else            {                return pruned;            }            if (pruned > sessionCache->cleanup_sessions)            {                /* Don't bother cleaning more than 'n' at a time */                break;            }        } while ((idx != NULL) && (got_one == 1));        return pruned;    }    else    {        /* Free up 'n' sessions at a time until we get under the         * memcap or free enough sessions to be able to create         * new ones.         */         unsigned int session_count;#define s5_sessions_in_table() \     ((session_count = sfxhash_count(sessionCache->hashTable)) > 1)#define s5_over_session_limit() \     (session_count > (sessionCache->max_sessions - sessionCache->cleanup_sessions))#define s5_havent_pruned_yet() \     (pruned == 0)#define s5_over_memcap() \     (s5_global_config.mem_in_use > s5_global_config.memcap)        while (s5_sessions_in_table() &&               ((!memCheck && (s5_over_session_limit() || s5_havent_pruned_yet())) ||               (memCheck && s5_over_memcap() )))        {            unsigned int i;            DEBUG_WRAP(                DebugMessage(DEBUG_STREAM,                    "S5: Pruning session cache by %d ssns for %s: %d/%d\n",                    sessionCache->cleanup_sessions,                    memCheck ? "memcap" : "hash limit",                    s5_global_config.mem_in_use,                     s5_global_config.memcap););                        idx = (Stream5LWSession *) sfxhash_lru(sessionCache->hashTable);            for (i=0;i<sessionCache->cleanup_sessions &&                      (sfxhash_count(sessionCache->hashTable) >= 1); i++)            {                if(idx != save_me)                {                    idx->session_flags |= SSNFLAG_PRUNED;                    DeleteLWSession(sessionCache, idx, memCheck ? "memcap/check" : "memcap/stale");                    pruned++;                    idx = (Stream5LWSession *) sfxhash_lru(sessionCache->hashTable);                }                else                {                    SFXHASH_NODE *lastNode = sfxhash_lru_node(sessionCache->hashTable);                    sfxhash_gmovetofront(sessionCache->hashTable, lastNode);                    lastNode = sfxhash_lru_node(sessionCache->hashTable);                    if ((lastNode) && (lastNode->data == idx))                    {                        /* Okay, this session is the only one left */                        break;                    }                    idx = (Stream5LWSession *) sfxhash_lru(sessionCache->hashTable);                    i--; /* Didn't clean this one */                }            }            /* Nothing (or the one we're working with) in table, couldn't              * kill it */            if (!memCheck && (pruned == 0))            {                break;            }        }    }    if (memCheck && pruned)    {        LogMessage("S5: Pruned %d sessions from cache for memcap. %d ssns remain.  memcap: %d/%d\n",            pruned, sfxhash_count(sessionCache->hashTable),            s5_global_config.mem_in_use,             s5_global_config.memcap);        DEBUG_WRAP(            if (sfxhash_count(sessionCache->hashTable) == 1)            {                DebugMessage(DEBUG_STREAM, "S5: Pruned, one session remains\n");            }        );    }    return pruned;}Stream5LWSession *NewLWSession(Stream5SessionCache *sessionCache, Packet *p, SessionKey *key){    Stream5LWSession *retSsn = NULL;    SFXHASH_NODE *hnode;    StreamFlowData *flowdata;    hnode = sfxhash_get_node(sessionCache->hashTable, key);    if (!hnode)    {        DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "HashTable full, clean it\n"););        if (!PruneLWSessionCache(sessionCache, p->pkth->ts.tv_sec, NULL, 0))        {            DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "HashTable full, no timeouts, clean it\n"););            PruneLWSessionCache(sessionCache, 0, NULL, 0);        }        /* Should have some freed nodes now */        hnode = sfxhash_get_node(sessionCache->hashTable, key);#ifdef DEBUG        if (!hnode)        {            DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "Problem, no freed nodes\n"););        }#endif    }    if (hnode && hnode->data)    {        retSsn = hnode->data;        /* Zero everything out */        memset(retSsn, 0, sizeof(Stream5LWSession));        /* Save the session key for future use */        memcpy(&(retSsn->key), key, sizeof(SessionKey));                retSsn->protocol = key->protocol;        retSsn->last_data_seen = p->pkth->ts.tv_sec;        retSsn->flowdata = mempool_alloc(&s5FlowMempool);        flowdata = retSsn->flowdata->data;        boInitStaticBITOP(&(flowdata->boFlowbits), giFlowbitSize,                flowdata->flowb);    }    return retSsn;}u_int32_t HashFunc(SFHASHFCN *p, unsigned char *d, int n) {    u_int32_t a,b,c;#ifdef MPLS    u_int32_t tmp = 0;#endif    #ifdef SUP_IP6    a = *(u_int32_t*)d;         /* IPv6 lo[0] */    b = *(u_int32_t*)(d+4);     /* IPv6 lo[1] */    c = *(u_int32_t*)(d+8);     /* IPv6 lo[2] */    mix(a,b,c);    a += *(u_int32_t*)(d+12);   /* IPv6 lo[3] */    b += *(u_int32_t*)(d+16);   /* IPv6 hi[0] */    c += *(u_int32_t*)(d+20);   /* IPv6 hi[1] */    mix(a,b,c);    a += *(u_int32_t*)(d+24);   /* IPv6 hi[2] */    b += *(u_int32_t*)(d+28);   /* IPv6 hi[3] */    c += *(u_int32_t*)(d+32);   /* port lo & port hi */    mix(a,b,c);    a += *(u_int32_t*)(d+36);   /* vlan, protocol, & pad */#ifdef MPLS    tmp = *(u_int32_t *)(d+40);    if( tmp )    {        b += tmp;   /* mpls label */    }    mix(a,b,c);#endif#else    a = *(u_int32_t*)d;         /* IPv4 lo */    b = *(u_int32_t*)(d+4);     /* IPv4 hi */    c = *(u_int32_t*)(d+8);     /* port lo & port hi */    mix(a,b,c);    a += *(u_int32_t*)(d+12);   /* vlan, protocol, & pad */#ifdef MPLS    tmp = *(u_int32_t *)(d+16);    if( tmp )    {        b += tmp;   /* mpls label */    }    mix(a,b,c);#endif#endif    final(a,b,c);    return c;}    int HashKeyCmp(const void *s1, const void *s2, size_t n) {    UINT64 *a,*b;    a = (UINT64*)s1;    b = (UINT64*)s2;    if(*a - *b) return 1;       /* Compares IPv4 lo/hi */                                /* SUP_IP6 Compares IPv6 low[0,1] */    a++;    b++;    if(*a - *b) return 1;       /* Compares port lo/hi, vlan, protocol, pad */                                /* SUP_IP6 Compares IPv6 low[2,3] */#ifdef SUP_IP6    a++;    b++;    if(*a - *b) return 1;       /* SUP_IP6 Compares IPv6 hi[0,1] */    a++;    b++;    if(*a - *b) return 1;       /* SUP_IP6 Compares IPv6 hi[2,3] */    a++;    b++;    if(*a - *b) return 1;       /* SUP_IP6 Compares port lo/hi, vlan, protocol, pad */#endif#ifdef MPLS    a++;    b++;    if(*a - *b) return 1;       /* mpls label and pad */                               #endif        return 0;}Stream5SessionCache *InitLWSessionCache(int max_sessions,                                        u_int32_t session_timeout,                                        u_int32_t cleanup_sessions,                                        u_int32_t cleanup_percent,                                        Stream5SessionCleanup cleanup_fcn){    Stream5SessionCache *sessionCache = NULL;    /* Rule of thumb, size should be 1.4 times max to avoid     * collisions.     */    int hashTableSize = max_sessions;//    int hashTableSize = sfxhash_calcrows((int) (max_sessions * 1.4));    /* Memory required for 1 node: LW Session + Session Key +     * Node + NodePtr.     */    //int maxSessionMem = max_sessions * (    //                        sizeof(Stream5LWSession) +    //                        sizeof(SFXHASH_NODE) +    //                        sizeof(SessionKey) +    //                        sizeof(SFXHASH_NODE *));    /* Memory required for table entries */    //int tableMem = (hashTableSize +1) * sizeof(SFXHASH_NODE*);    sessionCache = SnortAlloc(sizeof(Stream5SessionCache));    if (sessionCache)    {        sessionCache->timeout = session_timeout;        sessionCache->max_sessions = max_sessions;        if (cleanup_percent)        {            sessionCache->cleanup_sessions = max_sessions * cleanup_percent/100;        }        else        {            sessionCache->cleanup_sessions = cleanup_sessions;        }        if (sessionCache->cleanup_sessions == 0)        {            sessionCache->cleanup_sessions = 1;        }        sessionCache->cleanup_fcn = cleanup_fcn;        /* Okay, now create the table */        sessionCache->hashTable = sfxhash_new(            hashTableSize,            sizeof(SessionKey),            sizeof(Stream5LWSession),            //maxSessionMem + tableMem, 0, NULL, NULL, 1);            0, 0, NULL, NULL, 1);        sfxhash_set_max_nodes(sessionCache->hashTable, max_sessions);//#ifdef SUP_IP6        sfxhash_set_keyops(sessionCache->hashTable, HashFunc, HashKeyCmp);//#endif    }    return sessionCache;}void PrintLWSessionCache(Stream5SessionCache *sessionCache){    DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "%lu sessions active\n",                             sfxhash_count(sessionCache->hashTable)););}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -