diff --git a/README b/README
deleted file mode 100644
index 4c8ed85..0000000
--- a/README
+++ /dev/null
@@ -1,313 +0,0 @@
-[](https://travis-ci.org/tomac/yersinia)
-
-Spanning Tree
--------------
-
-#1: DOS attack sending conf BPDUs
-
- Let's send some conf BPDUs claiming be root!!! By sending continously conf BPDU with root pathcost 0, randomly
- generated bridge id (and therefore the same root id), and some default values for other fields, we try to
- annoy the switches close to us, causing a DoS when trying to parse and recalculate their STP engines.
-
- Source MAC: randomly generated.
- Destination MAC: 01:80:c2:00:00:00
- Bridge ID: 8000:source_mac
- Root ID: 8000:source_mac
- Hello time: 2
- Forward delay: 15
- Max age: 20
- Root pathcost: 0
-
-
-
-
-#2: DOS attack sending tcn BPDUs
-
- This attack sends continously tcn BPDUs causing the root switch to send conf BPDUs acknowledging the change.
- Besides, the root switch will send topology change notifications to the members of the tree, and they will
- have to recalculate their STP engine to learn the new change.
-
- Source MAC: randomly generated.
- Destination MAC: 01:80:c2:00:00:00
-
-
-
-
-#3: NONDOS attack Claiming Root Role
-
- Now our aim is to get the root role of the tree. How can we accomplish this issue? Just listening to the network
- to find out which one is the root role, and start sending conf BPDU with lower priority to become root.
-
- Source MAC: same one as the sniffed BPDU.
- Destination MAC: same one as the sniffed BPDU.
- Bridge ID: the sniffed one slightly modified to have a lower priority
- Root ID: 8000: same as bridge id.
- Hello time: same one as the sniffed BPDU.
- Forward delay: same one as the sniffed BPDU.
- Max age: same one as the sniffed BPDU.
- Root pathcost: same one as the sniffed BPDU.
-
-
-
-
-#4 NONDOS attack Claiming a non-root role
-
- We pretend to be another weird switch playing with STP and praising our root id :)
-
-
-#5 DOS attack causing eternal root elections
-
- By sending config BPDUs autodecrementing their priority, we can cause infinite root elections in the STP tree.
- It would be something similar to recount the election's votes to determine the winner (do you remember Florida?)
-
-
-
-
-#6 DOS Attack causing root dissapearance
-
- This time we try to exhaust the root election proccess. We manage to become root in the STP tree,
- but we stop sending config BPDUs until it reaches max_age seconds (usually 20), forcing a new
- election proccess.
-
-
-
-
-Mitigations (Cisco only)
-------------------------
-
-- Use port security and disable STP in those ports that don't require STP.
-For information about port security, please check the following url:
-http://www.cisco.com/en/US/products/hw/switches/ps628/products_configuration_guide_chapter09186a0080150bcd.html
-
-- If you are using the portfast feature in your STP configuration, enable also the BPDU guard for avoiding these
-attacks when the port automatically enters the forwarding state:
-http://www.cisco.com/warp/public/473/65.html
-
-- Use the root guard feature for avoiding rogue devices to become root:
-http://www.cisco.com/en/US/tech/tk389/tk621/technologies_tech_note09186a00800ae96b.shtml
-
-
-Further reading
----------------
-
-- Guillermo Marro's nice Master Thesis:
-http://seclab.cs.ucdavis.edu/papers/Marro_masters_thesis.pdf
-
-- Oleg K. Artemjev, Vladislav V. Myasnyankin. Fun with the Spanning Tree Protocol
-http://phrack.org/issues/61/12.html
-
-
-
-CDP
----
-
-Cisco devices have always spoken a different language to communicate among them,
-to tell everybody that they are alive and which nifty features they have. CDP
-stands for Cisco Discovery Protocol. By means of this particular language, Cisco
-devices set up a virtual world where everyone is happy and ther is no crime at
-all. Or at least it seems to be this way, since many network administrators
-aren't worried for CDP yet. Although some of information that can be sent in a
-CDP packet is still undocumented (CDP is a propietary protocol and it seems that
-Cisco does not want to give details about it), at least one old attack (that it
-is still valid) is known, and there is a public implementation (FX did it!).
-
-This attack is a DoS trying to exhaust the device memory so that it can't
-allocate more memory for any device process. How can we do it? Simply sending
-CDP packets with bogus data simulating real Cisco devices. The target device
-will begin to allocate memory in its CDP table to save the new neighbor
-information, but without knowing that it is going to have thousands or millions
-of new friends.
-
-Other attack implemented in the current code is the ability to set up a new
-virtual Cisco device that it is designated only for make a little mess, trying
-to confuse network administrators.
-
-Screenshot of the attack running:
-
-Output of a Cisco 2503 router:
-
-athens#sh mem
- Head Total(b) Used(b) Free(b) Lowest(b) Largest(b)
-Processor 4873C 3893444 3893444 0 0 0
-I/O 400000 2097152 2097088 64 64 64
-
-
-%SCHED-3-THRASHING: Process thrashing on watched queue 'CDP packets' (count 57).
--Process= "CDP Protocol", ipl= 6, pid= 9
--Traceback= 3159232 31594DE 3201660
-%LANCE-5-COLL: Unit 0, excessive collisions. TDR=7
-%SCHED-3-THRASHING: Process thrashing on watched queue 'CDP packets' (count 57).
--Process= "CDP Protocol", ipl= 6, pid= 9
--Traceback= 3159232 31594DE 3201660
-%SYS-2-MALLOCFAIL: Memory allocation of 100 bytes failed from 0x3201B3E, pool Processor, alignment 0
--Process= "CDP Protocol", ipl= 0, pid= 9
--Traceback= 314E8A4 314FA06 3201B46 32016C8
-%SCHED-3-THRASHING: Process thrashing on watched queue 'CDP packets' (count 57).
--Process= "CDP Protocol", ipl= 6, pid= 9
--Traceback= 3159232 31594DE 3201660
-%SYS-2-MALLOCFAIL: Memory allocation of 100 bytes failed from 0x3201B3E, pool Processor, alignment 0
--Process= "CDP Protocol", ipl= 0, pid= 9
--Traceback= 314E8A4 314FA06 3201B46 32016C8
-%SYS-2-MALLOCFAIL: Memory allocation of 100 bytes failed from 0x3201B3E, pool Processor, alignment 0
--Process= "CDP Protocol", ipl= 0, pid= 9
--Traceback= 314E8A4 314FA06 3201B46 32016C8
-
-
-And a couple of minutes later after killing the attack, the router surprisingly gets halted for several seconds,
-and then kicks you out of the terminal :)
-
-
-%SYS-3-CPUHOG: Task ran for 16884 msec (69/69), Process = Exec, PC = 3158D42
--Traceback= 3158CEE 3158D4A 30F7330 30F742A 30FF3A4 30FEF76 30FEF1C 3116860
-
-
-
-Output of a Cisco 2950 switch:
-
-00:06:08: %SYS-2-MALLOCFAIL: Memory allocation of 224 bytes failed from 0x800118D0, alignment 0
-Pool: Processor Free: 0 Cause: Not enough free memory
-Alternate Pool: I/O Free: 32 Cause: Not enough free memory
-
--Process= "CDP Protocol", ipl= 0, pid= 26
--Traceback= 801DFC30 801E1DD8 800118D8 80011218 801D932C 801D9318
-00:06:08: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:09: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:10: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:11: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:12: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:13: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:14: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:15: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:16: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:17: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:18: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:19: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:20: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:21: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:22: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:23: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:38: %SYS-2-MALLOCFAIL: Memory allocation of 140 bytes failed from 0x801E28BC, alignment 0
-Pool: Processor Free: 0 Cause: Not enough free memory
-Alternate Pool: I/O Free: 32 Cause: Not enough free memory
-
--Process= "Calhoun Statistics Process", ipl= 0, pid= 21
--Traceback= 801DFC30 801E1DD8 801E28C4 801F13BC 801F1470 802F7C90 802F9190 802F9788 801D932C 801D9318
-00:06:38: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:39: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:40: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:41: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:42: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:44: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:45: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:46: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:47: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:48: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:49: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:50: ../src-calhoun/strata_stats.c at line 137: can't not push event list
-00:06:59: %SYS-3-CPUHOG: Task ran for 2076 msec (11/10), process = Net Background, PC = 801ABD40.
--Traceback= 801ABD48 801D932C 801D9318
-
-And then, the CDP process is totally down, even when we stop the attack. No more CDP babies...
diff --git a/README.md b/README.md
index cb840a3..b6e7f18 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,26 @@
[](https://travis-ci.org/tomac/yersinia)
+How to Install
+-------------
+
+Clone this repo inside `/opt/yersinia`.
+Install the dependencies:
+```
+sudo apt install autoconf libgtk-3-dev libnet1-dev libgtk2.0-dev libpcap-dev -y
+```
+Then go inside `/opt/yersinia` and execute:
+```
+./autogen.sh
+./configure --with-gtk # flag required to compile with GUI support
+make
+make install
+```
+
+And that's it, you can now start it with:
+```
+yersinia -G
+```
+
Spanning Tree
-------------
diff --git a/src/admin.c b/src/admin.c
index d007b22..135f796 100644
--- a/src/admin.c
+++ b/src/admin.c
@@ -5,6 +5,8 @@
* By David Barroso and Alfredo Andres
* Copyright 2005-2017 Alfredo Andres and David Barroso
*
+ * << Code amended by Nicolae Mercore - 11.2024 >>
+ *
* 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
@@ -232,7 +234,7 @@ admin_th_listen(void *arg)
else
{
write_log(0,"\n Connection accepted for %s\n", inet_ntoa(*ip_addr));
- if ( pthread_create( &tid, NULL, &admin_th_network_peer, (void *)sock2 ) < 0)
+ if ( pthread_create( &tid, NULL, &admin_th_network_peer, (void *)(intptr_t)sock2 ) < 0)
{
n=errno;
thread_error("pthread_create admin_th_listen",n);
@@ -330,13 +332,13 @@ admin_th_network_peer(void *sock)
if (pthread_mutex_lock(&terms->mutex) != 0)
thread_error("th_network_peer pthread_mutex_lock",errno);
- fail = term_add_node(&term_node, TERM_VTY, sock, pthread_self());
+ fail = term_add_node(&term_node, TERM_VTY, (int)sock, pthread_self());
if (fail == -1)
{
if (pthread_mutex_unlock(&terms->mutex) != 0)
thread_error("th_network_peer pthread_mutex_unlock",errno);
- admin_th_network_peer_exit(term_node, sock);
+ admin_th_network_peer_exit(term_node, (int)(intptr_t)sock);
}
if (term_node == NULL)
@@ -346,7 +348,7 @@ admin_th_network_peer(void *sock)
if (pthread_mutex_unlock(&terms->mutex) != 0)
thread_error("th_network_peer pthread_mutex_unlock",errno);
- admin_th_network_peer_exit(term_node, sock);
+ admin_th_network_peer_exit(term_node, (int)(intptr_t)sock);
}
pthread_mutex_lock(&term_node->thread.finished);
@@ -377,14 +379,14 @@ admin_th_network_peer(void *sock)
thread_error("getpeername",errno);
if (pthread_mutex_unlock(&terms->mutex) != 0)
thread_error("th_vty_peer pthread_mutex_unlock",errno);
- admin_th_network_peer_exit(term_node, sock);
+ admin_th_network_peer_exit(term_node, (int)(intptr_t)sock);
}
if (init_attribs(term_node) < 0)
{
if (pthread_mutex_unlock(&terms->mutex) != 0)
thread_error("th_vty_peer pthread_mutex_unlock",errno);
- admin_th_network_peer_exit(term_node, sock);
+ admin_th_network_peer_exit(term_node, (int)(intptr_t)sock);
}
term_node->from_port = ntohs(name.sin_port);
diff --git a/src/admin.h b/src/admin.h
index 338c049..a1114e8 100644
--- a/src/admin.h
+++ b/src/admin.h
@@ -5,6 +5,8 @@
* By David Barroso and Alfredo Andres
* Copyright 2005-2017 Alfredo Andres and David Barroso
*
+ * << Code amended by Nicolae Mercore - 11.2024 >>
+ *
* 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
@@ -48,7 +50,7 @@ extern int8_t bin_data[];
/* Extern functions...*/
extern void write_log( u_int16_t mode, char *msg, ... );
extern int8_t attack_kill_th(struct term_node *, pthread_t);
-extern int8_t term_add_node(struct term_node **, int8_t, int32_t, pthread_t);
+extern int8_t term_add_node(struct term_node **, int8_t, int, pthread_t);
extern int8_t term_write(struct term_node *, char *, u_int16_t);
extern void term_delete_all(void);
extern void term_delete_node(struct term_node *, int8_t);
diff --git a/src/gtk-callbacks.c b/src/gtk-callbacks.c
index d6ddab9..7aeb015 100644
--- a/src/gtk-callbacks.c
+++ b/src/gtk-callbacks.c
@@ -33,6 +33,7 @@
#include
#include "gtk-callbacks.h"
+#include "gtk-interface.h"
#define GLADE_HOOKUP_OBJECT(component,widget,name) \
g_object_set_data_full (G_OBJECT (component), name, \
@@ -765,13 +766,18 @@ gtk_c_clock_update(GtkWidget *clock)
void
-gtk_c_tree_update( GtkWidget *tree_model )
+gtk_c_tree_update( GtkListStore *tree_model )
{
u_int8_t i, j;
GtkTreeIter iter;
GtkTreePath *path;
char tmp[3];
+ if (!GTK_IS_LIST_STORE(tree_model)) {
+ write_log(0, "Error: tree_model is not a valid GtkListStore\n");
+ return;
+ }
+
j = 0;
for( i=0; i < MAX_PROTOCOLS; i++ )
{
@@ -782,8 +788,9 @@ gtk_c_tree_update( GtkWidget *tree_model )
path = gtk_tree_path_new_from_string( tmp );
if ( path )
{
- gtk_tree_model_get_iter( GTK_TREE_MODEL( tree_model ), &iter, path );
- gtk_list_store_set( GTK_LIST_STORE( tree_model ), &iter, 1, protocols[i].packets, -1 );
+ if (gtk_tree_model_get_iter( GTK_TREE_MODEL( tree_model ), &iter, path )) {
+ gtk_list_store_set( tree_model, &iter, 1, protocols[i].packets, -1 );
+ }
gtk_tree_path_free( path );
}
j++;
@@ -794,8 +801,9 @@ gtk_c_tree_update( GtkWidget *tree_model )
path = gtk_tree_path_new_from_string( tmp );
if ( path )
{
- gtk_tree_model_get_iter( GTK_TREE_MODEL( tree_model ), &iter, path );
- gtk_list_store_set( GTK_LIST_STORE( tree_model ), &iter, 1, packet_stats.global_counter.total_packets, -1 );
+ if (gtk_tree_model_get_iter( GTK_TREE_MODEL( tree_model ), &iter, path )) {
+ gtk_list_store_set( tree_model, &iter, 1, packet_stats.global_counter.total_packets, -1 );
+ }
gtk_tree_path_free( path );
}
}
@@ -840,14 +848,28 @@ gtk_c_refresh_mwindow(gpointer userdata)
values = NULL;
/* Check if it is Yersinia log */
- if ( ! helper->mode || ( helper->mode >= MAX_PROTOCOLS ) )
+ if ( ! helper->mode || ( helper->mode >= MAX_PROTOCOLS ) ) {
+ return TRUE;
+ }
+
+ /* Get the protocol tree using access function */
+ GtkWidget *protocol_tree = gtk_i_get_protocol_tree(helper->mode);
+ if (!protocol_tree || !GTK_IS_TREE_VIEW(protocol_tree)) {
return TRUE;
+ }
params = protocols[helper->mode].parameters;
extra_params = protocols[helper->mode].extra_parameters;
- if ((tree_model = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(protocols_tree[helper->mode])))) == NULL)
+ if ((tree_model = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(protocol_tree)))) == NULL) {
write_log(0, "Error in gtk_tree_view_get_model\n");
+ return TRUE;
+ }
+
+ if (!GTK_IS_LIST_STORE(tree_model)) {
+ write_log(0, "Error: tree_model is not a valid GtkListStore\n");
+ return TRUE;
+ }
valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL(tree_model), &iter);
@@ -971,6 +993,21 @@ gtk_c_refresh_mwindow(gpointer userdata)
}
}
+ /* Auto-select first row with data to trigger detail display */
+ if (helper->mode < MAX_PROTOCOLS && protocols[helper->mode].stats[0].header->ts.tv_sec > 0) {
+ GtkWidget *protocol_tree = gtk_i_get_protocol_tree(helper->mode);
+ if (protocol_tree) {
+ GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(protocol_tree));
+ if (selection) {
+ GtkTreePath *path = gtk_tree_path_new_from_string("0");
+ if (path) {
+ gtk_tree_selection_select_path(selection, path);
+ gtk_tree_path_free(path);
+ }
+ }
+ }
+ }
+
return TRUE;
}
@@ -979,99 +1016,56 @@ void gtk_c_tree_selection_changed_cb( GtkTreeSelection *selection, gpointer user
{
GtkTreeIter iter;
GtkTreeModel *model;
- GtkWidget *tree;
- GtkListStore *tree_model;
- u_int8_t row = 0;
- u_int8_t j, k, mode;
- char **values = NULL, *ptrtlv;
- struct commands_param *params;
+ char *protocol_name = NULL;
+ int protocol_index = -1;
struct gtk_s_helper *helper = (struct gtk_s_helper *) userdata;
- if ( gtk_tree_selection_get_selected( selection, &model, &iter ) )
- gtk_tree_model_get(model, &iter, 0, &row, -1);
-
- mode = gtk_notebook_get_current_page(GTK_NOTEBOOK(helper->notebook));
- params = (struct commands_param *)protocols[mode].parameters;
-
- if ( protocols[mode].stats[row].header->ts.tv_sec <= 0)
- {
- /* write_log(0, "Ohhh no hay paquetes del modo %d, fila %d :(\n", mode, row); */
+ /* Basic validation */
+ if (!helper) {
return;
}
- tree = lookup_widget(GTK_WIDGET(helper->notebook), "main_vhvvs_tree");
-
- if ((tree_model = (GtkListStore *)gtk_tree_view_get_model(GTK_TREE_VIEW(tree))) == NULL)
- {
- write_log(0, "Error in gtk_tree_view_get_model\n");
+ if (!selection) {
return;
}
- gtk_list_store_clear(tree_model);
-
- if (protocols[mode].get_printable_packet)
- {
- values = (*protocols[mode].get_printable_packet)(&protocols[mode].stats[row]);
-
- if ( ! values )
- {
- write_log(0, "Error in get_printable_packet (mode %d)\n", mode);
- return ;
- }
- }
- else
- {
- write_log(0, "Warning: there is no get_printable_packet for protocol %d\n", mode);
- return ;
+ if (!gtk_tree_selection_get_selected(selection, &model, &iter)) {
+ return;
}
- j = 0;
- k = 0;
-
- /* Normal parameters (-2 for the interface and defaults) */
- while (j < protocols[mode].nparams)
- {
- if ((params[j].type != FIELD_IFACE) && (params[j].type != FIELD_DEFAULT) && (params[j].type != FIELD_EXTRA))
- {
- gtk_list_store_append(GTK_LIST_STORE(tree_model), &iter);
- gtk_list_store_set(GTK_LIST_STORE(tree_model), &iter, 0, params[j].ldesc, -1);
- gtk_list_store_set(GTK_LIST_STORE(tree_model), &iter, 1, values[k], -1);
- if (params[j].meaning)
- gtk_list_store_set( GTK_LIST_STORE( tree_model ), &iter, 2, parser_get_meaning( values[k], params[j].meaning ), -1 );
- k++;
- }
- j++;
+ /* Get the protocol name from the first column */
+ gtk_tree_model_get(model, &iter, 0, &protocol_name, -1);
+
+ if (!protocol_name) {
+ return;
}
- ptrtlv = values[k];
- if (protocols[mode].extra_nparams > 0)
- {
- while( ptrtlv && strlen( ptrtlv ) )
- {
- gtk_list_store_append(GTK_LIST_STORE(tree_model), &iter);
- gtk_list_store_set(GTK_LIST_STORE(tree_model), &iter, 0, ptrtlv, -1);
- ptrtlv += strlen( ptrtlv ) + 1;
- if (ptrtlv)
- {
- gtk_list_store_set(GTK_LIST_STORE(tree_model), &iter, 1, ptrtlv, -1);
- ptrtlv += strlen( ptrtlv ) + 1;
- }
+ /* Find the protocol index */
+ for (int i = 0; i < MAX_PROTOCOLS; i++) {
+ if (protocols[i].visible && protocols[i].namep &&
+ strcmp(protocols[i].namep, protocol_name) == 0) {
+ protocol_index = i;
+ break;
}
}
- gtk_list_store_append (GTK_LIST_STORE (tree_model), &iter);
- gtk_list_store_set (GTK_LIST_STORE(tree_model), &iter, 0, "Interface", -1);
- gtk_list_store_set (GTK_LIST_STORE(tree_model), &iter, 1, protocols[mode].stats[row].iface, -1);
-
- k = 0;
+ if (protocol_index == -1) {
+ g_free(protocol_name);
+ return;
+ }
- while( values[k] )
- {
- free((void *)values[k]);
- k++;
+ /* Switch to the corresponding notebook tab */
+ if (helper->notebook) {
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(helper->notebook), protocol_index);
+
+ /* Update helper->mode to match the new tab */
+ helper->mode = protocol_index;
+
+ /* Refresh the TreeView for this protocol to show packet data */
+ gtk_c_refresh_mwindow(helper);
}
- free(values);
+ g_free(protocol_name);
}
diff --git a/src/gtk-callbacks.h b/src/gtk-callbacks.h
index 345f52a..f068e2c 100644
--- a/src/gtk-callbacks.h
+++ b/src/gtk-callbacks.h
@@ -68,7 +68,7 @@ void gtk_c_attackparams_ok_click( GtkWidget *, gpointer );
gboolean gtk_c_attackparams_delete_event( GtkWidget *, GdkEvent *, gpointer );
void gtk_c_update_hexview(GtkTreeSelection *, gpointer);
void gtk_c_clock_update(GtkWidget *);
-void gtk_c_tree_update(GtkWidget *);
+void gtk_c_tree_update( GtkListStore * );
void gtk_c_refresh_mwindow_notebook(GtkNotebook *, GtkNotebookPage *, guint, gpointer);
gboolean gtk_c_refresh_mwindow(gpointer);
void gtk_c_tree_selection_changed_cb (GtkTreeSelection *, gpointer);
diff --git a/src/gtk-interface.c b/src/gtk-interface.c
index eee367e..c2913c0 100644
--- a/src/gtk-interface.c
+++ b/src/gtk-interface.c
@@ -402,7 +402,32 @@ gtk_i_create_Main (struct gtk_s_helper *helper)
gtk_widget_show (toolbar_clear_img);
toolbar_clear = (GtkWidget*) gtk_menu_tool_button_new (toolbar_clear_img, _("Clear stats"));
gtk_tool_item_set_tooltip(GTK_TOOL_ITEM(toolbar_clear), tooltips, ("Clear ALL packet statistics"), NULL);
- gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(toolbar_clear), menu_actions_clear_menu);
+ /* Create a separate menu for the toolbar to avoid the warning */
+ GtkWidget *toolbar_clear_menu = gtk_menu_new();
+
+ /* Copy the menu items to the toolbar menu */
+ for (i = 0; i < MAX_PROTOCOLS; i++)
+ {
+ GtkWidget *toolbar_clear_proto = gtk_menu_item_new_with_mnemonic (_(protocols[i].namep));
+ gtk_widget_set_name(toolbar_clear_proto, protocols[i].namep);
+ if (protocols[i].visible)
+ gtk_widget_show (toolbar_clear_proto);
+ gtk_container_add (GTK_CONTAINER (toolbar_clear_menu), toolbar_clear_proto);
+ g_signal_connect ((gpointer) toolbar_clear_proto, "activate",
+ G_CALLBACK (gtk_c_on_actions_clear_activate),
+ helper);
+ }
+
+ /* Add "All protocols" option */
+ GtkWidget *toolbar_clear_all = gtk_menu_item_new_with_mnemonic (_("All protocols"));
+ gtk_widget_set_name(toolbar_clear_all, "ALL");
+ gtk_widget_show (toolbar_clear_all);
+ gtk_container_add (GTK_CONTAINER (toolbar_clear_menu), toolbar_clear_all);
+ g_signal_connect ((gpointer) toolbar_clear_all, "activate",
+ G_CALLBACK (gtk_c_on_actions_clear_activate),
+ helper);
+
+ gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(toolbar_clear), toolbar_clear_menu);
gtk_widget_show (toolbar_clear);
gtk_container_add (GTK_CONTAINER (toolbar), toolbar_clear);
@@ -411,7 +436,32 @@ gtk_i_create_Main (struct gtk_s_helper *helper)
gtk_widget_show (toolbar_capture_img);
toolbar_capture = (GtkWidget*) gtk_menu_tool_button_new (toolbar_capture_img, _("Capture"));
gtk_tool_item_set_tooltip(GTK_TOOL_ITEM(toolbar_capture), tooltips, ("Capture traffic in PCAP format"), NULL);
- gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(toolbar_capture), menu_capture_menu);
+ /* Create a separate menu for the toolbar to avoid the warning */
+ GtkWidget *toolbar_capture_menu = gtk_menu_new();
+
+ /* Copy the capture menu items to the toolbar menu */
+ for (i = 0; i < MAX_PROTOCOLS; i++)
+ {
+ GtkWidget *toolbar_capture_proto = gtk_menu_item_new_with_mnemonic (_(protocols[i].namep));
+ gtk_widget_set_name(toolbar_capture_proto, protocols[i].namep);
+ if (protocols[i].visible)
+ gtk_widget_show (toolbar_capture_proto);
+ gtk_container_add (GTK_CONTAINER (toolbar_capture_menu), toolbar_capture_proto);
+ g_signal_connect ((gpointer) toolbar_capture_proto, "activate",
+ G_CALLBACK (gtk_c_on_capture_activate),
+ helper);
+ }
+
+ /* Add "All protocols" option */
+ GtkWidget *toolbar_capture_all = gtk_menu_item_new_with_mnemonic (_("All protocols"));
+ gtk_widget_set_name(toolbar_capture_all, "ALL");
+ gtk_widget_show (toolbar_capture_all);
+ gtk_container_add (GTK_CONTAINER (toolbar_capture_menu), toolbar_capture_all);
+ g_signal_connect ((gpointer) toolbar_capture_all, "activate",
+ G_CALLBACK (gtk_c_on_capture_activate),
+ helper);
+
+ gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(toolbar_capture), toolbar_capture_menu);
gtk_widget_show (toolbar_capture);
gtk_container_add (GTK_CONTAINER (toolbar), toolbar_capture);
@@ -480,6 +530,11 @@ gtk_i_create_Main (struct gtk_s_helper *helper)
column = gtk_tree_view_column_new_with_attributes ("Packets", cell2, "text", 1, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (main_vhvs_tree), GTK_TREE_VIEW_COLUMN (column));
+ /* Connect selection signal for left tree to update central tree */
+ GtkTreeSelection *left_selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(main_vhvs_tree));
+ g_signal_connect(G_OBJECT(left_selection), "changed",
+ G_CALLBACK(gtk_c_tree_selection_changed_cb), helper);
+
main_vhv_vbox = gtk_vbox_new (FALSE, 5);
gtk_widget_show (main_vhv_vbox);
gtk_paned_pack2 (GTK_PANED (main_vh_vpaned), main_vhv_vbox, TRUE, TRUE);
@@ -494,19 +549,32 @@ gtk_i_create_Main (struct gtk_s_helper *helper)
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(main_vhvvs_tree), TRUE);
main_vhvvs_tree_model = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
- gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (main_vhvv_scroll), main_vhvvs_tree);
+ gtk_container_add (GTK_CONTAINER (main_vhvv_scroll), main_vhvvs_tree);
gtk_tree_view_set_model (GTK_TREE_VIEW (main_vhvvs_tree), GTK_TREE_MODEL (main_vhvvs_tree_model));
gtk_widget_show (main_vhvvs_tree);
+ /* Create separate cell renderers for each column */
cell = gtk_cell_renderer_text_new ();
-
+ g_object_set(cell, "background", "#EEEEEE", "background-set", TRUE, NULL);
+ g_object_set(cell, "foreground", "#000000", "foreground-set", TRUE, NULL);
column = gtk_tree_view_column_new_with_attributes ("Field", cell, "text", 0, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (main_vhvvs_tree), GTK_TREE_VIEW_COLUMN (column));
+
+ cell = gtk_cell_renderer_text_new ();
+ g_object_set(cell, "background", "#FFFFFF", "background-set", TRUE, NULL);
+ g_object_set(cell, "foreground", "#000000", "foreground-set", TRUE, NULL);
column = gtk_tree_view_column_new_with_attributes ("Value", cell, "text", 1, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (main_vhvvs_tree), GTK_TREE_VIEW_COLUMN (column));
+
+ cell = gtk_cell_renderer_text_new ();
+ g_object_set(cell, "background", "#ADD8E6", "background-set", TRUE, NULL);
+ g_object_set(cell, "foreground", "#000000", "foreground-set", TRUE, NULL);
column = gtk_tree_view_column_new_with_attributes ("Description", cell, "text", 2, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (main_vhvvs_tree), GTK_TREE_VIEW_COLUMN (column));
+ /* Force column headers to be visible */
+ gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(main_vhvvs_tree), TRUE);
+
main_vhvv_eventbox = gtk_event_box_new();
gtk_widget_set_size_request (main_vhvv_eventbox, 20, 20);
//color.red = 0;
@@ -1561,6 +1629,21 @@ GtkWidget *gtk_i_create_attackparamsdialog( GTK_ATTACK_PARAMS_CONTEXT *params_ct
return main_dialog;
}
+/* Protocol TreeView access functions */
+GtkWidget* gtk_i_get_protocol_tree(int protocol_index) {
+ if (protocol_index < 0 || protocol_index >= MAX_PROTOCOLS) {
+ return NULL;
+ }
+ return protocols_tree[protocol_index];
+}
+
+GtkListStore* gtk_i_get_protocol_tree_model(int protocol_index) {
+ if (protocol_index < 0 || protocol_index >= MAX_PROTOCOLS) {
+ return NULL;
+ }
+ return protocols_tree_model[protocol_index];
+}
+
GtkWidget*
create_protocol_mwindow(GtkWidget *Main, struct gtk_s_helper *helper, u_int8_t proto)
@@ -1619,7 +1702,6 @@ create_protocol_mwindow(GtkWidget *Main, struct gtk_s_helper *helper, u_int8_t p
gtk_widget_set_size_request (scroll, 250, 250);
gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scroll), protocols_tree[proto]);
gtk_tree_view_set_model (GTK_TREE_VIEW(protocols_tree[proto]), GTK_TREE_MODEL(protocols_tree_model[proto]));
- g_object_unref(protocols_tree_model[proto]);
gtk_widget_show (protocols_tree[proto]);
cell = gtk_cell_renderer_text_new ();
diff --git a/src/gtk-interface.h b/src/gtk-interface.h
index 78bcf84..286c248 100644
--- a/src/gtk-interface.h
+++ b/src/gtk-interface.h
@@ -29,6 +29,10 @@
static GtkWidget *protocols_tree[MAX_PROTOCOLS + 1];
static GtkListStore *protocols_tree_model[MAX_PROTOCOLS + 1];
+/* Protocol TreeView access functions */
+GtkWidget* gtk_i_get_protocol_tree(int protocol_index);
+GtkListStore* gtk_i_get_protocol_tree_model(int protocol_index);
+
GtkWidget* gtk_i_create_Main (struct gtk_s_helper *);
GtkWidget* gtk_i_create_opendialog (struct gtk_s_helper *);
GtkWidget* gtk_i_create_savedialog (struct gtk_s_helper *);
diff --git a/src/parser.c b/src/parser.c
index f3912c3..ca35edc 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -103,7 +103,7 @@ parser_initial(struct term_tty *tty, struct cl_args *cl_args, int argc, char **a
if (!strcmp(argv[i],"-h") || !strcmp(argv[i],"--help"))
{
parser_help();
- break;
+ return -1;
}
else
if (!strcmp(argv[i],"-V") || !strcmp(argv[i],"--Version"))