📄 ifstats.c
字号:
if ((options->promisc) && (is_last_instance())) { load_promisc_list(&promisc_list); srpromisc(0, promisc_list); destroy_promisc_list(&promisc_list); } adjust_instance_count(PROCCOUNTFILE, -1); del_panel(table.statpanel); delwin(table.statwin); del_panel(table.borderpanel); delwin(table.borderwin); update_panels(); doupdate(); if (logging) { signal(SIGUSR1, SIG_DFL); writegstatlog(&table, options->actmode, time((time_t *) NULL) - statbegin, logfile); writelog(logging, logfile, "******** General interface statistics stopped ********"); fclose(logfile); } destroyiflist(table.head); pkt_cleanup(); unmark_facility(GSTATIDFILE, ""); strcpy(current_logfile, "");}void printdetlabels(WINDOW * win, struct iftotals *totals){ wattrset(win, BOXATTR); mvwprintw(win, 2, 14, " Total Total Incoming Incoming Outgoing Outgoing"); mvwprintw(win, 3, 14, "Packets Bytes Packets Bytes Packets Bytes"); wattrset(win, STDATTR); mvwprintw(win, 4, 2, "Total:"); mvwprintw(win, 5, 2, "IP:"); mvwprintw(win, 6, 2, "TCP:"); mvwprintw(win, 7, 2, "UDP:"); mvwprintw(win, 8, 2, "ICMP:"); mvwprintw(win, 9, 2, "Other IP:"); mvwprintw(win, 10, 2, "Non-IP:"); mvwprintw(win, 13, 2, "Total rates:"); mvwprintw(win, 16, 2, "Incoming rates:"); mvwprintw(win, 19, 2, "Outgoing rates:"); mvwprintw(win, 13, 45, "Broadcast packets:"); mvwprintw(win, 14, 45, "Broadcast bytes:"); mvwprintw(win, 18, 45, "IP checksum errors:"); update_panels(); doupdate();}void printstatrow(WINDOW * win, int row, unsigned long long total, unsigned long long btotal, unsigned long long total_in, unsigned long long btotal_in, unsigned long long total_out, unsigned long long btotal_out){ wmove(win, row, 12); printlargenum(total, win); wmove(win, row, 23); printlargenum(btotal, win); wmove(win, row, 35); printlargenum(total_in, win); wmove(win, row, 46); printlargenum(btotal_in, win); wmove(win, row, 58); printlargenum(total_out, win); wmove(win, row, 69); printlargenum(btotal_out, win);}void printdetails(struct iftotals *totals, WINDOW * win){ wattrset(win, HIGHATTR); /* Print totals on the IP protocols */ printstatrow(win, 4, totals->total, totals->bytestotal, totals->total_in, totals->bytestotal_in, totals->total_out, totals->bytestotal_out); printstatrow(win, 5, totals->iptotal, totals->ipbtotal, totals->iptotal_in, totals->ipbtotal_in, totals->iptotal_out, totals->ipbtotal_out); printstatrow(win, 6, totals->tcptotal, totals->tcpbtotal, totals->tcptotal_in, totals->tcpbtotal_in, totals->tcptotal_out, totals->tcpbtotal_out); printstatrow(win, 7, totals->udptotal, totals->udpbtotal, totals->udptotal_in, totals->udpbtotal_in, totals->udptotal_out, totals->udpbtotal_out); printstatrow(win, 8, totals->icmptotal, totals->icmpbtotal, totals->icmptotal_in, totals->icmpbtotal_in, totals->icmptotal_out, totals->icmpbtotal_out); printstatrow(win, 9, totals->othtotal, totals->othbtotal, totals->othtotal_in, totals->othbtotal_in, totals->othtotal_out, totals->othbtotal_out); /* Print non-IP totals */ printstatrow(win, 10, totals->noniptotal, totals->nonipbtotal, totals->noniptotal_in, totals->nonipbtotal_in, totals->noniptotal_out, totals->nonipbtotal_out); /* Broadcast totals */ wmove(win, 13, 67); printlargenum(totals->bcast, win); wmove(win, 14, 67); printlargenum(totals->bcastbytes, win); /* Bad packet count */ mvwprintw(win, 18, 68, "%8lu", totals->badtotal);}/* * The detailed interface statistics function */void detstats(char *iface, const struct OPTIONS *options, int facilitytime, struct filterstate *ofilter){ int logging = options->logging; WINDOW *statwin; PANEL *statpanel; char buf[MAX_PACKET_SIZE]; char *packet; struct iphdr *ipacket = NULL; char *tpacket; unsigned int iphlen; unsigned int sport, dport; char ifname[8]; struct sockaddr_ll fromaddr; unsigned short linktype; int fd; int br; int framelen = 0; int pkt_result = 0; FILE *logfile = NULL; unsigned int iplen = 0; struct iftotals totals; int ch; struct timeval tv; unsigned long updtime = 0; unsigned long long updtime_usec = 0; unsigned long starttime, now; unsigned long statbegin, startlog; unsigned long long unow; float spanbr = 0; float spanpkt = 0; float spanbr_in = 0; float spanbr_out = 0; float spanpkt_in = 0; float spanpkt_out = 0; float activity = 0; float activity_in = 0; float activity_out = 0; float peakactivity = 0; float peakactivity_in = 0; float peakactivity_out = 0; float pps = 0; float peakpps = 0; float pps_in = 0; float pps_out = 0; float peakpps_in = 0; float peakpps_out = 0; char unitstring[7]; struct promisc_states *promisc_list; char err_msg[80]; /* * Mark this facility */ if (!facility_active(DSTATIDFILE, iface)) mark_facility(DSTATIDFILE, "detailed interface statistics", iface); else { snprintf(err_msg, 80, "Detailed interface stats already monitoring %s", iface); write_error(err_msg, daemonized); return; } open_socket(&fd); if (fd < 0) { unmark_facility(DSTATIDFILE, iface); return; } if (!iface_supported(iface)) { err_iface_unsupported(); unmark_facility(DSTATIDFILE, iface); return; } if (!iface_up(iface)) { err_iface_down(); unmark_facility(DSTATIDFILE, iface); 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'; move(LINES - 1, 1); stdexitkeyhelp(); statwin = newwin(LINES - 2, COLS, 1, 0); statpanel = new_panel(statwin); tx_stdwinset(statwin); wtimeout(statwin, -1); wattrset(statwin, BOXATTR); tx_colorwin(statwin); box(statwin, ACS_VLINE, ACS_HLINE); wmove(statwin, 0, 1); wprintw(statwin, " Statistics for %s ", iface); wattrset(statwin, STDATTR); update_panels(); doupdate(); bzero(&totals, sizeof(struct iftotals)); if (logging) { if (strcmp(current_logfile, "") == 0) snprintf(current_logfile, 64, "%s-%s.log", DSTATLOG, iface); if (!daemonized) input_logfile(current_logfile, &logging); } if (logging) { opentlog(&logfile, current_logfile); if (logfile == NULL) logging = 0; } if (logging) signal(SIGUSR1, rotate_dstat_log); rotate_flag = 0; writelog(logging, logfile, "******** Detailed interface statistics started ********"); printdetlabels(statwin, &totals); printdetails(&totals, statwin); update_panels(); doupdate(); spanbr = 0; gettimeofday(&tv, NULL); starttime = startlog = statbegin = tv.tv_sec; leaveok(statwin, TRUE); isdnfd = -1; exitloop = 0; dispmode(options->actmode, unitstring); /* * Data-gathering loop */ while (!exitloop) { getpacket(fd, buf, &fromaddr, &ch, &br, ifname, statwin); if (ch != ERR) { switch (ch) { case 12: case 'l': case 'L': tx_refresh_screen(); break; case 'Q': case 'q': case 'X': case 'x': case 24: case 27: exitloop = 1; break; } } if (br > 0) { framelen = br; pkt_result = processpacket(buf, &packet, &br, NULL, &sport, &dport, &fromaddr, &linktype, ofilter, ifname, iface); if (pkt_result == INVALID_PACKET) continue; totals.total++; totals.bytestotal += framelen; if (fromaddr.sll_pkttype == PACKET_OUTGOING) { totals.total_out++; totals.bytestotal_out += framelen; spanbr_out += framelen; spanpkt_out++; } else { totals.total_in++; totals.bytestotal_in += framelen; spanbr_in += framelen; spanpkt_in++; } if (fromaddr.sll_pkttype == PACKET_BROADCAST) { totals.bcast++; totals.bcastbytes += framelen; } spanbr += framelen; spanpkt++; if (fromaddr.sll_protocol == ETH_P_IP) { if (pkt_result == CHECKSUM_ERROR) { totals.badtotal++; continue; } ipacket = (struct iphdr *) packet; iphlen = ipacket->ihl * 4; tpacket = packet + iphlen; iplen = ntohs(ipacket->tot_len); totals.iptotal++; totals.ipbtotal += iplen; if (fromaddr.sll_pkttype == PACKET_OUTGOING) { totals.iptotal_out++; totals.ipbtotal_out += iplen; } else { totals.iptotal_in++; totals.ipbtotal_in += iplen; } switch (ipacket->protocol) { case IPPROTO_TCP: totals.tcptotal++; totals.tcpbtotal += iplen; if (fromaddr.sll_pkttype == PACKET_OUTGOING) { totals.tcptotal_out++; totals.tcpbtotal_out += iplen; } else { totals.tcptotal_in++; totals.tcpbtotal_in += iplen; } break; case IPPROTO_UDP: totals.udptotal++; totals.udpbtotal += iplen; if (fromaddr.sll_pkttype == PACKET_OUTGOING) { totals.udptotal_out++; totals.udpbtotal_out += iplen; } else { totals.udptotal_in++; totals.udpbtotal_in += iplen; } break; case IPPROTO_ICMP: totals.icmptotal++; totals.icmpbtotal += iplen; if (fromaddr.sll_pkttype == PACKET_OUTGOING) { totals.icmptotal_out++; totals.icmpbtotal_out += iplen; } else { totals.icmptotal_in++; totals.icmpbtotal_in += iplen; } break; default: totals.othtotal++; totals.othbtotal += iplen; if (fromaddr.sll_pkttype == PACKET_OUTGOING) { totals.othtotal_out++; totals.othbtotal_out += iplen; } else { totals.othtotal_in++; totals.othbtotal_in += iplen; } break; } } else { totals.noniptotal++; totals.nonipbtotal += br; if (fromaddr.sll_pkttype == PACKET_OUTGOING) { totals.noniptotal_out++; totals.nonipbtotal_out += br; } else { totals.noniptotal_in++; totals.nonipbtotal_in += br; } } } gettimeofday(&tv, NULL); now = tv.tv_sec; unow = tv.tv_sec * 1e+6 + tv.tv_usec; if (now - starttime >= 5) { wattrset(statwin, BOXATTR); printelapsedtime(statbegin, now, LINES - 3, 1, statwin); if (options->actmode == KBITS) { activity = (float) (spanbr * 8 / 1000) / (float) (now - starttime); activity_in = (float) (spanbr_in * 8 / 1000) / (float) (now - starttime); activity_out = (float) (spanbr_out * 8 / 1000) / (float) (now - starttime); } else { activity = (float) (spanbr / 1024) / (float) (now - starttime); activity_in = (float) (spanbr_in / 1024) / (float) (now - starttime); activity_out = (float) (spanbr_out / 1024) / (float) (now - starttime); } pps = (float) (spanpkt) / (float) (now - starttime); pps_in = (float) (spanpkt_in) / (float) (now - starttime); pps_out = (float) (spanpkt_out) / (float) (now - starttime); spanbr = spanbr_in = spanbr_out = 0; spanpkt = spanpkt_in = spanpkt_out = 0; starttime = now; wattrset(statwin, HIGHATTR); mvwprintw(statwin, 13, 19, "%8.1f %s/sec", activity, unitstring); mvwprintw(statwin, 14, 19, "%8.1f packets/sec", pps); mvwprintw(statwin, 16, 19, "%8.1f %s/sec", activity_in, unitstring); mvwprintw(statwin, 17, 19, "%8.1f packets/sec", pps_in); mvwprintw(statwin, 19, 19, "%8.1f %s/sec", activity_out, unitstring); mvwprintw(statwin, 20, 19, "%8.1f packets/sec", pps_out); if (activity > peakactivity) peakactivity = activity; if (activity_in > peakactivity_in) peakactivity_in = activity_in; if (activity_out > peakactivity_out) peakactivity_out = activity_out; if (pps > peakpps) peakpps = pps; if (pps_in > peakpps_in) peakpps_in = pps_in; if (pps_out > peakpps_out) peakpps_out = pps_out; } if (((now - startlog) >= options->logspan) && (logging)) { writedstatlog(iface, options->actmode, activity, pps, peakactivity, peakpps, peakactivity_in, peakpps_in, peakactivity_out, peakpps_out, &totals, time((time_t *) NULL) - statbegin, logfile); startlog = now; } if (((options->updrate == 0) && (unow - updtime_usec >= DEFAULT_UPDATE_DELAY)) || ((options->updrate != 0) && (now - updtime >= options->updrate))) { printdetails(&totals, statwin); update_panels(); doupdate(); updtime_usec = unow; updtime = now; } check_rotate_flag(&logfile, logging); if ((facilitytime != 0) && (((now - statbegin) / 60) >= facilitytime)) exitloop = 1; } close(fd); if ((options->promisc) && (is_last_instance())) { load_promisc_list(&promisc_list); srpromisc(0, promisc_list); destroy_promisc_list(&promisc_list); } adjust_instance_count(PROCCOUNTFILE, -1); if (logging) { signal(SIGUSR1, SIG_DFL); writedstatlog(iface, options->actmode, activity, pps, peakactivity, peakpps, peakactivity_in, peakpps_in, peakactivity_out, peakpps_out, &totals, time((time_t *) NULL) - statbegin, logfile); writelog(logging, logfile, "******** Detailed interface statistics stopped ********"); fclose(logfile); } del_panel(statpanel); delwin(statwin); unmark_facility(DSTATIDFILE, iface); strcpy(current_logfile, ""); pkt_cleanup(); update_panels(); doupdate();}void selectiface(char *ifname, int withall, int *aborted){ int ch; struct iflist *list; struct iflist *ptmp; struct scroll_list scrolllist; initiflist(&list); if (list == NULL) { no_ifaces_error(); *aborted = 1; return; } if ((withall) && (list != NULL)) { ptmp = malloc(sizeof(struct iflist)); strcpy(ptmp->ifname, "All interfaces"); ptmp->prev_entry = NULL; list->prev_entry = ptmp; ptmp->next_entry = list; list = ptmp; } tx_listkeyhelp(STDATTR, HIGHATTR); ptmp = list; tx_init_listbox(&scrolllist, 24, 14, (COLS - 24) / 2 - 9, (LINES - 14) / 2, STDATTR, BOXATTR, BARSTDATTR, HIGHATTR); tx_set_listbox_title(&scrolllist, "Select Interface", 1); while (ptmp != NULL) { tx_add_list_entry(&scrolllist, (char *) ptmp, ptmp->ifname); ptmp = ptmp->next_entry; } tx_show_listbox(&scrolllist); tx_operate_listbox(&scrolllist, &ch, aborted); tx_close_listbox(&scrolllist); if (!(*aborted) && (list != NULL)) { ptmp = (struct iflist *) scrolllist.textptr->nodeptr; if ((withall) && (ptmp->prev_entry == NULL)) /* All Interfaces */ strcpy(ifname, ""); else strcpy(ifname, ptmp->ifname); } tx_destroy_list(&scrolllist); destroyiflist(list); update_panels(); doupdate();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -