📄 hostmon.c
字号:
/***hostmon.c - Host traffic monitorDiscovers LAN hosts and displays packet statistics for themWritten by Gerard Paul JavaCopyright (c) Gerard Paul Java 1997, 1998This software is open source; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed WITHOUT ANY WARRANTY; without even theimplied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the GNU General Public License in the included COPYING file fordetails.***/#include <curses.h>#include <panel.h>#include <string.h>#include <unistd.h>#include <signal.h>#include <ctype.h>#include <sys/socket.h>#include <sys/types.h>#include <asm/types.h>#include <netinet/in.h>#include <linux/if_packet.h>#include <linux/if_ether.h>#include <linux/if_fddi.h>#include <linux/if_tr.h>#include <net/if_arp.h>#include <stdlib.h>#include <time.h>#include <sys/time.h>#include <winops.h>#include <labels.h>#include "dirs.h"#include "deskman.h"#include "links.h"#include "fltdefs.h"#include "fltselect.h"#include "isdntab.h" /* needed by packet.h */#include "packet.h"#include "ifaces.h"#include "hostmon.h"#include "attrs.h"#include "log.h"#include "timer.h"#include "landesc.h"#include "options.h"#include "instances.h"#include "mode.h"#include "logvars.h"#include "promisc.h"#include "error.h"#define SCROLLUP 0#define SCROLLDOWN 1extern int exitloop;extern int daemonized;/* * from log.c, applicable only to this module */extern void writeethlog(struct ethtabent *list, int units, unsigned long nsecs, FILE * logfile);extern char *ltrim(char *buf);/* * SIGUSR1 logfile rotation handler */void rotate_lanlog(){ rotate_flag = 1; strcpy(target_logname, current_logfile); signal(SIGUSR1, rotate_lanlog);}void ethlook(struct desclist *list, char *address, char *target){ struct desclistent *ptmp = list->head; while (ptmp != NULL) { if (strcmp(address, ptmp->rec.address) == 0) { strcpy(target, ptmp->rec.desc); return; } ptmp = ptmp->next_entry; }}void initethtab(struct ethtab *table, int unit){ char unitstring[7]; table->head = table->tail = NULL; table->firstvisible = table->lastvisible = NULL; table->count = table->entcount = 0; table->borderwin = newwin(LINES - 2, COLS, 1, 0); table->borderpanel = new_panel(table->borderwin); table->tabwin = newwin(LINES - 4, COLS - 2, 2, 1); table->tabpanel = new_panel(table->tabwin); wattrset(table->borderwin, BOXATTR); tx_box(table->borderwin, ACS_VLINE, ACS_HLINE); wmove(table->borderwin, 0, 5 * COLS / 80); wprintw(table->borderwin, " PktsIn "); wmove(table->borderwin, 0, 16 * COLS / 80); wprintw(table->borderwin, " IP In "); wmove(table->borderwin, 0, 24 * COLS / 80); wprintw(table->borderwin, " BytesIn "); wmove(table->borderwin, 0, 34 * COLS / 80); wprintw(table->borderwin, " InRate "); wmove(table->borderwin, 0, 42 * COLS / 80); wprintw(table->borderwin, " PktsOut "); wmove(table->borderwin, 0, 53 * COLS / 80); wprintw(table->borderwin, " IP Out "); wmove(table->borderwin, 0, 61 * COLS / 80); wprintw(table->borderwin, " BytesOut "); wmove(table->borderwin, 0, 70 * COLS / 80); wprintw(table->borderwin, " OutRate "); wmove(table->borderwin, LINES - 3, 40); dispmode(unit, unitstring); wprintw(table->borderwin, " InRate and OutRate are in %s/sec ", unitstring); wattrset(table->tabwin, STDATTR); tx_colorwin(table->tabwin); tx_stdwinset(table->tabwin); wtimeout(table->tabwin, -1); update_panels(); doupdate();}struct ethtabent *addethnode(struct ethtab *table, int *nomem){ struct ethtabent *ptemp; ptemp = malloc(sizeof(struct ethtabent)); if (ptemp == NULL) { printnomem(); *nomem = 1; return NULL; } if (table->head == NULL) { ptemp->prev_entry = NULL; table->head = ptemp; table->firstvisible = ptemp; } else { ptemp->prev_entry = table->tail; table->tail->next_entry = ptemp; } table->tail = ptemp; ptemp->next_entry = NULL; table->count++; ptemp->index = table->count; if (table->count <= LINES - 4) table->lastvisible = ptemp; return ptemp;}void convmacaddr(char *addr, char *result){ unsigned int i; u_int8_t *ptmp = addr; char hexbyte[3]; strcpy(result, ""); for (i = 0; i <= 5; i++) { sprintf(hexbyte, "%02x", *ptmp); strcat(result, hexbyte); ptmp++; }}struct ethtabent *addethentry(struct ethtab *table, unsigned int linktype, char *ifname, char *addr, int *nomem, struct desclist *list){ struct ethtabent *ptemp; ptemp = addethnode(table, nomem); if (ptemp == NULL) return NULL; ptemp->type = 0; memcpy(&(ptemp->un.desc.eth_addr), addr, ETH_ALEN); strcpy(ptemp->un.desc.desc, ""); convmacaddr(addr, ptemp->un.desc.ascaddr); ptemp->un.desc.linktype = linktype; ethlook(list, ptemp->un.desc.ascaddr, ptemp->un.desc.desc); strcpy(ptemp->un.desc.ifname, ifname); if (strcmp(ptemp->un.desc.desc, "") == 0) ptemp->un.desc.withdesc = 0; else ptemp->un.desc.withdesc = 1; ptemp->un.desc.printed = 0; ptemp = addethnode(table, nomem); if (ptemp == NULL) return NULL; ptemp->type = 1; ptemp->un.figs.inpcount = ptemp->un.figs.inpktact = 0; ptemp->un.figs.outpcount = ptemp->un.figs.outpktact = 0; ptemp->un.figs.inspanbr = ptemp->un.figs.outspanbr = 0; ptemp->un.figs.inippcount = ptemp->un.figs.outippcount = 0; ptemp->un.figs.inbcount = ptemp->un.figs.outbcount = 0; ptemp->un.figs.inrate = ptemp->un.figs.outrate = 0; ptemp->un.figs.past5 = 0; table->entcount++; wmove(table->borderwin, LINES - 3, 1); wprintw(table->borderwin, " %u entries ", table->entcount); return ptemp;}struct ethtabent *in_ethtable(struct ethtab *table, unsigned int linktype, char *addr){ struct ethtabent *ptemp = table->head; while (ptemp != NULL) { if ((ptemp->type == 0) && (memcmp(addr, ptemp->un.desc.eth_addr, ETH_ALEN) == 0) && (ptemp->un.desc.linktype == linktype)) return ptemp->next_entry; ptemp = ptemp->next_entry; } return NULL;}void updateethent(struct ethtabent *entry, int pktsize, int is_ip, int inout){ if (inout == 0) { entry->un.figs.inpcount++; entry->un.figs.inbcount += pktsize; entry->un.figs.inspanbr += pktsize; if (is_ip) entry->un.figs.inippcount++; } else { entry->un.figs.outpcount++; entry->un.figs.outbcount += pktsize; entry->un.figs.outspanbr += pktsize; if (is_ip) entry->un.figs.outippcount++; }}void printethent(struct ethtab *table, struct ethtabent *entry, unsigned int idx){ unsigned int target_row; if ((entry->index < idx) || (entry->index > idx + LINES - 5)) return; target_row = entry->index - idx; if (entry->type == 0) { wmove(table->tabwin, target_row, 1); wattrset(table->tabwin, STDATTR); if (entry->un.desc.linktype == LINK_ETHERNET) wprintw(table->tabwin, "Ethernet"); else if (entry->un.desc.linktype == LINK_PLIP) wprintw(table->tabwin, "PLIP"); else if (entry->un.desc.linktype == LINK_FDDI) wprintw(table->tabwin, "FDDI"); wprintw(table->tabwin, " HW addr: %s", entry->un.desc.ascaddr); if (entry->un.desc.withdesc) wprintw(table->tabwin, " (%s)", entry->un.desc.desc); wprintw(table->tabwin, " on %s ", entry->un.desc.ifname); entry->un.desc.printed = 1; } else { wattrset(table->tabwin, PTRATTR); wmove(table->tabwin, target_row, 1); waddch(table->tabwin, ACS_LLCORNER); wattrset(table->tabwin, HIGHATTR); /* Inbound traffic counts */ wmove(table->tabwin, target_row, 2 * COLS / 80); printlargenum(entry->un.figs.inpcount, table->tabwin); wmove(table->tabwin, target_row, 12 * COLS / 80); printlargenum(entry->un.figs.inippcount, table->tabwin); wmove(table->tabwin, target_row, 22 * COLS / 80); printlargenum(entry->un.figs.inbcount, table->tabwin); /* Outbound traffic counts */ wmove(table->tabwin, target_row, 40 * COLS / 80); printlargenum(entry->un.figs.outpcount, table->tabwin); wmove(table->tabwin, target_row, 50 * COLS / 80); printlargenum(entry->un.figs.outippcount, table->tabwin); wmove(table->tabwin, target_row, 60 * COLS / 80); printlargenum(entry->un.figs.outbcount, table->tabwin); }}void destroyethtab(struct ethtab *table){ struct ethtabent *ptemp = table->head; struct ethtabent *cnext = NULL; if (table->head != NULL) cnext = table->head->next_entry; while (ptemp != NULL) { free(ptemp); ptemp = cnext; if (cnext != NULL) cnext = cnext->next_entry; }}void hostmonhelp(){ move(LINES - 1, 1); scrollkeyhelp(); sortkeyhelp(); stdexitkeyhelp();}void printrates(struct ethtab *table, unsigned int target_row, struct ethtabent *ptmp){ if (ptmp->un.figs.past5) { wmove(table->tabwin, target_row, 32 * COLS / 80); wprintw(table->tabwin, "%8.1f", ptmp->un.figs.inrate); wmove(table->tabwin, target_row, 69 * COLS / 80); wprintw(table->tabwin, "%8.1f", ptmp->un.figs.outrate); }}void updateethrates(struct ethtab *table, int unit, time_t starttime, time_t now, unsigned int idx){ struct ethtabent *ptmp = table->head; unsigned int target_row = 0; if (table->lastvisible == NULL) return; while (ptmp != NULL) { if (ptmp->type == 1) { ptmp->un.figs.past5 = 1; if (unit == KBITS) { ptmp->un.figs.inrate = ((float) (ptmp->un.figs.inspanbr * 8 / 1000)) / ((float) (now - starttime)); ptmp->un.figs.outrate = ((float) (ptmp->un.figs.outspanbr * 8 / 1000)) / ((float) (now - starttime)); } else { ptmp->un.figs.inrate = ((float) (ptmp->un.figs.inspanbr / 1024)) / ((float) (now - starttime)); ptmp->un.figs.outrate = ((float) (ptmp->un.figs.outspanbr / 1024)) / ((float) (now - starttime)); } if ((ptmp->index >= idx) && (ptmp->index <= idx + LINES - 5)) { wattrset(table->tabwin, HIGHATTR); target_row = ptmp->index - idx; printrates(table, target_row, ptmp); } ptmp->un.figs.inspanbr = ptmp->un.figs.outspanbr = 0; } ptmp = ptmp->next_entry; }}void refresh_hostmon_screen(struct ethtab *table, int idx){ struct ethtabent *ptmp = table->firstvisible; wattrset(table->tabwin, STDATTR); tx_colorwin(table->tabwin); while ((ptmp != NULL) && (ptmp->prev_entry != table->lastvisible)) { printethent(table, ptmp, idx); ptmp = ptmp->next_entry; } update_panels(); doupdate();}void scrollethwin(struct ethtab *table, int direction, int *idx){ char sp_buf[10]; sprintf(sp_buf, "%%%dc", COLS - 2); wattrset(table->tabwin, STDATTR); if (direction == SCROLLUP) { if (table->lastvisible != table->tail) { wscrl(table->tabwin, 1); table->lastvisible = table->lastvisible->next_entry; table->firstvisible = table->firstvisible->next_entry; (*idx)++; wmove(table->tabwin, LINES - 5, 0); scrollok(table->tabwin, 0); wprintw(table->tabwin, sp_buf, ' '); scrollok(table->tabwin, 1); printethent(table, table->lastvisible, *idx); if (table->lastvisible->type == 1) printrates(table, LINES - 5, table->lastvisible); } } else { if (table->firstvisible != table->head) { wscrl(table->tabwin, -1); table->lastvisible = table->lastvisible->prev_entry; table->firstvisible = table->firstvisible->prev_entry; (*idx)--; wmove(table->tabwin, 0, 0); wprintw(table->tabwin, sp_buf, ' '); printethent(table, table->firstvisible, *idx); if (table->firstvisible->type == 1) printrates(table, 0, table->firstvisible); } }}void pageethwin(struct ethtab *table, int direction, int *idx){ int i = 1; if (direction == SCROLLUP) { while ((i <= LINES - 7) && (table->lastvisible != table->tail)) { i++; table->firstvisible = table->firstvisible->next_entry; table->lastvisible = table->lastvisible->next_entry; (*idx)++; } } else { while ((i <= LINES - 7) && (table->firstvisible != table->head)) { i++; table->firstvisible = table->firstvisible->prev_entry; table->lastvisible = table->lastvisible->prev_entry; (*idx)--; } } refresh_hostmon_screen(table, *idx);}void show_hostsort_keywin(WINDOW ** win, PANEL ** panel){ *win = newwin(13, 35, (LINES - 10) / 2, COLS - 40); *panel = new_panel(*win); wattrset(*win, DLGBOXATTR); tx_colorwin(*win); tx_box(*win, ACS_VLINE, ACS_HLINE); wattrset(*win, DLGTEXTATTR); mvwprintw(*win, 2, 2, "Select sort criterion"); wmove(*win, 4, 2); tx_printkeyhelp("P", " - total packets in", *win, DLGHIGHATTR, DLGTEXTATTR); wmove(*win, 5, 2); tx_printkeyhelp("I", " - IP packets in", *win, DLGHIGHATTR, DLGTEXTATTR); wmove(*win, 6, 2); tx_printkeyhelp("B", " - total bytes in", *win, DLGHIGHATTR, DLGTEXTATTR); wmove(*win, 7, 2); tx_printkeyhelp("K", " - total packets out", *win, DLGHIGHATTR, DLGTEXTATTR); wmove(*win, 8, 2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -