1 /* firewall_rules_dlg.c
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 * Generate firewall ACL rules based on packet addresses and ports.
22 * For directional rules, an outside interface is assumed.
24 * There may be better ways to present the information, e.g. all rules
25 * in one huge text window, or some sort of tree view.
29 * To add a new product, add syntax functions modify the products[] array.
31 * To add a new syntax function, add its prototype above the products[]
32 * array, and add the function below with all the others.
35 /* Copied from ssl-dlg.c */
55 #include <gtk/dlg_utils.h>
56 #include <gtk/file_dlg.h>
59 #include <alert_box.h>
60 #include <simple_dialog.h>
61 #include <epan/dissectors/packet-ipv6.h>
62 #include <epan/prefs.h>
63 #include <epan/addr_resolv.h>
64 #include <epan/charsets.h>
66 #include <gtk/gui_utils.h>
67 #include <epan/epan_dissect.h>
68 #include <epan/filesystem.h>
69 #include <gtk/compat_macros.h>
70 #include <epan/ipproto.h>
71 #include <gtk/font_utils.h>
72 #include <wiretap/file_util.h>
74 #include "firewall_dlg.h"
76 #define MAX_RULE_LEN 200
93 /* Copied from packet_info struct */
94 typedef struct _rule_info_t {
104 GtkWidget *filter_om;
106 GtkWidget *inbound_cb;
107 GtkWidget *firewall_save_as_w;
110 rule_type_t rule_type;
113 /* Syntax function prototypes */
114 typedef void (*syntax_func)(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
116 static void sf_dummy(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
118 static void sf_ipfw_mac(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
119 static void sf_netfilter_mac(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
121 static void sf_ios_std_ipv4(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
122 static void sf_ios_ext_ipv4(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
123 static void sf_ipfilter_ipv4(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
124 static void sf_ipfw_ipv4(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
125 static void sf_netfilter_ipv4(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
126 static void sf_pf_ipv4(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
127 /* XXX - Can you addresses-only filters using WFW/netsh? */
129 static void sf_ios_ext_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
130 static void sf_ipfilter_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
131 static void sf_ipfw_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
132 static void sf_netfilter_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
133 static void sf_pf_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
134 static void sf_netsh_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
136 static void sf_ios_ext_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
137 static void sf_ipfilter_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
138 static void sf_ipfw_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
139 static void sf_netfilter_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
140 static void sf_pf_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
141 static void sf_netsh_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
143 typedef struct _fw_product_t {
146 syntax_func mac_func;
147 syntax_func ipv4_func;
148 syntax_func port_func;
149 syntax_func ipv4_port_func;
150 gboolean does_inbound;
153 fw_product products[] = {
154 { "Cisco IOS (standard)", "!", NULL, sf_ios_std_ipv4, NULL, NULL, FALSE },
155 { "Cisco IOS (extended)", "!",
156 NULL, sf_ios_ext_ipv4, sf_ios_ext_port, sf_ios_ext_ipv4_port, TRUE },
157 { "IP Filter (ipfilter)", "#",
158 NULL, sf_ipfilter_ipv4, sf_ipfilter_port, sf_ipfilter_ipv4_port, TRUE },
159 { "IPFirewall (ipfw)", "#",
160 sf_ipfw_mac, sf_ipfw_ipv4, sf_ipfw_port, sf_ipfw_ipv4_port, TRUE },
161 { "Netfilter (iptables)", "#",
162 sf_netfilter_mac, sf_netfilter_ipv4, sf_netfilter_port,
163 sf_netfilter_ipv4_port, TRUE },
164 { "Packet Filter (pf)", "#",
165 NULL, sf_pf_ipv4, sf_pf_port, sf_pf_ipv4_port, TRUE },
166 { "Windows Firewall (netsh)", "#",
167 NULL, NULL, sf_netsh_port, sf_netsh_ipv4_port, FALSE }
169 #define NUM_PRODS (sizeof(products) / sizeof(fw_product))
172 static void select_product(GtkWidget * win, gpointer data);
173 static void select_filter(GtkWidget * win, gpointer data);
174 static void toggle_inbound(GtkToggleButton *t, gpointer data);
175 static void toggle_deny(GtkToggleButton *t, gpointer data);
176 static void set_rule_text(rule_info_t *rule_info);
177 static void firewall_destroy_cb(GtkWidget * win, gpointer data);
178 static void firewall_copy_cmd_cb(GtkWidget * w, gpointer data);
179 static void firewall_save_as_cmd_cb(GtkWidget * w, gpointer data);
180 static void firewall_save_as_ok_cb(GtkWidget * w, gpointer fs);
181 static void firewall_save_as_destroy_cb(GtkWidget * win, gpointer user_data);
183 #define WS_RULE_INFO_KEY "rule_info_key"
185 /* List of "rule_info_t" structures for all rule windows. */
186 static GList *rule_infos;
188 /* Remove a "rule_info_t" structure from the list. */
190 forget_rule_info(rule_info_t *rule_info)
192 rule_infos = g_list_remove(rule_infos, rule_info);
196 firewall_rule_cb(GtkWidget *w _U_, gpointer data _U_)
198 GtkWidget *rule_w, *vbox, *txt_scrollw, *text;
199 GtkWidget *label, *product_om, *menu, *menu_item;
200 GtkWidget *hbox, *button_hbox, *button;
201 GtkTooltips *tooltips;
202 rule_info_t *rule_info;
203 packet_info *pinfo = &cfile.edt->pi;
206 rule_info = g_new0(rule_info_t, 1);
207 COPY_ADDRESS(&(rule_info->dl_src), &(pinfo->dl_src));
208 COPY_ADDRESS(&(rule_info->dl_dst), &(pinfo->dl_dst));
209 COPY_ADDRESS(&(rule_info->net_src), &(pinfo->net_src));
210 COPY_ADDRESS(&(rule_info->net_dst), &(pinfo->net_dst));
211 rule_info->ptype = pinfo->ptype;
212 rule_info->srcport = pinfo->srcport;
213 rule_info->destport = pinfo->destport;
214 rule_info->inbound = TRUE;
215 rule_info->deny = TRUE;
216 rule_info->product = 0;
218 rule_w = dlg_window_new("Firewall ACL Rules");
220 gtk_widget_set_name(rule_w, "Firewall ACL rule window");
221 gtk_container_border_width(GTK_CONTAINER(rule_w), 6);
223 /* setup the container */
224 tooltips = gtk_tooltips_new ();
226 vbox = gtk_vbox_new(FALSE, 6);
227 gtk_container_add(GTK_CONTAINER(rule_w), vbox);
229 /* rule type selectors hbox */
230 hbox = gtk_hbox_new(FALSE, 1);
231 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
233 /* product selector */
234 label = gtk_label_new("Product");
235 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
237 product_om = gtk_option_menu_new();
238 menu = gtk_menu_new();
239 for (i = 0; i < NUM_PRODS; i++) {
240 menu_item = gtk_menu_item_new_with_label(products[i].name);
241 SIGNAL_CONNECT(menu_item, "activate", select_product, GUINT_TO_POINTER(i));
242 OBJECT_SET_DATA(menu_item, WS_RULE_INFO_KEY, rule_info);
243 gtk_menu_append(GTK_MENU(menu), menu_item);
245 gtk_menu_item_select(GTK_MENU_ITEM(menu_item)); */
247 gtk_option_menu_set_menu(GTK_OPTION_MENU(product_om), menu);
248 gtk_box_pack_start(GTK_BOX(hbox), product_om, FALSE, FALSE, 5);
251 label = gtk_label_new("Filter");
252 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 10);
254 rule_info->filter_om = gtk_option_menu_new();
255 gtk_box_pack_start(GTK_BOX(hbox), rule_info->filter_om, FALSE, FALSE, 5);
257 /* inbound selector */
258 rule_info->inbound_cb = gtk_check_button_new_with_label("Inbound");
259 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rule_info->inbound_cb),
261 gtk_box_pack_start(GTK_BOX(hbox), rule_info->inbound_cb, FALSE, FALSE, 10);
262 SIGNAL_CONNECT(rule_info->inbound_cb, "toggled", toggle_inbound, rule_info);
265 rule_info->deny_cb = gtk_check_button_new_with_label("Deny");
266 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rule_info->deny_cb),
268 gtk_box_pack_start(GTK_BOX(hbox), rule_info->deny_cb, FALSE, FALSE, 10);
269 SIGNAL_CONNECT(rule_info->deny_cb, "toggled", toggle_deny, rule_info);
271 /* create a scrolled window for the text */
272 txt_scrollw = scrolled_window_new(NULL, NULL);
273 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(txt_scrollw),
275 gtk_box_pack_start(GTK_BOX(vbox), txt_scrollw, TRUE, TRUE, 0);
277 /* create a text box */
278 text = gtk_text_view_new();
279 gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE);
280 gtk_container_add(GTK_CONTAINER(txt_scrollw), text);
281 rule_info->text = text;
284 button_hbox = gtk_hbutton_box_new();
285 gtk_box_pack_start(GTK_BOX(vbox), button_hbox, FALSE, FALSE, 0);
286 gtk_button_box_set_layout (GTK_BUTTON_BOX(button_hbox), GTK_BUTTONBOX_END);
287 gtk_button_box_set_spacing(GTK_BUTTON_BOX(button_hbox), 5);
289 /* Create Copy Button */
290 button = BUTTON_NEW_FROM_STOCK(GTK_STOCK_COPY);
291 SIGNAL_CONNECT(button, "clicked", firewall_copy_cmd_cb, rule_info);
292 gtk_tooltips_set_tip (tooltips, button, "Copy rule to clipboard ", NULL);
293 gtk_box_pack_start(GTK_BOX(button_hbox), button, FALSE, FALSE, 0);
295 /* Create Save As Button */
296 button = BUTTON_NEW_FROM_STOCK(GTK_STOCK_SAVE_AS);
297 SIGNAL_CONNECT(button, "clicked", firewall_save_as_cmd_cb, rule_info);
298 gtk_tooltips_set_tip (tooltips, button, "Save the rule as currently displayed ", NULL);
299 gtk_box_pack_start(GTK_BOX(button_hbox), button, FALSE, FALSE, 0);
301 /* Create Close Button */
302 button = BUTTON_NEW_FROM_STOCK(GTK_STOCK_CLOSE);
303 gtk_tooltips_set_tip (tooltips, button,
304 "Close the dialog", NULL);
305 gtk_box_pack_start(GTK_BOX(button_hbox), button, FALSE, FALSE, 0);
306 GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
308 window_set_cancel_button(rule_w, button, window_cancel_button_cb);
310 /* Tuck away the rule_info object into the window */
311 OBJECT_SET_DATA(rule_w, WS_RULE_INFO_KEY, rule_info);
313 SIGNAL_CONNECT(rule_w, "delete_event", window_delete_event_cb, NULL);
314 SIGNAL_CONNECT(rule_w, "destroy", firewall_destroy_cb, NULL);
316 /* Make sure this widget gets destroyed if we quit the main loop,
317 so that if we exit, we clean up any temporary files we have
318 for "Follow SSL Stream" windows. */
319 gtk_quit_add_destroy(gtk_main_level(), GTK_OBJECT(rule_w));
321 gtk_widget_show_all(rule_w);
322 window_present(rule_w);
323 gtk_option_menu_set_history(GTK_OPTION_MENU(product_om), 0);
324 select_product(rule_w, GUINT_TO_POINTER(0));
327 /* Set the current product. */
328 #define ADD_TO_FILTER_MENU(rt) \
329 menu_item = gtk_menu_item_new_with_label(name); \
330 SIGNAL_CONNECT(menu_item, "activate", select_filter, \
331 GUINT_TO_POINTER(rt)); \
332 OBJECT_SET_DATA(menu_item, WS_RULE_INFO_KEY, rule_info); \
333 gtk_menu_append(GTK_MENU(menu), menu_item); \
336 first_mi = menu_item; \
340 #define NAME_TCP_UDP (rule_info->ptype == PT_TCP ? "TCP" : "UDP")
342 select_product(GtkWidget *w, gpointer data)
344 guint prod = GPOINTER_TO_UINT(data);
345 rule_info_t *rule_info;
346 gchar name[MAX_RULE_LEN], addr_str[MAX_RULE_LEN];
348 GtkWidget *menu, *menu_item, *first_mi = NULL;
349 rule_type_t rule_type = RT_NONE;
350 gboolean rt_set = FALSE, sensitive = FALSE;
352 rule_info = OBJECT_GET_DATA(w, WS_RULE_INFO_KEY);
354 if (prod >= NUM_PRODS || !rule_info)
357 rule_info->product = prod;
360 gtk_option_menu_remove_menu(GTK_OPTION_MENU(rule_info->filter_om));
361 menu = gtk_menu_new();
362 gtk_option_menu_set_menu(GTK_OPTION_MENU(rule_info->filter_om), menu);
364 /* Fill in valid menu items. */
365 if (products[prod].mac_func && rule_info->dl_src.type == AT_ETHER) {
366 addr = &(rule_info->dl_src);
367 address_to_str_buf(addr, name, MAX_RULE_LEN);
368 ADD_TO_FILTER_MENU(RT_MAC_SRC);
370 addr = &(rule_info->dl_dst);
371 address_to_str_buf(addr, name, MAX_RULE_LEN);
372 ADD_TO_FILTER_MENU(RT_MAC_DST);
375 if (products[prod].ipv4_func && rule_info->net_src.type == AT_IPv4) {
376 addr = &(rule_info->net_src);
377 address_to_str_buf(addr, name, MAX_RULE_LEN);
378 ADD_TO_FILTER_MENU(RT_IPv4_SRC);
380 addr = &(rule_info->net_dst);
381 address_to_str_buf(addr, name, MAX_RULE_LEN);
382 ADD_TO_FILTER_MENU(RT_IPv4_DST);
385 if (products[prod].port_func && (rule_info->ptype == PT_TCP || rule_info->ptype == PT_UDP)) {
386 g_snprintf(name, MAX_RULE_LEN, "%s port %u", NAME_TCP_UDP,
388 ADD_TO_FILTER_MENU(RT_PORT_SRC);
389 if (rule_info->srcport != rule_info->destport) {
390 g_snprintf(name, MAX_RULE_LEN, "%s port %u", NAME_TCP_UDP,
391 rule_info->destport);
392 ADD_TO_FILTER_MENU(RT_PORT_DST);
396 if (products[prod].ipv4_port_func && rule_info->net_src.type == AT_IPv4 &&
397 (rule_info->ptype == PT_TCP || rule_info->ptype == PT_UDP)) {
398 addr = &(rule_info->net_src);
399 address_to_str_buf(addr, addr_str, MAX_RULE_LEN);
400 g_snprintf(name, MAX_RULE_LEN, "%s + %s port %u", addr_str,
401 NAME_TCP_UDP, rule_info->srcport);
402 ADD_TO_FILTER_MENU(RT_IPv4_PORT_SRC);
404 addr = &(rule_info->net_dst);
405 address_to_str_buf(addr, addr_str, MAX_RULE_LEN);
406 g_snprintf(name, MAX_RULE_LEN, "%s + %s port %u", addr_str,
407 NAME_TCP_UDP, rule_info->destport);
408 ADD_TO_FILTER_MENU(RT_IPv4_PORT_DST);
412 if (rule_type != RT_NONE) {
413 gtk_widget_show_all(rule_info->filter_om);
414 gtk_option_menu_set_history(GTK_OPTION_MENU(rule_info->filter_om), 0);
417 gtk_widget_set_sensitive(rule_info->filter_om, sensitive);
418 gtk_widget_set_sensitive(rule_info->inbound_cb,
419 products[prod].does_inbound && sensitive);
420 gtk_widget_set_sensitive(rule_info->deny_cb, sensitive);
422 select_filter(w, GUINT_TO_POINTER(rule_type));
425 /* Set the current product. */
427 select_filter(GtkWidget *w, gpointer data)
429 rule_type_t cur_type = GPOINTER_TO_UINT(data);
430 rule_info_t *rule_info;
432 rule_info = OBJECT_GET_DATA(w, WS_RULE_INFO_KEY);
434 if (cur_type >= NUM_RULE_TYPES || !rule_info)
437 rule_info->rule_type = cur_type;
439 set_rule_text(rule_info);
442 /* Set inbound/outbound */
444 toggle_inbound(GtkToggleButton *t, gpointer data)
446 rule_info_t *rule_info = (rule_info_t *) data;
448 rule_info->inbound = gtk_toggle_button_get_active(t);
450 set_rule_text(rule_info);
453 /* Set deny/allow. */
455 toggle_deny(GtkToggleButton *t, gpointer data)
457 rule_info_t *rule_info = (rule_info_t *) data;
459 rule_info->deny = gtk_toggle_button_get_active(t);
461 set_rule_text(rule_info);
464 /* Set the rule text */
465 #define DL_ADDR (rt == RT_MAC_SRC ? &(rule_info->dl_src) : &(rule_info->dl_dst))
466 #define NET_ADDR (rt == RT_IPv4_SRC ? &(rule_info->net_src) : &(rule_info->net_dst))
467 #define NET_PORT (rt == RT_PORT_SRC ? rule_info->srcport : rule_info->destport)
469 set_rule_text(rule_info_t *rule_info) {
470 GString *rtxt = g_string_new("");
471 gchar addr_str[MAX_RULE_LEN];
472 rule_type_t rt = rule_info->rule_type;
473 guint prod = rule_info->product;
474 address *addr = NULL;
476 syntax_func rt_func = NULL;
478 GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(rule_info->text));
480 if (prod < NUM_PRODS) {
481 g_string_sprintf(rtxt, "%s %s\n", products[prod].comment_pfx, products[prod].name);
484 g_string_sprintfa(rtxt, "%s Not supported", products[prod].comment_pfx);
490 address_to_str_buf(addr, addr_str, MAX_RULE_LEN);
491 rt_func = products[prod].mac_func;
496 address_to_str_buf(addr, addr_str, MAX_RULE_LEN);
497 rt_func = products[prod].ipv4_func;
502 rt_func = products[prod].port_func;
504 case RT_IPv4_PORT_SRC:
505 case RT_IPv4_PORT_DST:
507 address_to_str_buf(addr, addr_str, MAX_RULE_LEN);
509 rt_func = products[prod].ipv4_port_func;
517 rt_func(rtxt, addr_str, port, rule_info->ptype, rule_info->inbound, rule_info->deny);
519 g_string_sprintfa(rtxt, "ERROR: Unable to create rule");
522 gtk_text_buffer_set_text(buf, rtxt->str, rtxt->len);
524 g_string_free(rtxt, TRUE);
528 /* Rule text functions */
530 static void sf_dummy(GString *rtxt _U_, gchar *addr _U_, guint32 port _U_, port_type ptype _U_, gboolean inbound _U_, gboolean deny _U_) {
534 #define IPFW_DENY (deny ? "deny" : "allow")
535 #define IPFW_IN (inbound ? "in" : "out")
536 static void sf_ipfw_mac(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
537 g_string_sprintfa(rtxt, "add %s MAC %s any %s",
538 IPFW_DENY, addr, IPFW_IN);
541 #define NF_DROP (deny ? "DROP" : "ACCEPT")
542 #define NF_INPUT (inbound ? "INPUT" : "OUTPUT")
543 static void sf_netfilter_mac(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
544 g_string_sprintfa(rtxt, "iptables -A %s --mac-source %s -j %s",
545 NF_INPUT, addr, NF_DROP);
549 #define IOS_DENY (deny ? "deny" : "permit")
550 static void sf_ios_std_ipv4(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound _U_, gboolean deny) {
551 g_string_sprintfa(rtxt, "access-list NUMBER %s host %s", IOS_DENY, addr);
554 static void sf_ios_ext_ipv4(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
556 g_string_sprintfa(rtxt, "access-list NUMBER %s ip host %s any", IOS_DENY, addr);
558 g_string_sprintfa(rtxt, "access-list NUMBER %s ip any host %s", IOS_DENY, addr);
561 #define IPFILTER_DENY (deny ? "block" : "pass")
562 #define IPFILTER_IN (inbound ? "in" : "out")
563 static void sf_ipfilter_ipv4(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
564 g_string_sprintfa(rtxt, "%s %s on le0 from %s to any",
565 IPFILTER_DENY, IPFILTER_IN, addr);
568 static void sf_ipfw_ipv4(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
569 g_string_sprintfa(rtxt, "add %s ip from %s to any %s",
570 IPFW_DENY, addr, IPFW_IN);
573 static void sf_netfilter_ipv4(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
574 g_string_sprintfa(rtxt, "iptables -A %s -i eth0 -d %s/32 -j %s",
575 NF_INPUT, addr, NF_DROP);
578 #define PF_DENY (deny ? "block" : "pass")
579 #define PF_IN (inbound ? "in" : "out")
580 static void sf_pf_ipv4(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
581 g_string_sprintfa(rtxt, "%s %s quick on $ext_if from %s to any",
582 PF_DENY, PF_IN, addr);
586 #define RT_TCP_UDP (ptype == PT_TCP ? "tcp" : "udp")
587 static void sf_ios_ext_port(GString *rtxt, gchar *addr _U_, guint32 port, port_type ptype, gboolean inbound _U_, gboolean deny) {
588 g_string_sprintfa(rtxt, "access-list NUMBER %s %s any any eq %u",
589 IOS_DENY, RT_TCP_UDP, port);
592 static void sf_ipfilter_port(GString *rtxt, gchar *addr _U_, guint32 port, port_type ptype _U_, gboolean inbound, gboolean deny) {
593 g_string_sprintfa(rtxt, "%s %s on le0 proto %s from any to any port = %u",
594 IPFILTER_DENY, IPFILTER_IN, RT_TCP_UDP, port);
597 static void sf_ipfw_port(GString *rtxt, gchar *addr _U_, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
598 g_string_sprintfa(rtxt, "add %s %s from any to any %u %s",
599 IPFW_DENY, RT_TCP_UDP, port, IPFW_IN);
602 static void sf_netfilter_port(GString *rtxt, gchar *addr _U_, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
603 g_string_sprintfa(rtxt, "iptables -A %s -p %s --destination-port %u -j %s",
604 NF_INPUT, RT_TCP_UDP, port, NF_DROP);
607 static void sf_pf_port(GString *rtxt, gchar *addr _U_, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
608 g_string_sprintfa(rtxt, "%s %s quick on $ext_if proto %s from any to any port %u",
609 PF_DENY, PF_IN, RT_TCP_UDP, port);
612 #define NETSH_DENY (deny ? "DISABLE" : "ENABLE")
613 static void sf_netsh_port(GString *rtxt, gchar *addr _U_, guint32 port, port_type ptype, gboolean inbound _U_, gboolean deny) {
614 g_string_sprintfa(rtxt, "add portopening %s %u Wireshark %s",
615 RT_TCP_UDP, port, NETSH_DENY);
619 static void sf_ios_ext_ipv4_port(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
621 g_string_sprintfa(rtxt, "access-list NUMBER %s %s host %s any eq %u", IOS_DENY, RT_TCP_UDP, addr, port);
623 g_string_sprintfa(rtxt, "access-list NUMBER %s %s any host %s eq %u", IOS_DENY, RT_TCP_UDP, addr, port);
626 static void sf_ipfilter_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
628 g_string_sprintfa(rtxt, "%s %s on le0 proto %s from %s to any port = %u",
629 IPFILTER_DENY, IPFILTER_IN, RT_TCP_UDP, addr, port);
631 g_string_sprintfa(rtxt, "%s %s on le0 proto %s from any to %s port = %u",
632 IPFILTER_DENY, IPFILTER_IN, RT_TCP_UDP, addr, port);
635 static void sf_ipfw_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
636 g_string_sprintfa(rtxt, "add %s %s from %s to any %u %s",
637 IPFW_DENY, RT_TCP_UDP, addr, port, IPFW_IN);
640 static void sf_pf_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
641 g_string_sprintfa(rtxt, "%s %s quick on $ext_if proto %s from %s to any port %u",
642 PF_DENY, PF_IN, RT_TCP_UDP, addr, port);
645 static void sf_netfilter_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
646 g_string_sprintfa(rtxt, "iptables -A %s -p %s -d %s/32 --destination-port %u -j %s",
647 NF_INPUT, RT_TCP_UDP, addr, port, NF_DROP);
650 static void sf_netsh_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound _U_, gboolean deny) {
651 g_string_sprintfa(rtxt, "add portopening %s %u Wireshark %s %s",
652 RT_TCP_UDP, port, NETSH_DENY, addr);
655 /* The destroy call back has the responsibility of
656 * unlinking the temporary file
657 * and freeing the filter_out_filter */
659 firewall_destroy_cb(GtkWidget *w, gpointer data _U_)
661 rule_info_t *rule_info;
663 rule_info = OBJECT_GET_DATA(w, WS_RULE_INFO_KEY);
664 forget_rule_info(rule_info);
670 firewall_copy_cmd_cb(GtkWidget *w _U_, gpointer data)
672 rule_info_t *rule_info = data;
674 GtkTextIter start, end;
677 buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(rule_info->text));
678 gtk_text_buffer_get_start_iter(buf, &start);
679 gtk_text_buffer_get_end_iter(buf, &end);
680 gtk_text_buffer_move_mark_by_name(buf, "insert", &start);
681 gtk_text_buffer_move_mark_by_name(buf, "selection_bound", &end);
682 gtk_text_buffer_copy_clipboard(buf, gtk_clipboard_get(GDK_SELECTION_CLIPBOARD));
686 * Keep a static pointer to the current "Save SSL Follow Stream As" window, if
687 * any, so that if somebody tries to do "Save"
688 * while there's already a "Save SSL Follow Stream" window up, we just pop
689 * up the existing one, rather than creating a new one.
692 firewall_save_as_cmd_cb(GtkWidget *w _U_, gpointer data)
695 rule_info_t *rule_info = data;
697 if (rule_info->firewall_save_as_w != NULL) {
698 /* There's already a dialog box; reactivate it. */
699 reactivate_window(rule_info->firewall_save_as_w);
703 new_win = file_selection_new("Wireshark: Save Firewall ACL Rule",
704 FILE_SELECTION_SAVE);
705 rule_info->firewall_save_as_w = new_win;
707 /* Tuck away the rule_info object into the window */
708 OBJECT_SET_DATA(new_win, WS_RULE_INFO_KEY, rule_info);
710 SIGNAL_CONNECT(new_win, "destroy", firewall_save_as_destroy_cb, rule_info);
712 #if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2
713 if (gtk_dialog_run(GTK_DIALOG(new_win)) == GTK_RESPONSE_ACCEPT)
715 firewall_save_as_ok_cb(new_win, new_win);
717 window_destroy(new_win);
720 /* Connect the ok_button to file_save_as_ok_cb function and pass along a
721 pointer to the file selection box widget */
722 SIGNAL_CONNECT(GTK_FILE_SELECTION(new_win)->ok_button,
723 "clicked", firewall_save_as_ok_cb, new_win);
725 window_set_cancel_button(new_win,
726 GTK_FILE_SELECTION(new_win)->cancel_button, window_cancel_button_cb);
728 gtk_file_selection_set_filename(GTK_FILE_SELECTION(new_win), "");
730 SIGNAL_CONNECT(new_win, "delete_event", window_delete_event_cb, NULL);
732 gtk_widget_show_all(new_win);
733 window_present(new_win);
739 firewall_save_as_ok_cb(GtkWidget * w _U_, gpointer fs)
741 gchar *to_name, *rule;
742 rule_info_t *rule_info;
746 GtkTextIter start, end;
749 #if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2
750 to_name = g_strdup(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fs)));
752 to_name = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(fs)));
755 /* Perhaps the user specified a directory instead of a file.
756 Check whether they did. */
757 if (test_for_directory(to_name) == EISDIR) {
758 /* It's a directory - set the file selection box to display that
759 directory, and leave the selection box displayed. */
760 set_last_open_dir(to_name);
762 file_selection_set_current_folder(fs, get_last_open_dir());
766 rule_info = OBJECT_GET_DATA(fs, WS_RULE_INFO_KEY);
767 fh = eth_fopen(to_name, "w");
769 open_failure_alert_box(to_name, errno, TRUE);
774 buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(rule_info->text));
775 gtk_text_buffer_get_start_iter(buf, &start);
776 gtk_text_buffer_get_end_iter(buf, &end);
777 rule = gtk_text_buffer_get_text(buf, &start, &end, FALSE);
782 gtk_widget_hide(GTK_WIDGET(fs));
783 window_destroy(GTK_WIDGET(fs));
785 /* Save the directory name for future file dialogs. */
786 dirname = get_dirname(to_name); /* Overwrites to_name */
787 set_last_open_dir(dirname);
792 firewall_save_as_destroy_cb(GtkWidget * win _U_, gpointer data)
794 rule_info_t *rule_info = data;
796 /* Note that we no longer have a dialog box. */
797 rule_info->firewall_save_as_w = NULL;