📄 inet.c
字号:
/* GKrellM| Copyright (C) 1999-2006 Bill Wilson|| Author: Bill Wilson billw@gkrellm.net| Latest versions might be found at: http://gkrellm.net|| This program is free software which I release under the GNU General Public| License. You may redistribute and/or modify this program under the terms| of that license as published by the Free Software Foundation; either| version 2 of the License, or (at your option) any later version.|| This program is distributed in the hope that it will be useful,| but WITHOUT ANY WARRANTY; without even the implied warranty of| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the| GNU General Public License for more details. Version 2 is in the| COPYRIGHT file in the top level directory of this distribution.| | To get a copy of the GNU General Puplic License, write to the Free Software| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/ #include "gkrellm.h"#include "gkrellm-private.h"#include "gkrellm-sysdeps.h"#include "inet.h"typedef struct { GtkWidget *vbox; gchar *name; GkrellmChart *chart; GkrellmChart *chart_minute; GkrellmChart *chart_hour; GkrellmChartconfig *chart_config_minute; GkrellmChartconfig *chart_config_hour; GkrellmPanel *panel; gboolean hour_mode; gint cd_length; gboolean extra_info; GkrellmLauncher launch; GtkWidget *launch_entry, *tooltip_entry; GtkWidget *launch_table; gshort *mark_data; /* Draw marks if hits for any second */ gint mark_position, mark_prev_hits; GkrellmDecal *list_decal; GkrellmDecalbutton *list_button; GString *connection_string; GList *tcp_save_list; gboolean busy; gboolean connection_string_event; gboolean config_modified; gchar *label0; gint active0; gint prev_active0; gulong hits0_minute, hits0_hour; gboolean data0_is_range; gulong port0_0, port0_1; gchar *label1; gint active1; gint prev_active1; gulong hits1_minute, hits1_hour; gboolean data1_is_range; gulong port1_0, port1_1; gulong krell_hits; } InetMon;static GkrellmMonitor *mon_inet;static GList *inet_mon_list;static GList *active_tcp_list, *free_tcp_list;void (*read_tcp_data)();static GtkWidget *inet_vbox;static GdkImage *grid;static gchar *inet_data_dir;static gchar *text_format, *text_format_locale;static gint n_inet_monitors, update_interval = 1;static gint style_id;static ActiveTCP *_tcp_alloc(void) { ActiveTCP *tcp; if (free_tcp_list) { tcp = free_tcp_list->data; free_tcp_list = g_list_remove(free_tcp_list, tcp); } else tcp = g_new0(ActiveTCP, 1); return tcp; }static ActiveTCP *_log_active_port(ActiveTCP *tcp) { GList *list; ActiveTCP *active_tcp, *new_tcp; gchar *ap, *aap; gint slen; for (list = active_tcp_list; list; list = list->next) { active_tcp = (ActiveTCP *) (list->data); 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); }#endif else return 0; if ( memcmp(aap, ap, slen) == 0 && active_tcp->remote_port == tcp->remote_port && active_tcp->local_port == tcp->local_port ) { active_tcp->state = TCP_ALIVE; return active_tcp; /* Old hit still alive, not a new hit */ } } tcp->state = TCP_ALIVE; tcp->new_hit = 1; new_tcp = _tcp_alloc(); *new_tcp = *tcp; active_tcp_list = g_list_prepend(active_tcp_list, (gpointer) new_tcp); return new_tcp; /* A new hit */ }voidgkrellm_inet_log_tcp_port_data(gpointer data) { GList *list; InetMon *in; ActiveTCP *tcp, *active_tcp = NULL; gint krell_hit; tcp = (ActiveTCP *) data; for (list = inet_mon_list; list; list = list->next) { 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) ) { ++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; } /* 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 | same if found for both data0 and data1. */ if (active_tcp) active_tcp->new_hit = 0; }static gbooleansetup_inet_interface(void) { if (!read_tcp_data && !_GK.client_mode && gkrellm_sys_inet_init()) { read_tcp_data = gkrellm_sys_inet_read_tcp_data; } return read_tcp_data ? TRUE : FALSE; }voidgkrellm_inet_client_divert(void (*read_tcp_func)()) { read_tcp_data = read_tcp_func; }/* ======================================================================== */#define DUMP_IN(in,tag) printf("%s: %s %s %ld %ld %ld %ld\n", \ tag, in->label0, in->label1, \ in->port0_0, in->port0_1, in->port1_0, in->port1_1);static voidformat_chart_text(InetMon *in, gchar *src_string, gchar *buf, gint size) { GList *list; GkrellmChart *cp; GkrellmChartdata *cd; gchar c, *s, *s1; gint len, value, n, i, w; if (!buf || size < 1) return; --size; *buf = '\0'; if (!src_string) return; cp = in->chart; w = gkrellm_chart_width(); for (s = text_format_locale; *s != '\0' && size > 0; ++s) { len = 1; if (*s == '$' && *(s + 1) != '\0') { value = -1; s1 = " "; if ((c = *(s + 1)) == 'M') value = gkrellm_get_chart_scalemax(cp); else if (c == 'a' && *in->label0) value = in->active0; else if (c == 'l' && *in->label0) s1 = in->label0; else if (c == 'c' && *(s + 2)) { 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); } } else if (c == 'A' && *in->label1) value = in->active1; else if (c == 'L' && *in->label1) s1 = in->label1; else if (c == 'C' && *(s + 2)) { 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); } } if (value >= 0) len = snprintf(buf, size, "%d", value); else len = snprintf(buf, size, "%s", s1); ++s; } else *buf = *s; size -= len; buf += len; } *buf = '\0'; }static voiddraw_inet_extra(InetMon *in) { gchar buf[128]; if (!in->extra_info) return; format_chart_text(in, text_format_locale, buf, sizeof(buf)); gkrellm_draw_chart_text(in->chart, style_id, buf); } /* Use the reserved area below the main chart to draw marks if any | hits in second intervals. */static voiddraw_inet_mark_data(InetMon *in, gint minute_mark) { GkrellmChart *cp; GdkGC *gc1, *gc2, *gc3; gint hits, x, y, n; cp = in->chart; in->mark_position = (in->mark_position + 1) % cp->w; if (minute_mark) { in->mark_data[in->mark_position] = -1; /* minute flag in the data */ return; } hits = in->hits0_minute + in->hits1_minute; in->mark_data[in->mark_position] = hits - in->mark_prev_hits; in->mark_prev_hits = hits; gc1 = gkrellm_draw_GC(1); gc2 = gkrellm_draw_GC(2); gc3 = gkrellm_draw_GC(3); /* Clear out the area and redraw the marks. */ y = cp->h - cp->y; gdk_draw_drawable(cp->pixmap, gc1, cp->bg_src_pixmap, 0, y, 0, y, cp->w, cp->y); gdk_gc_set_foreground(gc1, gkrellm_out_color()); gdk_gc_set_foreground(gc2, gkrellm_in_color()); gdk_gc_set_foreground(gc3, gkrellm_white_color()); for (n = 0; n < cp->w; ++n) { x = (in->mark_position + n + 1) % cp->w; if (in->mark_data[x] > 0) gdk_draw_line(cp->pixmap, gc1, cp->x + n, cp->h - 1, cp->x + n, y); else if (in->mark_data[x] == -1) /* Minute tick */ gdk_draw_line(cp->pixmap, gc3, cp->x + n, cp->h - 1, cp->x + n, y); } gdk_draw_drawable(cp->drawing_area->window, gc1, cp->pixmap, 0, y, 0, y, cp->w, cp->y); }static voiddraw_inet_chart(InetMon *in) { struct tm tm; GdkGC *gc3; GkrellmChart *cp; GkrellmTextstyle *ts; GdkColor tmp_color; gchar buf[32]; guint32 pixel0, pixel1; gint y0, h4, w, h, n; cp = in->chart; gkrellm_draw_chartdata(cp); y0 = cp->h - cp->y; h4 = y0 / 4; 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); tm = *gkrellm_get_current_time(); gc3 = gkrellm_draw_GC(3); gdk_gc_set_foreground(gkrellm_draw_GC(3), gkrellm_white_color()); if (in->hour_mode) { for (n = cp->w - 1; n >= 0; --n) { /* When hour ticked to 0, 23rd hour data was stored and a slot | was skipped. */ if (tm.tm_hour == 0) /* Draw day mark at midnight */ { pixel0 = gdk_image_get_pixel(grid, cp->x + n, 0); tmp_color.pixel = pixel0; gdk_gc_set_foreground(gc3, &tmp_color); gdk_draw_line(cp->pixmap, gc3, cp->x + n - 1, y0 - 3, cp->x + n - 1, 3); if (h > 1) { pixel1 = gdk_image_get_pixel(grid, cp->x + n, 1); tmp_color.pixel = pixel1; gdk_gc_set_foreground(gc3, &tmp_color); gdk_draw_line(cp->pixmap, gc3, cp->x + n, y0 - 3, cp->x + n, 3); } } if (in->extra_info && tm.tm_hour == 1 && n < cp->w - 5) { strftime(buf, sizeof(buf), "%a", &tm); buf[1] = '\0'; gkrellm_draw_chart_label(in->chart, ts, cp->x + n, in->chart->h - 4, buf); } if (--tm.tm_hour < 0) { tm.tm_hour = 24; /* Extra hour for skipped slot */ if (--tm.tm_wday < 0) tm.tm_wday = 6; } } } else { for (n = cp->w - 1; n >= 0; --n) { /* When minute ticked to 0, 59 minute data was stored and a slot | was skipped. */ if (tm.tm_min == 0) /* Draw hour mark */ { pixel0 = gdk_image_get_pixel(grid, cp->x + n, 0); tmp_color.pixel = pixel0; gdk_gc_set_foreground(gc3, &tmp_color); gdk_draw_line(cp->pixmap, gc3, cp->x + n - 1, y0 - 3, cp->x + n - 1, y0 - h4); if (h > 1) { pixel1 = gdk_image_get_pixel(grid, cp->x + n, 1); tmp_color.pixel = pixel1; gdk_gc_set_foreground(gc3, &tmp_color); gdk_draw_line(cp->pixmap, gc3, cp->x + n, y0 - 3, cp->x + n, y0 - h4); } } if (--tm.tm_min < 0) tm.tm_min = 60; /* extra minute for skipped slot */ } } if (in->extra_info) draw_inet_extra(in); gkrellm_draw_chart_to_screen(cp); in->prev_active0 = in->active0; in->prev_active1 = in->active1; }static voidselect_hour_or_minute_chart(InetMon *in) { gkrellm_freeze_side_frame_packing(); if (in->hour_mode && in->chart == in->chart_minute) { 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); } else if (!in->hour_mode && in->chart == in->chart_hour) { 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); } gkrellm_thaw_side_frame_packing(); }static voidupdate_inet(void) { InetMon *in; GkrellmChart *cp; ActiveTCP *tcp; GList *list; gchar buf[32]; gint i; static gint check_tcp; if (!inet_mon_list) return; if (GK.second_tick && check_tcp == 0) { for (list = inet_mon_list; list; list = list->next) { in = (InetMon *) list->data; in->active0 = 0; in->active1 = 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -