📄 itrafmon.c
字号:
*low = right; if (*high == right) *high = pivot; return pivot;}/* * Quicksort the TCP entries. */void quicksort_tcp_entries(struct tcptable *table, struct tcptableent *low, struct tcptableent *high, int ch, struct OPTIONS *opts, int logging, FILE *logfile, int *nomem){ struct tcptableent *pivot; if ((high == NULL) || (low == NULL)) return; if (high->index > low->index) { pivot = qt_partition(table, &low, &high, ch, opts, logging, logfile, nomem); if (pivot->prev_entry != NULL) quicksort_tcp_entries(table, low, pivot->prev_entry->prev_entry, ch, opts, logging, logfile, nomem); quicksort_tcp_entries(table, pivot->next_entry->next_entry, high, ch, opts, logging, logfile, nomem); }}/* * This function sorts the TCP window. The old exchange sort has been * replaced with a Quicksort algorithm. */ void sortipents(struct tcptable *table, unsigned long *idx, int ch, int mode, int logging, FILE *logfile, time_t timeout, int *nomem, struct OPTIONS *opts){ struct tcptableent *tcptmp1; unsigned int idxtmp; if ((table->head == NULL) || (table->head->next_entry->next_entry == NULL)) return; ch = toupper(ch); if ((ch != 'P') && (ch != 'B')) return; quicksort_tcp_entries(table, table->head, table->tail->prev_entry, ch, opts, logging, logfile, nomem); update_panels(); doupdate(); tx_colorwin(table->tcpscreen); tcptmp1 = table->firstvisible = table->head; *idx = 1; idxtmp = 0; while ((tcptmp1 != NULL) && (idxtmp <= table->imaxy - 1)) { if (idxtmp++ <= table->imaxy - 1) table->lastvisible = tcptmp1; tcptmp1 = tcptmp1->next_entry; }}/* * Attempt to communicate with rvnamed, and if it doesn't respond, try * to start it. */int checkrvnamed(void){ int execstat = 0; pid_t cpid = 0; int cstat; extern int errno; indicate("Trying to communicate with reverse lookup server"); if (!rvnamedactive()) { indicate("Starting reverse lookup server"); if ((cpid = fork()) == 0) { execstat = execl(RVNDFILE, NULL); /* * execl() never returns, so if we reach this point, we have * a problem. */ _exit(1); } else if (cpid == -1) { write_error("Can't spawn new process; lookups will block", daemonized); return 0; } else { while (waitpid(cpid, &cstat, 0) < 0) if (errno != EINTR) break; if (WEXITSTATUS(cstat) == 1) { write_error("Can't start rvnamed; lookups will block", daemonized); return 0; } else { sleep(1); return 1; } } } return 1;}void update_flowrate(WINDOW *win, struct tcptableent *entry, time_t now, int *cleared, int mode){ float rate = 0; char units[10]; wattrset(win, IPSTATLABELATTR); mvwprintw(win, 0, COLS * 47 / 80, "TCP flow rate: "); wattrset(win, IPSTATATTR); if (mode == KBITS) { strcpy(units, "kbits/s"); rate = (float) (entry->spanbr * 8 / 1000) / (float) (now - entry->starttime); } else { strcpy(units, "kbytes/s"); rate = (float) (entry->spanbr / 1024) / (float) (now - entry->starttime); } mvwprintw(win, 0, COLS * 50 / 80 + 13, "%8.2f %s", rate, units); entry->spanbr = 0; *cleared = 0;} /* * The IP Traffic Monitor */void ipmon(struct OPTIONS *options, struct filterstate *ofilter, int facilitytime, char *ifptr){ int logging = options->logging; struct sockaddr_ll fromaddr; /* iface info */ unsigned short linktype; /* data link type */ int fd; /* raw socket */ char tpacket[MAX_PACKET_SIZE]; /* raw packet data */ char *packet = NULL; /* network packet ptr */ struct iphdr *ippacket; struct tcphdr *transpacket; /* IP-encapsulated packet */ unsigned int sport = 0, dport = 0; /* TCP/UDP port values */ char sp_buf[10]; unsigned long screen_idx = 1; struct timeval tv; unsigned long starttime = 0; unsigned long now = 0; unsigned long timeint = 0; unsigned long updtime = 0; unsigned long long updtime_usec = 0; unsigned long long unow = 0; unsigned long closedint = 0; WINDOW *statwin; PANEL *statpanel; WINDOW *sortwin; PANEL *sortpanel; FILE *logfile = NULL; int curwin = 0; int readlen; char ifname[8]; unsigned long long total_pkts = 0; unsigned int br; /* bytes read. Differs from readlen */ /* only when packets fragmented */ unsigned int iphlen; unsigned int totalhlen; struct tcptable table; struct tcptableent *tcpentry; struct tcptableent *tmptcp; int mode = 0; struct othptable othptbl; struct othptabent *othpent; int p_sstat = 0, p_dstat = 0; /* Reverse lookup statuses prior to */ /* reattempt in updateentry() */ int pkt_result = 0; /* Non-IP filter ok */ int fragment = 0; /* Set to 1 if not first fragment */ int ch; int keymode = 0; char msgstring[80]; int nomem = 0; struct promisc_states *promisc_list; int rvnfd = 0; int instance_id; int revlook = options->revlook; int statcleared = 0; int wasempty = 1; const int statx = COLS * 47 / 80; /* * Mark this instance of the traffic monitor */ if (!facility_active(IPMONIDFILE, ifptr)) mark_facility(IPMONIDFILE, "IP traffic monitor", ifptr); else { snprintf(msgstring, 80, "IP Traffic Monitor already listening on %s", gen_iface_msg(ifptr)); write_error(msgstring, daemonized); return; } if (ifptr != NULL) { if (!iface_supported(ifptr)) { err_iface_unsupported(); unmark_facility(IPMONIDFILE, ifptr); return; } if (!iface_up(ifptr)) { err_iface_down(); unmark_facility(IPMONIDFILE, ifptr); return; } } open_socket(&fd); if (fd < 0) { unmark_facility(IPMONIDFILE, ifptr); return; } if (options->promisc) { if (first_active_facility()) { init_promisc_list(&promisc_list); save_promisc_list(promisc_list); srpromisc(1, promisc_list); } } /* * Adjust instance counters */ adjust_instance_count(PROCCOUNTFILE, 1); instance_id = adjust_instance_count(ITRAFMONCOUNTFILE, 1); strncpy(active_facility_countfile, ITRAFMONCOUNTFILE, 64); init_tcp_table(&table); init_othp_table(&othptbl, options->mac); statwin = newwin(1, COLS, LINES - 2, 0); statpanel = new_panel(statwin); wattrset(statwin, IPSTATLABELATTR); wmove(statwin, 0, 0); sprintf(sp_buf, "%%%dc", COLS); wprintw(statwin, sp_buf, ' '); prepare_statwin(statwin); show_stats(statwin, 0); markactive(curwin, table.borderwin, othptbl.borderwin); update_panels(); doupdate(); if (revlook) { if (checkrvnamed()) open_rvn_socket(&rvnfd); } else rvnfd = 0; ipmonhelp(); uniq_help(0); update_panels(); doupdate(); if (options->servnames) setservent(1); /* * Try to open log file if logging activated. Turn off logging * (for this session only) if an error was discovered in opening * the log file. Configuration setting is kept. Who knows, the * situation may be corrected later. */ if (logging) { if (strcmp(current_logfile, "") == 0) strncpy(current_logfile, gen_instance_logname(IPMONLOG, instance_id), 80); if (!daemonized) input_logfile(current_logfile, &logging); } if (logging) opentlog(&logfile, current_logfile); if (logfile == NULL) logging = 0; if (logging) signal(SIGUSR1, rotate_ipmon_log); rotate_flag = 0; writelog(logging, logfile, "******** IP traffic monitor started ********"); isdnfd = -1; exitloop = 0; gettimeofday(&tv, NULL); starttime = timeint = closedint = tv.tv_sec; while (!exitloop) { gettimeofday(&tv, NULL); now = tv.tv_sec; unow = tv.tv_sec * 1e+06 + tv.tv_usec; /* * Print timer at bottom of screen */ if (now - timeint >= 5) { printelapsedtime(starttime, now, othptbl.obmaxy - 1, 15, othptbl.borderwin); timeint = now; } /* * Automatically clear closed/timed out entries */ if ((options->closedint != 0) && ((now - closedint) / 60 >= options->closedint)) { flushclosedentries(&table, &screen_idx, logging, logfile, options); refreshtcpwin(&table, screen_idx, mode); closedint = now; } /* * Update screen at configured intervals. */ if (((options->updrate != 0) && (now - updtime >= options->updrate)) || ((options->updrate == 0) && (unow - updtime_usec >= DEFAULT_UPDATE_DELAY))) { update_panels(); doupdate(); updtime = now; updtime_usec = unow; } /* * If highlight bar is on some entry, update the flow rate * indicator after five seconds. */ if (table.barptr != NULL) { if ((now - table.barptr->starttime) >= 5) { update_flowrate(statwin, table.barptr, now, &statcleared, options->actmode); table.barptr->starttime = now; } } else { wattrset(statwin, IPSTATATTR); mvwprintw(statwin, 0, statx, "No TCP entries "); } /* * Terminate facility should a lifetime be specified at the * command line */ if ((facilitytime != 0) && (((now - starttime) / 60) >= facilitytime)) exitloop = 1; /* * Close and rotate log file if signal was received */ if ((rotate_flag == 1) && (logging)) { announce_rotate_prepare(logfile); write_tcp_unclosed(logging, logfile, &table); rotate_logfile(&logfile, target_logname); announce_rotate_complete(logfile); rotate_flag = 0; } getpacket(fd, tpacket, &fromaddr, &ch, &readlen, ifname, table.tcpscreen); if (ch != ERR) { if (keymode == 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -