📄 sniff.c
字号:
sniffer_log_print(si, slog); slog->src_to_dst = 1; } } while (data_len) { if ((space = LOG_BUF_SIZE - slog->loged_bytes) < 0) space = 0; i = min(data_len, space); memcpy(&slog->buf[slog->loged_bytes], data, i); slog->loged_bytes += i; data += i; data_len -= i; if (slog->loged_bytes == LOG_BUF_SIZE) { sniffer_log_print(si, slog); slog->state = si->search ? STATE_SRCH : STATE_LOG; } } if (slog->loged_bytes >= si->log_bytes) { sniffer_log_print(si, slog); slog->state = si->search ? STATE_SRCH : STATE_LOG; }}static void *sniffer(void *arg){ struct sniff_info *si; struct sniff_log *slog; struct packet *p; char *data; pthread_sigmask(SIG_BLOCK, &intr_mask, NULL); setpriority(PRIO_PROCESS, getpid(), 10); while ((p = list_consume(&l_sniff_pkt, NULL))) { si = p->p_arg[MODULE_SNIFF]; if ((data = sniffer_match(p, si, &slog))) sniffer_log(data, p, si, slog); pthread_mutex_unlock(&si->mutex); packet_free(p); } return NULL;}/***************************************************************************************** * * management * */static int sniff_daemon_init(void){ struct stat stat_buf; if (stat(SNIFF_FILE_DIR, &stat_buf) == 0) { if (!S_ISDIR(stat_buf.st_mode)) { printf(SNIFF_FILE_DIR " isn't directory\n"); return -1; } } else { if (errno == ENOENT) { if (mkdir(SNIFF_FILE_DIR, 0700) < 0) { printf(SNIFF_FILE_DIR " can't be created\n"); return -1; } printf("directory " SNIFF_FILE_DIR " created\n"); } else { printf(SNIFF_FILE_DIR " error\n"); return -1; } } return 0;}static void start_sniff(void){ if (sniffer_running) { printf("sniffer already running\n"); return; } if (sniff_daemon_init()) return; list_produce_start(&l_sniff_pkt); pthread_create(&sniff_thr, NULL, (void *(*)(void *)) sniffer, NULL); ifunc_sniff.func = func_sniff; ifunc_sniff.arg = NULL; list_enqueue(&l_ifunc_tcp, &ifunc_sniff); sniffer_running = 1; printf("sniffer started\n");}static void stop_sniff(void){ struct list_iterator li; struct sniff_info *si; struct sniff_log *slog; if (!sniffer_running) { printf("sniffer isn't running\n"); return; } list_remove(&l_ifunc_tcp, &ifunc_sniff); packet_flush(&l_sniff_pkt); list_produce_done(&l_sniff_pkt); pthread_join(sniff_thr, NULL); list_lock(&l_sniff_db); list_iter_set(&li, &l_sniff_db); while ((si = list_iter_get(&li))) { while ((slog = list_pop(&si->log))) free_sniff_log(slog); } list_iter_end(&li); list_unlock(&l_sniff_db); sniffer_running = 0; printf("sniffer stopped\n");}void print_sniff_daemon(void){ if (sniffer_running) { if (pthread_kill(sniff_thr, 0) != 0) { pthread_join(sniff_thr, NULL); sniff_thr = (pthread_t) 0; sniffer_running = 0; set_tty_color(COLOR_BRIGHTRED); printf("Sniffer daemon failed - bug\n"); set_tty_color(COLOR_LIGHTGRAY); } else printf("S"); }}/* * user interface */static void sniff_item_log_print(FILE *f, int *l_nr, struct sniff_info *si){ struct list_iterator li; struct sniff_log *slog; char *state; char host_buf[BUFSIZE]; list_iter_set(&li, &si->log); while ((slog = list_iter_get(&li))) { switch (slog->state) { case STATE_LOG: state = "LOG"; break; case STATE_SRCH: state = "SRCH"; break; default: state = "ERR"; break; } sprintf(host_buf, "%s [%s]", host_lookup(slog->src_addr, hl_mode), port_lookup(slog->src_port, hl_mode)); fprintf(f, "\t%-24s -> %s [%s] loged=%dB state=%s\n", host_buf, host_lookup(slog->dst_addr, hl_mode), port_lookup(slog->dst_port, hl_mode), slog->loged_bytes, state); if (++(*l_nr) % lines_o == 0) lines_o_press_key(); } list_iter_end(&li);}static void sniff_list_db(int all){ struct list_iterator li; struct sniff_info *si; int i = 0; int l_nr = 0; list_iter_set(&li, &l_sniff_db); while ((si = list_iter_get(&li))) { sniff_item_print(stdout, i++, si); if (++l_nr % lines_o == 0) lines_o_press_key(); if (all) sniff_item_log_print(stdout, &l_nr, si); } list_iter_end(&li);} static void sniff_add_item(void){ char buf[BUFSIZE], *buf_p; char file_name[BUFSIZE], file_name_buf[BUFSIZE]; struct sniff_info *si; unsigned int src_ip, dst_ip; int src_mask, dst_mask; int src_ports[MAX_PORTS + 1], dst_ports[MAX_PORTS + 1]; int srch_mode, len; int log_mode, log_bytes; int nr; FILE *f; if (menu_choose_host_mask_ports_dfl("src ip addr/mask ports", &src_ip, &src_mask, src_ports, 0, 0, NULL) < 0) return; if (menu_choose_host_mask_ports_dfl("dst ip addr/mask ports", &dst_ip, &dst_mask, dst_ports, 0, 0, NULL) < 0) return; buf_p = NULL; srch_mode = MODE_BOTH; switch (menu_choose_char("want to search for y/n", "yn", 'y')) { case 'y': if ((srch_mode = menu_choose_sdb("srch_mode", 'b')) == -1) return; if (menu_choose_string("search for", buf, sizeof(buf), NULL) < 0) return; buf_p = buf; break; }; if ((log_mode = menu_choose_sdb("log mode", 's')) < 0) return; if ((log_bytes = menu_choose_unr("log bytes", 0, 1000000000, 64)) < 0) return; if (menu_choose_string("log file name [by conn]", file_name_buf, sizeof(file_name_buf), NULL) < 0) file_name_buf[0] = 0; if ((nr = menu_choose_unr("insert at", 0, list_count(&l_sniff_db), list_count(&l_sniff_db))) == -1) return; if (file_name_buf[0]) { sprintf(file_name, "%s/%s", SNIFF_FILE_DIR, file_name_buf); if (!(f = fopen(file_name, "a+"))) { printf("can't open %s for writing\n", file_name); return; } } else f = NULL; si = malloc(sizeof(struct sniff_info)); memset(si, 0, sizeof(struct sniff_info)); pthread_mutex_init(&si->mutex, NULL); list_init(&si->log, offset_of(struct sniff_log, next)); si->src_addr = src_ip; si->src_mask = src_mask; port_htons(src_ports); memcpy(si->src_ports, src_ports, sizeof(int) * (MAX_PORTS + 1)); si->dst_addr = dst_ip; si->dst_mask = dst_mask; port_htons(dst_ports); memcpy(si->dst_ports, dst_ports, sizeof(int) * (MAX_PORTS + 1)); si->srch_mode = sdb_to_int(srch_mode); if (buf_p) { len = strlen(buf_p) + 1; assert(si->search = malloc(len)); memcpy(si->search, buf_p, len); } si->log_mode = sdb_to_int(log_mode); si->log_bytes = log_bytes; if (f) { si->file = f; si->file_close = 1; } else si->file_close = 0; list_insert_at(&l_sniff_db, nr, si);}static void sniff_mod_item(void){ char buf[BUFSIZE], *buf_p; struct sniff_info *si; struct sniff_log *slog; unsigned int src_ip, dst_ip; int src_mask, dst_mask; int src_ports[MAX_PORTS + 1], dst_ports[MAX_PORTS + 1]; int srch_mode, len; int log_mode, log_bytes; int nr; sniff_list_db(0); if ((nr = menu_choose_unr("choose item", 0, list_count(&l_sniff_db) - 1, list_count(&l_sniff_db) - 1)) == -1) return; if (!(si = list_at(&l_sniff_db, nr))) return; if (menu_choose_host_mask_ports_dfl("src ip addr/mask ports", &src_ip, &src_mask, src_ports, si->src_addr, si->src_mask, si->src_ports) < 0) return; if (menu_choose_host_mask_ports_dfl("dst ip addr/mask ports", &dst_ip, &dst_mask, dst_ports, si->dst_addr, si->dst_mask, si->dst_ports) < 0) return; if ((srch_mode = menu_choose_sdb("srch_mode", int_to_sdb(si->srch_mode))) < 0) return; buf_p = NULL; switch (menu_choose_char("want to search for y/n", "yn", 'y')) { case 'y': if (menu_choose_string("search for", buf, sizeof(buf), si->search) < 0) return; buf_p = buf; break; }; if ((log_mode = menu_choose_sdb("log mode", int_to_sdb(si->log_mode))) < 0) return; if ((log_bytes = menu_choose_unr("log bytes", 0, 1000000000, si->log_bytes)) < 0) return; port_htons(src_ports); port_htons(dst_ports); list_lock(&l_sniff_db); pthread_mutex_lock(&si->mutex); while ((slog = list_pop(&si->log))) free_sniff_log(slog); si->src_addr = src_ip; si->src_mask = src_mask; memcpy(si->src_ports, src_ports, sizeof(int) * (MAX_PORTS + 1)); si->dst_addr = dst_ip; si->dst_mask = dst_mask; memcpy(si->dst_ports, dst_ports, sizeof(int) * (MAX_PORTS + 1)); si->srch_mode = sdb_to_int(srch_mode); if (buf_p) { free(si->search); len = strlen(buf_p) + 1; assert(si->search = malloc(len)); memcpy(si->search, buf_p, len); } si->log_mode = sdb_to_int(log_mode); si->log_bytes = log_bytes; pthread_mutex_unlock(&si->mutex); list_unlock(&l_sniff_db);}static void sniff_del_item(void){ int i; struct sniff_info *si; sniff_list_db(0); i = menu_choose_unr("item nr. to delete", 0, list_count(&l_sniff_db) - 1, -1); if (i >= 0) { list_lock(&l_sniff_db); si = list_remove_at(&l_sniff_db, i); pthread_mutex_lock(&si->mutex); free_sniff_info(si); list_unlock(&l_sniff_db); }}void newline_option(void){ switch (menu_choose_char("Print newline,... as newline,...", "yn", o_newline ? 'y' : 'n')) { case 'y': o_newline = 1; break; case 'n': o_newline = 0; break; default: break; }}void sniff_options(void){ char *o_menu = "n) print new line,... as new line,...\n" "x) return\n"; char *o_keys = "nx"; int run_it; run_it = 1; while (run_it) { switch (menu("sniff options", o_menu, "sniffopt", o_keys, 0)) { case 'n': newline_option(); break; case 'x': run_it = 0; break; } }}void sniff_menu(void){ char *r_menu = "s/k) start/stop sniff daemon\n" "l) list sniff database c) list sniff connection\n" "a/m/d) add/mod/del sniff item\n" "o) options\n" "x) return\n"; char *r_keys = "sklcamdox"; int run_it; run_it = 1; while (run_it) { switch (menu("sniff daemon", r_menu, "sniff", r_keys, 0)) { case 's': start_sniff(); break; case 'k': stop_sniff(); break; case 'l': sniff_list_db(0); break; case 'c': sniff_list_db(1); break; case 'a': sniff_add_item(); break; case 'm': sniff_mod_item(); break; case 'd': sniff_del_item(); break; case 'o': sniff_options(); break; case 'x': run_it = 0; break; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -