libnids-TCP流重组

44 篇文章 0 订阅
17 篇文章 1 订阅

1.  void process_tcp(u_char * data, int skblen) 
2.  { 
3.    
4.    struct ip *this_iphdr = (struct ip *)data; 
5.    /*tcphdr 的头*/ 
6.    struct tcphdr *this_tcphdr = (struct tcphdr *)(data + 4 * this_iphdr->ip_hl); 
7.    int datalen, iplen; 
8.    int from_client = 1; /*客户发送数据*/ 
9.    unsigned int tmp_ts; 
10.      
11.   /*流分为客户端服务端*/ 
12.   struct tcp_stream *a_tcp; 
13.   struct half_stream *snd, *rcv; 
14.   
15.   ugly_iphdr = this_iphdr; 
16.   iplen = ntohs(this_iphdr->ip_len); 
17.      
18.   if ((unsigned)iplen < 4 * this_iphdr->ip_hl + sizeof(struct tcphdr)) { 
19.     nids_params.syslog(NIDS_WARN_TCP, NIDS_WARN_TCP_HDR, this_iphdr, this_tcphdr); 
20.     return; 
21.   } // ktos sie bawi 

22.   /*tcp 数据长度*/ 
23.   datalen = iplen - 4 * this_iphdr->ip_hl - 4 * this_tcphdr->th_off; 
24.   if (datalen < 0) { 
25.     nids_params.syslog(NIDS_WARN_TCP, NIDS_WARN_TCP_HDR, this_iphdr, this_tcphdr); 
26.     return; 
27.   } // ktos sie bawi 
28.   
29.   /*源和目的地址都存在*/ 
30.   if ((this_iphdr->ip_src.s_addr | this_iphdr->ip_dst.s_addr) == 0) { 
31.     nids_params.syslog(NIDS_WARN_TCP, NIDS_WARN_TCP_HDR, this_iphdr, this_tcphdr); 
32.     return; 
33.   } 
34.   
35.   /*如果没有th_ack 包,则进行扫描是否有攻击包*/ 
36.   if (!(this_tcphdr->th_flags & TH_ACK)) 
37.     detect_scan(this_iphdr); 
38.  
39.   /* 表示有扫描攻击发生 */ 
40.   if (!nids_params.n_tcp_streams) return; 
41.     
42.   /*tcp 头的长度,iplen -4*this_iphdr->ip_hl, 进行包头的校验*/ 
43.   if (my_tcp_check(this_tcphdr, iplen - 4 * this_iphdr->ip_hl, 
44.            this_iphdr->ip_src.s_addr, this_iphdr->ip_dst.s_addr)) { 
45.     nids_params.syslog(NIDS_WARN_TCP, NIDS_WARN_TCP_HDR, this_iphdr, this_tcphdr); 
46.     return; 
47.   } 
48.     
49. #if 0 
50.   check_flags(this_iphdr, this_tcphdr); 
51. #endif 
52.   
53. /*查找添加流*/ 
54.   
55. /* 
56.     ************* 三次握手的第一次握手***************************************** 
57. */ 
58.   
59.   if (!(a_tcp = find_stream(this_tcphdr, this_iphdr, &from_client))) { 
60.   /*是三次握手的第一个包*/ 
61.   /*tcp里流不存在时:且tcp数据包里的(syn=1 && ack==0 && rst==0)时,添加一条tcp流*/ 
62.  /*tcp第一次握手*/ 
63.     if ((this_tcphdr->th_flags & TH_SYN) && 
64.     !(this_tcphdr->th_flags & TH_ACK) && 
65.     !(this_tcphdr->th_flags & TH_RST)) 
66.     /*并且没有收到th_rest 包*/ 
67.       add_new_tcp(this_tcphdr, this_iphdr);/*节点加入链表中*/ 
68.    /*第一次握手完毕返回*/ 
69.     return; 
70.   } 
71.   
72.   if (from_client) { /*从client -->server的包*/ 
73.     snd = &a_tcp->client; 
74.     rcv = &a_tcp->server; 
75.   } else {/* server --> client的包 */ 
76.     rcv = &a_tcp->client; 
77.     snd = &a_tcp->server; 
78.   } 
79. /********************************************************************** 
80.                 三次握手的第二次握手 
81. ************************************************************************/ 
82.   
83.   /*tcp 三次握手, SYN ==1,ACK==1,tcp第二次握手(server -> client的同步响应)*/ 
84.   if ((this_tcphdr->th_flags & TH_SYN)) { 
85.     if (from_client || a_tcp->client.state != TCP_SYN_SENT || 
86.       a_tcp->server.state != TCP_CLOSE || !(this_tcphdr->th_flags & TH_ACK)) 
87.       return; 
88.   
89. /*第二次回应包的ACK 值为第一个包的序列号+1,在初始化的时候已经加1*/ 
90.     if (a_tcp->client.seq != ntohl(this_tcphdr->th_ack)) 
91.       return; 
92.     /*第二个包服务端赋值*/ 
93.     /*a_tcp 中服务端赋值,*/ 
94.     a_tcp->server.state = TCP_SYN_RECV; 
95.     a_tcp->server.seq = ntohl(this_tcphdr->th_seq) + 1; 
96.     a_tcp->server.first_data_seq = a_tcp->server.seq; 
97.     a_tcp->server.ack_seq = ntohl(this_tcphdr->th_ack); 
98.     a_tcp->server.window = ntohs(this_tcphdr->th_win); 
99.   
100.          
101.          /*对于tcp 选项的赋值*/ 
102.          //初始化客户端和服务器的时间截 
103.            if (a_tcp->client.ts_on) { 
104.                a_tcp->server.ts_on = get_ts(this_tcphdr, &a_tcp->server.curr_ts); 
105.            if (!a_tcp->server.ts_on) 
106.                a_tcp->client.ts_on = 0; 
107.            } else a_tcp->server.ts_on = 0; 
108.          
109.          
110.        //初始化窗口大小 
111.            if (a_tcp->client.wscale_on) { 
112.                a_tcp->server.wscale_on = get_wscale(this_tcphdr, &a_tcp->server.wscale); 
113.            if (!a_tcp->server.wscale_on) { 
114.                a_tcp->client.wscale_on = 0; 
115.                a_tcp->client.wscale = 1; 
116.                a_tcp->server.wscale = 1; 
117.            } 
118.            } else { 
119.                a_tcp->server.wscale_on = 0; 
120.                a_tcp->server.wscale = 1; 
121.            } 
122.         /*第二次握手完毕,返回*/ 
123.            return; 
124.          } 
125.          
126.           /* 
127.                (如果有数据存在或者修列号不等于确认号的)并且 
128.                序列号在窗口之外 
129.                已经确认过的序号 
130.           */ 
131.            
132.          if ( 
133.            ! ( !datalen && ntohl(this_tcphdr->th_seq) == rcv->ack_seq ) 
134.            && 
135.            /*th_seq- (ack_seq+ wscale) > 0 或者th_seq+datalen - ack_sql < 0*/ 
136.            ( !before(ntohl(this_tcphdr->th_seq), rcv->ack_seq + rcv->window*rcv->wscale) || 
137.                  before(ntohl(this_tcphdr->th_seq) + datalen, rcv->ack_seq) 
138.                ) 
139.             ) 
140.             return; 
141.          
142.          /*发送th_rst 重新开启一个连接*/ 
143.          if ((this_tcphdr->th_flags & TH_RST)) { 
144.            /*是tcp 数据*/ 
145.            if (a_tcp->nids_state == NIDS_DATA) { 
146.              struct lurker_node *i; 
147.              a_tcp->nids_state = NIDS_RESET; 
148.              for (i = a_tcp->listeners; i; i = i->next) 
149.                 i->item) (a_tcp, &i->data); 
150.             } 
151.            nids_free_tcp_stream(a_tcp); 
152.            return; 
153.          } 
154.          
155.          /*PAWS check */ 
156.          if (rcv->ts_on && get_ts(this_tcphdr, &tmp_ts) && 
157.            before(tmp_ts, snd->curr_ts)) 
158.          return; 
159.          
160.        /* ********************************************************************** 
161.                                第三次握手包 
162.           ********************************************************************** 
163.        */ 
164.          
165.          /* 从client -->server的包 
166.           是从三次握手的第三个包分析开始的,进行一部分数据分析,和初始化 
167.           连接状态 
168.          */ 
169.          if ((this_tcphdr->th_flags & TH_ACK)) { 
170.            if (from_client && a_tcp->client.state == TCP_SYN_SENT && 
171.            a_tcp->server.state == TCP_SYN_RECV) { 
172.              if (ntohl(this_tcphdr->th_ack) == a_tcp->server.seq) { 
173.            a_tcp->client.state = TCP_ESTABLISHED; 
174.            a_tcp->client.ack_seq = ntohl(this_tcphdr->th_ack); 
175.            { 
176.              struct proc_node *i; 
177.              struct lurker_node *j; 
178.              void *data; 
179.                 
180.              a_tcp->server.state = TCP_ESTABLISHED; 
181.              a_tcp->nids_state = NIDS_JUST_EST; 
182.              /*开始全双工传输,clientserver 连接已经建立起来了*/ 
183.          
184.              /*三次握手tcp ip 连接建立*/ 
185.              for (i = tcp_procs; i; i = i->next) { 
186.                char whatto = 0; 
187.                char cc = a_tcp->client.collect; 
188.                char sc = a_tcp->server.collect; 
189.                char ccu = a_tcp->client.collect_urg; 
190.                char scu = a_tcp->server.collect_urg; 
191.          
192.                /*进入回调函数处理*/ 
193.          
194.                /* 如果在相应端口出现 
195.                 client.collect ++ ; 
196.                测审计次数据 
197.                对应用来说tcp 连接已经建立 
198.               */ 
199.                (i->item) (a_tcp, &data); 
200.          
201.               /**/ 
202.                if (cc < a_tcp->client.collect) 
203.                  whatto |= COLLECT_cc; 
204.                if (ccu < a_tcp->client.collect_urg) 
205.                  whatto |= COLLECT_ccu; 
206.                if (sc < a_tcp->server.collect) 
207.                  whatto |= COLLECT_sc; 
208.                if (scu < a_tcp->server.collect_urg) 
209.                  whatto |= COLLECT_scu; 
210.                if (nids_params.one_loop_less) { 
211.                        if (a_tcp->client.collect >=2) { 
212.                            a_tcp->client.collect=cc; 
213.                            whatto&=~COLLECT_cc; 
214.                        } 
215.                        if (a_tcp->server.collect >=2 ) { 
216.                            a_tcp->server.collect=sc; 
217.                            whatto&=~COLLECT_sc; 
218.                        } 
219.                } 
220.                      
221.               /*加入监听队列,开始数据接收*/ 
222.                if (whatto) { 
223.                  j = mknew(struct lurker_node); 
224.                  j->item = i->item;/*放入监听队列*/ 
225.                  j->data = data; 
226.                  j->whatto = whatto; 
227.                     
228.                  j->next = a_tcp->listeners; 
229.                  a_tcp->listeners = j; 
230.                } 
231.                   
232.              } 
233.                 
234.                 
235.              /*不存在监听着*/{ 
236.                nids_free_tcp_stream(a_tcp); 
237.                return; 
238.              } 
239.              if (!a_tcp->listeners) 
240.                 
241.              a_tcp->nids_state = NIDS_DATA; 
242.            } 
243.              } 
244.              //return; 

245.         
246.            } 
247.          } 
248.        /* 
249.        ************************************************************ 
250.                        挥手过程 
251.        ************************************************************* 
252.        */ 
253.        /*数据结束的包的判断*/ 
254.        if ((this_tcphdr->th_flags & TH_ACK)) { 
255.          /* 从数据传输过程不断更新服务器客户端的ack_seq 
256.            一直到接收到fin 包,数据传输结束
257.           */ 
258.            handle_ack(snd, ntohl(this_tcphdr->th_ack)); 
259.            if (rcv->state == FIN_SENT) 
260.              rcv->state = FIN_CONFIRMED; 
261.            if (rcv->state == FIN_CONFIRMED && snd->state == FIN_CONFIRMED) { 
262.              struct lurker_node *i; 
263.              a_tcp->nids_state = NIDS_CLOSE; 
264.              for (i = a_tcp->listeners; i; i = i->next) 
265.            (i->item) (a_tcp, &i->data); 
266.              nids_free_tcp_stream(a_tcp); 
267.              return; 
268.            } 
269.          } 
270.         /* 
271.        ************************************************************* 
272.                                数据处理过程 
273.        ************************************************************* 
274.         */ 
275.          if (datalen + (this_tcphdr->th_flags & TH_FIN) > 0) 
276.          /* 
            a_tcp-----a_tcp 客户端连接包 
277.            this_tcphdrtcp 包头 
278.            snd-----发送包 
279.            rcv-----接收包 
280.            (char*) (this_tcphdr) + 4 * this_tcphdr->th_off -----数据包内容 
281.            datalen---------数据包长度 
282.           */ 
283.            tcp_queue(a_tcp, this_tcphdr, snd, rcv, (char *) (this_tcphdr) + 4 * this_tcphdr->th_off, datalen, skblen); 
284.             
285.          snd->window = ntohs(this_tcphdr->th_win); 
286.             
287.          if (rcv->rmem_alloc > 65535) 
288.               prune_queue(rcv, this_tcphdr); 
289.          if (!a_tcp->listeners) 
290.            nids_free_tcp_stream(a_tcp); 
291.        } 
292.         
293.        static void tcp_queue(
294.        struct tcp_stream * a_tcp, struct tcphdr * this_tcphdr, 
295.              struct half_stream * snd, struct half_stream* rcv, 
296.              char *data, int datalen, int skblen 
297.              ) 
298.        { 
299.          
300.          u_intthis_seq = ntohl(this_tcphdr->th_seq); 
301.             
302.          struct skbuff *pakiet, *tmp; 
303.          
304.          
305.         /* #defineEXP_SEQ (snd->first_data_seq + rcv->count + rcv->urg_count) 
306.            EXP_SEQ> this_seq 
307.          */ 
308.          
309.          /* 如果this_seq <= EXP_SEQ*/ 
310.          if ( !after(this_seq, EXP_SEQ) ) { 
311.            /*this_seq+ datalen + (this_tcphdr->th_flags & TH_FIN)> EXP_SEQ*/ 
312.            /*有重叠数据存在(重叠数据怎么处理呢) */ 
313.               
314.            if ( after(this_seq + datalen + (this_tcphdr->th_flags & TH_FIN), EXP_SEQ) ) { 
315.              /*the packet straddles our window end */ 
316.              get_ts(this_tcphdr, &snd->curr_ts); 
317.                 
318.              add_from_skb(a_tcp, rcv, snd, data, datalen, this_seq, 
319.                   (this_tcphdr->th_flags & TH_FIN), 
320.                   (this_tcphdr->th_flags & TH_URG), 
321.                           ntohs(this_tcphdr->th_urp) + this_seq - 1); 
322.          
323.             /*从头节点释放节点*/ 
324.              pakiet = rcv->list; 
325.              while (pakiet) { 
326.             /* 期望的序列号小于该包的序列号则直接返回 */ 
327.            if (after(pakiet->seq, EXP_SEQ)) 
328.              break; 
329.               
330.            /*  对失序队列数据包的处理 
331.               如果包序列号加上长度还小于期望序列号 
332.               则把该包添加到数据区,并在失序队列中删除该包 
333.            */ 
334.            if (after(pakiet->seq + pakiet->len + pakiet->fin, EXP_SEQ)) { 
335.              add_from_skb(a_tcp, rcv, snd, pakiet->data, 
336.                       pakiet->len, pakiet->seq, pakiet->fin, pakiet->urg, 
337.                       pakiet->urg_ptr + pakiet->seq - 1); 
338.                } 
339.                 rcv->rmem_alloc -= pakiet->truesize; 
340.               
341.                /*从头节点释放链表*/ 
342.            if (pakiet->prev) 
343.              pakiet->prev->next = pakiet->next; 
344.            else 
345.              rcv->list = pakiet->next; 
346.            if (pakiet->next) 
347.              pakiet->next->prev = pakiet->prev; 
348.            else 
349.              rcv->listtail = pakiet->prev; 
350.            tmp = pakiet->next; 
351.            free(pakiet->data); 
352.            free(pakiet); 
353.            pakiet = tmp; 
354.              } 
355.            } 
356.            else 
357.              return; 
358.          } 
359.          
360.             
361.        /*提前到达数据的加入失去顺序队列中链表*/ 
362.        //序列号大于我们期望的序列号,则把该包添加到list双向链表中 
363.        /*链表加入节点 */ 
364.          else { 
365.            /*初始化*/ 
366.            struct skbuff *p = rcv->listtail; 
367.               /*pakiet 加入rcv->listtal 链表中 */ 
368.               /* pakiet节点的初始化 */ 
369.            pakiet = mknew(struct skbuff); 
370.            pakiet->truesize = skblen; 
371.            rcv->rmem_alloc += pakiet->truesize; 
372.          
373.            /*数据包填充pakiet->data 中*/ 
374.            pakiet->len = datalen; 
375.            pakiet->data = malloc(datalen); 
376.            if (!pakiet->data) 
377.            nids_params.no_mem("tcp_queue"); 
378.            memcpy(pakiet->data, data, datalen); 
379.          
380.            /*是否是结束包*/ 
381.            pakiet->fin = (this_tcphdr->th_flags & TH_FIN); 
382.              /* 
383.                 硬件接收一个tcp 终止的链接, 
384.                 即使包在一个结束包的时候丢失,并且不再重传, 
385.                 处理这种方法就是引入时间机制处理 
386.              */ 
387.                 
388.            if (pakiet->fin) { 
389.              snd->state = TCP_CLOSING; 
390.              if (rcv->state == FIN_SENT || rcv->state == FIN_CONFIRMED) 
391.            add_tcp_closing_timeout(a_tcp); 
392.            } 
393.               
394.             /* seq,urg,urg_ptr 赋值 */ 
395.            pakiet->seq = this_seq; 
396.            pakiet->urg = (this_tcphdr->th_flags & TH_URG); 
397.            pakiet->urg_ptr = ntohs(this_tcphdr->th_urp); 
398.               
399.            for (;;) { 
400.                   
401.              if (!p || !after(p->seq, this_seq)) 
402.            break; 
403.              p = p->prev; 
404.        } 
405.               
406.            if (!p) { 
407.        /*建立首节点*/ 
408.              pakiet->prev = 0; 
409.              pakiet->next = rcv->list; 
410.              if (rcv->list) 
411.                 rcv->list->prev = pakiet; 
412.                 
413.              rcv->list = pakiet; 
414.              if (!rcv->listtail) 
415.            rcv->listtail = pakiet; 
416.            } 
417.          
418.        /*链表后插入*/ 
419.            else { 
420.              pakiet->next = p->next; 
421.              p->next = pakiet; 
422.              pakiet->prev = p; 
423.              if (pakiet->next) 
424.            pakiet->next->prev = pakiet; 
425.              else 
426.            rcv->listtail = pakiet; 
427.            } 
428.               
429.          } 
430.             
431.        } 
432.        /* 
433.        分配空间,数据保存rcv->data 中 
434.        长度为:rcv->count 
435.        新数据为date 
436.        长度为datalen 
437.        接收到新数据,重新分配空间,要根据收到的数据的大小 
438.        buffersize重分配的空间 
439.        */ 
440.        static void add2buf(struct half_stream * rcv, char *data, int datalen) 
441.        { 
442.          
443.          int toalloc; 
444.          
445.          /*datalen+ rcv->count - rcv->offset 如果大于buffersize 需要重新分配空间*/ 
446.             
447.          if (datalen + rcv->count - rcv->offset > rcv->bufsize) { 
448.            /*如果rcv->data 不存在*/ 
449.            if (!rcv->data) { 
450.              if (datalen < 2048) 
451.            toalloc = 4096; 
452.              else 
453.            toalloc = datalen * 2; 
454.          
455.              /*数据分配空间,bufsize 为分配空间的大小*/ 
456.              rcv->data = malloc(toalloc); 
457.              rcv->bufsize = toalloc; 
458.            } 
459.           /*第一次分配空间,如果空间不够重新分配*/ 
460.            else { 
461.              if (datalen < rcv->bufsize) 
462.                toalloc = 2 * rcv->bufsize; 
463.              else 
464.                toalloc = rcv->bufsize + 2*datalen; 
465.                 
466.              rcv->data = realloc(rcv->data, toalloc); 
467.              rcv->bufsize = toalloc; 
468.            } 
469.            if (!rcv->data) 
470.              nids_params.no_mem("add2buf"); 
471.          } 
472.          
473.          
474.          memcpy(rcv->data + rcv->count - rcv->offset, data, datalen); 
475.             
476.          rcv->count_new = datalen; 
477.             
478.          rcv->count += datalen; /*count累加为收到的数据之和,从流开始建立*/ 
479.          
480.        } 
481.         
482.        /* 通知服务器或者客户端接受数据 */ 
483.        static void notify(struct tcp_stream * a_tcp, struct half_stream * rcv) 
484.        { 
485.          
486.        /* 监听节点 */ 
487.          struct lurker_node *i, **prev_addr; 
488.          char mask; 
489.        /* 紧急数据 */ 
490.          if (rcv->count_new_urg) { 
491.            if (!rcv->collect_urg) 
492.              return; 
493.            if (rcv == &a_tcp->client) 
494.              mask = COLLECT_ccu; 
495.            else 
496.              mask = COLLECT_scu; 
497.               
498.            ride_lurkers(a_tcp, mask); 
499.            goto prune_listeners; 
500.          } 
501.          
502.          
503.        /* 常规数据 */ 
504.          if (rcv->collect) { 
505.            if (rcv == &a_tcp->client) 
506.              mask = COLLECT_cc; 
507.            else 
508.              mask = COLLECT_sc; 
509.          
510.          /* 不断读取数据,一直到读取到数据结束 */ 
511.           do { 
512.                    int total; 
513.                /*a_tcp 为为收到的datalen, total = dalalen; */ 
514.                a_tcp->read = rcv->count - rcv->offset; 
515.                total = a_tcp->read; 
516.                   
517.                /*处理监听节点上报信息*/ 
518.                ride_lurkers(a_tcp, mask); 
519.                if (a_tcp->read > total-rcv->count_new) 
520.                    rcv->count_new = total-a_tcp->read; 
521.                   
522.                if (a_tcp->read > 0) { 
523.                       
524.                /*已经读过的数据部再读,把没有读的数据放在rcv->data 中, 继续循环,hlf->data 指向新数据 rcv->count_new 为新数据的长度  */ 
525.                memmove(rcv->data, rcv->data + a_tcp->read, rcv->count - rcv->offset - a_tcp->read); 
526.          
527.                  /*rcv->ofset最终== rcv->count*/ 
528.                  rcv->offset += a_tcp->read; 
529.                } 
530.            }while (nids_params.one_loop_less && a_tcp->read>0 && rcv->count_new); 
531.        // we know thatif one_loop_less!=0, we have only one callback to notify 

532.         
533.          
534.        /* rcv->count_new初始化为0 */ 
535.           rcv->count_new=0; 
536.          } 
537.          
538.             
539.         prune_listeners: 
540.          prev_addr = &a_tcp->listeners; 
541.          i = a_tcp->listeners; 
542.          while (i) 
543.            if (!i->whatto) { 
544.              *prev_addr = i->next; 
545.              free(i); 
546.              i = *prev_addr; 
547.            } 
548.            else { 
549.              prev_addr = &i->next; 
550.              i = i->next; 
551.            } 
552.               
553.        } 


  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值