/* * Copyright (c) 2001 Hellmuth Michaelis. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *--------------------------------------------------------------------------- * * nifmon - curses fullscreen output * --------------------------------- * * last edit-date: [Sun Sep 9 11:53:51 2001] * *---------------------------------------------------------------------------*/ #include "nifmon.h" /*---------------------------------------------------------------------------* * init curses fullscreen display *---------------------------------------------------------------------------*/ void init_screen(char *interface) { char buffer[512]; int uheight, lheight; initscr(); /* curses init */ if ((COLS < 80) || (LINES < 24)) { endwin(); fprintf(stderr, "ERROR, minimal screensize must be 80x24, is %dx%d, terminating!", COLS, LINES); do_exit(1); } noecho(); raw(); uheight = 10; if ((upper_w = newwin(uheight, COLS, 0, 0)) == NULL) { endwin(); fprintf(stderr, "ERROR, curses init upper window, terminating!"); do_exit(1); } lheight = LINES - uheight; /* rest of display */ if ((lower_w = newwin(lheight, COLS, 0 + uheight, 0)) == NULL) { endwin(); fprintf(stderr, "ERROR, curses init lower window, LINES = %d, lheight = %d, uheight = %d, terminating!", LINES, lheight, uheight); do_exit(1); } scrollok(lower_w, 1); sprintf(buffer, "----- network interface monitor (%d.%d) ---------------- %s -", VERSION, RELEASE, interface); while (strlen(buffer) < COLS) strcat(buffer, "-"); wmove(upper_w, 0, 0); wstandout(upper_w); waddstr(upper_w, buffer); wstandend(upper_w); wmove(upper_w, 1, 0); /* 01234567890123456789012345678901234567890123456789012345678901234567890123456789 */ if (if_flags & IFF_POINTOPOINT) waddstr(upper_w, "addr: dst: "); else waddstr(upper_w, "addr: brc: "); wmove(upper_w, 2, 0); /* 01234567890123456789012345678901234567890123456789012345678901234567890123456789 */ waddstr(upper_w, "chg: "); wmove(upper_w, 3, 0); /* 01234567890123456789012345678901234567890123456789012345678901234567890123456789 */ waddstr(upper_w, " bytes in: bytes out: "); wmove(upper_w, 4, 0); waddstr(upper_w, "packets in: packets out: "); wmove(upper_w, 5, 0); waddstr(upper_w, " inbytes/h: - inbytes/m: - inbytes/s: - "); wmove(upper_w, 6, 0); waddstr(upper_w, "outbytes/h: - outbytes/m: - outbytes/s: - "); wmove(upper_w, 7, 0); waddstr(upper_w, " inpkts/h: - inpkts/m: - inpkts/s: - "); wmove(upper_w, 8, 0); waddstr(upper_w, " outpkts/h: - outpkts/m: - outpkts/s: - "); wmove(upper_w, 9, 0); sprintf(buffer, "----- tcpdump output --------------------------------------------------"); while (strlen(buffer) < COLS) strcat(buffer, "-"); wstandout(upper_w); waddstr(upper_w, buffer); wstandend(upper_w); leaveok(upper_w, 1); leaveok(lower_w, 1); refresh(); wrefresh(upper_w); wmove(lower_w, 0, 0); wrefresh(lower_w); curses_ready = 1; } /*---------------------------------------------------------------------------* * curses menu for fullscreen command mode *---------------------------------------------------------------------------*/ void do_menu(void) { static char *menu[WMITEMS] = { "1 - (D)isplay refresh", "2 - (Q)uit the program", }; WINDOW *menu_w; int c; int mpos; fd_set set; struct timeval timeout; /* create a new window in the lower screen area */ if ((menu_w = newwin(WMENU_HGT, WMENU_LEN, WMENU_POSLN, WMENU_POSCO)) == NULL) return; /* create a border around the window */ box(menu_w, '|', '-'); /* add a title */ wstandout(menu_w); mvwaddstr(menu_w, 0, (WMENU_LEN / 2) - (strlen(WMENU_TITLE) / 2), WMENU_TITLE); wstandend(menu_w); /* fill the window with the menu options */ for (mpos = 0; mpos <= (WMITEMS - 1); mpos++) mvwaddstr(menu_w, mpos + 2, 2, menu[mpos]); /* highlight the first menu option */ mpos = 0; wstandout(menu_w); mvwaddstr(menu_w, mpos + 2, 2, menu[mpos]); wstandend(menu_w); /* input loop */ for (;;) { wrefresh(menu_w); FD_ZERO(&set); FD_SET(STDIN_FILENO, &set); timeout.tv_sec = WMTIMEOUT; timeout.tv_usec = 0; /* if no char is available within timeout, exit menu */ if ((select(STDIN_FILENO + 1, &set, NULL, NULL, &timeout)) <= 0) goto mexit; c = wgetch(menu_w); switch (c) { case ' ': case '\t': /* hilite next option */ mvwaddstr(menu_w, mpos + 2, 2, menu[mpos]); mpos++; if (mpos >= WMITEMS) mpos = 0; wstandout(menu_w); mvwaddstr(menu_w, mpos + 2, 2, menu[mpos]); wstandend(menu_w); break; case ('0' + WREFRESH + 1): /* display refresh */ case 'D': case 'd': wrefresh(curscr); goto mexit; case ('0' + WQUIT + 1): /* quit program */ case 'Q': case 'q': do_exit(0); goto mexit; case '\n': case '\r': /* exec highlighted option */ switch (mpos) { case WREFRESH: wrefresh(curscr); break; case WQUIT: do_exit(0); break; } goto mexit; break; default: goto mexit; break; } } mexit: /* delete the menu window */ delwin(menu_w); /* re-display the original lower window contents */ touchwin(lower_w); wrefresh(lower_w); } /*---------------------------------------------------------------------------* * data from keyboard available, read and process it *---------------------------------------------------------------------------*/ void kbdrdhdl(void) { int ch = getch(); switch (ch) { case 0x0c: /* control L */ wrefresh(curscr); break; case 0x03: /* control C */ do_exit(0); break; case '\n': case '\r': do_menu(); break; } } /*---------------------------------------------------------------------------* * remove string from buffer *---------------------------------------------------------------------------*/ static void sremove(char *buffer, char *string) { char *p; p = strstr(buffer, string); if(p) { bcopy(p+strlen(string), p, 1+strlen(p+strlen(string)) ); } } /*---------------------------------------------------------------------------* * remove bytes from buffer start at from with length l *---------------------------------------------------------------------------*/ static void sremovefl(char *buffer, int f, int l) { bcopy(buffer+f+l, buffer+f, 1+strlen(buffer+f+l)); } #ifdef nowineedthis /*---------------------------------------------------------------------------* * replace in buffer string from with string to *---------------------------------------------------------------------------*/ static void sreplace(char *buffer, char *from, char *to) { char *p; p = strstr(buffer, from); if(p) { bcopy(to, p, strlen(to)); bcopy(p+strlen(from), p+strlen(to), 1+strlen(p+strlen(from))); } } #endif /*---------------------------------------------------------------------------* * data from tcpdump available, read (as much as possible) and print *---------------------------------------------------------------------------*/ #define PBS 1024 void loghdl(FILE *fp) { char *p; fd_set set; struct timeval timeout; char buffer[PBS]; if ((fgets(buffer, PBS, fp)) == NULL) return; timeout.tv_sec = 0; timeout.tv_usec = 0; for(;;) { /* check if the line has a time stamp, if yes, we display it */ if(buffer[2] == ':' && buffer[5] == ':') { /* remove date */ sremovefl(buffer, 8, 7); /* remove our own hostname */ sremove(buffer, hostname); /* remove more useless stuff */ sremove(buffer, " [tcp sum ok]"); sremove(buffer, " [udp sum ok]"); /* remove newline */ p = index(buffer, '\n'); if(p != NULL) *p = '\0'; /* check for and enforce max length */ *(buffer+COLS-1) = '\0'; /* print line */ wprintw(lower_w, "\n%s", buffer); } /* check for more data from tcpdump */ FD_ZERO(&set); FD_SET(fileno(fp), &set); if((select((fileno(fp))+1, &set, NULL, NULL, &timeout)) <= 0) break; /* no data, exit loop */ fgets(buffer, PBS, fp); /* more data, continue looping */ } wrefresh(lower_w); } /* EOF */