libnids tcp 重组代码注释

void
process_tcp(u_char * data, int skblen)
{

  struct ip *this_iphdr = (struct ip *)data;
  /*tcphdr 的头*/
  struct tcphdr *this_tcphdr = (struct tcphdr *)(data + 4 * this_iphdr->ip_hl);
  int datalen, iplen;
  int from_client = 1; /*客户发送数据*/
  unsigned int tmp_ts;
  
  /*流分为客户端服务端*/
  struct tcp_stream *a_tcp;
  struct half_stream *snd, *rcv;

  ugly_iphdr = this_iphdr;
  iplen = ntohs(this_iphdr->ip_len);
  
  if ((unsigned)iplen < 4 * this_iphdr->ip_hl + sizeof(struct tcphdr)) {
    nids_params.syslog(NIDS_WARN_TCP, NIDS_WARN_TCP_HDR, this_iphdr,
		       this_tcphdr);
    return;
  } // ktos sie bawi

  /*tcp 数据长度*/
  datalen = iplen - 4 * this_iphdr->ip_hl - 4 * this_tcphdr->th_off;
  
  if (datalen < 0) {
    nids_params.syslog(NIDS_WARN_TCP, NIDS_WARN_TCP_HDR, this_iphdr,
		       this_tcphdr);
    return;
  } // ktos sie bawi


  /*源和目的地址都存在*/

  if ((this_iphdr->ip_src.s_addr | this_iphdr->ip_dst.s_addr) == 0) {
    nids_params.syslog(NIDS_WARN_TCP, NIDS_WARN_TCP_HDR, this_iphdr,
		       this_tcphdr);
    return;
  }

  /*如果没有th_ack 包,则进行扫描是否有攻击包*/
  if (!(this_tcphdr->th_flags & TH_ACK))
    detect_scan(this_iphdr);
    /*

   /* 表示有扫描攻击发生 */
	  
  if (!nids_params.n_tcp_streams) return;
 
  /*tcp 头的长度,iplen -4*this_iphdr->ip_hl, 进行包头的校验*/
  if (my_tcp_check(this_tcphdr, iplen - 4 * this_iphdr->ip_hl,
		   this_iphdr->ip_src.s_addr, this_iphdr->ip_dst.s_addr)) {
    nids_params.syslog(NIDS_WARN_TCP, NIDS_WARN_TCP_HDR, this_iphdr,
		       this_tcphdr);
    return;
	
  }
  
#if 0
  check_flags(this_iphdr, this_tcphdr);
//ECN
#endif

/*查找添加流*/

/*

	*************		三次握手的第一次握手*****************************************

*/

  if (!(a_tcp = find_stream(this_tcphdr, this_iphdr, &from_client))) {

   /*是三次握手的第一个包*/
  /*tcp里流不存在时:且tcp数据包里的(syn=1 && ack==0 && rst==0)时,添加一条tcp流*/
 /*tcp第一次握手*/
    if ((this_tcphdr->th_flags &  TH_SYN) &&
	!(this_tcphdr->th_flags & TH_ACK) &&
	!(this_tcphdr->th_flags & TH_RST))
	/*并且没有收到th_rest 包*/
      add_new_tcp(this_tcphdr, this_iphdr);/*节点加入链表中*/

   /*第一次握手完毕返回*/	
    return;
  }

 
  if (from_client) { /*从client --> server的包*/
    snd = &a_tcp->client;
    rcv = &a_tcp->server;
  }
  else {/* server --> client的包 */
    rcv = &a_tcp->client;
    snd = &a_tcp->server;
  }


/**********************************************************************

				三次握手的第二次握手
 
************************************************************************/

   /*tcp 三次握手, SYN ==1,ACK==1,tcp第二次握手(server -> client的同步响应)*/
  if ((this_tcphdr->th_flags & TH_SYN)) {
    if (from_client || a_tcp->client.state != TCP_SYN_SENT ||
      a_tcp->server.state != TCP_CLOSE || !(this_tcphdr->th_flags & TH_ACK))
      return;


/*第二次回应包的ACK 值为第一个包的序列号+1,在初始化的时候已经加一*/			
    if (a_tcp->client.seq != ntohl(this_tcphdr->th_ack))
      return;
	
	
	/*第二个包服务端赋值*/
	/*a_tcp 中服务端赋值,*/

    a_tcp->server.state = TCP_SYN_RECV;
    a_tcp->server.seq = ntohl(this_tcphdr->th_seq) + 1;
    a_tcp->server.first_data_seq = a_tcp->server.seq;
    a_tcp->server.ack_seq = ntohl(this_tcphdr->th_ack);
    a_tcp->server.window = ntohs(this_tcphdr->th_win);


  /*对于tcp 选项的赋值*/   
  //初始化客户端和服务器的时间截
    if (a_tcp->client.ts_on) {
    	a_tcp->server.ts_on = get_ts(this_tcphdr, &a_tcp->server.curr_ts);
	if (!a_tcp->server.ts_on)
		a_tcp->client.ts_on = 0;
    } else a_tcp->server.ts_on = 0;	


//初始化窗口大小	
    if (a_tcp->client.wscale_on) {
    	a_tcp->server.wscale_on = get_wscale(this_tcphdr, &a_tcp->server.wscale);
	if (!a_tcp->server.wscale_on) {
		a_tcp->client.wscale_on = 0;
		a_tcp->client.wscale  = 1;
		a_tcp->server.wscale = 1;
	}	
    } else {
    	a_tcp->server.wscale_on = 0;	
    	a_tcp->server.wscale = 1;
    }	
 /*第二次握手完毕,返回*/
	
    return;
  }
  




   /*
                (如果有数据存在或者修列号不等于确认号的)并且

		序列号在窗口之外
 		已经确认过的序号

   */
 
  if (
  	! (  !datalen && ntohl(this_tcphdr->th_seq) == rcv->ack_seq  )
  	&&

 	/*th_seq - (ack_seq+ wscale) >  0 或者th_seq+datalen - ack_sql < 0*/ 
  	( !before(ntohl(this_tcphdr->th_seq), rcv->ack_seq + rcv->window*rcv->wscale) ||
          before(ntohl(this_tcphdr->th_seq) + datalen, rcv->ack_seq)  
        )
     )     
     return; 

  

  /*发送th_rst 重新开启一个连接*/
  if ((this_tcphdr->th_flags & TH_RST)) {
  	/*是tcp 数据*/
    if (a_tcp->nids_state == NIDS_DATA) {
      struct lurker_node *i;
      a_tcp->nids_state = NIDS_RESET;
      for (i = a_tcp->listeners; i; i = i->next)
	(i->item) (a_tcp, &i->data);
    }
    nids_free_tcp_stream(a_tcp);
    return;
  }




  /* PAWS check */
  if (rcv->ts_on && get_ts(this_tcphdr, &tmp_ts) && 
  	before(tmp_ts, snd->curr_ts))
  return; 	






/*
	**********************************************************************
						第三次握手包

	**********************************************************************
*/

  /*
  

  从client --> server的包

   是从三次握手的第三个包分析开始的,进行一部分数据分析,和初始化
   连接状态

  */
  
  if ((this_tcphdr->th_flags & TH_ACK)) {
    if (from_client && a_tcp->client.state == TCP_SYN_SENT &&
	a_tcp->server.state == TCP_SYN_RECV) {
      if (ntohl(this_tcphdr->th_ack) == a_tcp->server.seq) {
	a_tcp->client.state = TCP_ESTABLISHED;
	a_tcp->client.ack_seq = ntohl(this_tcphdr->th_ack);
	{
	  struct proc_node *i;
	  struct lurker_node *j;
	  void *data;
	  
	  a_tcp->server.state = TCP_ESTABLISHED;
	  a_tcp->nids_state = NIDS_JUST_EST;
	  /*开始全双工传输,client server 连接已经建立起来了*/

	  /*三次握手tcp ip 连接建立*/
	  for (i = tcp_procs; i; i = i->next) {
	    char whatto = 0;
		
	    char cc = a_tcp->client.collect;
	    char sc = a_tcp->server.collect;
	    char ccu = a_tcp->client.collect_urg;
	    char scu = a_tcp->server.collect_urg;

	    /*进入回调函数处理*/

	    /*

	        如果在相应端口出现

		client.collect ++ ;

		测审计次数据
		对应用来说tcp 连接已经建立

	   */	
	   
	   
	    (i->item) (a_tcp, &data);

	   /**/	
	    if (cc < a_tcp->client.collect)
	      whatto |= COLLECT_cc;		
	    if (ccu < a_tcp->client.collect_urg)
	      whatto |= COLLECT_ccu;
	    if (sc < a_tcp->server.collect)
	      whatto |= COLLECT_sc;
	    if (scu < a_tcp->server.collect_urg)
	      whatto |= COLLECT_scu;
	    if (nids_params.one_loop_less) {
	    		if (a_tcp->client.collect >=2) {
	    			a_tcp->client.collect=cc;
	    			whatto&=~COLLECT_cc;
	    		}
	    		if (a_tcp->server.collect >=2 ) {
	    			a_tcp->server.collect=sc;
	    			whatto&=~COLLECT_sc;
	    		}
	    }  
           
	   /*加入监听队列,开始数据接收*/	
	    if (whatto) {
	      j = mknew(struct lurker_node);
	      j->item = i->item;/*放入监听队列*/
	      j->data = data;
	      j->whatto = whatto;
		  
	      j->next = a_tcp->listeners;
	      a_tcp->listeners = j;
	    }
		
	  }
	  
	  
	  /*不存在监听着*/{
	    nids_free_tcp_stream(a_tcp);
	    return;
	  }
	  if (!a_tcp->listeners) 
	  
	  a_tcp->nids_state = NIDS_DATA;
	}
      }
      // return;
    }
  }



/*
************************************************************

				挥手过程

*************************************************************

*/

/*数据结束的包的判断*/

  if ((this_tcphdr->th_flags & TH_ACK)) {
  	

   /* 从数据传输过程不断更新服务器客户端的ack_seq
	一直到接收到fin 包,数据传输结束

   */
    handle_ack(snd, ntohl(this_tcphdr->th_ack));
	
    if (rcv->state == FIN_SENT)
      rcv->state = FIN_CONFIRMED;
    if (rcv->state == FIN_CONFIRMED && snd->state == FIN_CONFIRMED) {
      struct lurker_node *i;

      a_tcp->nids_state = NIDS_CLOSE;
      for (i = a_tcp->listeners; i; i = i->next)
	(i->item) (a_tcp, &i->data);
      nids_free_tcp_stream(a_tcp);
      return;
    }
  }


 /*

*************************************************************	
						数据处理过程
*************************************************************

 */


 
  
  if (datalen + (this_tcphdr->th_flags & TH_FIN) > 0)

  /*
		
	a_tcp -----a_tcp 客户端连接包
	this_tcphdr  tcp 包头
	snd-----发送包
	rcv -----接收包

	(char *) (this_tcphdr) + 4 * this_tcphdr->th_off -----数据包内容
	datalen---------数据包长度
	

  */
  
    tcp_queue(a_tcp, this_tcphdr, snd, rcv,
	      (char *) (this_tcphdr) + 4 * this_tcphdr->th_off,
	      datalen, skblen);
  
  snd->window = ntohs(this_tcphdr->th_win);
  
  if (rcv->rmem_alloc > 65535)
  	
    prune_queue(rcv, this_tcphdr);
  
  if (!a_tcp->listeners)
    nids_free_tcp_stream(a_tcp);


}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值