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

📄 spp_stream4.c

📁 Linux snort-2.4.4源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
void PreprocRestartFunction(int);void PreprocCleanExitFunction(int);static INLINE int isBetween(u_int32_t low, u_int32_t high, u_int32_t cur);static INLINE int NotForStream4(Packet *p);static INLINE int SetFinSent(Packet *p, Session *ssn, int direction);static INLINE int WithinSessionLimits(Packet *p, Stream *stream); /* helpers for dealing with session byte_counters */static INLINE void StreamSegmentSub(Stream *stream, u_int16_t sub);static INLINE void StreamSegmentAdd(Stream *stream, u_int16_t add);/*  Here is where we separate which functions will be called in the  normal case versus in the asynchronus state*/   int UpdateState(Session *, Packet *, u_int32_t); int UpdateState2(Session *, Packet *, u_int32_t); int UpdateStateAsync(Session *, Packet *, u_int32_t);static void TcpAction(Session *ssn, Packet *p, int action, int direction,                       u_int32_t pkt_seq, u_int32_t pkt_ack);static void TcpActionAsync(Session *ssn, Packet *p, int action, int direction,                            u_int32_t pkt_seq, u_int32_t pkt_ack);/**  * See if a sequence number is in range. *  * @param low base sequence number * @param high acknowledged sequence number * @param cur sequence number to check *  * @return 1 if we are between these sequence numbers, 0 otherwise */static INLINE int isBetween(u_int32_t low, u_int32_t high, u_int32_t cur){    DEBUG_WRAP(DebugMessage(DEBUG_STREAM,"(%u,%u,%u) = (low, high, cur)\n",                low,high,cur););    return (cur - low) <= (high - low);}#ifdef USE_HASH_TABLE#else /* USE_SPLAY_TREE */int GetSessionCount(){    return ubi_trCount(RootPtr);}static int CompareFunc(ubi_trItemPtr ItemPtr, ubi_trNodePtr NodePtr){    Session *nSession;    Session *iSession;     nSession = ((Session *)NodePtr);    iSession = (Session *)ItemPtr;    if(nSession->server.ip < iSession->server.ip) return 1;    else if(nSession->server.ip > iSession->server.ip) return -1;    if(nSession->client.ip < iSession->client.ip) return 1;    else if(nSession->client.ip > iSession->client.ip) return -1;            if(nSession->server.port < iSession->server.port) return 1;    else if(nSession->server.port > iSession->server.port) return -1;    if(nSession->client.port < iSession->client.port) return 1;    else if(nSession->client.port > iSession->client.port) return -1;    return 0;}#endif/**  * Check to if retransmissions are occuring too quickly *  * @param old previous timeval * @param cur current timeval *  * @return 1 if the Retransmission is too quick, 0 if it's ok */static int RetransTooFast(struct timeval *old, struct timeval *cur){    struct timeval diff;    TIMERSUB(cur, old, &diff);    /* require retransmissions wait atleast 1.1s */    if(diff.tv_sec > 1)        return 0;    else if(diff.tv_sec == 1 && diff.tv_usec > 100)        return 0;            return 1;}static int DataCompareFunc(ubi_trItemPtr ItemPtr, ubi_trNodePtr NodePtr){    StreamPacketData *nStream;    StreamPacketData *iStream;     nStream = ((StreamPacketData *)NodePtr);    iStream = ((StreamPacketData *)ItemPtr);    if(nStream->seq_num < iStream->seq_num) return 1;    else if(nStream->seq_num > iStream->seq_num) return -1;    return 0;}static int OverlapCompareFunc(ubi_trItemPtr ItemPtr, void *data){    OverlapData *overlap_info = (OverlapData *)data;    StreamPacketData *iStream;     iStream = ((StreamPacketData *)ItemPtr);    if ((iStream->seq_num > overlap_info->seq_low) &&        (iStream->seq_num < overlap_info->seq_hi))        return 1;    return 0;}static void KillSpd(ubi_trNodePtr NodePtr){    StreamPacketData *tmp;    tmp = (StreamPacketData *)NodePtr;    stream4_memory_usage -= tmp->pkt_size;    free(tmp->pktOrig);    stream4_memory_usage -= sizeof(StreamPacketData);    free(tmp);}static void TraverseFunc(ubi_trNodePtr NodePtr, void *build_data){    Stream *s;    StreamPacketData *spd;    BuildData *bd;    u_int8_t *buf;    int trunc_size;    int offset = 0;    if(s4data.stop_traverse)        return;    spd = (StreamPacketData *) NodePtr;    bd = (BuildData *) build_data;    s = bd->stream;    buf = bd->buf;    /* Don't reassemble if there's nothing to reassemble.     * The first two cases can probably never happen. I personally     * prefer strong error checking (read: paranoia).     */    if(spd->payload_size == 0)    {        DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "not reassembling because "                    "the payload size is zero.\n"););        spd->chuck = SEG_FULL;        return;    }    else if(SEQ_EQ(s->base_seq, s->last_ack))    {        DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "not reassembling because "                    "base_seq = last_ack (%u).\n", s->base_seq););        return;    }    /* Packet is completely before the current window. */    else if(SEQ_LEQ(spd->seq_num, s->base_seq) &&            SEQ_LEQ(spd->seq_num + spd->payload_size, s->base_seq))    {        /* ignore this segment, we've already looked at it */        spd->chuck = SEG_FULL;        return;    }    /* Packet starts outside the window and ends inside it. */    else if(SEQ_LT(spd->seq_num, s->base_seq) &&            isBetween(s->base_seq+1, s->last_ack, (spd->seq_num + spd->payload_size)))    {        /* case where we've got a segment that wasn't completely ack'd          * last time it was processed, do a partial copy into the buffer         */        DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "Incompleted segment, copying up "                    "to last-ack\n"););        /* calculate how much un-ack'd data to copy */        trunc_size = (spd->seq_num+spd->payload_size) - s->base_seq;        /* figure out where in the original data payload to start copying */        offset = s->base_seq - spd->seq_num;        if(trunc_size < 65500 && trunc_size > 0)        {            DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "Copying %d bytes into buffer, "                        "offset %d, buf %p\n", trunc_size, offset,                         buf););            SafeMemcpy(buf, spd->payload+offset, trunc_size,                    stream_pkt->data, stream_pkt->data + MAX_STREAM_SIZE);                        pc.rebuilt_segs++;            bd->total_size += trunc_size;        }        else        {            DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "Woah, got bad TCP segment "                        "trunctation value (%d)\n", trunc_size););        }        spd->chuck = SEG_FULL;    }    /* if it's in bounds... */    else if(isBetween(s->base_seq, s->last_ack-1, spd->seq_num) &&            isBetween(s->base_seq, s->last_ack, (spd->seq_num + spd->payload_size)))    {        offset = spd->seq_num - s->base_seq;        s->next_seq = spd->seq_num + spd->payload_size;        DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "Copying %d bytes into buffer, "                    "offset %d, buf %p\n", spd->payload_size, offset,                     buf););        DEBUG_WRAP(DebugMessage(DEBUG_STREAM,                    "spd->seq_num (%u)  s->last_ack (%u) "                    "s->base_seq(%u) size: (%u) s->next_seq(%u), "                    "offset(%u), MAX(%u)\n",                    spd->seq_num, s->last_ack, s->base_seq,                    spd->payload_size, s->next_seq, offset,                     MAX_STREAM_SIZE));        SafeMemcpy(buf+offset, spd->payload, spd->payload_size,                stream_pkt->data, stream_pkt->data + MAX_STREAM_SIZE);        pc.rebuilt_segs++;        spd->chuck = SEG_FULL;        bd->total_size += spd->payload_size;    }     else if(isBetween(s->base_seq, s->last_ack-1, spd->seq_num) &&            SEQ_GT((spd->seq_num + spd->payload_size), s->last_ack))    {        /*         *  if it starts in bounds and hasn't been completely ack'd,          *  truncate the last piece and copy it in          */        trunc_size = s->last_ack - spd->seq_num;         DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "Truncating overlap of %d bytes\n",                     spd->seq_num + spd->payload_size - s->last_ack);                DebugMessage(DEBUG_STREAM, "    => trunc info seq: 0x%X   "                    "size: %d  last_ack: 0x%X\n",                     spd->seq_num, spd->payload_size, s->last_ack);                );        offset = spd->seq_num - s->base_seq;        if(trunc_size < (65500-offset) && trunc_size > 0)        {            DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "Copying %d bytes into buffer, "                        "offset %d, buf %p\n", trunc_size, offset,                         buf););            SafeMemcpy(buf+offset, spd->payload, trunc_size,                    stream_pkt->data, stream_pkt->data + MAX_STREAM_SIZE);                        pc.rebuilt_segs++;            bd->total_size += trunc_size;            spd->chuck = SEG_PARTIAL;        }        else        {            DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "Woah, got bad TCP segment "                        "trunctation value (%d)\n", trunc_size););        }    }    else if(SEQ_GEQ(spd->seq_num,s->last_ack))    {        /* we're all done, we've walked past the end of the ACK'd data */        DEBUG_WRAP(DebugMessage(DEBUG_STREAM,                      "   => Segment is past last ack'd data, "                    "ignoring for now...\n");                DebugMessage(DEBUG_STREAM,  "        => (%d bytes @ seq 0x%X, "                    "ack: 0x%X)\n", spd->payload_size, spd->seq_num, s->last_ack);                );        /* since we're reassembling in order, once we hit an overflow condition         * let's stop trying for now         */        s4data.stop_traverse = 1;        //s4data.stop_seq = spd->seq_num;        s4data.stop_seq = s->last_ack;    }    else    {        /* The only case that should reach this point is if         * spd->seq_num < s->base_seq &&         * spd->seq_num + spd->payload_size >= s->last_ack         * Can that ever happen?         */        DEBUG_WRAP(DebugMessage(DEBUG_STREAM,                    "Ended up in the default case somehow.. !\n"                    "spd->seq_num(%u) spd->payload_size(%u)\n",                    spd->seq_num, spd->payload_size););            }} void SegmentCleanTraverse(Stream *s){    StreamPacketData *spd;    StreamPacketData *foo;    if (!s->data.root)        return;    spd = (StreamPacketData *) ubi_btFirst((ubi_btNodePtr)&s->data);    while(spd != NULL)    {        if(spd->chuck == SEG_FULL || SEQ_GEQ(s->last_ack,(spd->seq_num+spd->payload_size)))        {            StreamPacketData *savspd = spd;            spd = (StreamPacketData *) ubi_btNext((ubi_btNodePtr)spd);#ifdef DEBUG            if(savspd->chuck == SEG_FULL)            {                DebugMessage(DEBUG_STREAM, "[sct] chucking used segment\n");            }            else            {                DebugMessage(DEBUG_STREAM, "[sct] tossing unused segment\n");            }#endif /*DEBUG*/            foo = (StreamPacketData *) ubi_sptRemove(&s->data,                     (ubi_btNodePtr) savspd);            StreamSegmentSub(s, foo->payload_size);            stream4_memory_usage -= foo->pkt_size;            free(foo->pktOrig);            stream4_memory_usage -= sizeof(StreamPacketData);            free(foo);        }        else        {            spd = (StreamPacketData *) ubi_btNext((ubi_btNodePtr)spd);        }    }}/* XXX: this will be removed as we clean up the modularization */void DirectLogTcpdump(struct pcap_pkthdr *, u_int8_t *);static void LogTraverse(ubi_trNodePtr NodePtr, void *foo){    StreamPacketData *spd;    spd = (StreamPacketData *) NodePtr;    /* XXX: modularization violation */    DirectLogTcpdump((struct pcap_pkthdr *)&spd->pkth, spd->pkt); }void *SafeAlloc(unsigned long size, int tv_sec, Session *ssn){    void *tmp;    stream4_memory_usage += size;    /* if we use up all of our RAM, try to free up some stale sessions */    if(stream4_memory_usage > s4data.memcap)    {        pc.str_mem_faults++;        sfPerf.sfBase.iStreamFaults++;        if(!PruneSessionCache((u_int32_t)tv_sec, 0, ssn))        {            /* if we can't prune due to time, just nuke 5 random sessions */            PruneSessionCache(0, 5, ssn);                    }    }    tmp = (void *) calloc(size, sizeof(char));    if(tmp == NULL)    {        FatalError("Unable to allocate memory! (%lu bytes in use)\n",                    (unsigned long)stream4_memory_usage);    }    return tmp;}/* * Function: SetupStream4() * * Purpose: Registers the preprocessor keyword and initialization  *          function into the preprocessor list.  This is the function that *          gets called from InitPreprocessors() in plugbase.c. * * Arguments: None. * * Returns: void function */void SetupStream4(){    /* link the preprocessor keyword to the init function in        the preproc list */

⌨️ 快捷键说明

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