home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume25 / ethertop / ethertop.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-12  |  9.9 KB  |  441 lines

  1. /*
  2.  * Copyright (c) 1991 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Irvine.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17. #include <stdio.h>
  18. #include <curses.h>
  19. #include <signal.h>
  20. #include <ctype.h>
  21. #include <sys/types.h>
  22. #include <sys/time.h>
  23. #include <math.h>
  24. #include "ethertop.h"
  25. #include "buffer.h"
  26. #include "sort.h"
  27. #ifndef lint
  28. char copyright[]="Copyright (c) 1991 Regents of the University of California. All rights reserved.";
  29. #endif 
  30. WINDOW *src_window;
  31. WINDOW *dest_window;
  32. WINDOW *size_window1;
  33. WINDOW *size_window2;
  34. WINDOW *load_window;
  35. WINDOW *user_window;
  36.  
  37. struct sgttyb tty_settings;
  38.  
  39. displayip=FALSE;
  40. total=FALSE;
  41. char *server;
  42. int maxlines;
  43.  
  44. void swan_song(message)
  45. char *message;
  46. {
  47.   clear();
  48.   mvcur(0, COLS-1, LINES-1, 0);
  49.   refresh();
  50.   endwin();
  51.   perror(message);
  52.   fflush(stderr);
  53.   exit(0);
  54. }
  55.  
  56. void death()
  57. {
  58.   signal(SIGINT, SIG_IGN);
  59.   clear();
  60.   mvcur(0, COLS-1, LINES-1, 0);
  61.   refresh();
  62.   endwin();
  63.   exit(0);
  64. }
  65.  
  66. /*
  67.          1         2         3         4         5         6         7         
  68. 1234567890123456789012345678901234567890123456789012345678901234567890123456789
  69. */
  70. /*
  71.        |       |       |       |       |       |       |       |       |
  72. */
  73.  
  74.  
  75. void setup_screen()
  76. {
  77.   int x;
  78.   signal(SIGINT, death);
  79.   ioctl(0,TIOCGETP,&tty_settings);
  80.   initscr();
  81.   maxlines=LINES-9;
  82.   noecho();
  83.   crmode();
  84.   nonl();
  85.   user_window=newwin(1,0,0,0);
  86.   scrollok(stdscr,0);
  87.   load_window=subwin(stdscr,1,0,2,0);
  88.   size_window1=subwin(stdscr,1,0,5,0);
  89.   size_window2=subwin(stdscr,1,0,7,0);
  90.   src_window=subwin(stdscr,LINES-10,39,10,0);
  91.   dest_window=subwin(stdscr,LINES-10,39,10,41);
  92.   move(0,0);
  93.   printw("Network load as seen from %s", server);
  94.   move(1,0);
  95.   printw("   bytes    pkts    bcst     tcp     udp    icmp     arp      nd     oth");
  96.   move(3,0);
  97.   printw("packet sizes:");
  98.   move(4,0);
  99.   printw(" 64-154  155-245    246-336    337-427   428-518   519-609   610-699   700-790");
  100.   move(6,0);
  101.   printw("791-881  882-972   973-1063  1064-1154 1155-1245 1246-1336 1337-1427 1428-1518");
  102.   move(8,0);
  103.   printw("--------------------------------------------------------------------------------");
  104.   move(9,0);
  105.   printw("HOSTNAME                          SENT | HOSTNAME                          RECV ");
  106.   for (x=9; x!=LINES; x++)
  107.     {
  108.       move(x,39);
  109.       addch('|');
  110.     }
  111. }
  112.  
  113. void display_data(diffstat)
  114. etherfloatstat *diffstat;
  115. {
  116.       
  117.       wmove(load_window,0,0);
  118.       wprintw(load_window,"%7.2fK %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f",
  119.           (double) diffstat->e_bytes/1024.0,
  120.           (double) diffstat->e_packets,
  121.           (double) diffstat->e_bcast,
  122.           (double) diffstat->e_proto[3], 
  123.           (double) diffstat->e_proto[2],
  124.           (double) diffstat->e_proto[1],
  125.           (double) diffstat->e_proto[4],
  126.           (double) diffstat->e_proto[0],
  127.           (double) diffstat->e_proto[5]);
  128.       
  129.       wmove(size_window1,0,0);
  130.       wprintw(size_window1,"%7.2f  %7.2f    %7.2f    %7.2f   %7.2f   %7.2f   %7.2f   %7.2f ",
  131.           (double) diffstat->e_size[0],
  132.           (double) diffstat->e_size[1],
  133.           (double) diffstat->e_size[2],
  134.           (double) diffstat->e_size[3],
  135.           (double) diffstat->e_size[4],
  136.           (double) diffstat->e_size[5],
  137.           (double) diffstat->e_size[6],
  138.           (double) diffstat->e_size[7]);
  139.  
  140.       wmove(size_window2,0,0);
  141.       wprintw(size_window2,"%7.2f  %7.2f    %7.2f    %7.2f   %7.2f   %7.2f   %7.2f   %7.2f ",
  142.           (double) diffstat->e_size[8],
  143.           (double) diffstat->e_size[9],
  144.           (double) diffstat->e_size[10],
  145.           (double) diffstat->e_size[11],
  146.           (double) diffstat->e_size[12],
  147.           (double) diffstat->e_size[13],
  148.           (double) diffstat->e_size[14],
  149.           (double) diffstat->e_size[15]);
  150.  
  151. }
  152.  
  153. void display_a_list(window,buf)
  154.      WINDOW *window;
  155.      buffer *buf;
  156. {
  157.   register unsigned int i;
  158.   etherfloat_node *ptr;
  159.   for (i=0; i<maxlines && i<buf->end; i++)
  160.     {
  161.       wmove(window,i,0);
  162.       ptr=buf->p[i];
  163.       wprintw(window, "%-30.30s %7.2f", 
  164.           gethostnamebyip(ptr->h_addr),
  165.           (double)ptr->h_cnt);
  166.     }
  167.   wmove(window,i,0);
  168.   wclrtobot(window);
  169. }
  170.  
  171. /* I am not proud of this routine, but it works */
  172. int wgnum(window,min,max)
  173. WINDOW *window;
  174. int min;
  175. int max;
  176. {
  177.   int ch;
  178.   int i=0;
  179.   int x,y;
  180.   int maxchar;
  181.   int minchar;
  182.   char string[80];
  183.   bzero(string,80);
  184.   maxchar=(int) log10 ((double) (max*10));
  185.   nl();
  186.   noecho();
  187.   getyx(window,y,x);
  188.   while(1)
  189.     {
  190.       ch=getch();
  191.       if ((ch=='\n')
  192.       && i>0
  193.       && (atoi(string) <=max)
  194.       && (atoi(string) >= min) )
  195.     {
  196.       nonl();
  197.       noecho();
  198.       return(atoi(string));
  199.     }
  200.       if(ch==tty_settings.sg_erase)
  201.     {
  202.       if(i>0)
  203.         {
  204.           string[--i]=0;
  205.           mvwdelch(window,y,x+i);
  206.           wrefresh(window);
  207.           continue;
  208.         }
  209.       else
  210.         {
  211.           continue;
  212.         }
  213.     }
  214.       if(isdigit(ch))
  215.     {
  216.       if (i<maxchar)
  217.         {
  218.           string[i++]=ch;
  219.           mvwaddch(window,y,x+i-1,ch);
  220.           wrefresh(window);
  221.           continue;
  222.         }
  223.     }
  224.     }
  225. }
  226.  
  227.  
  228. void process_input()
  229. {
  230.   switch(tolower(getch()))
  231.     {
  232.     case 'i':
  233.       displayip=!displayip;
  234.       break;
  235.     case 't':
  236.       total=!total;
  237.       break;
  238.     case 'q':
  239.       death();
  240.       break;
  241.     case 'l':
  242.       wrefresh(curscr);
  243.       break;
  244.     case 's':
  245.       {
  246.     werase(user_window);
  247.     wstandout(user_window);
  248.     waddstr(user_window,"Seconds to delay:");
  249.     wstandend(user_window);
  250.     waddstr(user_window," ");
  251.     touchwin(user_window);
  252.     wrefresh(user_window);
  253.     timeout.tv_sec=wgnum(user_window,2,3600);
  254.     touchwin(stdscr);
  255.     refresh();
  256.     break;
  257.       }
  258.     case 'n':
  259.           werase(user_window);
  260.     wstandout(user_window);
  261.     waddstr(user_window,"Hosts to display:");
  262.     wstandend(user_window);
  263.     waddstr(user_window," ");
  264.     touchwin(user_window);
  265.     wrefresh(user_window);
  266.     maxlines=wgnum(user_window,0,LINES-9);
  267.     touchwin(stdscr);
  268.     refresh();
  269.     break;
  270.     default:
  271.       ;
  272.     }
  273. }
  274.  
  275.  
  276. int errflg=0;
  277. etherfloatstat diffstat;
  278. etheraddrs old_src_addrs;
  279. etheraddrs old_dest_addrs; 
  280. etherstat old_stat_data;
  281. fd_set readfds,tempreadfds;
  282. struct timeval timeout={5,0};
  283. struct timeval temptimeout;
  284. extern char *optarg;
  285. extern int optind, opterr;
  286.       
  287.  
  288. main(argc, argv)
  289.  
  290.      char *argv[];
  291. {
  292.   CLIENT *cl;
  293.   etherstat *stat_data;
  294.   etheraddrs *src_addrs;
  295.   etheraddrs *dest_addrs;
  296.   buffer *src_buf;
  297.   buffer *dest_buf;
  298.   char c;
  299.  
  300.   while ((c=getopt(argc, argv, "is:t"))!=-1)
  301.     switch(c)
  302.       {
  303.       case 'i':
  304.     displayip++;
  305.     break;
  306.     
  307.       case 's':
  308.     timeout.tv_sec=atol(optarg);
  309.     if (timeout.tv_sec<2)
  310.       errflg++;
  311.     break;
  312.     
  313.       case 't':
  314.     total++;
  315.     break;
  316.  
  317.       case '?':
  318.     errflg++;
  319.     break;
  320.       }
  321.  
  322.   if (optind!=argc-1  || errflg)
  323.     {
  324.       fprintf(stderr,"Usage:\n");
  325.       fprintf(stderr,"%s [options] hostname\n\n",argv[0]);
  326.       fprintf(stderr,"options are:\n");
  327.       fprintf(stderr,"-i           don't map ip numbers to hostnames\n");
  328.       fprintf(stderr,"-s int       seconds between updates.  Minimum of 2 seconds.\n");
  329.       fprintf(stderr,"-t           display time averaged totals, rather than instantanous averages\n");
  330.       exit(2);
  331.     }
  332.   server=argv[optind];
  333.  
  334.   src_buf=init_buffer();     
  335.   dest_buf=init_buffer();
  336.   cl = clnt_create(server, ETHERPROG, ETHERVERS, "udp");
  337.   if (cl == NULL)
  338.     {
  339.       clnt_pcreateerror(server);
  340.       exit(1);
  341.     }
  342.   setup_screen();
  343.   init_gethostnamebyip();
  344.   FD_ZERO(&readfds);
  345.   FD_SET(0,&readfds); /* set up stdin for select */
  346.   
  347.  
  348.   if((etherproc_on_1((void *)NULL,cl))==NULL)
  349.     swan_song("etherproc_on failed. rpc.etherd probably died");
  350.  
  351.   if((stat_data=etherproc_getdata_1((void *) NULL, cl))==NULL)
  352.     swan_song("etherproc_getdata failed. rpc.etherd probably died");
  353.      
  354.   old_stat_data=*stat_data;
  355.   
  356.   if((src_addrs=etherproc_getsrcdata_1((void *) NULL, cl))==NULL)
  357.     swan_song("etherproc_getdata failed. rpc.etherd probably died");
  358.  
  359.   old_src_addrs=*src_addrs;
  360.  
  361.   if( (dest_addrs =etherproc_getdstdata_1((void *) NULL, cl))==NULL)
  362.     swan_song("etherproc_getdata failed. rpc.etherd probably died");
  363.  
  364.  
  365.   old_dest_addrs=*dest_addrs;
  366.   sleep(1); /*snewz*/
  367.   
  368.   for (;;)
  369.     {
  370.       move(2,0);
  371.       refresh();
  372.       tempreadfds=readfds;
  373.       temptimeout=timeout;
  374.       if(select(3,&tempreadfds,NULL,NULL,&temptimeout))
  375.     process_input();
  376.  
  377.       if( (stat_data=etherproc_getdata_1((void *) NULL, cl))==NULL)
  378.     swan_song("etherproc_getdata failed. rpc.etherd probably died");
  379.  
  380.       subtract_etherstat(stat_data,&old_stat_data,&diffstat);
  381.       if (total)
  382.     {
  383.       xdr_free(xdr_etherstat,stat_data);
  384.     }
  385.       else
  386.     {
  387.       xdr_free(xdr_etherstat,&old_stat_data);
  388.       old_stat_data=*stat_data;
  389.     }
  390.       
  391.       display_data(&diffstat);
  392.       
  393.       if( (src_addrs =etherproc_getsrcdata_1((void *) NULL, cl))==NULL)
  394.     swan_song("etherproc_getsrcdata failed. rpc.etherd probably died");
  395.  
  396.       subtract_and_sort_etheraddrs(src_addrs, &old_src_addrs, src_buf);
  397.  
  398.       if (total)
  399.     {
  400.       xdr_free(xdr_etheraddrs,src_addrs);
  401.     }
  402.       else
  403.     {
  404.       xdr_free(xdr_etheraddrs,&old_src_addrs);
  405.       old_src_addrs=*src_addrs;
  406.     }
  407.  
  408.       
  409.       if( (dest_addrs=etherproc_getdstdata_1((void *) NULL, cl))==NULL)
  410.     swan_song("etherproc_getdstdata failed. rpc.etherd probably died");
  411.  
  412.       subtract_and_sort_etheraddrs(dest_addrs, &old_dest_addrs, dest_buf);
  413.       if (total)
  414.     {
  415.       xdr_free(xdr_etheraddrs,dest_addrs);
  416.     }
  417.       else
  418.     {
  419.       xdr_free(xdr_etheraddrs,&old_dest_addrs);
  420.       old_dest_addrs=*dest_addrs;
  421.     }
  422.       display_a_list(src_window,src_buf);
  423.       display_a_list(dest_window,dest_buf);
  424.       free_buffer(src_buf);
  425.       free_buffer(dest_buf);
  426.     }
  427. }
  428.  
  429.  
  430.  
  431.  
  432.  
  433.  
  434.       
  435.  
  436.  
  437.  
  438.  
  439.  
  440.  
  441.