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

📄 detect.c

📁 dnsguard是一种高性能DoS攻击检测和防护工具。它可以监听以太网上的ip协议数据流
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/time.h>#include <arpa/inet.h>#include <pcap.h>/* * Ethernet header */#define	ETHER_ADDR_LEN	6			/* length of ethernet address */#define ETHERTYPE_IP	0x0800  		/* IP protocol */#define ETHERTYPE_8021Q	0x8100			/* IEEE 802.1Q(vlan) protocol */struct	ether_header {    uint8_t	ether_dhost[ETHER_ADDR_LEN];	/* destination address */    uint8_t	ether_shost[ETHER_ADDR_LEN];	/* source address */    uint16_t	ether_type;			/* ether packet type */};/* * IP header */struct ip_header {    uint8_t		ip_vhl;		/* header length, version */#define IP_V(ip)	(((ip)->ip_vhl & 0xf0) >> 4)#define IP_HL(ip)	((ip)->ip_vhl & 0x0f)    uint8_t		ip_tos;		/* type of service */    uint16_t		ip_len;		/* total length */    uint16_t		ip_id;		/* identification */    uint16_t		ip_off;		/* fragment offset field */#define	IP_DF		0x4000		/* dont fragment flag */#define	IP_MF		0x2000		/* more fragments flag */#define	IP_OFFMASK	0x1fff		/* mask for fragmenting bits */    uint8_t		ip_ttl;		/* time to live */    uint8_t		ip_p;		/* protocol */    uint16_t		ip_sum;		/* checksum */    struct in_addr	ip_src,ip_dst;	/* source and dest address */};/* * monitor definition */#ifndef DEFAULT_MONITOR_INTERVAL#define DEFAULT_MONITOR_INTERVAL	3		/* default value of "-t" */#endif#ifndef DEFAULT_MONITOR_THRESHOLD#define DEFAULT_MONITOR_THRESHOLD	1000		/* default value of "-a" */#endif#define HASH_TABLE_SIZE			1000000		/* size of hash table,							 * it should be at least							 * two times of total							 * number of packets in							 * one interval to get							 * better performance. 							 */#define BLACKLIST_SIZE			1000		/* size of blacklist, that							 * means the maximum number							 * of attacker in a interval.							 */#define HASH_SEARCH_DEPTH		2		/* hash search depth, the							 * larger, the more accurate,							 * but slower as well.							 */#define MAX_ACCESS			10		/* maximum number of access							 * for distribution analysis.							 */#define MSG_RECV_ADDR			0x00010000	/* message type for receiving							 * a new address.							 */#define MSG_ATTACK			0x00000001	/* message type for get an							 * attacker.							 */#define MSG_REPORT			0x00000100	/* message type for generating							 * report every interval.							 */#define MAX_COUNTDOWN			10		/* maximum number of times							 * of receiving address							 * before refreshing timer.							 */struct monitor;/* * The handler for processing monitor message, e.g. MSG_RECV_ADDR, MSG_ATTACK. */typedef void (*message_handler)(void *, struct monitor *, int);/* * Address node struct to store address and the number of access from it. */struct address_node {    uint32_t 		addr;    unsigned int	age;    unsigned int	counter;};/* * Struct monitor is used to filter packets to find attacker. */struct monitor {    struct address_node	hash_table[HASH_TABLE_SIZE];	/* hash table. */    unsigned int	access[MAX_ACCESS + 1];		/* access distribution */    unsigned int	num;				/* number of access in one							 * interval. */    time_t		age;				/* timer. */    unsigned int	interval;			/* interval, that is "-t". */    unsigned int	threshold;			/* threshold, that is "-a". */    unsigned int	countdown;			/* see MAX_COUNTDOWN. */    struct address_node	*blacklist[BLACKLIST_SIZE];	/* attackers in one interval. */    unsigned int	n_blacklist;			/* number of attackers. */    uint32_t 		addr;				/* most recently received							 * address. */    message_handler	msghnd;				/* the function to process							 * messages of monitor. */    void 		*msghnd_data;			/* payload data for msghnd. */};/* * Make monitor to enter next interval. */time_t monitor_set_age(struct monitor *mon, time_t age);/* * Check whether next interval comes. */time_t monitor_is_new_age(struct monitor *mon);/* * Initialize monitor. */void monitor_init(struct monitor *mon);/* * Receive an address. */unsigned int monitor_recv_ip(struct monitor *mon, uint32_t addr);/* * Receive a packet. */void monitor_recv_packet(struct monitor *mon, const struct pcap_pkthdr *pkthdr,			 const u_char *packet);/* * session definition *//* Convert numeric address to xxx.xxx.xxx.xxx form. */#define INET_NTOA_HELPER(addr) inet_ntoa(*((struct in_addr *)(&(addr))))		/*  * Struct session is used to control the process of detecting attacker. */struct session {    char		*dev;		/* name of network interface to detect. */    pcap_t		*handle;	/* pcap handle. */    char		*filter_str;	/* filter string to build pcap filter. */    struct monitor	mon;		/* monitor. */    int			verbose;	/* verbose mode. */    int			count;		/* the number of packet received before exit*/};/* * Parse parameter. */int session_parse(struct session *s, int argc, char **argv);/* * Initialize session. */void session_init(struct session *s);/* * Callback funtion for receiving monitor message. */void session_recv_message(struct session *s, struct monitor *mon, int type);/* * Start detect. */int session_start(struct session *s);#ifdef	DEBUG			/* decide if show verbose ip information */#ifndef IPPROTO_ICMP#define IPPROTO_ICMP	1	/* control message protocol */#endif#ifndef IPPROTO_TCP#define IPPROTO_TCP	6	/* tcp */#endif#ifndef IPPROTO_UDP#define IPPROTO_UDP	17	/* user datagram protocol */#endif/* * UDP header */struct udp_header {    uint16_t	uh_sport;	/* source port */    uint16_t	uh_dport;	/* destination port */    uint16_t	uh_ulen;	/* udp length */    uint16_t	uh_sum;		/* udp checksum */};/* * Show somewhat detailed information of ip packet * * Parameters: *  iphdr	pointer of head of ip packet. */void show_ip_info(const struct ip_header *iphdr) {    char	*p;    char	buf[10];    /* probe protocol. */    switch (iphdr->ip_p) {    case IPPROTO_ICMP:	p = "icmp";	break;    case IPPROTO_TCP:	p = "tcp";	break;    case IPPROTO_UDP:	p = "udp";	break;    default:	p = buf;	sprintf(p, "ip:%d", iphdr->ip_p);	break;	    }    printf("%s  src=%s", p, INET_NTOA_HELPER(iphdr->ip_src.s_addr));    if (p == "udp" || p == "tcp") {	printf(":%d", ntohs(((struct udp_header *)(iphdr + 1))->uh_sport));    }    printf("  dst=%s", INET_NTOA_HELPER(iphdr->ip_dst.s_addr));    if (p == "udp" || p == "tcp") {	printf(":%d", ntohs(((struct udp_header *)(iphdr + 1))->uh_dport));    }    fputc('\n', stdout);}#endif/* * Get ip header from packet captured by pcap. * * Parameter: *  packet	packet captured by pcap. *  caplen	length of captured part. * * Return: *  pointer to ip head. */struct ip_header *get_ip_header(const char *packet,				bpf_u_int32 caplen) { recurse:    /* check if ip_header had been completely captured. */    if (caplen < sizeof(struct ether_header) + sizeof(struct ip_header)) {	return NULL;    }    switch (ntohs(((struct ether_header *)packet)->ether_type)) {    case ETHERTYPE_IP:		/* common ip packet of ethernet. */	return (struct ip_header *)((struct ether_header *)packet + 1);    case ETHERTYPE_8021Q:	/* virtual lan packet of ethernet. */	caplen -= 4;	packet += 4;	goto recurse;    default:			/* unknown ethernet protocol. */	return NULL;    }}/* * Make monitor to enter next interval. * * Parameter: *  monitor	monitor to process. *  age		the age of new interval. * * Return: *  the old age. */time_t monitor_set_age(struct monitor *mon,		       time_t age) {    time_t tmp = mon->age;    memset(mon->access, 0, sizeof(mon->access));    mon->age = age;		/* set new age. */    mon->num = 0;		/* reset number of accesses. */    mon->n_blacklist = 0;	/* reset blacklist. */    return tmp;}/* * Check system time to find if next interval comes. * * Parameter: *  mon		monitor * * Return: *  0, if next interval does not come. *  age of next interval, if next interval comes. */time_t monitor_is_new_age(struct monitor *mon){    time_t age;        /* since fetching system time is time costly operation, so we do nothing     * before "countdown" times of probing. */    if (mon->countdown != 0) {	mon->countdown--;	return 0;    }    mon->countdown = (MAX_COUNTDOWN > mon->threshold)	? mon->threshold : MAX_COUNTDOWN;	    mon->countdown--;    age = time(NULL) / mon->interval;    return (mon->age != age) ? age : 0;}/* * Initialize monitor. * * Parameter: *  mon		monitor */void monitor_init(struct monitor *mon){    memset(mon->hash_table, 0, sizeof(mon->hash_table));    monitor_set_age(mon, 0);    mon->countdown = 0;    mon->interval = DEFAULT_MONITOR_INTERVAL;    mon->threshold = DEFAULT_MONITOR_THRESHOLD;}/* * Receive an address. * * Parameter: *  mon		monitor *  addr	address * * Return: *  number of accesses of this address in current interval.

⌨️ 快捷键说明

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