static void tcp_queue(struct tcp_stream * a_tcp, struct tcphdr * this_tcphdr, struct half_stream * snd, struct half_stream * rcv, char *data, int datalen, int skblen ) { a_tcp->lasttime = time((time_t *)0); u_int this_seq = ntohl(this_tcphdr->th_seq); struct skbuff *pakiet; /* * Did we get anything new to ack? */ if (!after(this_seq, EXP_SEQ)) { if (after(this_seq + datalen + (this_tcphdr->th_flags & TH_FIN), EXP_SEQ)) { // the packet straddles our window end get_ts(this_tcphdr, &snd->curr_ts); add_from_skb(a_tcp, rcv, snd, data, datalen, this_seq, (this_tcphdr->th_flags & TH_FIN), (this_tcphdr->th_flags & TH_URG), ntohs(this_tcphdr->th_urp) + this_seq - 1); // Do we have any old packets to ack that the above // made visible? (Go forward from skb) pakiet = rcv->list; while (pakiet) { if (after(pakiet->seq, EXP_SEQ)) break; if (after(pakiet->seq + pakiet->len + pakiet->fin, EXP_SEQ)) { struct skbuff *tmp; add_from_skb(a_tcp, rcv, snd, pakiet->data, pakiet->len, pakiet->seq, pakiet->fin, pakiet->urg, pakiet->urg_ptr + pakiet->seq - 1); rcv->rmem_alloc -= pakiet->truesize; if (pakiet->prev) pakiet->prev->next = pakiet->next; else rcv->list = pakiet->next; if (pakiet->next) pakiet->next->prev = pakiet->prev; else rcv->listtail = pakiet->prev; tmp = pakiet->next; free(pakiet->data); free(pakiet); pakiet = tmp; } else pakiet = pakiet->next; } } } else if(this_tcphdr->th_flags & TH_FIN || this_tcphdr->th_flags & TH_RST ) { pakiet = rcv->list; while (pakiet) { struct skbuff *tmp; add_from_skb(a_tcp, rcv, snd, pakiet->data, pakiet->len, pakiet->seq, pakiet->fin, pakiet->urg, pakiet->urg_ptr + pakiet->seq - 1); rcv->rmem_alloc -= pakiet->truesize; if (pakiet->prev) pakiet->prev->next = pakiet->next; else rcv->list = pakiet->next; if (pakiet->next) pakiet->next->prev = pakiet->prev; else rcv->listtail = pakiet->prev; tmp = pakiet->next; free(pakiet->data); free(pakiet); pakiet = tmp; } //free_tcp(a_tcp); } else { struct skbuff *p = rcv->listtail; pakiet = mknew(struct skbuff); pakiet->truesize = skblen; rcv->rmem_alloc += pakiet->truesize; pakiet->len = datalen; pakiet->data = malloc(datalen); if (!pakiet->data) nids_params.no_mem("tcp_queue"); memcpy(pakiet->data, data, datalen); pakiet->fin = (this_tcphdr->th_flags & TH_FIN); pakiet->seq = this_seq; pakiet->urg = (this_tcphdr->th_flags & TH_URG); pakiet->urg_ptr = ntohs(this_tcphdr->th_urp); for (;;) { /* if (!p || !after(p->seq, this_seq)) break; */ if( !p ) break; if ( !after(p->seq, this_seq)) { if( p->seq != this_seq){ break; } else { if(p->len > datalen) break; }//if_else }//if p = p->prev; }//for if (!p) { pakiet->prev = 0; pakiet->next = rcv->list; if (rcv->list) rcv->list->prev = pakiet; rcv->list = pakiet; if (!rcv->listtail) rcv->listtail = pakiet; } else { pakiet->next = p->next; p->next = pakiet; pakiet->prev = p; if (pakiet->next) pakiet->next->prev = pakiet; else rcv->listtail = pakiet; } } }
static void tcp_queue(struct tcp_stream * a_tcp, struct tcphdr * this_tcphdr, struct half_stream * snd, struct half_stream * rcv, char *data, int datalen, int skblen ) { u_int this_seq = ntohl(this_tcphdr->th_seq); struct skbuff *pakiet, *tmp; /* * Did we get anything new to ack? */ if (!after(this_seq, EXP_SEQ)) { if (after(this_seq + datalen + (this_tcphdr->th_flags & TH_FIN), EXP_SEQ)) { /* the packet straddles our window end */ get_ts(this_tcphdr, &snd->curr_ts); add_from_skb(a_tcp, rcv, snd, (u_char *)data, datalen, this_seq, (this_tcphdr->th_flags & TH_FIN), (this_tcphdr->th_flags & TH_URG), ntohs(this_tcphdr->th_urp) + this_seq - 1); /* * Do we have any old packets to ack that the above * made visible? (Go forward from skb) */ pakiet = rcv->list; while (pakiet) { if (after(pakiet->seq, EXP_SEQ)) break; if (after(pakiet->seq + pakiet->len + pakiet->fin, EXP_SEQ)) { add_from_skb(a_tcp, rcv, snd, pakiet->data, pakiet->len, pakiet->seq, pakiet->fin, pakiet->urg, pakiet->urg_ptr + pakiet->seq - 1); } rcv->rmem_alloc -= pakiet->truesize; if (pakiet->prev) pakiet->prev->next = pakiet->next; else rcv->list = pakiet->next; if (pakiet->next) pakiet->next->prev = pakiet->prev; else rcv->listtail = pakiet->prev; tmp = pakiet->next; free(pakiet->data); free(pakiet); pakiet = tmp; } } else return; } else { struct skbuff *p = rcv->listtail; pakiet = mknew(struct skbuff); pakiet->truesize = skblen; rcv->rmem_alloc += pakiet->truesize; pakiet->len = datalen; pakiet->data = malloc(datalen); if (!pakiet->data) nids_params.no_mem("tcp_queue"); memcpy(pakiet->data, data, datalen); pakiet->fin = (this_tcphdr->th_flags & TH_FIN); /* Some Cisco - at least - hardware accept to close a TCP connection * even though packets were lost before the first TCP FIN packet and * never retransmitted; this violates RFC 793, but since it really * happens, it has to be dealt with... The idea is to introduce a 10s * timeout after TCP FIN packets were sent by both sides so that * corresponding libnids resources can be released instead of waiting * for retransmissions which will never happen. -- Sebastien Raveau */ if (pakiet->fin) { snd->state = TCP_CLOSING; if (rcv->state == FIN_SENT || rcv->state == FIN_CONFIRMED) add_tcp_closing_timeout(a_tcp); } pakiet->seq = this_seq; pakiet->urg = (this_tcphdr->th_flags & TH_URG); pakiet->urg_ptr = ntohs(this_tcphdr->th_urp); for (;;) { if (!p || !after(p->seq, this_seq)) break; p = p->prev; } if (!p) { pakiet->prev = 0; pakiet->next = rcv->list; if (rcv->list) rcv->list->prev = pakiet; rcv->list = pakiet; if (!rcv->listtail) rcv->listtail = pakiet; } else { pakiet->next = p->next; p->next = pakiet; pakiet->prev = p; if (pakiet->next) pakiet->next->prev = pakiet; else rcv->listtail = pakiet; } } }