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

📄 tcp.c

📁 libnids w32 libnids w32 libnids w32 libnids w32 libnids w32
💻 C
📖 第 1 页 / 共 2 页
字号:
    }    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);    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;    }  }}static voidprune_queue(struct half_stream * rcv, struct tcphdr * this_tcphdr){  struct skbuff *tmp, *p = rcv->list;  nids_params.syslog(NIDS_WARN_TCP, NIDS_WARN_TCP_BIGQUEUE, ugly_iphdr, this_tcphdr);  while (p) {    free(p->data);    tmp = p->next;    free(p);    p = tmp;  }  rcv->list = rcv->listtail = 0;  rcv->rmem_alloc = 0;}static voidhandle_ack(struct tcp_stream * a_tcp, struct half_stream * snd,	   struct half_stream * rcv, u_int acknum){  int ackdiff;  ackdiff = acknum - snd->ack_seq;  if (ackdiff > 0) {    snd->ack_seq = acknum;  }}static voidcheck_flags(struct ip * iph, struct tcphdr * th){  u_char flag = *(((u_char *) th) + 13);    if (flag & 0x40 || flag & 0x80)    nids_params.syslog(NIDS_WARN_TCP, NIDS_WARN_TCP_BADFLAGS, iph, th);}struct tcp_stream *find_stream(struct tcphdr * this_tcphdr, struct ip * this_iphdr,	    int *from_client){  struct tuple4 this_addr, reversed;  int hash_index;  struct tcp_stream *a_tcp;  this_addr.source = ntohs(this_tcphdr->th_sport);  this_addr.dest = ntohs(this_tcphdr->th_dport);  this_addr.saddr = this_iphdr->ip_src.s_addr;  this_addr.daddr = this_iphdr->ip_dst.s_addr;  hash_index = mk_hash_index(this_addr);  for (a_tcp = tcp_stream_table[hash_index];       a_tcp && !b_comp(a_tcp->addr, this_addr);       a_tcp = a_tcp->next_node);  if (a_tcp) {    *from_client = 1;    return a_tcp;  }  reversed.source = ntohs(this_tcphdr->th_dport);  reversed.dest = ntohs(this_tcphdr->th_sport);  reversed.saddr = this_iphdr->ip_dst.s_addr;  reversed.daddr = this_iphdr->ip_src.s_addr;  hash_index = mk_hash_index(reversed);  for (a_tcp = tcp_stream_table[hash_index];       a_tcp && !b_comp(a_tcp->addr, reversed);       a_tcp = a_tcp->next_node);  if (a_tcp) {    *from_client = 0;    return a_tcp;  }  else    return 0;}void clear_stream_buffers(){  int i;  struct lurker_node *j;  struct tcp_stream *a_tcp;    for (i = 0; i < tcp_stream_table_size; i++) {    for (a_tcp = tcp_stream_table[i];         a_tcp;         a_tcp = a_tcp->next_node) {      for (j = a_tcp->listeners; j; j = j->next) {          a_tcp->nids_state = NIDS_EXITING;          (j->item)(a_tcp, &j->data);      }    }  }}        voidprocess_tcp(u_char * data, int skblen){  struct ip *this_iphdr = (struct ip *)data;  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 (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    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;  }  if (!(this_tcphdr->th_flags & TH_ACK))    detect_scan(this_iphdr);  if (!nids_params.n_tcp_streams) return;  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;  }  check_flags(this_iphdr, this_tcphdr);  if (!(a_tcp = find_stream(this_tcphdr, this_iphdr, &from_client))) {    if ((this_tcphdr->th_flags & TH_SYN) &&	!(this_tcphdr->th_flags & TH_ACK) &&	!(this_tcphdr->th_flags & TH_RST))      add_new_tcp(this_tcphdr, this_iphdr);    return;  }  if (from_client) {    snd = &a_tcp->client;    rcv = &a_tcp->server;  }  else {    rcv = &a_tcp->client;    snd = &a_tcp->server;  }  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;    if (a_tcp->client.seq != ntohl(this_tcphdr->th_ack))      return;    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);    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;	    return;  }  if (!before(ntohl(this_tcphdr->th_seq), rcv->ack_seq + rcv->window) ||      before(ntohl(this_tcphdr->th_seq) + datalen, rcv->ack_seq))    return;  if ((this_tcphdr->th_flags & TH_RST)) {    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);    }    free_tcp(a_tcp);    return;  }  /* PAWS check */  if (rcv->ts_on && get_ts(this_tcphdr, &tmp_ts) &&   	before(tmp_ts, snd->curr_ts))  return; 	    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;	  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;	    	    (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;	    }	  }	  if (!a_tcp->listeners) {	    free_tcp(a_tcp);	    return;	  }	  a_tcp->nids_state = NIDS_DATA;	}      }      // return;    }  }  if ((this_tcphdr->th_flags & TH_ACK)) {    handle_ack(a_tcp, snd, rcv, 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);      free_tcp(a_tcp);      return;    }  }  if (datalen + (this_tcphdr->th_flags & TH_FIN) > 0)    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)    free_tcp(a_tcp);}voidnids_discard(struct tcp_stream * a_tcp, int num){  if (num < a_tcp->read)    a_tcp->read = num;}voidnids_register_tcp(void (*x)){  struct proc_node *i;  i = mknew(struct proc_node);  i->item = x;  i->next = tcp_procs;  tcp_procs = i;}inttcp_init(int size){  int i;  if (!nids_params.n_tcp_streams) return 0;  tcp_stream_table_size = nids_params.n_tcp_streams;  tcp_stream_table = malloc(tcp_stream_table_size * sizeof(char *));  if (!tcp_stream_table)    nids_params.no_mem("tcp_init");  memset(tcp_stream_table, 0, tcp_stream_table_size * sizeof(char *));  max_stream = 3 * tcp_stream_table_size / 4;  streams_pool = (struct tcp_stream *) malloc((max_stream + 1) * sizeof(struct tcp_stream));  if (!streams_pool)    nids_params.no_mem("tcp_init");  for (i = 0; i < max_stream; i++)    streams_pool[i].next_free = &(streams_pool[i + 1]);  streams_pool[max_stream].next_free = 0;  free_streams = streams_pool;  init_hash();   return 0;}#if HAVE_ICMPHDR#define STRUCT_ICMP struct icmphdr#define ICMP_CODE   code#define ICMP_TYPE   type#else#define STRUCT_ICMP struct icmp#define ICMP_CODE   icmp_code#define ICMP_TYPE   icmp_type#endif#ifndef ICMP_DEST_UNREACH#define ICMP_DEST_UNREACH ICMP_UNREACH#define ICMP_PROT_UNREACH ICMP_UNREACH_PROTOCOL#define ICMP_PORT_UNREACH ICMP_UNREACH_PORT#define NR_ICMP_UNREACH   ICMP_MAXTYPE#endif				voidprocess_icmp(u_char * data){  struct ip *iph = (struct ip *) data;  struct ip *orig_ip;  STRUCT_ICMP *pkt;  struct tcphdr *th;  struct half_stream *hlf;  int match_addr;  struct tcp_stream *a_tcp;  struct lurker_node *i;  int from_client;  int len = ntohs(iph->ip_len) - (iph->ip_hl << 2);    if (len < sizeof(STRUCT_ICMP))    return;  pkt = (STRUCT_ICMP *) (data + (iph->ip_hl << 2));  if (ip_compute_csum((char *) pkt, len))    return;  if (pkt->ICMP_TYPE != ICMP_DEST_UNREACH)    return;  len -= 8;  // sizeof(struct icmp) is not what we want here    if (len < sizeof(struct ip))    return;  orig_ip = (struct ip *) (((char *) pkt) + 8);  len -= orig_ip->ip_hl << 2;  if (len < 8)    return;  if ((pkt->ICMP_CODE & 15) == ICMP_PROT_UNREACH ||      (pkt->ICMP_CODE & 15) == ICMP_PORT_UNREACH)    match_addr = 1;  else    match_addr = 0;  if (pkt->ICMP_CODE > NR_ICMP_UNREACH)    return;  if (match_addr && (iph->ip_src.s_addr != orig_ip->ip_dst.s_addr))    return;  if (orig_ip->ip_p != IPPROTO_TCP)    return;  th = (struct tcphdr *) (((char *) orig_ip) + (orig_ip->ip_hl << 2));  if (!(a_tcp = find_stream(th, orig_ip, &from_client)))    return;  if (a_tcp->addr.dest == iph->ip_dst.s_addr)    hlf = &a_tcp->server;  else    hlf = &a_tcp->client;  if (hlf->state != TCP_SYN_SENT && hlf->state != TCP_SYN_RECV)    return;  a_tcp->nids_state = NIDS_RESET;  for (i = a_tcp->listeners; i; i = i->next)    (i->item) (a_tcp, &i->data);  free_tcp(a_tcp);}

⌨️ 快捷键说明

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