📄 spp_tcp_stream.c
字号:
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 + -