📄 serv.c
字号:
int qp_compare(struct portlistent *entry, unsigned long long pv, int ch, int side){ int result = 0; unsigned long long value; value = qp_getkey(entry, ch); if (ch == 'R') { if (side == LEFT) result = (value <= pv); else result = (value > pv); } else { if (side == LEFT) result = (value >= pv); else result = (value < pv); } return result;}/* * Partition port list such that a pivot is selected, and that all values * left of the pivot are less (or greater) than or equal to the pivot, * and that all values right of the pivot are greater (or less) than * the pivot. */struct portlistent *qp_partition(struct portlist *table, struct portlistent **low, struct portlistent **high, int ch){ struct portlistent *pivot = *low; struct portlistent *left = *low; struct portlistent *right = *high; struct portlistent *ptmp; unsigned long long pivot_value; pivot_value = qp_getkey(pivot, ch); while (left->idx < right->idx) { while ((qp_compare(left, pivot_value, ch, LEFT)) && (left->next_entry != NULL)) left = left->next_entry; while (qp_compare(right, pivot_value, ch, RIGHT)) right = right->prev_entry; if (left->idx < right->idx) { swapportents(table, left, right); if (*low == left) *low = right; if (*high == right) *high = left; ptmp = left; left = right; right = ptmp; } } swapportents(table, pivot, right); if (*low == pivot) *low = right; if (*high == right) *high = pivot; return pivot;}/* * Quicksort for the port list. */void quicksort_port_entries(struct portlist *table, struct portlistent *low, struct portlistent *high, int ch){ struct portlistent *pivot; if ((high == NULL) || (low == NULL)) return; if (high->idx > low->idx) { pivot = qp_partition(table, &low, &high, ch); quicksort_port_entries(table, low, pivot->prev_entry, ch); quicksort_port_entries(table, pivot->next_entry, high, ch); }}void sortportents(struct portlist *list, int *idx, int command){ struct portlistent *ptemp1; unsigned int idxtmp; if (!(list->head)) return; command = toupper(command); if ((command != 'R') && (command != 'B') && (command != 'O') && (command != 'M') && (command != 'P') && (command != 'T') && (command != 'F')) return; quicksort_port_entries(list, list->head, list->tail, command); ptemp1 = list->firstvisible = list->head; *idx = 1; idxtmp = 1; while ((ptemp1) && (idxtmp <= LINES - 5)) { /* printout */ printportent(list, ptemp1, *idx); if (idxtmp <= LINES - 5) list->lastvisible = ptemp1; ptemp1 = ptemp1->next_entry; idxtmp++; }}void scrollservwin(struct portlist *table, int direction, int *idx){ char sp_buf[10]; sprintf(sp_buf, "%%%dc", COLS - 2); wattrset(table->win, STDATTR); if (direction == SCROLLUP) { if (table->lastvisible != table->tail) { wscrl(table->win, 1); table->lastvisible = table->lastvisible->next_entry; table->firstvisible = table->firstvisible->next_entry; (*idx)++; wmove(table->win, LINES - 6, 0); scrollok(table->win, 0); wprintw(table->win, sp_buf, ' '); scrollok(table->win, 1); printportent(table, table->lastvisible, *idx); } } else { if (table->firstvisible != table->head) { wscrl(table->win, -1); table->lastvisible = table->lastvisible->prev_entry; table->firstvisible = table->firstvisible->prev_entry; (*idx)--; wmove(table->win, 0, 0); wprintw(table->win, sp_buf, ' '); printportent(table, table->firstvisible, *idx); } }}void pageservwin(struct portlist *table, int direction, int *idx){ int i = 1; if (direction == SCROLLUP) { while ((i <= LINES - 9) && (table->lastvisible != table->tail)) { i++; table->firstvisible = table->firstvisible->next_entry; table->lastvisible = table->lastvisible->next_entry; (*idx)++; } } else { while ((i <= LINES - 9) && (table->firstvisible != table->head)) { i++; table->firstvisible = table->firstvisible->prev_entry; table->lastvisible = table->lastvisible->prev_entry; (*idx)--; } } refresh_serv_screen(table, *idx);}void show_portsort_keywin(WINDOW ** win, PANEL ** panel){ *win = newwin(14, 35, (LINES - 10) / 2, COLS - 40); *panel = new_panel(*win); wattrset(*win, DLGBOXATTR); tx_colorwin(*win); box(*win, ACS_VLINE, ACS_HLINE); wattrset(*win, DLGTEXTATTR); mvwprintw(*win, 2, 2, "Select sort criterion"); wmove(*win, 4, 2); tx_printkeyhelp("R", " - port number", *win, DLGHIGHATTR, DLGTEXTATTR); wmove(*win, 5, 2); tx_printkeyhelp("P", " - total packets", *win, DLGHIGHATTR, DLGTEXTATTR); wmove(*win, 6, 2); tx_printkeyhelp("B", " - total bytes", *win, DLGHIGHATTR, DLGTEXTATTR); wmove(*win, 7, 2); tx_printkeyhelp("T", " - packets to", *win, DLGHIGHATTR, DLGTEXTATTR); wmove(*win, 8, 2); tx_printkeyhelp("O", " - bytes to", *win, DLGHIGHATTR, DLGTEXTATTR); wmove(*win, 9, 2); tx_printkeyhelp("F", " - packets from", *win, DLGHIGHATTR, DLGTEXTATTR); wmove(*win, 10, 2); tx_printkeyhelp("M", " - bytes from", *win, DLGHIGHATTR, DLGTEXTATTR); wmove(*win, 11, 2); tx_printkeyhelp("Any other key", " - cancel sort", *win, DLGHIGHATTR, DLGTEXTATTR); update_panels(); doupdate();}void update_serv_rates(struct portlist *list, WINDOW *win, int actmode, int *cleared){ char act_unit[10]; float inrate, outrate, totalrate; time_t now = time(NULL); dispmode(actmode, act_unit); if (actmode == KBITS) { inrate = (float) (list->barptr->spans.spanbr_in * 8 / 1000) / (float) (now - list->barptr->starttime); outrate = (float) (list->barptr->spans.spanbr_out * 8 / 1000) / (float) (now - list->barptr->starttime); totalrate = (float) (list->barptr->spans.spanbr * 8 / 1000) / (float) (now - list->barptr->starttime); } else { inrate = (float) (list->barptr->spans.spanbr_in / 1024) / (float) (now - list->barptr->starttime); outrate = (float) (list->barptr->spans.spanbr_out / 1024) / (float) (now - list->barptr->starttime); totalrate = (float) (list->barptr->spans.spanbr / 1024) / (float) (now - list->barptr->starttime); } wattrset(win, IPSTATLABELATTR); mvwprintw(win, 0, 1, "Protocol data rates (%s/s): in out total", act_unit); wattrset(win, IPSTATATTR); mvwprintw(win, 0, 31, "%10.2f", inrate); mvwprintw(win, 0, 46, "%10.2f", outrate); mvwprintw(win, 0, 61, "%10.2f", totalrate); bzero(&(list->barptr->spans), sizeof(struct serv_spans)); list->barptr->starttime = time(NULL); *cleared = 0; }/* * The TCP/UDP service monitor */void servmon(char *ifname, struct porttab *ports, const struct OPTIONS *options, int facilitytime, struct filterstate *ofilter){ int logging = options->logging; int fd; int pkt_result; char buf[MAX_PACKET_SIZE]; char *ipacket; int keymode = 0; struct sockaddr_ll fromaddr; unsigned short linktype; int br; char iface[8]; unsigned int idx = 1; unsigned int sport = 0; unsigned int dport = 0; struct timeval tv; unsigned long starttime, startlog, timeint; unsigned long now; unsigned long long unow; unsigned long updtime = 0; unsigned long long updtime_usec = 0; unsigned int tot_br; int ch; struct portlist list; struct portlistent *serv_tmp; int statcleared = 0; FILE *logfile = NULL; struct promisc_states *promisc_list; WINDOW *sortwin; PANEL *sortpanel; WINDOW *statwin; PANEL *statpanel; char msgstring[80]; char sp_buf[10]; const int statx = 1; /* * Mark this facility */ if (!facility_active(TCPUDPIDFILE, ifname)) mark_facility(TCPUDPIDFILE, "TCP/UDP monitor", ifname); else { snprintf(msgstring, 80, "TCP/UDP monitor already running on %s", ifname); write_error(msgstring, daemonized); return; } open_socket(&fd); if (fd < 0) { unmark_facility(TCPUDPIDFILE, ifname); return; } if (!iface_supported(ifname)) { err_iface_unsupported(); unmark_facility(TCPUDPIDFILE, ifname); return; } if (!iface_up(ifname)) { err_iface_down(); unmark_facility(TCPUDPIDFILE, ifname); return; } if ((first_active_facility()) && (options->promisc)) { init_promisc_list(&promisc_list); save_promisc_list(promisc_list); srpromisc(1, promisc_list); destroy_promisc_list(&promisc_list); } adjust_instance_count(PROCCOUNTFILE, 1); active_facility_countfile[0] = '\0'; initportlist(&list); statwin = newwin(1, COLS, LINES - 2, 0); statpanel = new_panel(statwin); scrollok(statwin, 0); wattrset(statwin, IPSTATLABELATTR); sprintf(sp_buf, "%%%dc", COLS); mvwprintw(statwin, 0, 0, sp_buf, ' '); move(LINES - 1, 1); scrollkeyhelp(); sortkeyhelp(); stdexitkeyhelp(); if (options->servnames) setservent(1); if (logging) { if (strcmp(current_logfile, "") == 0) snprintf(current_logfile, 80, "%s-%s.log", TCPUDPLOG, ifname); if (!daemonized) input_logfile(current_logfile, &logging); } if (logging) { opentlog(&logfile, current_logfile); if (logfile == NULL) logging = 0; } if (logging) signal(SIGUSR1, rotate_serv_log); rotate_flag = 0; writelog(logging, logfile, "******** TCP/UDP service monitor started ********"); isdnfd = -1; exitloop = 0; gettimeofday(&tv, NULL); starttime = startlog = timeint = tv.tv_sec; wattrset(statwin, IPSTATATTR); mvwprintw(statwin, 0, 1, "No entries"); update_panels(); doupdate(); while (!exitloop) { getpacket(fd, buf, &fromaddr, &ch, &br, iface, list.win); if (ch != ERR) { if (keymode == 0) { switch (ch) { case KEY_UP: if (list.barptr != NULL) { if (list.barptr->prev_entry != NULL) { serv_tmp = list.barptr; set_barptr((char **) &(list.barptr), (char *) list.barptr->prev_entry, &(list.barptr->prev_entry->starttime), (char *) &(list.barptr->prev_entry->spans), sizeof(struct serv_spans), statwin, &statcleared, statx); printportent(&list, serv_tmp, idx); if (list.baridx == 1) { scrollservwin(&list, SCROLLDOWN, &idx); } else list.baridx--; printportent(&list, list.barptr, idx); } } break; case KEY_DOWN: if (list.barptr != NULL) { if (list.barptr->next_entry != NULL) { serv_tmp = list.barptr; set_barptr((char **) &(list.barptr), (char *) list.barptr->next_entry, &(list.barptr->next_entry->starttime), (char *) &(list.barptr->next_entry->spans), sizeof(struct serv_spans), statwin, &statcleared, statx); printportent(&list, serv_tmp, idx); if (list.baridx == list.imaxy) { scrollservwin(&list, SCROLLUP, &idx); } else list.baridx++; printportent(&list, list.barptr, idx); } } break; case KEY_PPAGE: case '-': if (list.barptr != NULL) { pageservwin(&list, SCROLLDOWN, &idx); set_barptr((char **) &(list.barptr), (char *) (list.lastvisible), &(list.lastvisible->starttime), (char *) &(list.lastvisible->spans), sizeof(struct serv_spans), statwin, &statcleared, statx); list.baridx = list.lastvisible->idx - idx + 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -