博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
libnids tcp 重组代码注释
阅读量:4125 次
发布时间:2019-05-25

本文共 7698 字,大约阅读时间需要 25 分钟。

voidprocess_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);}

转载地址:http://zwmpi.baihongyu.com/

你可能感兴趣的文章
laravel 制作通用的curd 后台操作
查看>>
【小红书2017年笔试】求一个数组中平均数最大的子数组
查看>>
Linux基础系列-定时器与时间管理
查看>>
Linux基础系列-可执行程序的产生过程
查看>>
Linux基础系列-Kernel 初始化宏
查看>>
Linux子系统系列-I2C
查看>>
<iOS>关于自定义description的一点用法
查看>>
Unix 命令,常用到的
查看>>
DLL中建立进程共享数据段需要注意的语法问题
查看>>
服务器端技术----Http请求的处理过程
查看>>
C语言-预处理指令2-条件编译
查看>>
C语言-预处理指令3-文件包含
查看>>
C语言-变量类型
查看>>
C语言-static和extern关键字1-对函数的作用
查看>>
C 语言-static和extern关键字2-对变量的作用
查看>>
【JavaScript 教程】浏览器—History 对象
查看>>
还不会正则表达式?看这篇!
查看>>
100道+ JavaScript 面试题,助你查漏补缺
查看>>
JavaScript深入理解之闭包
查看>>
这才是学习Vite2的正确姿势!
查看>>