📄 hitview.c
字号:
/*---[ hitview.c ]----------------------------------------------------- * Copyright (C) 2002-2004 Tomas Junnonen (majix@sci.fi) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * The Events page and related functions *--------------------------------------------------------------------*/#include <config.h>#include <gnome.h>#include <libgnomevfs/gnome-vfs.h>#include "firestarter.h"#include "globals.h"#include "hitview.h"#include "util.h"#include "menus.h"#include "preferences.h"#include "statusview.h"#include "logread.h"#include "scriptwriter.h"#define COLOR_SERIOUS_HIT "#bd1f00"#define COLOR_BROADCAST_HIT "#6d6d6d"static GtkListStore *hitstore;static GtkWidget *hitview;static Hit *last_hit = NULL;static GnomeVFSAsyncHandle *hitview_ghandle = (GnomeVFSAsyncHandle*)NULL;const Hit *get_last_hit (void){ return last_hit;}gbooleanhitview_reload_in_progress (void){ return (hitview_ghandle != NULL);}voidhitview_abort_reload_callback (GnomeVFSAsyncHandle *handle, GnomeVFSResult result, gpointer data){ Parse *info = data; if (result != GNOME_VFS_OK) { g_warning ("Close error"); } g_free (info->buffer); g_pattern_spec_free (info->pattern); g_free (info); hitview_ghandle = (GnomeVFSAsyncHandle*)NULL; menus_update_events_reloading (FALSE, gui_get_active_view () == EVENTS_VIEW); printf ("Finished reading events list\n");}/* [ create_text_column ] * Convinience funtion for creating a text column for a treeview */static GtkTreeViewColumn *create_text_column (gint number, gchar * title){ GtkTreeViewColumn *column; GtkCellRenderer *renderer; renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes (title, renderer, "text", number, "foreground", HITCOL_COLOR, NULL); return column;}/* [ hitview_clear ] * Clears the log CList */voidhitview_clear (void){ if (status_get_state () == STATUS_HIT) status_set_state (STATUS_RUNNING); menus_events_clear_enabled (FALSE); menus_events_save_enabled (FALSE); gtk_list_store_clear (hitstore); if (last_hit != NULL) { free_hit (last_hit); last_hit = NULL; } gtk_tree_view_columns_autosize (GTK_TREE_VIEW (hitview)); status_events_reset ();}/* [ unselect_all ] * Unselect all entries in the hitview */static voidunselect_all (void){ GtkTreeSelection *s; s = gtk_tree_view_get_selection (GTK_TREE_VIEW (hitview)); gtk_tree_selection_unselect_all (s);}/* [ has_selected ] * Return true if there are entries selected in the hitview */static gbooleanhas_selected (void){ GtkTreeSelection *selection; GtkTreeIter iter; gboolean has_selected; selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (hitview)); has_selected = gtk_tree_selection_get_selected (selection, NULL, &iter); return has_selected;}/* [ scroll_to_hit ] * Scroll the hitview to the hit iter points to. Only works in ascending sort mode */static voidscroll_to_hit (GtkTreeIter *iter){ static GtkTreeModel *model = NULL; gint colid; GtkSortType order; GtkTreePath *last; if (model == NULL) model = gtk_tree_view_get_model (GTK_TREE_VIEW (hitview)); last = gtk_tree_model_get_path (model, iter); gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (model), &colid, &order); if (order == GTK_SORT_ASCENDING) gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (hitview), last, NULL, TRUE, 1.0, 1.0); gtk_tree_path_free (last);}/* [ compare_to_last_hit ] * Loosely compare a hit to the previous one. Return true if they are similiar */static gbooleancompare_to_last_hit (Hit *new){ const Hit *old = get_last_hit (); gboolean same = TRUE; if (old == NULL || new == NULL) return FALSE; /* Going from most likely to differ to least */ if (strcmp (new->port, old->port) != 0) { same = FALSE; } else if (strcmp (new->protocol, old->protocol) != 0) { same = FALSE; } else if (strcmp (new->source, old->source) != 0) { same = FALSE; } else if (strcmp (new->destination, old->destination) != 0) { same = FALSE; }/* else if (strcmp (new->in, old->in) == 0) same = FALSE; else if (strcmp (new->out, old->out) == 0) same = FALSE;*/ return same;}/* [ hit_is_for_me ] * Test if the destination of a hit matches the external interface IP */static gbooleanhit_is_for_me (Hit *h){ static gchar *myip = NULL; if (myip == NULL) { myip = get_ip_of_interface (preferences_get_string (PREFS_FW_EXT_IF)); } return (strcmp (myip, h->destination) == 0);}/* [ hit_is_serious ] * Test if a hit is classified as serious */static gbooleanhit_is_serious (Hit *h){ return (hit_is_for_me (h) && atoi (h->port) < 1024);}/* [ hit_is_broadcast ] * Test if the hit is a broadcasted message */static gbooleanhit_is_broadcast (Hit *h){ return (g_str_has_suffix (h->destination, ".255"));}static gbooleanhit_is_outbound (Hit *h){ return g_str_equal (h->direction, "Outbound");}static gbooleanhit_is_inbound (Hit *h){ return g_str_equal (h->direction, "Inbound");}/* [ hitview_append_hit ] * Append a hit to the hitlist, return true if successful */gbooleanhitview_append_hit (Hit *h){ GtkTreeIter iter; static gchar *color_serious = COLOR_SERIOUS_HIT; static gchar *color_broadcast = COLOR_BROADCAST_HIT; gchar *color = NULL; if (preferences_get_bool (PREFS_SKIP_REDUNDANT)) if (compare_to_last_hit (h)) { /* printf ("Hit filtered: Redundant\n"); */ return FALSE; } if (preferences_get_bool (PREFS_SKIP_NOT_FOR_FIREWALL)) if (!hit_is_for_me (h) && !hit_is_outbound (h)) { /* printf ("Hit filtered: Someone else's problem \n"); */ return FALSE; } if (hit_is_broadcast (h)) { color = color_broadcast; } else if (hit_is_serious (h)) { color = color_serious; if (hit_is_outbound (h)) status_serious_event_out_inc (); else status_serious_event_in_inc (); } if (hit_is_outbound (h)) { status_event_out_inc (); g_free (h->direction); h->direction = g_strdup (_("Outbound")); /* Localize the direction */ } else if (hit_is_inbound (h)) { status_event_in_inc (); g_free (h->direction); h->direction = g_strdup (_("Inbound")); } else { g_free (h->direction); h->direction = g_strdup (_("Unknown")); } gtk_list_store_append (hitstore, &iter); gtk_list_store_set (hitstore, &iter, HITCOL_TIME, h->time, HITCOL_DIRECTION, h->direction, HITCOL_IN, h->in, HITCOL_OUT, h->out, HITCOL_PORT, h->port, HITCOL_SOURCE, h->source, HITCOL_DESTINATION, h->destination, HITCOL_LENGTH, h->length, HITCOL_TOS, h->tos, HITCOL_PROTOCOL, h->protocol, HITCOL_SERVICE, h->service, HITCOL_COLOR, color, -1); if (!has_selected ()) scroll_to_hit (&iter); if (last_hit != NULL) { free_hit (last_hit); } last_hit = copy_hit (h); menus_events_clear_enabled (TRUE); menus_events_save_enabled (TRUE); /* Fixes a glitch in the view's rendering that causes text to jump around when mouse moves over an entry */ if (!hitview_reload_in_progress ()) gtk_tree_view_columns_autosize (GTK_TREE_VIEW (hitview)); return TRUE;}/* [ gvfs_open_callback ] * Open and read the file asynchronously */static voidgvfs_open_callback (GnomeVFSAsyncHandle *handle, GnomeVFSResult result, gpointer data){ Parse *info = g_new (Parse, 1); GnomeVFSFileInfo *file_info; if (result != GNOME_VFS_OK) { g_warning ("Failed to open file for async reading"); g_free (info); return; } file_info = gnome_vfs_file_info_new (); if (gnome_vfs_get_file_info((gchar *)data, file_info, GNOME_VFS_FILE_INFO_DEFAULT) != GNOME_VFS_OK) { g_warning ("File info error"); g_free (info); return; } info->size = file_info->size; info->bytes_read = 0; info->buffer = g_new (gchar, FILE_BUF+1); info->pattern = g_pattern_spec_new ("* IN=* OUT=* SRC=* "); info->continuous = FALSE; gnome_vfs_file_info_unref (file_info); gnome_vfs_async_read (handle, info->buffer, FILE_BUF, logread_async_read_callback, info);}voidhitview_reload_cancel (void){ printf ("Canceled reload of events list\n"); gnome_vfs_async_cancel (hitview_ghandle); menus_update_events_reloading (FALSE, gui_get_active_view () == EVENTS_VIEW); hitview_ghandle = (GnomeVFSAsyncHandle*)NULL;}/* [ hitview_reload ] * Loads the entire kernel log file into the hitlist */voidhitview_reload (void){ const gchar *path; /* If a new reload request comes while the previous operation is still pending, cancel it */ if (hitview_reload_in_progress ()) { gnome_vfs_async_cancel (hitview_ghandle); } path = get_system_log_path (); if (!g_file_test (path, G_FILE_TEST_EXISTS)) { gchar *error = g_strdup_printf ("Error reading system log %s, file does not exist", path); show_error (error); g_free (error); return; } hitview_clear (); gnome_vfs_async_open (&hitview_ghandle, path, GNOME_VFS_OPEN_READ, GNOME_VFS_PRIORITY_DEFAULT, gvfs_open_callback, (gpointer)path); menus_update_events_reloading (TRUE, gui_get_active_view () == EVENTS_VIEW);}/* [ create_hitlist_model ] * Creates the list for storage of hits */static GtkTreeModel *create_hitlist_model (void){ hitstore = gtk_list_store_new (NUM_HITCOLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); return GTK_TREE_MODEL (hitstore);}/* [ hitview_toggle_column_visibility ] * Negate the visibility of a column */voidhitview_toggle_column_visibility (GtkWidget *widget, gint colnum){ GtkTreeViewColumn *column; gboolean visible; g_assert (colnum < NUM_HITCOLUMNS); if (hitview == NULL) return; column = gtk_tree_view_get_column (GTK_TREE_VIEW (hitview), colnum); visible = !gtk_tree_view_column_get_visible (column); gtk_tree_view_column_set_visible(column, visible); switch (colnum) { case 0: preferences_set_bool (PREFS_HITVIEW_TIME_COL, visible); break; case 1: preferences_set_bool (PREFS_HITVIEW_DIRECTION_COL, visible); break; case 2: preferences_set_bool (PREFS_HITVIEW_IN_COL, visible); break; case 3: preferences_set_bool (PREFS_HITVIEW_OUT_COL, visible); break; case 4: preferences_set_bool (PREFS_HITVIEW_PORT_COL, visible); break; case 5: preferences_set_bool (PREFS_HITVIEW_SOURCE_COL, visible); break; case 6: preferences_set_bool (PREFS_HITVIEW_DESTINATION_COL, visible); break; case 7: preferences_set_bool (PREFS_HITVIEW_LENGTH_COL, visible); break; case 8: preferences_set_bool (PREFS_HITVIEW_TOS_COL, visible); break; case 9: preferences_set_bool (PREFS_HITVIEW_PROTOCOL_COL, visible); break; case 10: preferences_set_bool (PREFS_HITVIEW_SERVICE_COL, visible); break; }}/* [ hitview_add_columns ] * Add the columns to the hit TreeView */static voidhitview_add_columns (GtkTreeView *treeview){ GtkTreeViewColumn *column; gboolean visible; /* column for time */ column = create_text_column (HITCOL_TIME, _("Time")); gtk_tree_view_column_set_sort_column_id (column, HITCOL_TIME); gtk_tree_view_append_column (treeview, column); visible = preferences_get_bool (PREFS_HITVIEW_TIME_COL); gtk_tree_view_column_set_visible (column, visible); /* column for direction */ column = create_text_column (HITCOL_DIRECTION, _("Direction")); gtk_tree_view_column_set_sort_column_id (column, HITCOL_DIRECTION); gtk_tree_view_append_column (treeview, column); visible = preferences_get_bool (PREFS_HITVIEW_DIRECTION_COL); gtk_tree_view_column_set_visible (column, visible); /* column for in device */ column = create_text_column (HITCOL_IN, _("In")); gtk_tree_view_column_set_sort_column_id (column, HITCOL_IN); gtk_tree_view_append_column (treeview, column); visible = preferences_get_bool (PREFS_HITVIEW_IN_COL); gtk_tree_view_column_set_visible (column, visible); /* column for out device */ column = create_text_column (HITCOL_OUT, _("Out")); gtk_tree_view_column_set_sort_column_id (column, HITCOL_OUT); gtk_tree_view_append_column (treeview, column); visible = preferences_get_bool (PREFS_HITVIEW_OUT_COL); gtk_tree_view_column_set_visible (column, visible); /* column for port */ column = create_text_column (HITCOL_PORT, _("Port")); gtk_tree_view_column_set_sort_column_id (column, HITCOL_PORT); gtk_tree_view_append_column (treeview, column); visible = preferences_get_bool (PREFS_HITVIEW_PORT_COL); gtk_tree_view_column_set_visible (column, visible); /* column for source */ column = create_text_column (HITCOL_SOURCE, _("Source")); gtk_tree_view_column_set_sort_column_id (column, HITCOL_SOURCE); gtk_tree_view_append_column (treeview, column); visible = preferences_get_bool (PREFS_HITVIEW_SOURCE_COL); gtk_tree_view_column_set_visible (column, visible); /* column for destination */ column = create_text_column (HITCOL_DESTINATION, _("Destination")); gtk_tree_view_column_set_sort_column_id (column, HITCOL_DESTINATION); gtk_tree_view_append_column (treeview, column); visible = preferences_get_bool (PREFS_HITVIEW_DESTINATION_COL); gtk_tree_view_column_set_visible (column, visible); /* column for packet length */ column = create_text_column (HITCOL_LENGTH, _("Length")); gtk_tree_view_column_set_sort_column_id (column, HITCOL_LENGTH); gtk_tree_view_append_column (treeview, column); visible = preferences_get_bool (PREFS_HITVIEW_LENGTH_COL); gtk_tree_view_column_set_visible (column, visible); /* column for ToS */ column = create_text_column (HITCOL_TOS, _("TOS")); gtk_tree_view_column_set_sort_column_id (column, HITCOL_TOS); gtk_tree_view_append_column (treeview, column); visible = preferences_get_bool (PREFS_HITVIEW_TOS_COL); gtk_tree_view_column_set_visible (column, visible); /* column for protocol */ column = create_text_column (HITCOL_PROTOCOL, _("Protocol"));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -