diff -Naur gkrellm-2.2.4o/server/monitor.c gkrellm-2.2.4/server/monitor.c --- gkrellm-2.2.4o/server/monitor.c 2004-05-02 20:23:19.000000000 -0600 +++ gkrellm-2.2.4/server/monitor.c 2004-10-07 11:16:22.341993708 -0600 @@ -616,41 +616,63 @@ gint slen; tcp = (ActiveTCP *) data; - for (list = inet_list; list; list = list->next) + switch (tcp->chain) { - in = (InetData *) list->data; - active_tcp = &in->tcp; - if (tcp->family == AF_INET) - { - ap = (char *)&tcp->remote_addr; - aap = (char *)&active_tcp->remote_addr; - slen = sizeof(struct in_addr); - } + case CHAIN_CONNECT: + for (list = inet_list; list; list = list->next) + { + in = (InetData *) list->data; + active_tcp = &in->tcp; + if (tcp->family == AF_INET) + { + ap = (char *)&tcp->remote_addr; + aap = (char *)&active_tcp->remote_addr; + slen = sizeof(struct in_addr); + } #if defined(INET6) - else if (tcp->family == AF_INET6) - { - ap = (char *)&tcp->remote_addr6; - aap = (char *)&active_tcp->remote_addr6; - slen = sizeof(struct in6_addr); - } + else if (tcp->family == AF_INET6) + { + ap = (char *)&tcp->remote_addr6; + aap = (char *)&active_tcp->remote_addr6; + slen = sizeof(struct in6_addr); + } #endif - else - return; - if ( memcmp(aap, ap, slen) == 0 - && active_tcp->remote_port == tcp->remote_port - && active_tcp->local_port == tcp->local_port - ) - { - in->alive = TRUE; /* Old alive connection still alive */ - return; - } + else + return; + + if ( memcmp(aap, ap, slen) == 0 + && active_tcp->remote_port == tcp->remote_port + && active_tcp->local_port == tcp->local_port + ) + { + in->alive = TRUE; /* Old alive connection still alive */ + return; + } + } + inet_new = TRUE; + in = g_new0(InetData, 1); + in->tcp = *tcp; + in->alive = TRUE; + in->new_connection = TRUE; + inet_list = g_list_append(inet_list, in); + break; + + default: +#if 0 +fprintf(stderr, "%lu local %d:%d remote %d:%d chain %d line %d target %d pkts %Lu bytes %Lu\n", time(0L), + tcp->local_port, tcp->local_port_hi, + tcp->remote_port, tcp->remote_port_hi, + tcp->chain, tcp->line, tcp->target, tcp->pkts, tcp->bytes); + +#endif + inet_new = TRUE; + in = g_new0(InetData, 1); + in->tcp = *tcp; + in->alive = TRUE; + in->new_connection = TRUE; + inet_list = g_list_append(inet_list, in); + break; } - inet_new = TRUE; - in = g_new0(InetData, 1); - in->tcp = *tcp; - in->alive = TRUE; - in->new_connection = TRUE; - inet_list = g_list_append(inet_list, in); } static void @@ -715,40 +737,57 @@ { in = (InetData *) list->data; tcp = &in->tcp; - if ( tcp->family == AF_INET - && (in->new_connection || first_serve) - ) + switch (tcp->chain) { - cp = inet_ntoa(tcp->remote_addr); - sprintf(buf, "+0 %x %s:%x\n", - tcp->local_port, cp, tcp->remote_port); - } + case CHAIN_CONNECT: + if ( tcp->family == AF_INET + && (in->new_connection || first_serve) + ) + { + cp = inet_ntoa(tcp->remote_addr); + sprintf(buf, "+0 %x %s:%x\n", + tcp->local_port, cp, tcp->remote_port); + } #if defined(INET6) && defined(HAVE_GETADDRINFO) - else if (tcp->family == AF_INET6 - && (in->new_connection || first_serve)) - { - memset(&sin6, 0, sizeof(sin6)); - memcpy(&sin6.sin6_addr, &tcp->remote_addr6, - sizeof(struct in6_addr)); - sin6.sin6_family = AF_INET6; + else if (tcp->family == AF_INET6 + && (in->new_connection || first_serve)) + { + memset(&sin6, 0, sizeof(sin6)); + memcpy(&sin6.sin6_addr, &tcp->remote_addr6, + sizeof(struct in6_addr)); + sin6.sin6_family = AF_INET6; #ifdef SIN6_LEN - sin6.sin6_len = sizeof(struct sockaddr_in6); + sin6.sin6_len = sizeof(struct sockaddr_in6); #endif - if (getnameinfo((struct sockaddr *)&sin6, - sizeof(struct sockaddr_in6), - addrbuf, sizeof(addrbuf), - NULL, 0, - NI_NUMERICHOST|NI_WITHSCOPEID) - != 0) - continue; - snprintf(buf, sizeof(buf), "+6 %x [%s]:%x\n", - tcp->local_port, addrbuf, - tcp->remote_port); - } + if (getnameinfo((struct sockaddr *)&sin6, + sizeof(struct sockaddr_in6), + addrbuf, sizeof(addrbuf), + NULL, 0, + NI_NUMERICHOST|NI_WITHSCOPEID) + != 0) + continue; + snprintf(buf, sizeof(buf), "+6 %x [%s]:%x\n", + tcp->local_port, addrbuf, + tcp->remote_port); + } #endif - else - continue; - + else + continue; + break; + default: + if (in->new_connection || first_serve) + { + snprintf(buf, sizeof(buf), "*F %x:%x %x:%x %d:%d:%d %Lu:%Lu\n", + tcp->local_port, tcp->local_port_hi, + tcp->remote_port, tcp->remote_port_hi, + tcp->chain, tcp->line, tcp->target, tcp->pkts, tcp->bytes); + in->alive = FALSE; +#if 0 +fprintf(stderr, "serving buf=%s", buf); +#endif + } + break; + } gkrellmd_serve_data(mon, buf); } } diff -Naur gkrellm-2.2.4o/src/chart.c gkrellm-2.2.4/src/chart.c --- gkrellm-2.2.4o/src/chart.c 2004-08-31 08:34:23.000000000 -0600 +++ gkrellm-2.2.4/src/chart.c 2004-10-07 11:07:40.469603674 -0600 @@ -66,7 +66,7 @@ return chart_list; } -gint +gint64 gkrellm_get_chart_scalemax(GkrellmChart *cp) { if (!cp) @@ -74,7 +74,7 @@ return cp->scale_max; } -gint +gint64 gkrellm_get_current_chartdata(GkrellmChartdata *cd) { if (!cd) @@ -82,7 +82,7 @@ return cd->data[cd->chart->position]; } -gint +gint64 gkrellm_get_chartdata_data(GkrellmChartdata *cd, gint index) { gint x; @@ -256,7 +256,7 @@ } static gint -chartdata_ycoord(GkrellmChart *cp, GkrellmChartdata *cd, gint yd) +chartdata_ycoord(GkrellmChart *cp, GkrellmChartdata *cd, gint64 yd) { glong y; guint64 Y; @@ -270,7 +270,7 @@ y = Y / cp->scale_max; } else - y = ((glong) yd * cd->h / cp->scale_max); + y = (yd * cd->h / cp->scale_max); if (y < 0) y = 0; @@ -366,7 +366,8 @@ { GList *list; GkrellmChartdata *cd; - gint n, x, y, y0, y1, yN, yI; + gint n, x, y, y0, y1; + gint64 yN, yI; gint current_split; gboolean need_next_split = FALSE; @@ -515,7 +516,7 @@ /* See the README for description of auto grid resolution behavior. */ static void -set_auto_grid_resolution(GkrellmChart *cp, gint maxval) +set_auto_grid_resolution(GkrellmChart *cp, gint64 maxval) { GkrellmChartconfig *cf = cp->config; gint grids, grid_res, maxval_base; @@ -568,7 +569,7 @@ setup_chart_scalemax(GkrellmChart *cp) { GkrellmChartconfig *cf = cp->config; - glong scalemax; + gint64 scalemax; gint grid_res, i0; /* maxval may change at any gkrellm_store_chartdata(), so at each chart @@ -680,7 +681,7 @@ cd->w = w; if (cd->data) g_free(cd->data); - cd->data = (gint *) g_new0(gint, w); + cd->data = (gint64 *) g_new0(gint64, w); cd->maxval = 0; cp->position = cp->w - 1; cp->tail = cp->position; @@ -712,7 +713,7 @@ { GList *list; GkrellmChartdata *cd; - gint N, I; + gint64 N, I; gint i, current_split; gboolean need_next_split = FALSE; @@ -800,7 +801,8 @@ GList *list; GkrellmChartdata *cd; gulong range, total_diff; - gint n, N_discard, I_discard, N, I; + gint n; + guint64 N, I, N_discard, I_discard; gint active_split, current_split; gboolean need_scan = FALSE; @@ -810,7 +812,7 @@ for (list = cp->cd_list; list; list = list->next) { cd = (GkrellmChartdata *) list->data; - cd->current = va_arg(args, gulong); + cd->current = va_arg(args, guint64); if (!cd->monotonic) { cd->previous = 0; @@ -843,7 +845,7 @@ { cd = (GkrellmChartdata *) list->data; cd->discard = cd->data[cp->tail]; - cd->data[n] = (gint)(cd->current - cd->previous); + cd->data[n] = (gint64)(cd->current - cd->previous); cd->previous = cd->current; /* If using totals, scale the stored data to range between 0 and the @@ -1919,7 +1921,7 @@ }; gint -gkrellm_125_sequence(gint value, gboolean use125, +gkrellm_125_sequence(gint64 value, gboolean use125, gint low, gint high, gboolean snap_to_table, gboolean roundup) { @@ -2086,9 +2088,9 @@ if (map_sequence) { cf->low = 1; - cf->low = (gfloat) gkrellm_125_sequence((gint) low, cf->sequence_125, + cf->low = (gfloat) gkrellm_125_sequence((gint64) low, cf->sequence_125, low, high, TRUE, FALSE); - cf->high = (gfloat) gkrellm_125_sequence((gint) high, + cf->high = (gfloat) gkrellm_125_sequence((gint64) high, cf->sequence_125, low, high, TRUE, TRUE); cf->step0 = 1.0; cf->step1 = 1.0; diff -Naur gkrellm-2.2.4o/src/client.c gkrellm-2.2.4/src/client.c --- gkrellm-2.2.4o/src/client.c 2004-05-14 13:45:14.000000000 -0600 +++ gkrellm-2.2.4/src/client.c 2004-10-07 11:07:40.470603529 -0600 @@ -490,6 +490,10 @@ #endif gint n, slen; +#if 0 + fprintf(stderr, "%s\n", line); +#endif + if (*(line + 1) == '0') { n = sscanf(line + 3, "%x %127[^:]:%x", &tcp.local_port, @@ -520,6 +524,28 @@ tcp.family = AF_INET6; } #endif + else if (*(line + 1) == 'F') + { + tcp.state = 0; + tcp.family = 0; + tcp.new_hit = 0; + n = sscanf(line + 3, "%x:%x %x:%x %d:%d:%d %Lu:%Lu", + &tcp.local_port, &tcp.local_port_hi, + &tcp.remote_port, &tcp.remote_port_hi, + &tcp.chain, &tcp.line, &tcp.target, + &tcp.pkts, &tcp.bytes); +#if 0 + fprintf(stderr, "%s\n", line); + fprintf(stderr, "local %d:%d remote %d:%d chain %d line %d target %d pkts %Lu bytes %Lu\n", + tcp.local_port, tcp.local_port_hi, + tcp.remote_port, tcp.remote_port_hi, + tcp.chain, tcp.line, tcp.target, tcp.pkts, tcp.bytes); +#endif + if (n != 9) + return; + gkrellm_inet_log_tcp_port_data(&tcp); + } + if (*line == '+') { t = g_new0(ActiveTCP, 1); diff -Naur gkrellm-2.2.4o/src/cpu.c gkrellm-2.2.4/src/cpu.c --- gkrellm-2.2.4o/src/cpu.c 2004-09-06 08:40:17.000000000 -0600 +++ gkrellm-2.2.4/src/cpu.c 2004-10-07 11:07:40.471603384 -0600 @@ -453,7 +453,7 @@ total = cpu->user + cpu->nice + cpu->sys + cpu->idle; if (GK.second_tick) { - gkrellm_store_chartdata(cp, total, cpu->sys, cpu->user, cpu->nice); + gkrellm_store_chartdata(cp, total, (gint64) cpu->sys, (gint64) cpu->user, (gint64) cpu->nice); refresh_cpu_chart(cpu); alert_value = cpu->sys + cpu->user; diff -Naur gkrellm-2.2.4o/src/disk.c gkrellm-2.2.4/src/disk.c --- gkrellm-2.2.4o/src/disk.c 2004-08-31 11:03:48.000000000 -0600 +++ gkrellm-2.2.4/src/disk.c 2004-10-07 11:07:40.472603239 -0600 @@ -589,7 +589,7 @@ if (GK.second_tick) { gkrellm_store_chartdata(cp, 0, - (gulong) disk->wb, (gulong) disk->rb); + (guint64) disk->wb, (guint64) disk->rb); if (disk->alert) { bytes = 0; diff -Naur gkrellm-2.2.4o/src/gkrellm.h gkrellm-2.2.4/src/gkrellm.h --- gkrellm-2.2.4o/src/gkrellm.h 2004-09-06 16:33:01.000000000 -0600 +++ gkrellm-2.2.4/src/gkrellm.h 2004-10-07 11:07:40.473603095 -0600 @@ -642,7 +642,7 @@ gint alloc_width; gint scale_max; - gint maxval, + gint64 maxval, maxval_auto, maxval_auto_base, maxval_peak; @@ -704,13 +704,13 @@ GkrellmChart *chart; /* GkrellmChart this data belong to */ gchar *label; - gulong current, + guint64 current, previous, discard; gboolean monotonic; GkrellmChartlayer layer; /* The image + grid for this data layer */ GdkBitmap *data_bitmap; /* Draw data here, use as clipmask for layer*/ - gint *data; + gint64 *data; gint draw_style; gboolean inverted; @@ -727,7 +727,7 @@ gint y, /* Each data layer draws at an offset y and */ h, /* within height h of its parent GkrellmChart*/ w; /* Width of data allocated. */ - gint maxval; + guint64 maxval; } GkrellmChartdata; diff -Naur gkrellm-2.2.4o/src/gkrellm-public-proto.h gkrellm-2.2.4/src/gkrellm-public-proto.h --- gkrellm-2.2.4o/src/gkrellm-public-proto.h 2004-07-16 10:54:12.000000000 -0600 +++ gkrellm-2.2.4/src/gkrellm-public-proto.h 2004-10-07 11:07:40.474602950 -0600 @@ -67,7 +67,7 @@ gint gkrellm_chart_width(void); void gkrellm_set_chart_height_default(GkrellmChart *, gint); void gkrellm_set_chart_height(GkrellmChart *, gint); -gint gkrellm_get_chart_scalemax(GkrellmChart *); +gint64 gkrellm_get_chart_scalemax(GkrellmChart *); void gkrellm_render_data_pixmap(GkrellmPiximage *, GdkPixmap **, GdkColor *, gint); void gkrellm_render_data_grid_pixmap(GkrellmPiximage *, @@ -84,8 +84,8 @@ void gkrellm_draw_chartdata(GkrellmChart *); void gkrellm_monotonic_chartdata(GkrellmChartdata *, gboolean); gboolean gkrellm_get_chartdata_hide(GkrellmChartdata *); -gint gkrellm_get_current_chartdata(GkrellmChartdata *); -gint gkrellm_get_chartdata_data(GkrellmChartdata *, gint); +gint64 gkrellm_get_current_chartdata(GkrellmChartdata *); +gint64 gkrellm_get_chartdata_data(GkrellmChartdata *, gint); void gkrellm_set_chartdata_draw_style(GkrellmChartdata *, gint); void gkrellm_set_chartdata_draw_style_default(GkrellmChartdata *, gint); void gkrellm_set_chartdata_flags(GkrellmChartdata *, gint); @@ -514,7 +514,7 @@ gchar *gkrellm_make_config_file_name(gchar *, gchar *); gchar *gkrellm_make_data_file_name(gchar *, gchar *); struct tm *gkrellm_get_current_time(void); -gint gkrellm_125_sequence(gint, gboolean, gint, gint, +gint gkrellm_125_sequence(gint64, gboolean, gint, gint, gboolean, gboolean); void gkrellm_save_all(void); diff -Naur gkrellm-2.2.4o/src/inet.c gkrellm-2.2.4/src/inet.c --- gkrellm-2.2.4o/src/inet.c 2004-05-14 13:45:14.000000000 -0600 +++ gkrellm-2.2.4/src/inet.c 2004-10-07 11:07:40.478602370 -0600 @@ -24,6 +24,17 @@ #include "gkrellm-sysdeps.h" #include "inet.h" +typedef struct gtcphistory + { + gint chain; + gint line; + gint test; + guint64 pkts; + guint64 bytes; + struct gtcphistory *next; + } GTCPHistory; + + typedef struct { GtkWidget *vbox; @@ -34,11 +45,21 @@ GkrellmChart *chart_hour; GkrellmChartconfig *chart_config_minute; GkrellmChartconfig *chart_config_hour; + GkrellmChart *chart_minute_pkts; + GkrellmChart *chart_hour_pkts; + GkrellmChartconfig *chart_config_minute_pkts; + GkrellmChartconfig *chart_config_hour_pkts; + GkrellmChart *chart_minute_bytes; + GkrellmChart *chart_hour_bytes; + GkrellmChartconfig *chart_config_minute_bytes; + GkrellmChartconfig *chart_config_hour_bytes; GkrellmPanel *panel; gboolean hour_mode; gint cd_length; - gboolean extra_info; + gboolean extra_info; // 0 no text or 1 text + gint display_mode; // 0 connections, 1 packets, 2 bytes + GkrellmLauncher launch; GtkWidget *launch_entry, *tooltip_entry; @@ -58,23 +79,46 @@ gchar *label0; gint active0; - gint prev_active0; - gulong hits0_minute, + gint prev_active0; + guint64 pkts0; + guint64 prev_pkts0; + guint64 bytes0; + guint64 prev_bytes0; + guint64 hits0_minute, hits0_hour; + guint64 pkts0_minute, + pkts0_hour, + bytes0_minute, + bytes0_hour; gboolean data0_is_range; - gulong port0_0, + gboolean data0_outbound; + + glong port0_0, port0_1; gchar *label1; gint active1; - gint prev_active1; - gulong hits1_minute, + gint prev_active1; + guint64 pkts1; + guint64 prev_pkts1; + guint64 bytes1; + guint64 prev_bytes1; + guint64 hits1_minute, hits1_hour; + guint64 pkts1_minute, + pkts1_hour, + bytes1_minute, + bytes1_hour; gboolean data1_is_range; - gulong port1_0, + gboolean data1_outbound; + + glong port1_0, port1_1; + GTCPHistory *tcp_history; gulong krell_hits; + guint64 krell_pkts; + guint64 krell_bytes; } InetMon; @@ -159,6 +203,109 @@ } void +update_iptables_counts(InetMon *in, ActiveTCP *tcp, gint test) + { + guint64 pdiff = 0; + guint64 bdiff = 0; + + GTCPHistory *at; + + at = in->tcp_history; + while (at) + { + if (at->chain == tcp->chain + && at->line == tcp->line + && at->test == test) + break; + at = at->next; + } + + if (!at) // need to allocate another historical holding structure for byte and packet counts + { + at = g_new0(GTCPHistory, 1); + at->chain = tcp->chain; + at->line = tcp->line; + at->test = test; + at->pkts = tcp->pkts; + at->bytes = tcp->bytes; + at->next = in->tcp_history; + in->tcp_history = at; + return; + } + + pdiff = tcp->pkts - at->pkts; + if (pdiff) + { + at->pkts = tcp->pkts; + in->krell_pkts += pdiff; + + if (test >= 4) + { + in->pkts1 += pdiff; + in->pkts1_minute += pdiff; + in->pkts1_hour += pdiff; + } + else + { + in->pkts0 += pdiff; + in->pkts0_minute += pdiff; + in->pkts0_hour += pdiff; + } + } + + bdiff = tcp->bytes - at->bytes; + if (bdiff) + { + at->bytes = tcp->bytes; + in->krell_bytes += bdiff; + + if (test >= 4) + { + in->bytes1 += bdiff; + in->bytes1_minute += bdiff; + in->bytes1_hour += bdiff; + } + else + { + in->bytes0 += bdiff; + in->bytes0_minute += bdiff; + in->bytes0_hour += bdiff; + } + } +#if 0 + if (bdiff || pdiff) +fprintf(stderr, "local %d:%d remote %d:%d chain %d line %d target %d pkts %Lu bytes %Lu test %d - pdiff=%Lu bdiff=%Lu, total pkts=%Lu bytes=%Lu\n", + tcp->local_port, tcp->local_port_hi, + tcp->remote_port, tcp->remote_port_hi, + tcp->chain, tcp->line, tcp->target, tcp->pkts, tcp->bytes, test, pdiff, bdiff, at->pkts, at->bytes); + +#endif + } + +void +check_iptables_range(InetMon *in, ActiveTCP *tcp, glong port) + { + if (!in->data0_is_range && in->port0_0 == port) + update_iptables_counts(in, tcp, 2); + + else if (!in->data0_is_range && in->port0_1 == port) + update_iptables_counts(in, tcp, 3); + + else if ( in->data0_is_range && in->port0_0 <= port && port <= in->port0_1) + update_iptables_counts(in, tcp, 2); + + + if (!in->data1_is_range && in->port1_0 == port) + update_iptables_counts(in, tcp, 6); + + else if (!in->data1_is_range && in->port1_1 == port) + update_iptables_counts(in, tcp, 7); + + else if ( in->data1_is_range && in->port1_0 <= port && port <= in->port1_1) + update_iptables_counts(in, tcp, 6); + } + +void gkrellm_inet_log_tcp_port_data(gpointer data) { GList *list; @@ -171,35 +318,163 @@ { krell_hit = 0; in = (InetMon *) list->data; - if ( (!in->data0_is_range - && ( in->port0_0 == tcp->local_port - || in->port0_1 == tcp->local_port)) - || (in->data0_is_range - && tcp->local_port >= in->port0_0 - && tcp->local_port <= in->port0_1) - ) + switch (tcp->chain) { - ++in->active0; - active_tcp = _log_active_port(tcp); - krell_hit = active_tcp->new_hit; - in->hits0_minute += krell_hit; - in->hits0_hour += krell_hit; - } - if ( (!in->data1_is_range - && ( in->port1_0 == tcp->local_port - || in->port1_1 == tcp->local_port)) - || (in->data1_is_range - && tcp->local_port >= in->port1_0 - && tcp->local_port <= in->port1_1) - ) - { - ++in->active1; - active_tcp = _log_active_port(tcp); - krell_hit = active_tcp->new_hit; - in->hits1_minute += krell_hit; - in->hits1_hour += krell_hit; + case CHAIN_CONNECT: + if ( (!in->data0_is_range + && ( in->port0_0 == tcp->local_port + || in->port0_1 == tcp->local_port)) + || (in->data0_is_range + && tcp->local_port >= in->port0_0 + && tcp->local_port <= in->port0_1) + ) + { + ++in->active0; + active_tcp = _log_active_port(tcp); + krell_hit = active_tcp->new_hit; + in->hits0_minute += krell_hit; + in->hits0_hour += krell_hit; + } + if ( (!in->data1_is_range + && ( in->port1_0 == tcp->local_port + || in->port1_1 == tcp->local_port)) + || (in->data1_is_range + && tcp->local_port >= in->port1_0 + && tcp->local_port <= in->port1_1) + ) + { + ++in->active1; + active_tcp = _log_active_port(tcp); + krell_hit = active_tcp->new_hit; + in->hits1_minute += krell_hit; + in->hits1_hour += krell_hit; + } + in->krell_hits += krell_hit; + break; + + default: // CHAIN_INPUT, CHAIN_FORWARD, CHAIN_OUTPUT, CHAIN_USER + switch (tcp->target) + { + case TARGET_ACCEPT: + case TARGET_USER: + if (in->data0_outbound) + { + // If the remote IPtables rule is a generic rule, then only matches if user is tracking that specific + // generic range - generally much more useful for local port comparisons if you are running or using a + // service in the unpriviliged port area. + + if ((tcp->remote_port == 0 || tcp->remote_port == 1024) + && tcp->remote_port_hi == 65535) + { + if (in->data0_is_range && tcp->remote_port == in->port0_0 && + tcp->remote_port_hi == in->port0_1) + update_iptables_counts(in, tcp, 0); + } + else + { + if (!in->data0_is_range && in->port0_0 && + in->port0_0 >= tcp->remote_port && in->port0_0 <= tcp->remote_port_hi) + update_iptables_counts(in, tcp, 0); + + else if (!in->data0_is_range && in->port0_1 && + in->port0_1 >= tcp->remote_port && in->port0_1 <= tcp->remote_port_hi) + update_iptables_counts(in, tcp, 1); + + else if (in->data0_is_range && !(tcp->remote_port > in->port0_1 || tcp->remote_port_hi < in->port0_0)) + update_iptables_counts(in, tcp, 0); + + } + } + else + { + if ((tcp->local_port == 0 || tcp->local_port == 1024) + && tcp->local_port_hi == 65535) + { + if (in->data0_is_range && tcp->local_port == in->port0_0 && + tcp->local_port_hi == in->port0_1) + update_iptables_counts(in, tcp, 2); + } + else + { + if (!in->data0_is_range && in->port0_0 && + in->port0_0 >= tcp->local_port && in->port0_0 <= tcp->local_port_hi) + update_iptables_counts(in, tcp, 2); + + else if (!in->data0_is_range && in->port0_1 && + in->port0_1 >= tcp->local_port && in->port0_1 <= tcp->local_port_hi) + update_iptables_counts(in, tcp, 3); + + else if (in->data0_is_range && !(tcp->local_port > in->port0_1 || tcp->local_port_hi < in->port0_0)) + update_iptables_counts(in, tcp, 2); + } + } + + if (in->data1_outbound) + { + if ((tcp->remote_port == 0 || tcp->remote_port == 1024) + && tcp->remote_port_hi == 65535) + { + if (in->data1_is_range && tcp->remote_port == in->port1_0 && + tcp->remote_port_hi == in->port1_1) + update_iptables_counts(in, tcp, 4); + } + else + { + if (!in->data1_is_range && in->port1_0 && + in->port1_0 >= tcp->remote_port && in->port1_0 <= tcp->remote_port_hi) + update_iptables_counts(in, tcp, 4); + + else if (!in->data1_is_range && in->port1_1 && + in->port1_1 >= tcp->remote_port && in->port1_1 <= tcp->remote_port_hi) + update_iptables_counts(in, tcp, 5); + + else if (in->data1_is_range && !(tcp->remote_port > in->port1_1 || tcp->remote_port_hi < in->port1_0)) + update_iptables_counts(in, tcp, 4); + } + } + else + { + if ((tcp->local_port == 0 || tcp->local_port == 1024) + && tcp->local_port_hi == 65535) + { + if (in->data1_is_range && tcp->local_port == in->port1_0 && + tcp->local_port_hi == in->port1_1) + update_iptables_counts(in, tcp, 6); + } + else + { + if (!in->data1_is_range && in->port1_0 && + in->port1_0 >= tcp->local_port && in->port1_0 <= tcp->local_port_hi) + update_iptables_counts(in, tcp, 6); + + else if (!in->data1_is_range && in->port1_1 && + in->port1_1 >= tcp->local_port && in->port1_1 <= tcp->local_port_hi) + update_iptables_counts(in, tcp, 7); + + else if (in->data1_is_range && !(tcp->local_port > in->port1_1 || tcp->local_port_hi < in->port1_0)) + update_iptables_counts(in, tcp, 6); + } + } + break; + + case TARGET_QUEUE: + check_iptables_range(in, tcp, PORT_QUEUE); + break; + + case TARGET_RETURN: + check_iptables_range(in, tcp, PORT_RETURN); + break; + + case TARGET_DROP: + check_iptables_range(in, tcp, PORT_DROP); + break; + + case TARGET_LOG: + check_iptables_range(in, tcp, PORT_LOG); + break; + } + break; } - in->krell_hits += krell_hit; } /* Defer setting new hit to 0 until here so multiple inet charts can | monitor the same port number. The above active_port will be the @@ -237,10 +512,11 @@ format_chart_text(InetMon *in, gchar *src_string, gchar *buf, gint size) { GList *list; - GkrellmChart *cp; - GkrellmChartdata *cd; + GkrellmChart *cp; + GkrellmChartdata *cd; gchar c, *s, *s1; - gint len, value, n, i, w; + gint len, n, i, w; + gint64 value; if (!buf || size < 1) return; @@ -260,7 +536,20 @@ if ((c = *(s + 1)) == 'M') value = gkrellm_get_chart_scalemax(cp); else if (c == 'a' && *in->label0) - value = in->active0; + { + switch (in->display_mode) + { + case 0: + value = in->active0; + break; + case 1: + value = in->pkts0; + break; + case 2: + value = in->bytes0; + break; + } + } else if (c == 'l' && *in->label0) s1 = in->label0; else if (c == 'c' && *(s + 2)) @@ -268,21 +557,56 @@ i = 0; sscanf(s + 2, "%d%n", &n, &i); s += i; - --n; - if (n > w || n < 0) - n = w; - list = in->hour_mode ? - in->chart_hour->cd_list : in->chart_minute->cd_list; - cd = (GkrellmChartdata *) list->data; + if (*in->label0) { - value = in->hour_mode ? in->hits0_hour : in->hits0_minute; - for ( ; n > 0; --n) - value += gkrellm_get_chartdata_data(cd, w - n); + --n; + if (n > w || n < 0) + n = w; + switch (in->display_mode) + { + case 0: + list = in->hour_mode ? + in->chart_hour->cd_list : in->chart_minute->cd_list; + cd = (GkrellmChartdata *) list->data; + value = in->hour_mode ? in->hits0_hour : in->hits0_minute; + for ( ; n > 0; --n) + value += gkrellm_get_chartdata_data(cd, w - n); + break; + case 1: + list = in->hour_mode ? + in->chart_hour_pkts->cd_list : in->chart_minute_pkts->cd_list; + cd = (GkrellmChartdata *) list->data; + value = in->hour_mode ? in->pkts0_hour : in->pkts0_minute; + for ( ; n > 0; --n) + value += gkrellm_get_chartdata_data(cd, w - n); + break; + case 2: + list = in->hour_mode ? + in->chart_hour_bytes->cd_list : in->chart_minute_bytes->cd_list; + cd = (GkrellmChartdata *) list->data; + value = in->hour_mode ? in->bytes0_hour : in->bytes0_minute; + for ( ; n > 0; --n) + value += gkrellm_get_chartdata_data(cd, w - n); + break; + } } } else if (c == 'A' && *in->label1) - value = in->active1; + { + switch (in->display_mode) + { + case 0: + value = in->active1; + break; + case 1: + value = in->pkts1; + break; + case 2: + value = in->bytes1; + break; + } + } else if (c == 'L' && *in->label1) s1 = in->label1; else if (c == 'C' && *(s + 2)) @@ -290,23 +614,101 @@ i = 0; sscanf(s + 2, "%d%n", &n, &i); s += i; - --n; - if (n > w || n < 0) - n = w; - list = in->hour_mode ? - in->chart_hour->cd_list : in->chart_minute->cd_list; - if (list->next) - list = list->next; - cd = (GkrellmChartdata *) list->data; + if (*in->label1) { - value = in->hour_mode ? in->hits1_hour : in->hits1_minute; - for ( ; n > 0; --n) - value += gkrellm_get_chartdata_data(cd, w - n); + --n; + if (n > w || n < 0) + n = w; + switch (in->display_mode) + { + case 0: + list = in->hour_mode ? + in->chart_hour->cd_list : in->chart_minute->cd_list; + if (list->next) + list = list->next; + cd = (GkrellmChartdata *) list->data; + value = in->hour_mode ? in->hits1_hour : in->hits1_minute; + for ( ; n > 0; --n) + value += gkrellm_get_chartdata_data(cd, w - n); + break; + case 1: + list = in->hour_mode ? + in->chart_hour_pkts->cd_list : in->chart_minute_pkts->cd_list; + if (list->next) + list = list->next; + cd = (GkrellmChartdata *) list->data; + value = in->hour_mode ? in->pkts1_hour : in->pkts1_minute; + for ( ; n > 0; --n) + value += gkrellm_get_chartdata_data(cd, w - n); + break; + case 2: + list = in->hour_mode ? + in->chart_hour_bytes->cd_list : in->chart_minute_bytes->cd_list; + if (list->next) + list = list->next; + cd = (GkrellmChartdata *) list->data; + value = in->hour_mode ? in->bytes1_hour : in->bytes1_minute; + for ( ; n > 0; --n) + value += gkrellm_get_chartdata_data(cd, w - n); + break; + } } } + if (value >= 0) - len = snprintf(buf, size, "%d", value); + { + gint index = 0; + gdouble svalue = 0; + char *vsuffix = " kMGTPEYZ"; + gchar *vtype = "HPB"; + if (value < 1e3) + { + index = 0; + svalue = value; + } + else if (value < 1e6) + { + index = 1; + svalue = value / 1e3; + } + else if (value < 1e9) + { + index = 2; + svalue = value / 1e6; + } + else if (value < 1e12) + { + index = 3; + svalue = value / 1e9; + } + else if (value < 1e15) + { + index = 4; + svalue = value / 1e12; + } + else if (value < 1e18) + { + index = 5; + svalue = value / 1e15; + } + else if (value < 1e21) + { + index = 6; + svalue = value / 1e18; + } + else if (value < 1e24) + { + index = 7; + svalue = value / 1e21; + } + else + { + index = 8; + svalue = value / 1e24; + } + len = snprintf(buf, size, "%.3lg %c%c", svalue, *(vsuffix+index), *(vtype+in->display_mode)); + } else len = snprintf(buf, size, "%s", s1); ++s; @@ -383,7 +785,7 @@ struct tm tm; GdkGC *gc3; GkrellmChart *cp; - GkrellmTextstyle *ts; + GkrellmTextstyle *ts_alt; GdkColor tmp_color; gchar buf[32]; guint32 pixel0, pixel1; @@ -397,7 +799,7 @@ gdk_drawable_get_size(in->chart->bg_grid_pixmap, &w, &h); if (grid == NULL) grid = gdk_drawable_get_image(in->chart->bg_grid_pixmap, 0, 0, w, h); - ts = gkrellm_chart_alt_textstyle(style_id); + ts_alt = gkrellm_chart_alt_textstyle(style_id); tm = *gkrellm_get_current_time(); gc3 = gkrellm_draw_GC(3); @@ -429,7 +831,7 @@ { strftime(buf, sizeof(buf), "%a", &tm); buf[1] = '\0'; - gkrellm_draw_chart_label(in->chart, ts, + gkrellm_draw_chart_label(in->chart, ts_alt, cp->x + n, in->chart->h - 4, buf); } if (--tm.tm_hour < 0) @@ -471,26 +873,112 @@ draw_inet_extra(in); gkrellm_draw_chart_to_screen(cp); in->prev_active0 = in->active0; + in->prev_pkts0 = in->pkts0; + in->prev_bytes0 = in->bytes0; in->prev_active1 = in->active1; + in->prev_pkts1 = in->pkts1; + in->prev_bytes1 = in->bytes1; } static void select_hour_or_minute_chart(InetMon *in) { gkrellm_freeze_side_frame_packing(); - if (in->hour_mode && in->chart == in->chart_minute) + if (in->hour_mode) { - gkrellm_chart_hide(in->chart_minute, FALSE); - gkrellm_chart_show(in->chart_hour, FALSE); - in->chart = in->chart_hour; - gkrellm_chartconfig_window_destroy(in->chart_minute); + switch (in->display_mode) + { + case 0: + gkrellm_chart_hide(in->chart_minute_bytes, FALSE); + gkrellm_chart_hide(in->chart_hour_bytes, FALSE); + gkrellm_chart_hide(in->chart_minute_pkts, FALSE); + gkrellm_chart_hide(in->chart_hour_pkts, FALSE); + gkrellm_chart_hide(in->chart_minute, FALSE); + gkrellm_chart_show(in->chart_hour, FALSE); + in->chart = in->chart_hour; + gkrellm_chartconfig_window_destroy(in->chart_minute_bytes); + gkrellm_chartconfig_window_destroy(in->chart_hour_bytes); + gkrellm_chartconfig_window_destroy(in->chart_minute_pkts); + gkrellm_chartconfig_window_destroy(in->chart_hour_pkts); + gkrellm_chartconfig_window_destroy(in->chart_minute); + break; + case 1: + gkrellm_chart_hide(in->chart_minute, FALSE); + gkrellm_chart_hide(in->chart_hour, FALSE); + gkrellm_chart_hide(in->chart_minute_bytes, FALSE); + gkrellm_chart_hide(in->chart_hour_bytes, FALSE); + gkrellm_chart_hide(in->chart_minute_pkts, FALSE); + gkrellm_chart_show(in->chart_hour_pkts, FALSE); + in->chart = in->chart_hour_pkts; + gkrellm_chartconfig_window_destroy(in->chart_minute); + gkrellm_chartconfig_window_destroy(in->chart_hour); + gkrellm_chartconfig_window_destroy(in->chart_minute_bytes); + gkrellm_chartconfig_window_destroy(in->chart_hour_bytes); + gkrellm_chartconfig_window_destroy(in->chart_minute_pkts); + break; + case 2: + gkrellm_chart_hide(in->chart_minute_pkts, FALSE); + gkrellm_chart_hide(in->chart_hour_pkts, FALSE); + gkrellm_chart_hide(in->chart_minute, FALSE); + gkrellm_chart_hide(in->chart_hour, FALSE); + gkrellm_chart_hide(in->chart_minute_bytes, FALSE); + gkrellm_chart_show(in->chart_hour_bytes, FALSE); + in->chart = in->chart_hour_bytes; + gkrellm_chartconfig_window_destroy(in->chart_minute_pkts); + gkrellm_chartconfig_window_destroy(in->chart_hour_pkts); + gkrellm_chartconfig_window_destroy(in->chart_minute); + gkrellm_chartconfig_window_destroy(in->chart_hour); + gkrellm_chartconfig_window_destroy(in->chart_minute_bytes); + break; + } } - else if (!in->hour_mode && in->chart == in->chart_hour) + else { - gkrellm_chart_hide(in->chart_hour, FALSE); - gkrellm_chart_show(in->chart_minute, FALSE); - in->chart = in->chart_minute; - gkrellm_chartconfig_window_destroy(in->chart_hour); + switch (in->display_mode) + { + case 0: + gkrellm_chart_hide(in->chart_hour_bytes, FALSE); + gkrellm_chart_hide(in->chart_minute_bytes, FALSE); + gkrellm_chart_hide(in->chart_hour_pkts, FALSE); + gkrellm_chart_hide(in->chart_minute_pkts, FALSE); + gkrellm_chart_hide(in->chart_hour, FALSE); + gkrellm_chart_show(in->chart_minute, FALSE); + in->chart = in->chart_minute; + gkrellm_chartconfig_window_destroy(in->chart_hour_bytes); + gkrellm_chartconfig_window_destroy(in->chart_minute_bytes); + gkrellm_chartconfig_window_destroy(in->chart_hour_pkts); + gkrellm_chartconfig_window_destroy(in->chart_minute_pkts); + gkrellm_chartconfig_window_destroy(in->chart_hour); + break; + case 1: + gkrellm_chart_hide(in->chart_hour, FALSE); + gkrellm_chart_hide(in->chart_minute, FALSE); + gkrellm_chart_hide(in->chart_hour_bytes, FALSE); + gkrellm_chart_hide(in->chart_minute_bytes, FALSE); + gkrellm_chart_hide(in->chart_hour_pkts, FALSE); + gkrellm_chart_show(in->chart_minute_pkts, FALSE); + in->chart = in->chart_minute_pkts; + gkrellm_chartconfig_window_destroy(in->chart_hour); + gkrellm_chartconfig_window_destroy(in->chart_minute); + gkrellm_chartconfig_window_destroy(in->chart_hour_bytes); + gkrellm_chartconfig_window_destroy(in->chart_minute_bytes); + gkrellm_chartconfig_window_destroy(in->chart_hour_pkts); + break; + case 2: + gkrellm_chart_hide(in->chart_hour_pkts, FALSE); + gkrellm_chart_hide(in->chart_minute_pkts, FALSE); + gkrellm_chart_hide(in->chart_hour, FALSE); + gkrellm_chart_hide(in->chart_minute, FALSE); + gkrellm_chart_hide(in->chart_hour_bytes, FALSE); + gkrellm_chart_show(in->chart_minute_bytes, FALSE); + in->chart = in->chart_minute_bytes; + gkrellm_chartconfig_window_destroy(in->chart_hour_pkts); + gkrellm_chartconfig_window_destroy(in->chart_minute_pkts); + gkrellm_chartconfig_window_destroy(in->chart_hour); + gkrellm_chartconfig_window_destroy(in->chart_minute); + gkrellm_chartconfig_window_destroy(in->chart_hour_bytes); + break; + } } gkrellm_thaw_side_frame_packing(); } @@ -515,7 +1003,11 @@ { in = (InetMon *) list->data; in->active0 = 0; + in->pkts0 = 0; + in->bytes0 = 0; in->active1 = 0; + in->pkts1 = 0; + in->bytes1 = 0; } /* Assume all connections are dead, then read_tcp_data() will set | still alive ones back to alive. Then I can prune really dead ones. @@ -552,34 +1044,66 @@ if (GK.hour_tick) { if (!*in->label0) + { in->hits0_hour = in->hits1_hour; + in->pkts0_hour = in->pkts1_hour; + in->bytes0_hour = in->bytes1_hour; + } gkrellm_store_chartdata(in->chart_hour, 0, in->hits0_hour, in->hits1_hour); + gkrellm_store_chartdata(in->chart_hour_pkts, 0, + in->pkts0_hour, in->pkts1_hour); + gkrellm_store_chartdata(in->chart_hour_bytes, 0, + in->bytes0_hour, in->bytes1_hour); in->hits0_hour = in->hits1_hour = 0; + in->pkts0_hour = in->pkts1_hour = 0; + in->bytes0_hour = in->bytes1_hour = 0; if (GK.day_tick) /* Make room for vertical day grid */ { - gkrellm_store_chartdata(in->chart_hour, 0, 0, 0); - gkrellm_store_chartdata(in->chart_hour, 0, 0, 0); + gkrellm_store_chartdata(in->chart_hour, 0, 0LL, 0LL); + gkrellm_store_chartdata(in->chart_hour, 0, 0LL, 0LL); + gkrellm_store_chartdata(in->chart_hour_pkts, 0, 0LL, 0LL); + gkrellm_store_chartdata(in->chart_hour_pkts, 0, 0LL, 0LL); + gkrellm_store_chartdata(in->chart_hour_bytes, 0, 0LL, 0LL); + gkrellm_store_chartdata(in->chart_hour_bytes, 0, 0LL, 0LL); } } if (GK.minute_tick) { if (!*in->label0) + { in->hits0_minute = in->hits1_minute; + in->pkts0_minute = in->pkts1_minute; + in->bytes0_minute = in->bytes1_minute; + } gkrellm_store_chartdata(in->chart_minute, 0, in->hits0_minute, in->hits1_minute); + gkrellm_store_chartdata(in->chart_minute_pkts, 0, + in->pkts0_minute, in->pkts1_minute); + gkrellm_store_chartdata(in->chart_minute_bytes, 0, + in->bytes0_minute, in->bytes1_minute); in->hits0_minute = in->hits1_minute = 0; + in->pkts0_minute = in->pkts1_minute = 0; + in->bytes0_minute = in->bytes1_minute = 0; if (GK.hour_tick) /* Make room for vertical hour grid */ { - gkrellm_store_chartdata(in->chart_minute, 0, 0, 0); - gkrellm_store_chartdata(in->chart_minute, 0, 0, 0); + gkrellm_store_chartdata(in->chart_minute, 0, 0LL, 0LL); + gkrellm_store_chartdata(in->chart_minute, 0, 0LL, 0LL); + gkrellm_store_chartdata(in->chart_minute_pkts, 0, 0LL, 0LL); + gkrellm_store_chartdata(in->chart_minute_pkts, 0, 0LL, 0LL); + gkrellm_store_chartdata(in->chart_minute_bytes, 0, 0LL, 0LL); + gkrellm_store_chartdata(in->chart_minute_bytes, 0, 0LL, 0LL); } gkrellm_refresh_chart(in->chart); draw_inet_mark_data(in, 1); } else if ( GK.second_tick - && ( in->prev_active0 != in->active0 - || in->prev_active1 != in->active1 + && ( (in->display_mode == 0 && (in->prev_active0 != in->active0 + || in->prev_active1 != in->active1)) || + (in->display_mode == 1 && (in->prev_pkts0 != in->pkts0 + || in->prev_pkts1 != in->pkts1)) || + (in->display_mode == 2 && (in->prev_bytes0 != in->bytes0 + || in->prev_bytes1 != in->bytes1)) ) ) draw_inet_chart(in); /* Just to update extra info draw */ @@ -593,7 +1117,19 @@ i = D_MISC_BUTTON_OUT; gkrellm_set_decal_button_index(in->list_button, i); - gkrellm_update_krell(in->panel, KRELL(in->panel), in->krell_hits); + switch (in->display_mode) + { + case 0: + gkrellm_update_krell(in->panel, KRELL(in->panel), in->krell_hits); + break; + case 1: + gkrellm_update_krell(in->panel, KRELL(in->panel), in->krell_pkts); + break; + case 2: + gkrellm_update_krell(in->panel, KRELL(in->panel), in->krell_bytes); + break; + } + gkrellm_draw_panel_layers(in->panel); if (in->connection_string_event) @@ -698,7 +1234,7 @@ static void cb_list_button(GkrellmDecalbutton *button) - { + { InetMon *in = (InetMon *) button->data; GList *list; ActiveTCP *tcp, *tcp_save; @@ -743,6 +1279,16 @@ pixmap = in->chart_minute->pixmap; else if (widget == in->chart_hour->drawing_area) pixmap = in->chart_hour->pixmap; + + else if (widget == in->chart_minute_pkts->drawing_area) + pixmap = in->chart_minute_pkts->pixmap; + else if (widget == in->chart_hour_pkts->drawing_area) + pixmap = in->chart_hour_pkts->pixmap; + + else if (widget == in->chart_minute_bytes->drawing_area) + pixmap = in->chart_minute_bytes->pixmap; + else if (widget == in->chart_hour_bytes->drawing_area) + pixmap = in->chart_hour_bytes->pixmap; if (pixmap) { gdk_draw_drawable(widget->window, gkrellm_draw_GC(1), pixmap, @@ -767,8 +1313,16 @@ continue; if (ev->button == 1 && ev->type == GDK_BUTTON_PRESS) { - in->extra_info = !in->extra_info; - gkrellm_refresh_chart(in->chart); + if (in->extra_info) + { + in->extra_info = FALSE; + if (++in->display_mode == 3) + in->display_mode = 0; + } + else + in->extra_info = TRUE; + select_hour_or_minute_chart(in); + gkrellm_rescale_chart(in->chart); gkrellm_config_modified(); } else if (ev->button == 2) @@ -777,9 +1331,7 @@ select_hour_or_minute_chart(in); gkrellm_rescale_chart(in->chart); } - else if ( ev->button == 3 - || (ev->button == 1 && ev->type == GDK_2BUTTON_PRESS) - ) + else if (ev->button == 3) gkrellm_chartconfig_window_create(in->chart); break; } @@ -806,11 +1358,20 @@ gkrellm_set_chart_height(in->chart_minute, h); if (in->chart_hour->h != h) gkrellm_set_chart_height(in->chart_hour, h); + if (in->chart_minute_pkts->h != h) + gkrellm_set_chart_height(in->chart_minute_pkts, h); + if (in->chart_hour_pkts->h != h) + gkrellm_set_chart_height(in->chart_hour_pkts, h); + if (in->chart_minute_bytes->h != h) + gkrellm_set_chart_height(in->chart_minute_bytes, h); + if (in->chart_hour_bytes->h != h) + gkrellm_set_chart_height(in->chart_hour_bytes, h); } static void destroy_inet_monitor(InetMon *in) { + GTCPHistory *list; if (in->launch_table) gtk_widget_destroy(in->launch_table); g_free(in->name); @@ -820,13 +1381,25 @@ g_free(in->launch.command); if (in->launch.button) gkrellm_destroy_button(in->launch.button); - in->launch.tooltip = NULL; + in->launch.tooltip = NULL; g_free(in->mark_data); /* The panel doesn't live in the chart struct, so destroy it separately */ gkrellm_panel_destroy(in->panel); + gkrellm_chartconfig_destroy(&in->chart_config_minute_bytes); + gkrellm_chart_destroy(in->chart_minute_bytes); + + gkrellm_chartconfig_destroy(&in->chart_config_hour_bytes); + gkrellm_chart_destroy(in->chart_hour_bytes); + + gkrellm_chartconfig_destroy(&in->chart_config_minute_pkts); + gkrellm_chart_destroy(in->chart_minute_pkts); + + gkrellm_chartconfig_destroy(&in->chart_config_hour_pkts); + gkrellm_chart_destroy(in->chart_hour_pkts); + gkrellm_chartconfig_destroy(&in->chart_config_minute); gkrellm_chart_destroy(in->chart_minute); @@ -834,6 +1407,14 @@ gkrellm_chart_destroy(in->chart_hour); gtk_widget_destroy(in->vbox); + list = in->tcp_history; + while (list) + { + GTCPHistory *tmp; + tmp = list; + list = list->next; + g_free(tmp); + } g_free(in); } @@ -915,6 +1496,10 @@ in->vbox = vbox; in->chart_minute = gkrellm_chart_new0(); in->chart_hour = gkrellm_chart_new0(); + in->chart_minute_pkts = gkrellm_chart_new0(); + in->chart_hour_pkts = gkrellm_chart_new0(); + in->chart_minute_bytes = gkrellm_chart_new0(); + in->chart_hour_bytes = gkrellm_chart_new0(); in->panel = gkrellm_panel_new0(); in->chart = in->chart_minute; in->name = g_strdup_printf(_("inet%d"), n_inet_monitors++); @@ -927,12 +1512,37 @@ } if (in->chart_config_hour && in->chart_config_minute) in->chart_config_hour->h = in->chart_config_minute->h; + + if (in->chart_config_minute_pkts && in->chart_config_minute) + in->chart_config_minute_pkts->h = in->chart_config_minute->h; + if (in->chart_config_hour_pkts && in->chart_config_minute) + in->chart_config_hour_pkts->h = in->chart_config_minute->h; + + if (in->chart_config_minute_bytes && in->chart_config_minute) + in->chart_config_minute_bytes->h = in->chart_config_minute->h; + if (in->chart_config_hour_bytes && in->chart_config_minute) + in->chart_config_hour_bytes->h = in->chart_config_minute->h; + chart_create(in, in->chart_minute, &in->chart_config_minute, first_create); gkrellm_chartconfig_grid_resolution_label(in->chart_config_minute, _("TCP hits per minute")); chart_create(in, in->chart_hour, &in->chart_config_hour, first_create); gkrellm_chartconfig_grid_resolution_label(in->chart_config_hour, _("TCP hits per hour")); + + chart_create(in, in->chart_minute_pkts, &in->chart_config_minute_pkts, first_create); + gkrellm_chartconfig_grid_resolution_label(in->chart_config_minute_pkts, + _("Packets per minute")); + chart_create(in, in->chart_hour_pkts, &in->chart_config_hour_pkts, first_create); + gkrellm_chartconfig_grid_resolution_label(in->chart_config_hour_pkts, + _("Packets per hour")); + + chart_create(in, in->chart_minute_bytes, &in->chart_config_minute_bytes, first_create); + gkrellm_chartconfig_grid_resolution_label(in->chart_config_minute_bytes, + _("Bytes per minute")); + chart_create(in, in->chart_hour_bytes, &in->chart_config_hour_bytes, first_create); + gkrellm_chartconfig_grid_resolution_label(in->chart_config_hour_bytes, + _("Bytes per hour")); cp = in->chart; p = in->panel; @@ -973,6 +1583,10 @@ gtk_widget_show(vbox); gkrellm_chart_hide(in->chart_hour, FALSE); + gkrellm_chart_hide(in->chart_minute_pkts, FALSE); + gkrellm_chart_hide(in->chart_hour_pkts, FALSE); + gkrellm_chart_hide(in->chart_minute_bytes, FALSE); + gkrellm_chart_hide(in->chart_hour_bytes, FALSE); } gkrellm_setup_launcher(p, &in->launch, CHART_PANEL_TYPE, 4); @@ -1047,17 +1661,30 @@ in = (InetMon *) list->data; l0 = (*in->label0) ? in->label0: "NONE"; l1 = (*in->label1) ? in->label1: "NONE"; - fprintf(f, "%s monitor %s %s %lu %lu %s %lu %lu %d %d %d\n", + fprintf(f, "%s monitor %s %s %ld %ld %s %ld %ld %d %d %d %d %d %d\n", INET_CONFIG_KEYWORD, in->name, l0, in->port0_0, in->port0_1, l1, in->port1_0, in->port1_1, - in->extra_info, in->data0_is_range, in->data1_is_range); + in->extra_info, in->display_mode, in->data0_is_range, in->data1_is_range, + in->data0_outbound, in->data1_outbound); snprintf(buf, sizeof(buf), "%s:minute", in->name); gkrellm_save_chartconfig(f, in->chart_config_minute, INET_CONFIG_KEYWORD, buf); snprintf(buf, sizeof(buf), "%s:hour", in->name); gkrellm_save_chartconfig(f, in->chart_config_hour, INET_CONFIG_KEYWORD, buf); + snprintf(buf, sizeof(buf), "%s:minute_pkts", in->name); + gkrellm_save_chartconfig(f, in->chart_config_minute_pkts, + INET_CONFIG_KEYWORD, buf); + snprintf(buf, sizeof(buf), "%s:hour_pkts", in->name); + gkrellm_save_chartconfig(f, in->chart_config_hour_pkts, + INET_CONFIG_KEYWORD, buf); + snprintf(buf, sizeof(buf), "%s:minute_bytes", in->name); + gkrellm_save_chartconfig(f, in->chart_config_minute_bytes, + INET_CONFIG_KEYWORD, buf); + snprintf(buf, sizeof(buf), "%s:hour_bytes", in->name); + gkrellm_save_chartconfig(f, in->chart_config_hour_bytes, + INET_CONFIG_KEYWORD, buf); if (in->launch.command) fprintf(f, "%s launch %s %s\n", INET_CONFIG_KEYWORD, in->name, in->launch.command); @@ -1079,12 +1706,12 @@ if (!*in->label0) { - in->port0_1 = in->port0_1 = in->data0_is_range = 0; + in->port0_1 = in->port0_1 = in->data0_is_range = in->data0_outbound = 0; --cd_length; } if (!*in->label1) { - in->port1_1 = in->port1_1 = in->data1_is_range = 0; + in->port1_1 = in->port1_1 = in->data1_is_range = in->data1_outbound = 0; --cd_length; } if (in->data0_is_range && (in->port0_1 < in->port0_0)) @@ -1133,10 +1760,11 @@ in = g_new0(InetMon, 1); label0[0] = '\0'; label1[0] = '\0'; - sscanf(item, "%15s %lu %lu %15s %lu %lu %d %d %d", + sscanf(item, "%15s %ld %ld %15s %ld %ld %d %d %d %d %d %d", label0, &in->port0_0, &in->port0_1, label1, &in->port1_0, &in->port1_1, - &in->extra_info, &in->data0_is_range, &in->data1_is_range); + &in->extra_info, &in->display_mode, &in->data0_is_range, &in->data1_is_range, + &in->data0_outbound, &in->data1_outbound); if (!strcmp(label0, "NONE")) label0[0] = '\0'; if (!strcmp(label1, "NONE")) @@ -1149,6 +1777,10 @@ in->name = g_strdup(name); in->chart_config_minute = gkrellm_chartconfig_new0(); in->chart_config_hour = gkrellm_chartconfig_new0(); + in->chart_config_minute_pkts = gkrellm_chartconfig_new0(); + in->chart_config_hour_pkts = gkrellm_chartconfig_new0(); + in->chart_config_minute_bytes = gkrellm_chartconfig_new0(); + in->chart_config_hour_bytes = gkrellm_chartconfig_new0(); inet_mon_list = g_list_append(inet_mon_list, in); } else /* Bogus config line */ @@ -1169,6 +1801,18 @@ if (hr_min && !strcmp(hr_min, "minute")) gkrellm_load_chartconfig(&in->chart_config_minute, item, in->cd_length); + if (hr_min && !strcmp(hr_min, "hour_pkts")) + gkrellm_load_chartconfig(&in->chart_config_hour_pkts, item, + in->cd_length); + if (hr_min && !strcmp(hr_min, "minute_pkts")) + gkrellm_load_chartconfig(&in->chart_config_minute_pkts, item, + in->cd_length); + if (hr_min && !strcmp(hr_min, "hour_bytes")) + gkrellm_load_chartconfig(&in->chart_config_hour_bytes, item, + in->cd_length); + if (hr_min && !strcmp(hr_min, "minute_bytes")) + gkrellm_load_chartconfig(&in->chart_config_minute_bytes, item, + in->cd_length); } else if (!strcmp(config, "launch")) gkrellm_dup_string(&in->launch.command, item); @@ -1188,7 +1832,8 @@ { struct tm *tm; gchar data[64]; - gint n, in, out, cur_slot, skew, day; + gint n, cur_slot, skew, day; + gint64 in, out; tm = gkrellm_get_current_time(); day = tm->tm_yday - yday; @@ -1222,7 +1867,7 @@ | Charts will circular buff fill until data runs out. */ out = in = 0; - sscanf(data, "%d %d", &out, &in); + sscanf(data, "%Ld %Ld", &out, &in); gkrellm_store_chartdata(cp, 0, out, in); } /* Need to store zero data for time slots not in read data to bring @@ -1235,18 +1880,18 @@ { while (n-- > 0) { - gkrellm_store_chartdata(cp, 0, 0, 0); + gkrellm_store_chartdata(cp, 0, 0LL, 0LL); if (minute_chart && min++ == 0) { - gkrellm_store_chartdata(cp, 0, 0, 0); - gkrellm_store_chartdata(cp, 0, 0, 0); + gkrellm_store_chartdata(cp, 0, 0LL, 0LL); + gkrellm_store_chartdata(cp, 0, 0LL, 0LL); if (min == 60) min = 0; } else if (!minute_chart && hour++ == 0) { - gkrellm_store_chartdata(cp, 0, 0, 0); - gkrellm_store_chartdata(cp, 0, 0, 0); + gkrellm_store_chartdata(cp, 0, 0LL, 0LL); + gkrellm_store_chartdata(cp, 0, 0LL, 0LL); if (hour == 24) hour = 0; } @@ -1264,7 +1909,7 @@ for (n = 0; n < cp->w; ++n) { for (list = cp->cd_list; list; list = list->next) - fprintf(f, "%d ", + fprintf(f, "%Ld ", gkrellm_get_chartdata_data((GkrellmChartdata *) list->data, n)); fprintf(f, "\n"); } @@ -1310,11 +1955,19 @@ | chart data array, and then save the chart data. */ fputs("hits0_minute hits1_minute hits0_hour hits1_hour\n", f); - fprintf(f, "%ld %ld %ld %ld\n", + fprintf(f, "%Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu\n", in->hits0_minute, in->hits1_minute, - in->hits0_hour, in->hits1_hour); + in->hits0_hour, in->hits1_hour, + in->pkts0_minute, in->pkts1_minute, + in->pkts0_hour, in->pkts1_hour, + in->bytes0_minute, in->bytes1_minute, + in->bytes0_hour, in->bytes1_hour); write_inet_data(in->chart_minute, f); write_inet_data(in->chart_hour, f); + write_inet_data(in->chart_minute_pkts, f); + write_inet_data(in->chart_hour_pkts, f); + write_inet_data(in->chart_minute_bytes, f); + write_inet_data(in->chart_hour_bytes, f); fclose(f); } } @@ -1343,9 +1996,13 @@ sscanf(buf, "%d %d %d %d", &min, &hour, &yday, &len); fgets(buf, sizeof(buf), f); /* Comment line */ fgets(buf, sizeof(buf), f); - sscanf(buf, "%ld %ld %ld %ld", + sscanf(buf, "%Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu", &in->hits0_minute, &in->hits1_minute, - &in->hits0_hour, &in->hits1_hour); + &in->hits0_hour, &in->hits1_hour, + &in->pkts0_minute, &in->pkts1_minute, + &in->pkts0_hour, &in->pkts1_hour, + &in->bytes0_minute, &in->bytes1_minute, + &in->bytes0_hour, &in->bytes1_hour); skew = read_inet_data(in->chart_minute, f, 1, min, hour, yday, len); if (skew > 0) /* Current minute slot is different from saved */ @@ -1355,6 +2012,22 @@ if (skew > 0) /* Current hour slot is different from saved */ in->hits0_hour = in->hits1_hour = 0; + skew = read_inet_data(in->chart_minute_pkts, f, 1, min, hour, yday, len); + if (skew > 0) /* Current minute slot is different from saved */ + in->pkts0_minute = in->pkts1_minute = 0; + + skew = read_inet_data(in->chart_hour_pkts, f, 0, min, hour, yday, len); + if (skew > 0) /* Current hour slot is different from saved */ + in->pkts0_hour = in->pkts1_hour = 0; + + skew = read_inet_data(in->chart_minute_bytes, f, 1, min, hour, yday, len); + if (skew > 0) /* Current minute slot is different from saved */ + in->bytes0_minute = in->bytes1_minute = 0; + + skew = read_inet_data(in->chart_hour_bytes, f, 0, min, hour, yday, len); + if (skew > 0) /* Current hour slot is different from saved */ + in->bytes0_hour = in->bytes1_hour = 0; + fclose(f); gkrellm_rescale_chart(in->chart); } @@ -1369,11 +2042,13 @@ PORT00_COLUMN, PORT01_COLUMN, RANGE0_COLUMN, + TYPE0_COLUMN, SPACER_COLUMN, LABEL1_COLUMN, PORT10_COLUMN, PORT11_COLUMN, RANGE1_COLUMN, + TYPE1_COLUMN, DUMMY_COLUMN, INET_COLUMN, N_COLUMNS @@ -1396,6 +2071,9 @@ static GtkWidget *data0_range_button, *data1_range_button; +static GtkWidget *data0_outbound, + *data1_outbound; + static GtkWidget *text_format_combo; @@ -1412,12 +2090,14 @@ LABEL0_COLUMN, in->label0, PORT00_COLUMN, p00, PORT01_COLUMN, p01, - SPACER_COLUMN, "", RANGE0_COLUMN, in->data0_is_range, + TYPE0_COLUMN, in->data0_outbound, + SPACER_COLUMN, "", LABEL1_COLUMN, in->label1, PORT10_COLUMN, p10, PORT11_COLUMN, p11, RANGE1_COLUMN, in->data1_is_range, + TYPE1_COLUMN, in->data1_outbound, DUMMY_COLUMN, "", -1); } @@ -1431,9 +2111,9 @@ InetMon *in; store = gtk_list_store_new(N_COLUMNS, - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_STRING, - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_POINTER); for (list = inet_mon_list; list; list = list->next) { @@ -1475,10 +2155,12 @@ PORT00_COLUMN, &ports[0], PORT01_COLUMN, &ports[1], RANGE0_COLUMN, &in->data0_is_range, + TYPE0_COLUMN, &in->data0_outbound, LABEL1_COLUMN, &in->label1, PORT10_COLUMN, &ports[2], PORT11_COLUMN, &ports[3], RANGE1_COLUMN, &in->data1_is_range, + TYPE1_COLUMN, &in->data1_outbound, -1); in->port0_0 = atoi(ports[0]); in->port0_1 = atoi(ports[1]); @@ -1533,12 +2215,16 @@ gtk_entry_set_text(GTK_ENTRY(port0_1_entry), ports[1]); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data0_range_button), in->data0_is_range); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data0_outbound), + in->data0_outbound); gtk_entry_set_text(GTK_ENTRY(label1_entry), in->label1); gtk_entry_set_text(GTK_ENTRY(port1_0_entry), ports[2]); gtk_entry_set_text(GTK_ENTRY(port1_1_entry), ports[3]); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data1_range_button), in->data1_is_range); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data1_outbound), + in->data1_outbound); g_free(in->label0); g_free(in->label1); for (i = 0; i < 4; ++i) @@ -1550,7 +2236,7 @@ { gkrellm_apply_launcher(&in->launch_entry, &in->tooltip_entry, in->panel, &in->launch, gkrellm_launch_button_cb); - } + } static void add_launch_entry(GtkWidget *vbox, InetMon *in) @@ -1609,6 +2295,17 @@ in_tmp->chart_config_minute = NULL; in->chart_config_hour = in_tmp->chart_config_hour; in_tmp->chart_config_hour = NULL; + + in->chart_config_minute_pkts = in_tmp->chart_config_minute_pkts; + in_tmp->chart_config_minute_pkts = NULL; + in->chart_config_hour_pkts = in_tmp->chart_config_hour_pkts; + in_tmp->chart_config_hour_pkts = NULL; + + in->chart_config_minute_bytes = in_tmp->chart_config_minute_bytes; + in_tmp->chart_config_minute_bytes = NULL; + in->chart_config_hour_bytes = in_tmp->chart_config_hour_bytes; + in_tmp->chart_config_hour_bytes = NULL; + in->extra_info = in_tmp->extra_info; in->hour_mode = in_tmp->hour_mode; } @@ -1620,6 +2317,20 @@ in->chart_config_minute, TRUE); gkrellm_set_chartconfig_auto_grid_resolution( in->chart_config_hour, TRUE); + + in->chart_config_minute_pkts = gkrellm_chartconfig_new0(); + in->chart_config_hour_pkts = gkrellm_chartconfig_new0(); + gkrellm_set_chartconfig_auto_grid_resolution( + in->chart_config_minute_pkts, TRUE); + gkrellm_set_chartconfig_auto_grid_resolution( + in->chart_config_hour_pkts, TRUE); + + in->chart_config_minute_bytes = gkrellm_chartconfig_new0(); + in->chart_config_hour_bytes = gkrellm_chartconfig_new0(); + gkrellm_set_chartconfig_auto_grid_resolution( + in->chart_config_minute_bytes, TRUE); + gkrellm_set_chartconfig_auto_grid_resolution( + in->chart_config_hour_bytes, TRUE); in->extra_info = TRUE; } if (in_tmp) @@ -1677,7 +2388,10 @@ in = g_new0(InetMon, 1); in->data0_is_range = GTK_TOGGLE_BUTTON(data0_range_button)->active; + in->data0_outbound = GTK_TOGGLE_BUTTON(data0_outbound)->active; + in->data1_is_range = GTK_TOGGLE_BUTTON(data1_range_button)->active; + in->data1_outbound = GTK_TOGGLE_BUTTON(data1_outbound)->active; in->label0 = gkrellm_gtk_entry_get_text(&label0_entry); if (*(in->label0)) @@ -1882,12 +2596,16 @@ hbox = gtk_hbox_new(FALSE, 2); gtk_table_attach_defaults(GTK_TABLE(table), hbox, 0, 3, 4, 5); gkrellm_gtk_check_button(hbox, &data0_range_button, 0, TRUE, 0, - _("Port0 - Port1 is a range")); + _("Range")); + gkrellm_gtk_check_button(hbox, &data0_outbound, 0, TRUE, 0, + _("Outbound")); hbox = gtk_hbox_new(FALSE, 2); gtk_table_attach_defaults(GTK_TABLE(table), hbox, 4, 7, 4, 5); gkrellm_gtk_check_button(hbox, &data1_range_button, 0, TRUE, 0, - _("Port0 - Port1 is a range")); + _("Range")); + gkrellm_gtk_check_button(hbox, &data1_outbound, 0, TRUE, 0, + _("Outbound")); separator = gtk_hseparator_new(); gtk_table_attach_defaults(GTK_TABLE(table), separator, 0, 7, 5, 6); @@ -1944,6 +2662,14 @@ gtk_tree_view_insert_column_with_attributes(treeview, -1, _("Port1"), renderer, "text", PORT01_COLUMN, NULL); + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_insert_column_with_attributes(treeview, -1, _("Range"), + renderer, + "text", RANGE0_COLUMN, NULL); + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_insert_column_with_attributes(treeview, -1, _("Outbound"), + renderer, + "text", TYPE0_COLUMN, NULL); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(treeview, -1, " ", @@ -1964,6 +2690,14 @@ gtk_tree_view_insert_column_with_attributes(treeview, -1, _("Port1"), renderer, "text", PORT11_COLUMN, NULL); + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_insert_column_with_attributes(treeview, -1, _("Range"), + renderer, + "text", RANGE1_COLUMN, NULL); + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_insert_column_with_attributes(treeview, -1, _("Outbound"), + renderer, + "text", TYPE1_COLUMN, NULL); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(treeview, -1, " ", diff -Naur gkrellm-2.2.4o/src/inet.h gkrellm-2.2.4/src/inet.h --- gkrellm-2.2.4o/src/inet.h 2004-05-14 13:45:14.000000000 -0600 +++ gkrellm-2.2.4/src/inet.h 2004-10-07 11:07:40.478602370 -0600 @@ -75,17 +75,45 @@ #define TCP_DEAD 0 #define TCP_ALIVE 1 + +#define CHAIN_CONNECT 0 // Monitor connections +#define CHAIN_INPUT 1 // Recorded packets from input chain +#define CHAIN_FORWARD 2 // Recorded packets from forward chain +#define CHAIN_OUTPUT 3 // Recorded packets from output chain +#define CHAIN_USER 4 // Recorded packets on a user chain - loses I/O delineation between client/source, but typically + // are convenience chains for log and drop or the like. +#define CHAIN_MAX 5 // Used as array limit for byte and packet count history in inet.c + +#define TARGET_ACCEPT 0 // Processed packet +#define TARGET_QUEUE 1 // Queue packet to user space (if supported) +#define TARGET_RETURN 2 // Return to previous rule set +#define TARGET_DROP 3 // Dropped packets +#define TARGET_LOG 4 // Log to /var/log/messages +#define TARGET_USER 5 // Other target - typically a user convenience chain + +#define PORT_QUEUE -1 +#define PORT_RETURN -2 +#define PORT_DROP -3 +#define PORT_LOG -4 + typedef struct { gint state; gint family; gint local_port; + gint local_port_hi; // for iptables range only struct in_addr remote_addr; #if defined(INET6) struct in6_addr remote_addr6; #endif gint remote_port; + gint remote_port_hi; // for iptables range only gint new_hit; + + gint chain; // chain the packet count was registered under from above list + gint line; // unique rule line number per chain to differentiate between ports handled with different rules + gint target; // the target from above list + guint64 pkts; + guint64 bytes; } ActiveTCP; - diff -Naur gkrellm-2.2.4o/src/mem.c gkrellm-2.2.4/src/mem.c --- gkrellm-2.2.4o/src/mem.c 2004-07-16 10:52:54.000000000 -0600 +++ gkrellm-2.2.4/src/mem.c 2004-10-07 11:07:40.479602225 -0600 @@ -444,7 +444,7 @@ if ((cp = mc->chart) != NULL && GK.second_tick) { - gkrellm_store_chartdata(cp, 0, mc->page_out, mc->page_in); + gkrellm_store_chartdata(cp, 0, (gint64) mc->page_out, (gint64) mc->page_in); refresh_chart(mc); } } diff -Naur gkrellm-2.2.4o/src/net.c gkrellm-2.2.4/src/net.c --- gkrellm-2.2.4o/src/net.c 2004-08-31 11:05:07.000000000 -0600 +++ gkrellm-2.2.4/src/net.c 2004-10-07 11:07:40.481601935 -0600 @@ -1768,7 +1768,7 @@ net->tx_old = net->tx; if (GK.second_tick) { - gkrellm_store_chartdata(net->chart, 0, net->tx, net->rx); + gkrellm_store_chartdata(net->chart, 0, (gint64) net->tx, (gint64) net->rx); net->rx_current = gkrellm_get_current_chartdata(net->rx_cd); net->tx_current = gkrellm_get_current_chartdata(net->tx_cd); rxd = (gdouble) net->rx_current; diff -Naur gkrellm-2.2.4o/src/proc.c gkrellm-2.2.4/src/proc.c --- gkrellm-2.2.4o/src/proc.c 2004-05-14 13:45:14.000000000 -0600 +++ gkrellm-2.2.4/src/proc.c 2004-10-07 11:07:40.482601791 -0600 @@ -139,7 +139,7 @@ len = snprintf(buf, size, "%.1f", (gfloat) gkrellm_get_chart_scalemax(cp) / LOAD_SCALING); else if (c == 'F' && fork_scaling > 0) - len = snprintf(buf, size, "%d", + len = snprintf(buf, size, "%Ld", gkrellm_get_chart_scalemax(cp) / fork_scaling); else if (c == 'H') len = snprintf(buf, size, "%s", gkrellm_sys_get_host_name()); @@ -266,7 +266,7 @@ | Scale the forks number by fork_scaling. See setup_proc_scaling(). */ load = (int) (LOAD_SCALING * proc.fload); - gkrellm_store_chartdata(cp, 0, load, fork_scaling * proc.n_forks); + gkrellm_store_chartdata(cp, 0, (gint64) load, (gint64) fork_scaling * proc.n_forks); refresh_proc_chart(cp); gkrellm_check_alert(load_alert, proc.fload); gkrellm_check_alert(processes_alert, proc.n_processes); diff -Naur gkrellm-2.2.4o/src/sysdeps/linux.c gkrellm-2.2.4/src/sysdeps/linux.c --- gkrellm-2.2.4o/src/sysdeps/linux.c 2004-05-10 11:10:26.000000000 -0600 +++ gkrellm-2.2.4/src/sysdeps/linux.c 2004-10-07 11:07:40.484601501 -0600 @@ -764,14 +764,38 @@ #define PROC_NET_TCP6_FILE "/proc/net/tcp6" #endif +// To reduce server traffic, we maintain information about the most recent invocation of the iptables program and only log packets to inet.c if there is a change +// in the packet or byte count of the rule. The first hit on each rule serves to initialize the counts for the rule. Subsequent changes are passed on. + +typedef struct giptableshistory + { + gint local_port; + gint local_port_hi; + gint remote_port; + gint remote_port_hi; + gint chain; + gint line; + gint target; + guint64 pkts; + guint64 bytes; + struct giptableshistory *next; + } GIPTablesHistory; + + +GIPTablesHistory *iptables_start = NULL, *iptables_last = NULL; + + void gkrellm_sys_inet_read_tcp_data(void) { - FILE *f; - ActiveTCP tcp; - gchar buf[512]; - gint tcp_status; - gulong addr; + FILE *f; + ActiveTCP tcp; + gchar buf[512]; + gint tcp_status; + gulong addr; + static int disable_iptables; + + tcp.chain = CHAIN_CONNECT; if ((f = fopen(PROC_NET_TCP_FILE, "r")) != NULL) { @@ -810,6 +834,219 @@ fclose(f); } #endif /* INET6 */ + + // For iptables to run so you can get statistics, you must be running as root :( If gkrellm/gkrellmd is running with reduced privileges, then you get + // a zero length stdout stream instead of actual information. If you see this, then turn off iptables completely for minimum impact on the + // system. A su wrapper would be one solution :< or just let gkrellm/gkrellmd stay as root. + + // It would be nice to just do a zero stats after each read, but that would be intrusive, so the calling program must keep track of each rules + // packet and byte counts and find the difference. Since multiple rules can specify a particular port (SSHD for example), each must be tracked + // separately. The --line-numbers option is used as part of the key to provide the separation for multiple rules. + + if (!disable_iptables && (f = popen("/sbin/iptables -L -v -n -x --line-numbers", "r")) != NULL) + { + gchar *bufp, *tbufp; + gchar target[512]; + gint i; + GIPTablesHistory *iptables_at; + + iptables_at = iptables_start; + + while (fgets(buf, sizeof(buf), f)) + { + if (*buf == '\n') + continue; + + if (strncmp(buf, "Chain", 5) == 0) + { + if (strncmp(buf + 6, "INPUT ", 6) == 0) + tcp.chain = CHAIN_INPUT; + else if (strncmp(buf + 6, "FORWARD ", 8) == 0) + tcp.chain = CHAIN_FORWARD; + else if (strncmp(buf + 6, "OUTPUT ", 7) == 0) + tcp.chain = CHAIN_OUTPUT; + else + tcp.chain = CHAIN_USER; + continue; + } + + if (strncmp(buf, "num pkts", 13) == 0) + continue; + + bufp = buf; + sscanf(bufp, "%d %Lu %n", &tcp.line, &tcp.pkts, &i); + + // If the packet count is 0, then we can ignore all other information on the line. + + if (tcp.pkts) + { + bufp += i; + sscanf(bufp, "%Lu %n", &tcp.bytes, &i); + bufp += i; + sscanf(bufp, "%[^ ]%i", target, &i); + bufp += i; + + if (strcmp(target, "ACCEPT") == 0) + tcp.target = TARGET_ACCEPT; + else if (strcmp(target, "DROP") == 0) + tcp.target = TARGET_DROP; + else if (strcmp(target, "QUEUE") == 0) + tcp.target = TARGET_QUEUE; + else if (strcmp(target, "RETURN") == 0) + tcp.target = TARGET_RETURN; + else if (strcmp(target, "LOG") == 0) + tcp.target = TARGET_LOG; + else + tcp.target = TARGET_USER; + + tcp.local_port = tcp.remote_port = 0; // Default to full range in case no rule specifies anything else + tcp.local_port_hi = tcp.remote_port_hi = 65535; + + switch (tcp.chain) + { + case CHAIN_INPUT: // On input, source is remote port and destination is local + + case CHAIN_FORWARD: // Arbitrary direction selection + case CHAIN_USER: // Arbitrary direction selection + if ((tbufp = strstr(bufp, " spt:"))) + { + sscanf(tbufp + 5, "%d", &tcp.remote_port); + tcp.remote_port_hi = tcp.remote_port; + } + else if ((tbufp = strstr(bufp, " spts:"))) + sscanf(tbufp + 6, "%d:%d", &tcp.remote_port, &tcp.remote_port_hi); + + if ((tbufp = strstr(bufp, " dpt:"))) + { + sscanf(tbufp + 5, "%d", &tcp.local_port); + tcp.local_port_hi = tcp.local_port; + } + else if ((tbufp = strstr(bufp, " dpts:"))) + sscanf(tbufp + 6, "%d:%d", &tcp.local_port, &tcp.local_port_hi); + break; + + case CHAIN_OUTPUT: // Source/Destination sense reverses local/remote for output. + if ((tbufp = strstr(bufp, " spt:"))) + { + sscanf(tbufp + 5, "%d", &tcp.local_port); + tcp.local_port_hi = tcp.local_port; + } + else if ((tbufp = strstr(bufp, " spts:"))) + sscanf(tbufp + 6, "%d:%d", &tcp.local_port, &tcp.local_port_hi); + + if ((tbufp = strstr(bufp, " dpt:"))) + { + sscanf(tbufp + 5, "%d", &tcp.remote_port); + tcp.remote_port_hi = tcp.remote_port; + } + else if ((tbufp = strstr(bufp, " dpts:"))) + sscanf(tbufp + 6, "%d:%d", &tcp.remote_port, &tcp.remote_port_hi); + break; + } + + if (iptables_at && + iptables_at->local_port == tcp.local_port && iptables_at->local_port_hi == tcp.local_port_hi && + iptables_at->remote_port == tcp.remote_port && iptables_at->remote_port_hi == tcp.remote_port_hi && + iptables_at->chain == tcp.chain && + iptables_at->line == tcp.line && + iptables_at->target == tcp.target) + { + // Unless the firewall is altered, then the nodes should move along in sequence with each iteration. + // Keep the node pointer matched up as the report is read and don't do anything special unless the packet or byte + // count changes. + + if (iptables_at->pkts != tcp.pkts || + iptables_at->bytes != tcp.bytes) + { + iptables_at->pkts = tcp.pkts; + iptables_at->bytes = tcp.bytes; + gkrellm_inet_log_tcp_port_data(&tcp); + } + iptables_at = iptables_at->next; + continue; + } + + + // If the user has added rules to the rule set in some particular chain, a new entry will be added at the end of the list + // so first go back to square one to look for existing entries that match. + + iptables_at = iptables_start; + while (iptables_at) + { + if (iptables_at->local_port == tcp.local_port && iptables_at->local_port_hi == tcp.local_port_hi && + iptables_at->remote_port == tcp.remote_port && iptables_at->remote_port_hi == tcp.remote_port_hi && + iptables_at->chain == tcp.chain && + iptables_at->line == tcp.line && + iptables_at->target == tcp.target) + break; + iptables_at = iptables_at->next; + } + + // No matching node to track this rule's history was found. + + if (!iptables_at) + { + iptables_at = g_new0(GIPTablesHistory, 1); + if (iptables_at) + { + // If you can allocate another node, the current iptables information is synced into it and automatically sent on for + // logging the first packet and byte count information for the rule + + if (iptables_last) + { + iptables_last->next = iptables_at; + iptables_last = iptables_at; + } + else + { + iptables_start = iptables_at; + iptables_last = iptables_at; + } + iptables_at->local_port = tcp.local_port; + iptables_at->local_port_hi = tcp.local_port_hi; + iptables_at->remote_port = tcp.remote_port; + iptables_at->remote_port_hi = tcp.remote_port_hi; + iptables_at->chain = tcp.chain; + iptables_at->line = tcp.line; + iptables_at->target = tcp.target; + iptables_at->pkts = tcp.pkts; + iptables_at->bytes = tcp.bytes; + } + + // If you can't allocate another node, send the information on the the display process which may be on another system which has + // more free RAM to track the history. + + gkrellm_inet_log_tcp_port_data(&tcp); + } + + // A matching node was found + + else + { + // Unless the firewall is altered, then the nodes should move along in sequence with each iteration. + // Keep the node pointer matched up as the report is read and don't do anything special unless the packet or byte + // count changes. + + if (iptables_at->pkts != tcp.pkts || + iptables_at->bytes != tcp.bytes) + { + iptables_at->pkts = tcp.pkts; + iptables_at->bytes = tcp.bytes; + gkrellm_inet_log_tcp_port_data(&tcp); + } + iptables_at = iptables_at->next; + continue; + } + } + } + fclose(f); + + // No chains were found which means iptables couldn't be run - If it ran you would at least get the basic chain names even with no + // rules + + if (tcp.chain == CHAIN_CONNECT) + disable_iptables = TRUE; + } } gboolean @@ -2507,7 +2744,7 @@ { fixed_chip_name = g_strdup(chip_name); gkrellm_sensors_linux_name_fix(fixed_chip_name); - + path = g_build_filename(SENSORS_DIR, chip_name, NULL); chip_dir = g_dir_open(path, 0, NULL); if (!chip_dir)