📄 detect.c
字号:
*/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 + -