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

📄 libnids.c

📁 基于TCP/IP协议的网络入侵检测系统是在Linux平台下
💻 C
字号:
/*  Copyright (c) 1999 Rafal Wojtczuk <nergal@avet.com.pl>. All rights reserved.  See the file COPYING for license details.*/#include <sys/types.h>#include <netinet/in.h>#include <netinet/in_systm.h>#include <netinet/ip.h>#include <netinet/tcp.h>#include <netinet/udp.h>#include <arpa/inet.h>#include <stdlib.h>#include <string.h>#include <syslog.h>#include <pcap.h>#include <errno.h>#include "checksum.h"#include "ip_fragment.h"#include "scan.h"#include "tcp.h"#include "util.h"#include "nids.h"#if (HAVE_NEW_PCAP)#include <linux/if_packet.h>extern int set_all_promisc();extern int pcap_open_live_new(u_char *, int, int, int,u_char *, int, u_short, void *);#endif#define int_ntoa(x)	inet_ntoa(*((struct in_addr *)&x))extern int ip_options_compile(char *);extern int raw_init();static void nids_syslog(int, int, struct ip *, void *);static int nids_ip_filter(struct ip *,int);static struct proc_node *ip_frag_procs;static struct proc_node *ip_procs;static struct proc_node *udp_procs;struct proc_node *tcp_procs;static int linkoffset = 0;static int linktype;static pcap_t *desc = 0;char nids_errbuf[PCAP_ERRBUF_SIZE];char *nids_warnings[] ={  "Murphy - you never should see this message !",  "Oversized IP packet",  "Invalid IP fragment list: fragment over size",  "Overlapping IP fragments",  "Invalid IP header",  "Source routed IP frame",  "Max number of TCP streams reached",  "Invalid TCP header",  "Too much data in TCP receive queue",  "Invalid TCP flags"};struct nids_prm nids_params = {  1040,			/* n_tcp_streams */  256,			/* n_hosts */  NULL,			/* device */  168,			/* sk_buff_size */  -1,			/* dev_addon */  nids_syslog,		/* syslog() */  LOG_ALERT,		/* syslog_level */  256,			/* scan_num_hosts */  3000,			/* scan_delay */  10,			/* scan_num_ports */  nids_no_mem,		/* no_mem() */  nids_ip_filter,	/* ip_filter() */  NULL,			/* pcap_filter */  1,                    /* promisc */  0			/* one_loop_less */};static intnids_ip_filter(struct ip * x, int len){  return 1;}static voidnids_syslog(int type, int errnum, struct ip * iph, void *data){  char saddr[20], daddr[20];  char buf[1024];  struct host *this_host;  unsigned char flagsand = 255, flagsor = 0;  int i;    switch (type) {  case NIDS_WARN_IP:    if (errnum != NIDS_WARN_IP_HDR) {      strcpy(saddr, int_ntoa(iph->ip_src.s_addr));      strcpy(daddr, int_ntoa(iph->ip_dst.s_addr));      syslog(nids_params.syslog_level,	   "%s, packet (apparently) from %s to %s\n", nids_warnings[errnum],	     saddr, daddr);    }    else      syslog(nids_params.syslog_level, "%s\n", nids_warnings[errnum]);    break;  case NIDS_WARN_TCP:    strcpy(saddr, int_ntoa(iph->ip_src.s_addr));    strcpy(daddr, int_ntoa(iph->ip_dst.s_addr));    if (errnum != NIDS_WARN_TCP_HDR)      syslog(nids_params.syslog_level,	     "%s,from %s:%hi to  %s:%hi\n", nids_warnings[errnum], saddr,	     ntohs(((struct tcphdr *) data)->th_sport), daddr,	     ntohs(((struct tcphdr *) data)->th_dport));    else      syslog(nids_params.syslog_level, "%s,from %s to %s\n",	     nids_warnings[errnum], saddr, daddr);    break;  case NIDS_WARN_SCAN:    this_host = (struct host *) data;    sprintf(buf, "Scan from %s. Scanned ports: ", int_ntoa(this_host->addr));    for (i = 0; i < this_host->n_packets; i++) {      strcat(buf, int_ntoa(this_host->packets[i].addr));      sprintf(buf + strlen(buf), ":%hi,", this_host->packets[i].port);      flagsand &= this_host->packets[i].flags;      flagsor |= this_host->packets[i].flags;    }    if (flagsand == flagsor) {      i = flagsand;      switch (flagsand) {      case 2:	strcat(buf, "scan type: SYN");	break;      case 0:	strcat(buf, "scan type: NULL");	break;      case 1:	strcat(buf, "scan type: FIN");	break;      default:	sprintf(buf + strlen(buf), "flags=0x%x", i);      }    }    else      strcat(buf, "various flags");    syslog(nids_params.syslog_level, "%s", buf);    break;  default:    syslog(nids_params.syslog_level, "Unknown warning number ?\n");  }}static voidpcap_hand(u_char *par, struct pcap_pkthdr *hdr, u_char *data){  struct proc_node *i;  /* Only handle IP packets below. */  if (linktype == DLT_EN10MB && (data[12] != 8 || data[13] != 0))    return;  #if ( HAVE_NEW_PCAP )  /* let's get rid of duplicate packets on loopback */  if (hdr->pkt_type==PACKET_OUTGOING) {  	 struct ip * iph = (struct ip *)(data + linkoffset);  	 if (ntohl(iph->ip_dst.s_addr) == 0x7f000001) return;  }  #endif	    for (i = ip_frag_procs; i; i = i->next)    (i->item) (data + linkoffset, hdr->len - linkoffset);}static voidgen_ip_frag_proc(u_char *data, int len){  struct proc_node *i;  struct ip *iph = (struct ip *)data;  int need_free = 0;  int skblen;    if (!nids_params.ip_filter(iph,len))    return;    if (len < sizeof(struct ip) || iph->ip_hl < 5 || iph->ip_v != 4 ||      ip_fast_csum((unsigned char *) iph, iph->ip_hl) != 0 ||      len < ntohs(iph->ip_len) ||      ntohs(iph->ip_len) < iph->ip_hl << 2) {    nids_params.syslog(NIDS_WARN_IP, NIDS_WARN_IP_HDR, iph, 0);    return;  }  if (iph->ip_hl > 5 && ip_options_compile(data)) {    nids_params.syslog(NIDS_WARN_IP, NIDS_WARN_IP_SRR, iph, 0);    return;  }  switch (ip_defrag_stub((struct ip *)data, &iph)) {  case IPF_ISF:    return;  case IPF_NOTF:    need_free = 0;    iph = (struct ip *) data;    break;  case IPF_NEW:    need_free = 1;    break;  default:;  }  skblen = ntohs(iph->ip_len) + 16;  if (!need_free)    skblen += nids_params.dev_addon;  skblen = (skblen + 15) & ~15;  skblen += nids_params.sk_buff_size;    for (i = ip_procs; i; i = i->next)    (i->item) (iph, skblen);  if (need_free)    free(iph);}#if HAVE_BSD_UDPHDR#define UH_ULEN uh_ulen#define UH_SPORT uh_sport#define UH_DPORT uh_dport#else#define UH_ULEN len#define UH_SPORT source#define UH_DPORT dest#endifstatic voidprocess_udp(char *data){  struct proc_node *ipp=udp_procs;  struct ip *iph = (struct ip *)data;  struct udphdr * udph;  struct tuple4 addr;  int hlen=iph->ip_hl<<2;  int len=ntohs(iph->ip_len);  int ulen;  if (len-hlen<sizeof(struct udphdr))  	return;  udph=(struct udphdr *)(data+hlen);  ulen=ntohs(udph->UH_ULEN);  if (len-hlen<ulen || ulen<sizeof(struct udphdr))  	return;  if (my_udp_check((void *)udph,ulen,iph->ip_src.s_addr, iph->ip_dst.s_addr))      return;  addr.source=ntohs(udph->UH_SPORT);  addr.dest=ntohs(udph->UH_DPORT);  addr.saddr=iph->ip_src.s_addr;  addr.daddr=iph->ip_dst.s_addr;  while (ipp)  {  ipp->item(&addr, ((char*)udph)+sizeof(struct udphdr),                   ulen-sizeof(struct udphdr),data);  ipp=ipp->next;  }}         	  	  static voidgen_ip_proc(u_char * data, int skblen){  switch (((struct ip *) data)->ip_p) {  case IPPROTO_TCP:    process_tcp(data, skblen);    break;  case IPPROTO_UDP:    process_udp(data);    break;  case IPPROTO_ICMP:    if (nids_params.n_tcp_streams)	    process_icmp(data);    break;  default:    break;  }}static voidinit_procs(){  ip_frag_procs = mknew(struct proc_node);  ip_frag_procs->item = gen_ip_frag_proc;  ip_frag_procs->next = 0;  ip_procs = mknew(struct proc_node);  ip_procs->item = gen_ip_proc;  ip_procs->next = 0;  tcp_procs = 0;  udp_procs = 0;}voidnids_register_udp(void (*x)){  struct proc_node *ipp = mknew(struct proc_node);  ipp->item = x;  ipp->next = udp_procs;  udp_procs = ipp;}voidnids_register_ip(void (*x)){  struct proc_node *ipp = mknew(struct proc_node);  ipp->item = x;  ipp->next = ip_procs;  ip_procs = ipp;}voidnids_register_ip_frag(void (*x)){  struct proc_node *ipp = mknew(struct proc_node);  ipp->item = x;  ipp->next = ip_frag_procs;  ip_frag_procs = ipp;}intnids_init(){  char *device;  if (nids_params.device == NULL)    nids_params.device = pcap_lookupdev(nids_errbuf);  if (nids_params.device == NULL)    return 0;  device = nids_params.device;  if (!strcmp(device,"all")) {  #if (HAVE_NEW_PCAP)      if ((desc=(pcap_t *)pcap_open_live_new(0, 16384, -2, 1000, nids_errbuf, 0, 0, 0)) == NULL )	return 0;      if (nids_params.promisc && !set_all_promisc())      {        nids_errbuf[0]=0;        strncat(nids_errbuf, strerror(errno), sizeof(nids_errbuf) - 1);      	return 0;      }	  #else      strcpy(nids_errbuf,"Unable to sniff on all devices - install new libpcap");      return 0;  #endif  } else              if ((desc = pcap_open_live(device, 16384, nids_params.promisc!=0, 1024, nids_errbuf)) == NULL)    return 0;  #if (HAVE_NEW_PCAP)  	/* and somehow broken...*/  	if (!nids_params.pcap_filter) nids_params.pcap_filter="";  #endif    if (nids_params.pcap_filter != NULL) {//    u_int net, mask=0;  u_int mask=0;    struct bpf_program fcode;    //    if (pcap_lookupnet(device, &net, &mask, nids_errbuf) == -1)//      return 0;    if (pcap_compile(desc, &fcode, nids_params.pcap_filter, 1, mask) < 0)      return 0;    if (pcap_setfilter(desc, &fcode) == -1)      return 0;  }  switch ((linktype = pcap_datalink(desc))) {  case DLT_EN10MB:    linkoffset = 14;    break;  case DLT_PPP:    linkoffset = 4;    break;  /* Token Ring Support by vacuum@technotronic.com, thanks dugsong! */   case DLT_IEEE802:     linkoffset = 22;     break;      case DLT_RAW:  case DLT_SLIP:    linkoffset = 0;    break;  default:    fprintf(stderr, "link type unknown, defaulting to ethernet.\n");    linktype = DLT_EN10MB;    linkoffset = 14;    break;  }  if (nids_params.dev_addon == -1) {    if (linktype == DLT_EN10MB)      nids_params.dev_addon = 16;    else      nids_params.dev_addon = 0;  }  if (nids_params.syslog == nids_syslog)    openlog("libnids", 0, LOG_LOCAL0);    init_procs();  tcp_init(nids_params.n_tcp_streams);  ip_frag_init(nids_params.n_hosts);  scan_init();  if (!raw_init())  {  	nids_errbuf[0]=0;        strncat(nids_errbuf, strerror(errno), sizeof(nids_errbuf) - 1);        return 0;  }  	                             return 1;}voidnids_run(){  if (!desc) {    strcpy(nids_errbuf, "Libnids not initialized");    return;  }  pcap_loop(desc, -1, (pcap_handler) pcap_hand, 0);  strcpy(nids_errbuf, "loop: ");  strncat(nids_errbuf, pcap_geterr(desc), sizeof(nids_errbuf) - 7);  pcap_close(desc);}intnids_getfd(){  if (!desc) {    strcpy(nids_errbuf, "Libnids not initialized");    return -1;  }  return pcap_fileno(desc);}intnids_next(){  struct pcap_pkthdr h;  char *data;  if (!desc) {    strcpy(nids_errbuf, "Libnids not initialized");    return 0;  }  if (!(data = (char *) pcap_next(desc, &h))) {    strcpy(nids_errbuf, "next: ");    strncat(nids_errbuf, pcap_geterr(desc), sizeof(nids_errbuf) - 7);    return 0;  }  pcap_hand(0, &h, data);  return 1;}

⌨️ 快捷键说明

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