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

📄 spp_stream4.c

📁 著名的入侵检测系统snort的最新版本的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
void Stream4ShutdownFunction(int, void *);void Stream4CleanExitFunction(int, void *);void Stream4RestartFunction(int, void *);void PrintSessionCache();int CheckRst(Session *, int, u_int32_t, Packet *);int PruneSessionCache(u_int8_t, u_int32_t, int, Session *);void StoreStreamPkt2(Session *, Packet *, u_int32_t);void FlushStream(Stream *, Packet *, int);void InitStream4Pkt();void Stream4VerifyConfig(void);int BuildPacket(Stream *, u_int32_t, Packet *, int);int CheckPorts(u_int16_t, u_int16_t);void PortscanWatch(Session *, u_int32_t);void PortscanDeclare(Packet *);int LogStream(Stream *);void WriteSsnStats(BinStats *);void OpenStatsFile();void Stream4Init(char *);void PreprocFunction(Packet *);void PreprocRestartFunction(int);void PreprocCleanExitFunction(int);static void Stream4PrintStats(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(Session *ssn, int direction, u_int32_t pkt_seq, Packet *p);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);static StreamPacketData *RemoveSpd(Stream *s, StreamPacketData *spd);static void AddSpd(Stream *s, StreamPacketData *prev, StreamPacketData *new);static int DupSpd(Packet *p, Stream *s, StreamPacketData *left, StreamPacketData **retSpd);static StreamPacketData *SpdSeqExists(Stream *s, u_int32_t pkt_seq);/*  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);/* * Define the functions for the Stream API */static int Stream4MidStreamDropAlert() { return s4data.ms_inline_alerts; }static void Stream4UpdateDirection(                    void * ssnptr,                    char dir,                    ip_p ip,                    u_int16_t port) { }static u_int32_t Stream4GetPacketDirection(                    Packet *p) { return 0;} static void SetIgnoreChannel(                    void * ssnptr,                    Packet *p,                    char dir,                    int32_t bytes,                    int response);static int Stream4IgnoreChannel(                    ip_p srcIP,                    u_int16_t srcPort,                    ip_p dstIP,                    u_int16_t dstPort,                    char protocol,                    char direction,                    char flags);static void Stream4ResumeInspection(                    void *ssnptr,                    char dir) { }static void Stream4DropTraffic(                    void *ssnptr,                    char dir);static void Stream4DropPacket(                    Packet *p);static void Stream4SetApplicationData(                    void *ssnptr,                    u_int32_t protocol,                    void *data,                    StreamAppDataFree free_func);static void *Stream4GetApplicationData(void *, u_int32_t);static u_int32_t Stream4SetSessionFlags(void *, u_int32_t);static u_int32_t Stream4GetSessionFlags(void *);static int AlertFlushStream(Packet *);static int ForceFlushStream(Packet *);static int Stream4AddSessionAlert(void *ssnptr,                                  Packet *p,                                  u_int32_t gid,                                  u_int32_t sid);static int Stream4CheckSessionAlert(void *ssnptr,                                  Packet *p,                                  u_int32_t gid,                                  u_int32_t sid);static char Stream4SetReassembly(void *ssnptr,                                   u_int8_t flush_policy,                                   char dir,                                   char flags);static char Stream4GetReassemblyDirection(void *ssnptr);static char Stream4GetReassemblyFlushPolicy(void *ssnptr, char dir);static char Stream4IsStreamSequenced(void *ssnptr, char dir);/* Not an API function but part of the Session alert tracking */void CleanSessionAlerts(Session *ssn, Packet *flushed_pkt);static int Stream4TraverseReassembly(                    Packet *p,                    PacketIterator callback,                    void *userdata);static StreamFlowData *Stream4GetFlowData(                    Packet *p);#ifdef TARGET_BASEDstatic int16_t Stream4GetApplicationProtocolId(void *ssnptr) { return 0; }static int16_t Stream4SetApplicationProtocolId(void *ssnptr, int16_t id) { return 0; }#endifStreamAPI s4api = {    STREAM_API_VERSION4,    Stream4MidStreamDropAlert,    Stream4UpdateDirection, /* Not supporrted in Stream4 */    Stream4GetPacketDirection,  /* Not supporrted in Stream4 */    SetIgnoreChannel,    Stream4IgnoreChannel,    Stream4ResumeInspection, /* Not supported in Stream4 */    Stream4DropTraffic,    Stream4DropPacket,    Stream4SetApplicationData,    Stream4GetApplicationData,    Stream4SetSessionFlags,    Stream4GetSessionFlags,    AlertFlushStream,    ForceFlushStream,    Stream4TraverseReassembly,    Stream4AddSessionAlert,    Stream4CheckSessionAlert,    Stream4GetFlowData,    Stream4SetReassembly,    Stream4GetReassemblyDirection,    Stream4GetReassemblyFlushPolicy,    Stream4IsStreamSequenced#ifdef TARGET_BASED    ,    Stream4GetApplicationProtocolId, /* Not supported in Stream4 */    Stream4SetApplicationProtocolId /* Not supported in Stream4 */#endif            /* More to follow */};/**  * 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);}static void TraverseFunc(StreamPacketData *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 = (u_int8_t *)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 (offset < 0)        {            DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "Negative offset, not using "                        "old packet: Base: 0x%x Packet: 0x%x Offset: %d\n",                        s->base_seq, spd->seq_num, offset););            spd->chuck = SEG_FULL;            return;        }        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;        if (offset < 0)        {            /* This shouldn't happen because of the bounds check above */            DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "Negative offset, not using "                        "old packet: Base: 0x%x Packet: 0x%x Offset: %d\n",                        s->base_seq, spd->seq_num, offset););            spd->chuck = SEG_FULL;            return;        }        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 (offset < 0)        {            /* This shouldn't happen because of the bounds check above */            DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "Negative offset, not using "                        "old packet: Base: 0x%x Packet: 0x%x Offset: %d\n",                        s->base_seq, spd->seq_num, offset););            spd->chuck = SEG_FULL;            return;        }        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;    spd = s->seglist;    while(spd != NULL)    {        if(spd->chuck == SEG_FULL || SEQ_GEQ(s->last_ack,(spd->seq_num+spd->payload_size)))        {            StreamPacketData *savspd = spd;

⌨️ 快捷键说明

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