⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcp.c

📁 基于TCP/IP协议的网络入侵检测系统是在Linux平台下
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  Copyright (c) 1999 Rafal Wojtczuk <nergal@avet.com.pl>. All rights reserved.  See the file COPYING for license details. */#include <sys/types.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <netinet/in.h>#include <netinet/in_systm.h>#include <netinet/ip.h>#include <netinet/tcp.h>#include <netinet/ip_icmp.h>#include "checksum.h"#include "scan.h"#include "tcp.h"#include "util.h"#include "nids.h"#include "hash.h"#if ! HAVE_TCP_STATESenum {  TCP_ESTABLISHED = 1,  TCP_SYN_SENT,  TCP_SYN_RECV,  TCP_FIN_WAIT1,  TCP_FIN_WAIT2,  TCP_TIME_WAIT,  TCP_CLOSE,  TCP_CLOSE_WAIT,  TCP_LAST_ACK,  TCP_LISTEN,  TCP_CLOSING			/* now a valid state */};#endif#define FIN_SENT 120#define FIN_CONFIRMED 121#define COLLECT_cc 1#define COLLECT_sc 2#define COLLECT_ccu 4#define COLLECT_scu 8#define EXP_SEQ (snd->first_data_seq + rcv->count + rcv->urg_count)extern struct proc_node *tcp_procs;static struct tcp_stream **tcp_stream_table;static struct tcp_stream *streams_pool;static int tcp_num = 0;static int tcp_stream_table_size;static int max_stream;static struct tcp_stream *tcp_latest = 0, *tcp_oldest = 0;static struct tcp_stream *free_streams;static struct ip *ugly_iphdr;static void purge_queue(struct half_stream * h){  struct skbuff *tmp, *p = h->list;  while (p) {    free(p->data);    tmp = p->next;    free(p);    p = tmp;  }  h->list = h->listtail = 0;  h->rmem_alloc = 0;}static voidfree_tcp(struct tcp_stream * a_tcp){  int hash_index = a_tcp->hash_index;  struct lurker_node *i, *j;   purge_queue(&a_tcp->server);  purge_queue(&a_tcp->client);     if (a_tcp->next_node)    a_tcp->next_node->prev_node = a_tcp->prev_node;  if (a_tcp->prev_node)    a_tcp->prev_node->next_node = a_tcp->next_node;  else    tcp_stream_table[hash_index] = a_tcp->next_node;  if (a_tcp->client.data)    free(a_tcp->client.data);  if (a_tcp->server.data)    free(a_tcp->server.data);  if (a_tcp->next_time)    a_tcp->next_time->prev_time = a_tcp->prev_time;  if (a_tcp->prev_time)    a_tcp->prev_time->next_time = a_tcp->next_time;  if (a_tcp == tcp_oldest)    tcp_oldest = a_tcp->prev_time;  if (a_tcp == tcp_latest)    tcp_latest = a_tcp->next_time;    i = a_tcp->listeners;    while (i) {    j = i->next;    free(i);    i = j;  }  a_tcp->next_free = free_streams;  free_streams = a_tcp;  tcp_num--;}static intmk_hash_index(struct tuple4 addr){  int hash=mkhash(addr.saddr, addr.source, addr.daddr, addr.dest);  return hash % tcp_stream_table_size;}static voidadd_new_tcp(struct tcphdr * this_tcphdr, struct ip * this_iphdr){  struct tcp_stream *tolink;  struct tcp_stream *a_tcp;  int hash_index;  struct tuple4 addr;    addr.source = ntohs(this_tcphdr->th_sport);  addr.dest = ntohs(this_tcphdr->th_dport);  addr.saddr = this_iphdr->ip_src.s_addr;  addr.daddr = this_iphdr->ip_dst.s_addr;  hash_index = mk_hash_index(addr);    if (tcp_num > max_stream) {    struct lurker_node *i;        tcp_oldest->nids_state = NIDS_TIMED_OUT;    for (i = tcp_oldest->listeners; i; i = i->next)      (i->item) (tcp_oldest, &i->data);    free_tcp(tcp_oldest);    nids_params.syslog(NIDS_WARN_TCP, NIDS_WARN_TCP_TOOMUCH, ugly_iphdr, this_tcphdr);  }  a_tcp = free_streams;  if (!a_tcp) {    fprintf(stderr, "gdb me ...\n");    pause();  }  free_streams = a_tcp->next_free;    tcp_num++;  tolink = tcp_stream_table[hash_index];  memset(a_tcp, 0, sizeof(struct tcp_stream));  a_tcp->hash_index = hash_index;  a_tcp->addr = addr;  a_tcp->client.state = TCP_SYN_SENT;  a_tcp->client.seq = ntohl(this_tcphdr->th_seq) + 1;  a_tcp->client.first_data_seq = a_tcp->client.seq;  a_tcp->client.window = ntohs(this_tcphdr->th_win);  a_tcp->server.state = TCP_CLOSE;  a_tcp->next_node = tolink;  a_tcp->prev_node = 0;  if (tolink)    tolink->prev_node = a_tcp;  tcp_stream_table[hash_index] = a_tcp;  a_tcp->next_time = tcp_latest;  a_tcp->prev_time = 0;  if (!tcp_oldest)    tcp_oldest = a_tcp;  if (tcp_latest)    tcp_latest->prev_time = a_tcp;  tcp_latest = a_tcp;}static voidadd2buf(struct half_stream * rcv, char *data, int datalen){  if (datalen + rcv->count - rcv->offset > rcv->bufsize) {    if (!rcv->data) {      int toalloc;            if (datalen < 2048)	toalloc = 4096;      else	toalloc = datalen * 2;      rcv->data = malloc(toalloc);      rcv->bufsize = toalloc;    }    else {      rcv->data = realloc(rcv->data, 2 * rcv->bufsize);      rcv->bufsize *= 2;    }    if (!rcv->data)      nids_params.no_mem("add2buf");  }  memcpy(rcv->data + rcv->count - rcv->offset, data, datalen);  rcv->count_new = datalen;  rcv->count += datalen;}static voidride_lurkers(struct tcp_stream * a_tcp, char mask){  struct lurker_node *i;  char cc, sc, ccu, scu;    for (i = a_tcp->listeners; i; i = i->next)    if (i->whatto & mask) {      cc = a_tcp->client.collect;      sc = a_tcp->server.collect;      ccu = a_tcp->client.collect_urg;      scu = a_tcp->server.collect_urg;            (i->item) (a_tcp, &i->data);      if (cc < a_tcp->client.collect)	i->whatto |= COLLECT_cc;      if (ccu < a_tcp->client.collect_urg)	i->whatto |= COLLECT_ccu;      if (sc < a_tcp->server.collect)	i->whatto |= COLLECT_sc;      if (scu < a_tcp->server.collect_urg)	i->whatto |= COLLECT_scu;      if (cc > a_tcp->client.collect)	i->whatto &= ~COLLECT_cc;      if (ccu > a_tcp->client.collect_urg)	i->whatto &= ~COLLECT_ccu;      if (sc > a_tcp->server.collect)	i->whatto &= ~COLLECT_sc;      if (scu > a_tcp->server.collect_urg)	i->whatto &= ~COLLECT_scu;    }}static voidnotify(struct tcp_stream * a_tcp, struct half_stream * rcv){  struct lurker_node *i, **prev_addr;  char mask;  if (rcv->count_new_urg) {    if (!rcv->collect_urg)      return;    if (rcv == &a_tcp->client)      mask = COLLECT_ccu;    else      mask = COLLECT_scu;    ride_lurkers(a_tcp, mask);    goto prune_listeners;  }  if (rcv->collect) {    if (rcv == &a_tcp->client)      mask = COLLECT_cc;    else      mask = COLLECT_sc;   do {	int total;		a_tcp->read = rcv->count - rcv->offset;		  total=a_tcp->read;  	    ride_lurkers(a_tcp, mask);	    if (a_tcp->read>total-rcv->count_new)	    	rcv->count_new=total-a_tcp->read;	    	    if (a_tcp->read > 0) {	      memmove(rcv->data, rcv->data + a_tcp->read, rcv->count - rcv->offset - a_tcp->read);	      rcv->offset += a_tcp->read;	    }	}while (nids_params.one_loop_less && a_tcp->read>0 && rcv->count_new); // we know that if one_loop_less!=0, we have only one callback to notify   rcv->count_new=0;	      } prune_listeners:  prev_addr = &a_tcp->listeners;  i = a_tcp->listeners;  while (i)    if (!i->whatto) {      *prev_addr = i->next;      free(i);      i = *prev_addr;    }    else {      prev_addr = &i->next;      i = i->next;    }}static voidadd_from_skb(struct tcp_stream * a_tcp, struct half_stream * rcv,	     struct half_stream * snd,	     u_char *data, int datalen,	     u_int this_seq, char fin, char urg, u_int urg_ptr){  u_int lost = EXP_SEQ - this_seq;  int to_copy, to_copy2;    if (urg && after(urg_ptr, EXP_SEQ - 1) &&      (!rcv->urg_seen || after(urg_ptr, rcv->urg_ptr))) {    rcv->urg_ptr = urg_ptr;    rcv->urg_seen = 1;  }  if (after(rcv->urg_ptr + 1, this_seq + lost) &&      before(rcv->urg_ptr, this_seq + datalen)) {    to_copy = rcv->urg_ptr - (this_seq + lost);    if (to_copy > 0) {      if (rcv->collect) {	add2buf(rcv, data + lost, to_copy);	notify(a_tcp, rcv);      }      else {	rcv->count += to_copy;      }    }    rcv->urgdata = data[rcv->urg_ptr - this_seq];    rcv->count_new_urg = 1;    notify(a_tcp, rcv);    rcv->count_new_urg = 0;    rcv->urg_count++;    to_copy2 = this_seq + datalen - rcv->urg_ptr - 1;    if (to_copy2 > 0) {      if (rcv->collect) {	add2buf(rcv, data + lost + to_copy + 1, to_copy2);	notify(a_tcp, rcv);      }      else {	rcv->count += to_copy2;      }    }  }  else {    if (datalen - lost > 0) {      if (rcv->collect) {	add2buf(rcv, data + lost, datalen - lost);	notify(a_tcp, rcv);      }      else {	rcv->count += datalen - lost;      }    }  }  if (fin)    snd->state = FIN_SENT;}static voidtcp_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;    /*   * 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 */      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, 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      return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -