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

📄 detect.c

📁 dnsguard是一种高性能DoS攻击检测和防护工具。它可以监听以太网上的ip协议数据流
💻 C
📖 第 1 页 / 共 2 页
字号:
 */unsigned int monitor_recv_ip(struct monitor *mon, 			     uint32_t addr){    unsigned int	hash, h1, h2;    unsigned int	counter_min;    int 		i;    struct address_node	*node, *node_min;	    mon->num++;	    h1 = addr % HASH_TABLE_SIZE;    h2 = 1 + (addr % (HASH_TABLE_SIZE - 1));	    /* open address hash search algorithm. */    counter_min = -1;    for (i = 0; i < HASH_SEARCH_DEPTH; i++) {	hash = (h1 + i * h2) % HASH_TABLE_SIZE;	/* hash. */	node = &mon->hash_table[hash];		/* find node. */	if (node->addr == addr || node->age < mon->age) {	    break;				/* got what we want. */	} else if (node->counter < counter_min) {	    counter_min = node->counter;	/* found a better slot to store 						 * address. */	    node_min = node;	}    }	    if (i == HASH_SEARCH_DEPTH) {	node = node_min;			/* not found what we want. */	node->addr = addr;	node->age = mon->age;	node->counter = 0;    } else if (node->age < mon->age) {	node->addr = addr;			/* update node. */	node->age = mon->age;	node->counter = 0;    }    node->counter++;				/* calculate distribution info. */    if (node->counter <= MAX_ACCESS) {	mon->access[node->counter - 1]--;	mon->access[node->counter]++;    }    if (node->counter == mon->threshold 	/* check if it is an attacker. */	&& mon->n_blacklist < BLACKLIST_SIZE) {	mon->blacklist[mon->n_blacklist] = node;	mon->n_blacklist++;	if (mon->msghnd != NULL) {	    mon->msghnd(mon->msghnd_data, mon, MSG_ATTACK);	}    }			    return node->counter; }/* * Receive a packet. * * Parameter: *  mon		monitor. *  pkthdr	packet head infomation. *  packet	packet. */void monitor_recv_packet(struct monitor *mon,			 const struct pcap_pkthdr *pkthdr,			 const u_char *packet){    const u_char		*end;    const struct ip_header	*iphdr;    const u_char		*p;    int				caplen;    time_t			new_age;    int				i;    /* get ip head from packet. */    if (!(iphdr = get_ip_header(packet, pkthdr->caplen))) {	return;    }    mon->addr = iphdr->ip_src.s_addr;    if (mon->msghnd != NULL) {#ifdef DEBUG	mon->addr = (uint32_t)iphdr;	mon->msghnd(mon->msghnd_data, mon, MSG_RECV_ADDR);	mon->addr = iphdr->ip_src.s_addr;#else	mon->msghnd(mon->msghnd_data, mon, MSG_RECV_ADDR);#endif	    }	    /* check if next interval comes. */    if (new_age = monitor_is_new_age(mon)) {	if (mon->msghnd != NULL) {	    /* if comes, then generate report. */	    mon->msghnd(mon->msghnd_data, mon, MSG_REPORT);	}	monitor_set_age(mon, new_age);    }	    /* detect the address. */    monitor_recv_ip(mon, mon->addr);}/* * Parse parameters. *  * Parameters: *  s		session. *  argc	number of parameters. *  argv	parameters array. * * Return: *  0, all parameters are correct. *  1, not all parameters are correct. */int session_parse(struct session *s, 		  int argc, 		  char **argv){    int			c;    int			i, tmp;    struct in_addr	tmp_addr;    struct hostent	*ent;    char		*net, *mask, *p;	    optind = 1;    while ((c = getopt(argc, argv, "ht:a:i:c:vw")) != -1) {	// printf("%c = %s, %d %d %d\n", c, optarg, optind, opterr, optopt);	switch (c) {	case 'h':	/* need help?? */	    fprintf(stderr, "Help is under construction...");	    return -1;				case 't':	/* interval. */	    if ((tmp = atoi(optarg)) <= 0) {		fprintf(stderr, "parameter (t)ime must be an integer greater than 0.\n");		return -1;	    }	    s->mon.interval = tmp;	    break;				case 'a':	/* threshold. */	    if ((tmp = atoi(optarg)) <= 0) {		fprintf(stderr, "parameter (a)ccess must be an integer greater than 0.\n");		return -1;	    }	    s->mon.threshold = tmp;	    break;				case 'i':	/* network interface. */	    s->dev = optarg;	    break;				case 'c':	/* number of packets to receive. */	    if ((tmp = atoi(optarg)) <= 0) {		fprintf(stderr, "parameter (c)ount must be an integer greater than 0.\n");		return -1;	    }	    s->count = tmp;	    break;			#ifdef DEBUG	case 'v':	/* verbose. */	    s->verbose = 1;	    break;			case 'w':	/* very verbose. */	    s->verbose = 2;	    break;#endif	case '?':	/* error */	    return -1;	}    }    /* parse filter */    if (optind < argc) {	for (tmp = argc - optind, i = optind; i < argc; i++) {	    tmp += strlen(argv[i]);	}	s->filter_str = p = (char *)malloc(tmp);	for (i = optind; i < argc; i++) {	    strcpy(p, argv[i]);	    p += strlen(argv[i]);	    *p++ = ' ';	}	*(p - 1) = 0;    }    //	printf("%c = %s, %d %d %d\n", c, optarg, optind, opterr, optopt);    return 0;}/* * Initialize session. * * Parameters: *  s	session */void session_init(struct session *s){    monitor_init(&s->mon);    s->dev = NULL;    s->handle = NULL;    s->filter_str = NULL;    s->verbose = 0;    s->count = -1;}/* * Callback funtion for receiving monitor message. * * Parameters: *  s		session *  mon		monitor *  type	message type */void session_recv_message(struct session *s, 			  struct monitor *mon, 			  int type){    int			i;    struct timeval	tv;    if (type > (1 << (8 * s->verbose))) {	return;    }	    switch (type) {    case MSG_RECV_ADDR:#ifndef DEBUG	printf("ip %s\n", INET_NTOA_HELPER(mon->addr));#else	show_ip_info((struct ip_header *)mon->addr);#endif	break;		    case MSG_REPORT:	for (i = 0; i < s->mon.n_blacklist; i++) {	    printf("blacklist %s %d\n", 		   INET_NTOA_HELPER(s->mon.blacklist[i]->addr),		   mon->blacklist[i]->counter);				}	printf("access %d %d\n", mon->num, -mon->access[0]);	fflush(stdout);	break;		    case MSG_ATTACK:	gettimeofday(&tv, NULL);	if (tv.tv_sec / mon->interval > mon->age) {	    i = mon->threshold;	} else {	    i = (double)mon->threshold * mon->interval		/ (tv.tv_sec % mon->interval + tv.tv_usec / 1000000.0);	}	printf("attack %s %d\n", INET_NTOA_HELPER(mon->addr), i);	fflush(stdout);	break;    }}/* * Start detect. * * Parameters: *  s	session */int session_start(struct session *s){    char		errbuf[PCAP_ERRBUF_SIZE];    bpf_u_int32		net, mask;    struct bpf_program	filter;	    /* find network interface. */    if (!s->dev && !(s->dev = pcap_lookupdev(errbuf))) {	fprintf(stderr, "%s\n", errbuf);	return -1;    }	    /* get network address and mask bound to the interface. */    if (pcap_lookupnet(s->dev, &net, &mask, errbuf)) {	fprintf(stderr, "pcap_lookupnet(): %s\n", errbuf);	return -1;    }    /* create pcap handle. */    if (!(s->handle = pcap_open_live(s->dev, 56, 1, 100, errbuf))) {	fprintf(stderr, "pcap_open_live(): %s\n", errbuf);	return -1;    }    /* check if it is ethernet interface. */    if (pcap_datalink(s->handle) != DLT_EN10MB) {	fprintf(stderr, "%s is not ethernet interface.\n", s->dev);	return -1;    }    if (s->filter_str != NULL) {	/* create pcap filter. */	// printf("filter_str: %s\n", s->filter_str);	if (pcap_compile(s->handle, &filter, s->filter_str, 1, 0)) {	    fprintf(stderr, "pcap_compile(): %s\n", 		    pcap_geterr(s->handle));	    return -1;	}	/* enable filter. */	pcap_setfilter(s->handle, &filter);    }	    /* show interface information. */    fputs("Detect network interface: ", stderr);    fputs(s->dev, stderr);    fputc('(', stderr);    fputs(INET_NTOA_HELPER(net), stderr);    fputc(':', stderr);    fputs(INET_NTOA_HELPER(mask), stderr);    fputs(")\n", stderr);	    s->mon.msghnd = (message_handler)session_recv_message;    s->mon.msghnd_data = (void *)s;    /* start pcap loop. */    if (pcap_loop(s->handle, s->count, (pcap_handler)monitor_recv_packet, 		  (u_char *)(&s->mon)) == -1) {	fprintf(stderr, "pcap_loop(): %s\n", errbuf);	return -1;    }    return 0;}/* * Main entry. */int main(int argc, 	 char **argv){    struct session *s;    s = (struct session *)malloc(sizeof(struct session));    session_init(s);    if (session_parse(s, argc, argv)) {	exit(1);    }    if (session_start(s)) {	exit(1);    }	    return 0;}

⌨️ 快捷键说明

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