⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 statusview.c

📁 Linux系统下著名的个人防火墙
💻 C
📖 第 1 页 / 共 3 页
字号:
/*---[ statusview.c ]----------------------------------------------------- * Copyright (C) 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 Status page and related functions *--------------------------------------------------------------------*/#include <config.h>#include <gnome.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <dirent.h>#include <sys/types.h>#include <fcntl.h>#include "firestarter.h"#include "globals.h"#include "statusview.h"#include "menus.h"#include "preferences.h"#include "util.h"#include "service.h"#include "tray.h"#include "gui.h"#include "xpm/firestarter-pixbufs.h" #define DEV_FILE "/proc/net/dev"#define TCP_FILE "/proc/net/tcp"#define CONNTRACK_FILE "/proc/net/ip_conntrack"#define CONNTRACK_TTL 10 /* Number of refresh cycles a non-established connection is kept in the GUI */#define REFRESH_RATE 1 /* Time in seconds between updates */#define HISTORY_LENGTH 5 /* Number of samples to use when averaging the traffic rate */#define COLOR_RETIRED_CONNECTION "#6d6d6d"static gboolean active_connections_visible = FALSE;static FirewallStatus current_status;static GtkWidget *connectionview;static GtkWidget *device_table;static GtkWidget *fw_state_icon;static GtkWidget *fw_state_label;static gint counter_events_in, counter_events_out, counter_serious_events_in, counter_serious_events_out;static GtkWidget *events_in, *events_out, *events_serious_in, *events_serious_out;static GHashTable *conntrack_programs = NULL;typedef struct _Interface_info Interface_info;struct _Interface_info{	gchar *type;	gulong received;	gulong sent;	gulong previous_total;	float  average;	float *traffic_history;	gint   history_index;};typedef struct _Interface_widgets Interface_widgets;struct _Interface_widgets{	GtkWidget *device;	GtkWidget *type;	GtkWidget *received;	GtkWidget *sent;	GtkWidget *activity;};typedef struct _Connection_entry Connection_entry;struct _Connection_entry{	GtkTreeIter *ref;	gint ttl;};enum{ 	CONNECTIONCOL_SOURCE,	CONNECTIONCOL_DESTINATION,	CONNECTIONCOL_PORT,	CONNECTIONCOL_SERVICE,	CONNECTIONCOL_PROGRAM,	CONNECTIONCOL_COLOR,	NUM_CONNECTIONCOLUMNS};static GtkListStore*get_connectionstore (void){	return GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (connectionview)));}static unsigned longget_inode (gchar *m_source, gchar *m_destination,           gchar *m_remote_port){	gint line_num = 0;	gchar *line;	static GIOChannel *in = NULL;	unsigned long inode;	GError *error = NULL;	if (in == NULL) {		in = g_io_channel_new_file (TCP_FILE, "r", &error);		if (in == NULL) {			printf ("Error reading %s: %s\n", TCP_FILE, error->message);			return 0;		}	}	while (TRUE) {		int local_port, rem_port;		gchar local_addr[128], rem_addr[128], more[512];		struct sockaddr_in localaddr, remaddr;		gchar *ip;		inode = -1;		g_io_channel_read_line (in, &line, NULL, NULL, &error);		if (line == NULL) // EOF reached			break;		line_num++;		if (line_num == 1) { // Skip tcp file header			g_free (line);			continue;		}		sscanf(line,		       "%*X: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %*X %*X:%*X %*X:%*X %*X %*d %*d %ld %512s\n",		       local_addr, &local_port, rem_addr, &rem_port, &inode, more);		sscanf(local_addr, "%X",			&((struct sockaddr_in *) &localaddr)->sin_addr.s_addr);		sscanf(rem_addr, "%X",			&((struct sockaddr_in *) &remaddr)->sin_addr.s_addr);		((struct sockaddr *) &localaddr)->sa_family = AF_INET;		((struct sockaddr *) &remaddr)->sa_family = AF_INET;		if (rem_port != atoi (m_remote_port)) {			g_free (line);			continue;		}		ip = inet_ntoa (localaddr.sin_addr);		if (!g_str_equal (ip, m_source)) {			g_free (line);			continue;		}		ip = inet_ntoa (remaddr.sin_addr);		if (!g_str_equal (ip, m_destination)) {			g_free (line);			continue;		}		/* printf ("MATCH %s %s\n", ip, m_destination); */		g_free (line);		break;	}	g_io_channel_seek_position (in, 0, G_SEEK_SET, &error); // Rewind	return inode;}static voidextract_socket_inode (gchar *lname, long *inode_p){	if (!g_str_has_suffix (lname, "]")) {		*inode_p = -1;	} else {		gchar *inode_str, *serr;		inode_str = get_text_between (lname, "[", "]");		*inode_p = strtol (inode_str, &serr, 0);		if (!serr || *serr || *inode_p < 0 || *inode_p >= INT_MAX)			*inode_p = -1;		g_free (inode_str);	}}static voidload_program_cache (void){	char line[40];	int procfdlen, fd, cmdllen;	char cmdlbuf[512];	long inode;	const char *cs, *cmdlp;	DIR *dirproc = NULL, *dirfd = NULL;	struct dirent *direproc, *direfd;	gchar *lname;	if (conntrack_programs == NULL)		conntrack_programs = g_hash_table_new_full (g_direct_hash, NULL, NULL, g_free);	if (!(dirproc=opendir("/proc"))) {		printf ("error opening proc filesystem\n");		return;	}	while (errno=0, direproc = readdir (dirproc)) {		if (direproc->d_type!=DT_DIR)			continue;		for (cs = direproc->d_name; *cs; cs++)			if (!g_ascii_isdigit(*cs) || *cs)				break;		procfdlen = snprintf (line, sizeof (line), "/proc/%s/fd", direproc->d_name);		if (procfdlen <= 0 || procfdlen >= sizeof (line)-5) 			continue;		errno = 0;		dirfd = opendir (line);		if (!dirfd)			continue;		line[procfdlen] = '/';				cmdlp = NULL;		while ((direfd = readdir (dirfd))) {			if (direfd->d_type!=DT_LNK) 				continue;			if (procfdlen+1+strlen(direfd->d_name)+1>sizeof(line)) 				continue;			memcpy(line + procfdlen - 2, "fd/", 2+1);			strcpy(line + procfdlen + 1, direfd->d_name);			lname = g_file_read_link (line, NULL);			extract_socket_inode (lname, &inode);			if (inode < 0) {				g_free (lname);				continue;			}			if (!cmdlp) {				if (procfdlen - 2 + 7 >= sizeof(line) - 5) {					g_free (lname);					continue;				}				strcpy (line + procfdlen-2, "cmdline");				fd = open(line, O_RDONLY);				if (fd < 0) {					g_free (lname);					continue;				}				cmdllen = read (fd, cmdlbuf, sizeof(cmdlbuf) - 1);				if (close(fd)) {					g_free (lname);					continue;				}				if (cmdllen == -1) {					g_free (lname);					continue;				}				if (cmdllen < sizeof (cmdlbuf) - 1) 					cmdlbuf[cmdllen] = '\0';				if ((cmdlp = strrchr(cmdlbuf, '/')))					cmdlp++;				else 					cmdlp = cmdlbuf;			}			g_hash_table_replace (conntrack_programs, GINT_TO_POINTER (inode), g_strdup (cmdlp));			g_free (lname);		}		closedir(dirfd); 		dirfd = NULL;	}	if (dirproc) 		closedir(dirproc);	if (dirfd) 		closedir(dirfd);}static gchar *get_program_name (gint inode){	gchar *name = NULL;	name = g_hash_table_lookup (conntrack_programs, GINT_TO_POINTER (inode));	/* printf ("Looking up: %d, got: %s\n", inode, name); */	return name;}/* [ connectionview_append_connection ] * Append a connection to the connectionlist */static GtkTreeIter*connectionview_append_connection (gchar *source, gchar *destination, gchar *port, gchar *service){	GtkListStore *store = get_connectionstore ();	GtkTreeIter *iter = g_new (GtkTreeIter, 1);	unsigned long inode = -1;	gchar *program;	static gchar *firewall_ip = NULL;	if (firewall_ip == NULL);		firewall_ip = get_ip_of_interface (preferences_get_string (PREFS_FW_EXT_IF));	 /* Only look up program names for local connections */	if (g_str_equal (firewall_ip, source)) {		load_program_cache ();		inode = get_inode (source, destination, port);	}	if (inode != -1)		program = get_program_name (inode);	else		program = g_strdup ("");	gtk_list_store_append (store, iter);	gtk_list_store_set (store, iter,	                    CONNECTIONCOL_SOURCE, source,	                    CONNECTIONCOL_DESTINATION, destination,	                    CONNECTIONCOL_PORT, port,	                    CONNECTIONCOL_SERVICE, service,			    CONNECTIONCOL_PROGRAM, program, 			    CONNECTIONCOL_COLOR, NULL,	                    -1);	gtk_tree_view_columns_autosize (GTK_TREE_VIEW (connectionview));	return iter;}static voidconnectionview_refresh (GHashTable *entries){	static GPatternSpec *pattern = NULL;	static GIOChannel *in = NULL;	GError *error = NULL;	gchar *line;	if (pattern == NULL)		pattern = g_pattern_spec_new ("* ESTABLISHED src=* dst=* dport=*");	if (in == NULL) {		in = g_io_channel_new_file (CONNTRACK_FILE, "r", &error);		if (in == NULL) {			printf ("Error reading %s: %s\n", CONNTRACK_FILE, error->message);			return;		}	}	while (TRUE) {		g_io_channel_read_line (in, &line, NULL, NULL, &error);		if (line == NULL) // EOF reached			break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -