]> gitweb.fperrin.net Git - iftop.git/blobdiff - ui.c
Import iftop-1.0pre4
[iftop.git] / ui.c
diff --git a/ui.c b/ui.c
index 9de8525ea5e51dd10e3eb52e085626bb737b74be..57ca6c04876900c8aca6230707aca0d092df552c 100644 (file)
--- a/ui.c
+++ b/ui.c
@@ -3,10 +3,12 @@
  *
  */
 
+#include "config.h"
+
 #include <sys/types.h>
 
 #include <ctype.h>
-#include <curses.h>
+#include <ncurses.h>
 #include <errno.h>
 #include <string.h>
 #include <math.h>
@@ -26,9 +28,7 @@
 #include "options.h"
 #include "screenfilter.h"
 
-#define HOSTNAME_LENGTH 256
-
-#define HISTORY_DIVISIONS   3
+#include "ui_common.h"
 
 #define HELP_TIME 2
 
 " > - sort by dest name\n"\
 " o - freeze current order\n"\
 "\n"\
-"iftop, version " IFTOP_VERSION 
-
-
-/* 2, 10 and 40 seconds */
-int history_divs[HISTORY_DIVISIONS] = {1, 5, 20};
-
-#define UNIT_DIVISIONS 4
-char* unit_bits[UNIT_DIVISIONS] =  { "b", "kb", "Mb", "Gb"};
-char* unit_bytes[UNIT_DIVISIONS] =  { "B", "kB", "MB", "GB"};
-
-typedef struct host_pair_line_tag {
-    addr_pair ap;
-    double long total_recv;
-    double long total_sent;
-    double long recv[HISTORY_DIVISIONS];
-    double long sent[HISTORY_DIVISIONS];
-} host_pair_line;
+"iftop, version " PACKAGE_VERSION
 
 
 extern hash_type* history;
@@ -78,12 +62,6 @@ extern options_t options ;
 
 void ui_finish();
 
-hash_type* screen_hash;
-hash_type* service_hash;
-sorted_list_type screen_list;
-host_pair_line totals;
-int peaksent, peakrecv, peaktotal;
-
 #define HELP_MSG_SIZE 80
 int showhelphint = 0;
 int persistenthelp = 0;
@@ -91,122 +69,6 @@ time_t helptimer = 0;
 char helpmsg[HELP_MSG_SIZE];
 int dontshowdisplay = 0;
 
-/*
- * Compare two screen lines based on bandwidth.  Start comparing from the 
- * specified column
- */
-int screen_line_bandwidth_compare(host_pair_line* aa, host_pair_line* bb, int start_div) {
-    int i;
-    switch(options.linedisplay) {
-      case OPTION_LINEDISPLAY_ONE_LINE_SENT:
-       for(i = start_div; i < HISTORY_DIVISIONS; i++) {
-           if(aa->sent[i] != bb->sent[i]) {
-               return(aa->sent[i] < bb->sent[i]);
-           }
-        }
-        break;
-      case OPTION_LINEDISPLAY_ONE_LINE_RECV:
-       for(i = start_div; i < HISTORY_DIVISIONS; i++) {
-           if(aa->recv[i] != bb->recv[i]) {
-               return(aa->recv[i] < bb->recv[i]);
-           }
-        }
-        break;
-      case OPTION_LINEDISPLAY_TWO_LINE:
-      case OPTION_LINEDISPLAY_ONE_LINE_BOTH:
-        /* fallback to the combined sent+recv that also act as fallback for sent/recv */
-       break;
-    }
-    for(i = start_div; i < HISTORY_DIVISIONS; i++) {
-       if(aa->recv[i] + aa->sent[i] != bb->recv[i] + bb->sent[i]) {
-           return(aa->recv[i] + aa->sent[i] < bb->recv[i] + bb->sent[i]);
-       }
-    }
-    return 1;
-}
-
-/*
- * Compare two screen lines based on hostname / IP.  Fall over to compare by
- * bandwidth.
- */
-int screen_line_host_compare(void* a, void* b, host_pair_line* aa, host_pair_line* bb) {
-    char hosta[HOSTNAME_LENGTH], hostb[HOSTNAME_LENGTH];
-    int r;
-
-    /* This isn't overly efficient because we resolve again before 
-       display. */
-    if (options.dnsresolution) {
-        resolve(aa->ap.af, a, hosta, HOSTNAME_LENGTH);
-        resolve(bb->ap.af, b, hostb, HOSTNAME_LENGTH);
-    }
-    else {
-        inet_ntop(aa->ap.af, a, hosta, sizeof(hosta));
-        inet_ntop(bb->ap.af, b, hostb, sizeof(hostb));
-    }
-
-    r = strcmp(hosta, hostb);
-
-    if(r == 0) {
-        return screen_line_bandwidth_compare(aa, bb, 2);
-    }
-    else {
-        return (r > 0);
-    }
-
-
-}
-
-int screen_line_compare(void* a, void* b) {
-    host_pair_line* aa = (host_pair_line*)a;
-    host_pair_line* bb = (host_pair_line*)b;
-    if(options.sort == OPTION_SORT_DIV1) {
-      return screen_line_bandwidth_compare(aa, bb, 0);
-    }
-    else if(options.sort == OPTION_SORT_DIV2) {
-      return screen_line_bandwidth_compare(aa, bb, 1);
-    }
-    else if(options.sort == OPTION_SORT_DIV3) {
-      return screen_line_bandwidth_compare(aa, bb, 2);
-    }
-    else if(options.sort == OPTION_SORT_SRC) {
-      return screen_line_host_compare(&(aa->ap.src6), &(bb->ap.src6), aa, bb);
-    }
-    else if(options.sort == OPTION_SORT_DEST) {
-      return screen_line_host_compare(&(aa->ap.dst6), &(bb->ap.dst6), aa, bb);
-    }
-
-    return 1;
-}
-
-void readable_size(float n, char* buf, int bsize, int ksize, int bytes) {
-
-    int i = 0;
-    float size = 1;
-
-    /* Convert to bits? */
-    if(bytes == 0) { 
-      n *= 8;
-    }
-
-    while(1) {
-      if(n < size * 1000 || i >= UNIT_DIVISIONS - 1) {
-        snprintf(buf, bsize, " %4.0f%s", n / size, bytes ? unit_bytes[i] : unit_bits[i]); 
-        break;
-      }
-      i++;
-      size *= ksize;
-      if(n < size * 10) {
-        snprintf(buf, bsize, " %4.2f%s", n / size, bytes ? unit_bytes[i] : unit_bits[i]); 
-        break;
-      }
-      else if(n < size * 100) {
-        snprintf(buf, bsize, " %4.1f%s", n / size, bytes ? unit_bytes[i] : unit_bits[i]); 
-        break;
-      }
-  }
-}
-
-
 /* Barchart scales. */
 static struct {
     int max, interval;
@@ -221,6 +83,8 @@ static struct {
     };
 static int rateidx = 0, wantbiggerrate;
 
+static int rateidx_init = 0;
+
 static int get_bar_interval(float bandwidth) {
     int i = 10;
     if(bandwidth > 100000000) {
@@ -245,8 +109,14 @@ static int get_bar_length(const int rate) {
     float l;
     if (rate <= 0)
         return 0;
-    if (rate > scale[rateidx].max)
-        wantbiggerrate = 1;
+    if (rate > scale[rateidx].max) {
+      wantbiggerrate = 1;
+      if(! rateidx_init) {
+       while(rate > scale[rateidx_init++].max) {
+       }
+       rateidx = rateidx_init;
+      }
+    }
     if(options.log_scale) {
         l = log(rate) / log(get_max_bandwidth());
     }
@@ -307,16 +177,9 @@ static void draw_bar_scale(int* y) {
     }
 }
 
-int history_length(const int d) {
-    if (history_len < history_divs[d])
-        return history_len * RESOLUTION;
-    else
-        return history_divs[d] * RESOLUTION;
-}
-
 void draw_line_total(float sent, float recv, int y, int x, option_linedisplay_t linedisplay, int bytes) {
     char buf[10];
-    float n;
+    float n = 0;
     switch(linedisplay) {
         case OPTION_LINEDISPLAY_TWO_LINE:
           draw_line_total(sent, recv, y, x, OPTION_LINEDISPLAY_ONE_LINE_SENT, bytes);
@@ -392,218 +255,6 @@ void draw_totals(host_pair_line* totals) {
 
 extern history_type history_totals;
 
-void screen_list_init() {
-    screen_list.compare = &screen_line_compare;
-    sorted_list_initialise(&screen_list);
-}
-
-void screen_list_clear() {
-    sorted_list_node* nn = NULL;
-    peaksent = peakrecv = peaktotal = 0;
-    while((nn = sorted_list_next_item(&screen_list, nn)) != NULL) {
-        free(nn->data);
-    }
-    sorted_list_destroy(&screen_list);
-}
-
-void calculate_totals() {
-    int i;
-
-    /**
-     * Calculate peaks and totals
-     */
-    for(i = 0; i < HISTORY_LENGTH; i++) {
-        int j;
-        int ii = (HISTORY_LENGTH + history_pos - i) % HISTORY_LENGTH;
-
-        for(j = 0; j < HISTORY_DIVISIONS; j++) {
-            if(i < history_divs[j]) {
-                totals.recv[j] += history_totals.recv[ii];
-                totals.sent[j] += history_totals.sent[ii];
-            }
-        }
-
-        if(history_totals.recv[i] > peakrecv) {
-            peakrecv = history_totals.recv[i];
-        }
-        if(history_totals.sent[i] > peaksent) {
-            peaksent = history_totals.sent[i];
-        }
-        if(history_totals.recv[i] + history_totals.sent[i] > peaktotal) {
-            peaktotal = history_totals.recv[i] + history_totals.sent[i];       
-        }
-    }
-    for(i = 0; i < HISTORY_DIVISIONS; i++) {
-      int t = history_length(i);
-      totals.recv[i] /= t;
-      totals.sent[i] /= t;
-    }
-}
-
-void make_screen_list() {
-    hash_node_type* n = NULL;
-    while(hash_next_item(screen_hash, &n) == HASH_STATUS_OK) {
-        host_pair_line* line = (host_pair_line*)n->rec;
-        int i;
-        for(i = 0; i < HISTORY_DIVISIONS; i++) {
-          line->recv[i] /= history_length(i);
-          line->sent[i] /= history_length(i);
-        }
-
-        /* Don't make a new, sorted screen list if order is frozen
-         */
-        if(!options.freezeorder) {
-            sorted_list_insert(&screen_list, line);
-        } 
-        
-    }
-}
-
-/*
- * Zeros all data in the screen hash, but does not remove items.
- */
-void screen_hash_clear() {
-    hash_node_type* n = NULL;
-    while(hash_next_item(screen_hash, &n) == HASH_STATUS_OK) {
-        host_pair_line* hpl = (host_pair_line*)n->rec;
-        hpl->total_recv = hpl->total_sent = 0;
-        memset(hpl->recv, 0, sizeof(hpl->recv));
-        memset(hpl->sent, 0, sizeof(hpl->sent));
-    }
-}
-
-void analyse_data() {
-    hash_node_type* n = NULL;
-
-    if(options.paused == 1) {
-      return;
-    }
-
-    // Zero totals
-    memset(&totals, 0, sizeof totals);
-
-    if(options.freezeorder) {
-      screen_hash_clear();
-    }
-    else {
-      screen_list_clear();
-      hash_delete_all(screen_hash);
-    }
-
-    while(hash_next_item(history, &n) == HASH_STATUS_OK) {
-        history_type* d = (history_type*)n->rec;
-        host_pair_line* screen_line;
-       union {
-           host_pair_line **h_p_l_pp;
-           void **void_pp;
-       } u_screen_line = { &screen_line };
-        addr_pair ap;
-        int i;
-        int tsent, trecv;
-        tsent = trecv = 0;
-
-
-        ap = *(addr_pair*)n->key;
-
-        /* Aggregate hosts, if required */
-        if(options.aggregate_src) {
-            memset(&ap.src6, '\0', sizeof(ap.src6));
-        }
-        if(options.aggregate_dest) {
-            memset(&ap.dst6, '\0', sizeof(ap.dst6));
-        }
-
-        /* Aggregate ports, if required */
-        if(options.showports == OPTION_PORTS_DEST || options.showports == OPTION_PORTS_OFF) {
-            ap.src_port = 0;
-        }
-        if(options.showports == OPTION_PORTS_SRC || options.showports == OPTION_PORTS_OFF) {
-            ap.dst_port = 0;
-        }
-        if(options.showports == OPTION_PORTS_OFF) {
-            ap.protocol = 0;
-        }
-
-       
-        if(hash_find(screen_hash, &ap, u_screen_line.void_pp) == HASH_STATUS_KEY_NOT_FOUND) {
-            screen_line = xcalloc(1, sizeof *screen_line);
-            hash_insert(screen_hash, &ap, screen_line);
-            screen_line->ap = ap;
-        }
-        
-       screen_line->total_sent += d->total_sent;
-       screen_line->total_recv += d->total_recv;
-
-        for(i = 0; i < HISTORY_LENGTH; i++) {
-            int j;
-            int ii = (HISTORY_LENGTH + history_pos - i) % HISTORY_LENGTH;
-
-            for(j = 0; j < HISTORY_DIVISIONS; j++) {
-                if(i < history_divs[j]) {
-                    screen_line->recv[j] += d->recv[ii];
-                    screen_line->sent[j] += d->sent[ii];
-                }
-            }
-        }
-
-    }
-
-    make_screen_list();
-
-    
-    calculate_totals();
-
-}
-
-void sprint_host(char * line, int af, struct in6_addr* addr, unsigned int port, unsigned int protocol, int L) {
-    char hostname[HOSTNAME_LENGTH];
-    char service[HOSTNAME_LENGTH];
-    char* s_name;
-    union {
-        char **ch_pp;
-        void **void_pp;
-    } u_s_name = { &s_name };
-
-    ip_service skey;
-    int left;
-
-    if(IN6_IS_ADDR_UNSPECIFIED(addr)) {
-        sprintf(hostname, " * ");
-    }
-    else {
-        if (options.dnsresolution)
-            resolve(af, addr, hostname, L);
-        else
-            inet_ntop(af, addr, hostname, sizeof(hostname));
-    }
-    left = strlen(hostname);
-
-    if(port != 0) {
-      skey.port = port;
-      skey.protocol = protocol;
-      if(options.portresolution && hash_find(service_hash, &skey, u_s_name.void_pp) == HASH_STATUS_OK) {
-        snprintf(service, HOSTNAME_LENGTH, ":%s", s_name);
-      }
-      else {
-        snprintf(service, HOSTNAME_LENGTH, ":%d", port);
-      }
-    }
-    else {
-      service[0] = '\0';
-    }
-
-
-    sprintf(line, "%-*s", L, hostname);
-    if(left > (L - strlen(service))) {
-        left = L - strlen(service);
-        if(left < 0) {
-           left = 0;
-        }
-    }
-    sprintf(line + left, "%-*s", L-left, service);
-}
-
-
 
 void ui_print() {
     sorted_list_node* nn = NULL;
@@ -661,11 +312,11 @@ void ui_print() {
                 sprint_host(host1, screen_line->ap.af,
                             &(screen_line->ap.src6),
                             screen_line->ap.src_port,
-                            screen_line->ap.protocol, L);
+                            screen_line->ap.protocol, L, options.aggregate_src);
                 sprint_host(host2, screen_line->ap.af,
                             &(screen_line->ap.dst6),
                             screen_line->ap.dst_port,
-                            screen_line->ap.protocol, L);
+                            screen_line->ap.protocol, L, options.aggregate_dest);
 
                 if(!screen_filter_match(host1) && !screen_filter_match(host2)) {
                   continue;
@@ -762,8 +413,8 @@ void ui_print() {
 
     /* Bar chart auto scale */
     if (wantbiggerrate && options.max_bandwidth == 0) {
-        ++rateidx;
-        wantbiggerrate = 0;
+      ++rateidx;
+      wantbiggerrate = 0;
     }
 }
 
@@ -783,6 +434,7 @@ void ui_curses_init() {
     (void) nonl();         /* tell curses not to do NL->CR/NL on output */
     (void) cbreak();       /* take input chars one at a time, no wait for \n */
     (void) noecho();       /* don't echo input */
+    (void) curs_set(0);    /* hide blinking cursor in ui */
     halfdelay(2);
 }