www.pudn.com > src.rar > scan.c


/* 
  Copyright (c) 1999 Rafal Wojtczuk . All rights reserved. 
  See the file COPYING for license details. 
*/ 
 
#include  
#ifndef WIN32 
	#include  
#endif 
#include  
#include  
#include  
#include  
#include  
#include  
 
#include "nids.h" 
#include "scan.h" 
 
static struct host **hashhost; 
static int time0; 
static int timenow; 
 
static int 
gettime() 
{ 
  struct timeval tv; 
   
  if (timenow) 
    return timenow; 
  gettimeofday(&tv, 0); 
  timenow = (tv.tv_sec - time0) * 1000 + tv.tv_usec / 1000; 
 
  return timenow; 
} 
 
void 
scan_init() 
{ 
  struct timeval tv; 
 
  if (nids_params.scan_num_hosts > 0) { 
    gettimeofday(&tv, 0); 
    time0 = tv.tv_sec; 
    hashhost = (struct host **) malloc(sizeof(struct host *) * nids_params.scan_num_hosts); 
    if (!hashhost) 
      nids_params.no_mem("scan_init"); 
    memset(hashhost, 0, sizeof(struct host *) * nids_params.scan_num_hosts); 
  } 
} 
 
static int 
scan_hash(int addr) 
{ 
  return ((addr % 65536) ^ (addr >> 16)) % (nids_params.scan_num_hosts); 
} 
 
void 
detect_scan(struct ip * iph) 
{ 
  int i; 
  struct tcphdr *th; 
  int hash; 
  struct host *this_host; 
  struct host *oldest; 
  int mtime = 2147483647; 
 
  if (nids_params.scan_num_hosts <= 0) 
    return; 
   
  th = (struct tcphdr *) (((char *) iph) + 4 * iph->ip_hl); 
  hash = scan_hash(iph->ip_src.s_addr); 
  this_host = hashhost[hash]; 
  oldest = 0; 
  timenow = 0; 
 
  for (i = 0; this_host && this_host->addr != iph->ip_src.s_addr; i++) { 
    if (this_host->modtime < mtime) { 
      mtime = this_host->modtime; 
      oldest = this_host; 
    } 
    this_host = this_host->next; 
  } 
  if (!this_host) { 
    if (i == 10) 
      this_host = oldest; 
    else { 
      this_host = (struct host *) malloc(sizeof(struct host) + \ 
		    (nids_params.scan_num_ports + 1) * sizeof(struct scan)); 
      if (!this_host) 
	nids_params.no_mem("detect_scan"); 
      this_host->packets = (struct scan *) (((char *) this_host) + sizeof(struct host)); 
      if (hashhost[hash]) { 
	hashhost[hash]->prev = this_host; 
	this_host->next = hashhost[hash]; 
      } 
      else 
	this_host->next = 0; 
      this_host->prev = 0; 
      hashhost[hash] = this_host; 
    } 
    this_host->addr = iph->ip_src.s_addr; 
    this_host->modtime = gettime(); 
    this_host->n_packets = 0; 
  } 
  if (this_host->modtime - gettime() > nids_params.scan_delay) 
    this_host->n_packets = 0; 
  this_host->modtime = gettime(); 
  for (i = 0; i < this_host->n_packets; i++) 
    if (this_host->packets[i].addr == iph->ip_dst.s_addr && 
	this_host->packets[i].port == ntohs(th->th_dport)) 
      return; 
  this_host->packets[this_host->n_packets].addr = iph->ip_dst.s_addr; 
  this_host->packets[this_host->n_packets].port = ntohs(th->th_dport); 
  this_host->packets[this_host->n_packets].flags = *((unsigned char *) (th) + 13); 
  this_host->n_packets++; 
  if (this_host->n_packets > nids_params.scan_num_ports) { 
    nids_params.syslog(NIDS_WARN_SCAN, 0, 0, this_host); 
    this_host->n_packets = 0; 
  } 
}