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

📄 spp_tcp_stream.c

📁 该源码是用C语言编写的,实现网络入侵检测系统的功能
💻 C
📖 第 1 页 / 共 2 页
字号:
        if(sptr->s_buf_allocd == 1)        {            if(made_packet >= 0)            {  /* shuffle data */                for(i=made_packet; i<(int)bytes_in_buf; i++)                {                    sptr->s_buf[i-made_packet] = sptr->s_buf[i];                }                sptr->s_first_seq += made_packet;                sptr->s_last_byte -= made_packet;            }        }    }    /* Check here to see if we inject client new packet */    if(server_packet && sptr->client_status >= ESTABLISHED)    {  /* check to see if client buffer has proper data */        if(lack - sptr->c_first_seq > 0x7fffffff) bytes_in_buf = 0;        else bytes_in_buf = lack - sptr->c_first_seq;        /* shouldn't happen in a sane world */        if(bytes_in_buf > sptr->c_buf_siz)        {#ifdef DEBUG            ErrorMessage("[!] WARNING: TCP stream reassembler, Client Bytes in Buffer > Buffer Size (%i > %i)\n", bytes_in_buf, sptr->c_buf_siz);#endif            bytes_in_buf = sptr->c_buf_siz;        }        made_packet = 0;        if(bytes_in_buf >= StreamData.maxbytes)        {            TcpStreamPacketize(p, sptr->c_buf, StreamData.maxbytes, server_packet);            made_packet = StreamData.maxbytes;        }        else        {            if (!sptr->c_buf_allocd)            {#ifdef DEBUG                printf("WARNING: TCP stream reassembler never got proper window size, setting to max!\n");#endif                sptr->c_buf_siz = 65536 + StreamData.maxbytes;                sptr->c_buf = (u_char *) malloc(sptr->c_buf_siz);                sptr->c_buf_allocd = 1;            }                        for(i=bytes_in_buf; i > (int)(sptr->c_last_acked - sptr->c_first_seq); i--)            {                if(sptr->c_buf[i-1] == 0xa || sptr->c_buf[i-1] == 0xd)                {                    TcpStreamPacketize(p, sptr->c_buf, i, server_packet);                    made_packet = i;                    break;                }            }        }        if(made_packet >= 0)        {  /* shuffle data */            for(i=made_packet; i<(int)bytes_in_buf; i++)            {                sptr->c_buf[i-made_packet] = sptr->c_buf[i];            }            sptr->c_first_seq += made_packet;            sptr->c_last_byte -= made_packet;            }    }    /* if something's been acknowledged, update last_acked        only if side being acked is in data transmission state       this keeps us from acknowledging FIN and having 1 extra       data byte in buffer     */    if(p->tcph->th_flags & R_ACK)    {        if(server_packet)            sptr->c_last_acked = lack;        if(!server_packet)            sptr->s_last_acked = lack;    }    if((sptr->client_status == ESTABLISHED) && (sptr->server_status == SYN_RCVD))    {        if(server_packet) return; /* shouldn't see a server packet here */        if(lack != sptr->s_first_seq) return; /* False ACK - bad seq */        if(p->tcph->th_flags == R_ACK) sptr->server_status = ESTABLISHED;        return;    }    if((sptr->client_status == ESTABLISHED ||         sptr->client_status == CLOSE_WAIT) &&        !server_packet)    {        /* Let's put new data in the buffers */        pos = lseq - sptr->c_first_seq;        if((unsigned long)(pos + p->dsize) < sptr->c_buf_siz && pos >= 0)        {            if((unsigned long)(pos + p->dsize) > sptr->c_last_byte) sptr->c_last_byte = pos + p->dsize;#if DEBUG            printf("Copying %i bytes to Client buffer at %i, lb now: %lu\n",p->dsize,pos,sptr->c_last_byte);#endif            /* make sure we have a buffer to write to */            if(sptr->c_buf_allocd)            {                memcpy(sptr->c_buf + pos,p->data,p->dsize);            }            else            {                /* make a buffer based on the current window size */                if (p->tcph->th_win != 0)                {                    sptr->c_buf_siz = ntohs(p->tcph->th_win) + StreamData.maxbytes;                }                else                {                    sptr->c_buf_siz = 65536 + StreamData.maxbytes;                }                sptr->c_buf = (u_char *) malloc(sptr->c_buf_siz);                sptr->c_buf_allocd = 1;                memcpy(sptr->c_buf + pos,p->data,p->dsize);            }        }    }    if((sptr->server_status == ESTABLISHED ||         sptr->server_status == CLOSE_WAIT) && server_packet)    {        pos = lseq - sptr->s_first_seq;        if((unsigned long)(pos + p->dsize) < sptr->s_buf_siz && pos >= 0)        {            if((unsigned long)(pos + p->dsize) > sptr->s_last_byte) sptr->s_last_byte = pos + p->dsize;#if DEBUG            printf("Copying %i bytes to Server buffer at %i, lb now: %lu\n",p->dsize,pos,sptr->s_last_byte);#endif            if(sptr->s_buf_allocd == 1)            {                memcpy(sptr->s_buf + pos,p->data,p->dsize);            }            else            {                if(p->tcph->th_win != 0)                {                    sptr->s_buf_siz = ntohs(p->tcph->th_win) + StreamData.maxbytes;                }                else                {                    sptr->s_buf_siz = 65536 + StreamData.maxbytes;                }                sptr->s_buf = (u_char *) malloc(sptr->s_buf_siz);                sptr->s_buf_allocd = 1;                memcpy(sptr->s_buf + pos,p->data,p->dsize);            }        }    }    if((sptr->server_status == ESTABLISHED) &&        (sptr->client_status == ESTABLISHED) &&        (p->tcph->th_flags & R_FIN))    {        if(server_packet)        {            sptr->server_status = FIN_WAIT_1;  /* server does active close */            sptr->client_status = CLOSE_WAIT;            sptr->s_fin_seq = lseq;        }        else        {            sptr->client_status = FIN_WAIT_1; /* client does active close */            sptr->server_status = CLOSE_WAIT;            sptr->c_fin_seq = lseq;        }    }    if(sptr->server_status == CLOSE_WAIT &&        server_packet && p->tcph->th_flags & R_FIN)    {        sptr->server_status = LAST_ACK;        sptr->client_status = TIME_WAIT;        sptr->c_fin_seq = lseq;    }    if(sptr->client_status == CLOSE_WAIT &&        !server_packet && p->tcph->th_flags & R_FIN)    {        sptr->server_status = TIME_WAIT;        sptr->client_status = LAST_ACK;        sptr->s_fin_seq = lseq;    }    return;}/* * Function: TcpStreamTime() * * Purpose:  what can i say, i like having my own timing routines * * Arguments: none * * Returns: u_long number of seconds since beginning of time (unix-centric) * */u_long TcpStreamTime(){    struct timeval t;    gettimeofday(&t, (struct timezone *)NULL);    return(t.tv_sec);}/* * Function: TcpStreamCheckSession(Packet *, int sp) * * Purpose:  return the TcpStreamSession of current packet (if any) w/  * respect to server port sp * * * Arguments:  * * Returns: appropriate TcpStreamSession (or null) * */TcpStreamSession * TcpStreamCheckSession(Packet *p, int sp, int *bin){    TcpStreamSession *sptr;    u_char hash;    u_char *ptr;    int i;    for(ptr=(u_char *)&p->iph->ip_src, i=0, hash=0; i<8; i++,ptr++)        hash += *ptr;      *bin = hash;#if DEBUG    printf("HASH: %x\n", hash);#endif    if(sp == p->sp)    {  /* this is coming from the server */        for(sptr=StreamData.heads[hash]; sptr!=NULL; sptr=sptr->next)        {            if(sptr->sip == p->iph->ip_src.s_addr && sptr->cip == p->iph->ip_dst.s_addr && sptr->sp == sp && sptr->cp == p->dp)            {                return sptr;            }        }    }    else    {  /* data from the client */        for(sptr=StreamData.heads[hash]; sptr!=NULL; sptr=sptr->next)        {            if(sptr->sip == p->iph->ip_dst.s_addr && sptr->cip == p->iph->ip_src.s_addr && sptr->sp == sp && sptr->cp == p->sp)            {                return sptr;            }        }    }    return(TcpStreamSession *)NULL;}/* * Function: TcpStreamPruneSessions() * * Purpose:  kill all inactive sessions * * Arguments: none * * Returns: void function * */void TcpStreamPruneSessions(){    TcpStreamSession * sptr = NULL;    TcpStreamSession * lastptr, *tmpptr;    u_long tm;    int i;#if DEBUG    int prunecount = 0;    int remain=0;    int orig=0;#endif#if DEBUG    for(i=0;i<256;i++)        for(sptr=StreamData.heads[i]; sptr!=NULL; sptr=sptr->next)        {            orig++;        }    printf("Trying to PRUNE!   %i streams\n",orig);#endif    tm = TcpStreamTime();    for(i=0;i<256;i++)    {        for(sptr=StreamData.heads[i], lastptr=NULL; sptr!=NULL;)        {            if(tm - sptr->timestamp >= StreamData.prunetime)            {                tmpptr = sptr->next;                if(lastptr == NULL)                    StreamData.heads[i] = sptr->next;                else                    lastptr->next = sptr->next;                if(sptr != NULL)                {                    if(sptr->c_buf != NULL)                        free(sptr->c_buf);                    if(sptr->s_buf != NULL)                        free(sptr->s_buf);                    free(sptr);#if DEBUG                    prunecount++;#endif                }                sptr = tmpptr;            }            else            {                lastptr = sptr;                sptr = sptr->next;            }        }    }#if DEBUG    for(i=0;i<256;i++)    {        for(sptr=StreamData.heads[i]; sptr!=NULL; sptr=sptr->next)        {            remain++;        }    }    printf("Done PRUNING!  %i deleted, %i remain\n",prunecount,remain);#endif    return;}void TcpStreamPacketize(Packet *pb, u_char *buf, u_long psize, int server_packet){    Packet *p;    int pcaplen;    int hdrsize;    struct pseudoheader       /* pseudo header for TCP checksum calculations */    {        u_int32_t sip, dip;   /* IP addr */        u_int8_t  zero;       /* checksum placeholder */        u_int8_t  protocol;   /* protocol number */        u_int16_t tcplen;     /* tcp packet length */    };    struct pseudoheader ph;    /* pseudo header declaration */    grinder_t tmp_grinder;#ifdef DEBUG    printf("Trying to make a new packet!  psize: %lu\n", psize);#endif    pc.rebuilt_tcp ++;  /* new phoney packet */#ifdef DEBUG    printf("Alignments: pb->pkth: %lx, pb->iph: %lx, pb->tcph: %lx\n",(u_long)pb->pkth & 0x03, (u_long)pb->iph & 0x03, (u_long)pb->tcph & 0x03);#endif    p = (Packet *) malloc(sizeof(Packet));    if(p == NULL) return;    pcaplen = 8 + sizeof(struct timeval);#ifdef DEBUG    printf("pcaplen = %i\n",pcaplen);#endif/* creating a fake NULL/IP/TCP packet */    p->pkth = (struct pcap_pkthdr *)malloc(pcaplen + 4 + 40 + psize);      if(p->pkth == NULL)    {        free(p);        return;    }    p->iph = (IPHdr *)((u_char*)p->pkth + pcaplen + 4);    hdrsize = 40 + NULL_HDRLEN;    p->tcph = (TCPHdr *)((u_char *) p->iph + 20);#ifdef DEBUG    printf("Alignments: p->pkth: %lx, p->iph: %lx, p->tcph: %lx\n",(u_long)p->pkth & 0x03, (u_long)p->iph & 0x03, (u_long)p->tcph & 0x03);#endif    memcpy((u_char *)p->pkth, (u_char *)pb->pkth, pcaplen);    p->pkth->caplen = p->pkth->len = hdrsize + psize;    p->pkt = ((u_char*)p->pkth + pcaplen);    /* IP stuff */    p->iph->ip_ver = 0x04;    p->iph->ip_hlen = 0x05;    p->iph->ip_src = pb->iph->ip_dst;    p->iph->ip_dst = pb->iph->ip_src;    p->iph->ip_tos = pb->iph->ip_tos;    p->iph->ip_len = htons((unsigned short)(40 + psize));    p->iph->ip_id = 0;    p->iph->ip_off = htons(0);    p->iph->ip_ttl = 255;    p->iph->ip_proto = pb->iph->ip_proto;    p->iph->ip_csum = 0;    p->iph->ip_csum = checksum((u_short *)p->iph, 20, (u_short *)NULL, 0);    /* TCP Stuff */    memset(p->tcph,0,sizeof(TCPHdr));    p->tcph->th_sport = pb->tcph->th_dport;    p->tcph->th_dport = pb->tcph->th_sport;    p->tcph->th_flags = R_PSH | R_ACK;    p->tcph->th_off = 0x05;    /* setup the pseudo header for checksum calculation */    ph.sip = (u_int32_t)(p->iph->ip_src.s_addr);    ph.dip = (u_int32_t)(p->iph->ip_dst.s_addr);    ph.zero = 0;    ph.protocol = p->iph->ip_proto;    ph.tcplen = htons((unsigned short)(20 + psize));    memcpy((u_char *)p->pkth+hdrsize+pcaplen, buf, psize);    /* calculate the checksum */    p->tcph->th_sum = checksum((u_int16_t *)&ph, 12, (u_int16_t *)(p->tcph), 20 + psize);    tmp_grinder = grinder;    grinder = DecodeNullPkt;    ProcessPacket(NULL, p->pkth, p->pkt);    grinder = tmp_grinder;    free(p->pkth);    free(p);}

⌨️ 快捷键说明

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