Пример #1
0
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;
    }
  }
}
Пример #2
0
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;
    }
  }
}