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 #if GTK_MAJOR_VERSION >= 2
274 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(txt_scrollw),
277 gtk_box_pack_start(GTK_BOX(vbox), txt_scrollw, TRUE, TRUE, 0);
279 /* create a text box */
280 #if GTK_MAJOR_VERSION < 2
281 text = gtk_text_new(NULL, NULL);
282 gtk_text_set_editable(GTK_TEXT(text), FALSE);
284 text = gtk_text_view_new();
285 gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE);
287 gtk_container_add(GTK_CONTAINER(txt_scrollw), text);
288 rule_info->text = text;
291 button_hbox = gtk_hbutton_box_new();
292 gtk_box_pack_start(GTK_BOX(vbox), button_hbox, FALSE, FALSE, 0);
293 gtk_button_box_set_layout (GTK_BUTTON_BOX(button_hbox), GTK_BUTTONBOX_END);
294 gtk_button_box_set_spacing(GTK_BUTTON_BOX(button_hbox), 5);
296 /* Create Copy Button */
297 button = BUTTON_NEW_FROM_STOCK(GTK_STOCK_COPY);
298 SIGNAL_CONNECT(button, "clicked", firewall_copy_cmd_cb, rule_info);
299 gtk_tooltips_set_tip (tooltips, button, "Copy rule to clipboard ", NULL);
300 gtk_box_pack_start(GTK_BOX(button_hbox), button, FALSE, FALSE, 0);
302 /* Create Save As Button */
303 button = BUTTON_NEW_FROM_STOCK(GTK_STOCK_SAVE_AS);
304 SIGNAL_CONNECT(button, "clicked", firewall_save_as_cmd_cb, rule_info);
305 gtk_tooltips_set_tip (tooltips, button, "Save the rule as currently displayed ", NULL);
306 gtk_box_pack_start(GTK_BOX(button_hbox), button, FALSE, FALSE, 0);
308 /* Create Close Button */
309 button = BUTTON_NEW_FROM_STOCK(GTK_STOCK_CLOSE);
310 gtk_tooltips_set_tip (tooltips, button,
311 "Close the dialog", NULL);
312 gtk_box_pack_start(GTK_BOX(button_hbox), button, FALSE, FALSE, 0);
313 GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
315 window_set_cancel_button(rule_w, button, window_cancel_button_cb);
317 /* Tuck away the rule_info object into the window */
318 OBJECT_SET_DATA(rule_w, WS_RULE_INFO_KEY, rule_info);
320 SIGNAL_CONNECT(rule_w, "delete_event", window_delete_event_cb, NULL);
321 SIGNAL_CONNECT(rule_w, "destroy", firewall_destroy_cb, NULL);
323 /* Make sure this widget gets destroyed if we quit the main loop,
324 so that if we exit, we clean up any temporary files we have
325 for "Follow SSL Stream" windows. */
326 gtk_quit_add_destroy(gtk_main_level(), GTK_OBJECT(rule_w));
328 gtk_widget_show_all(rule_w);
329 window_present(rule_w);
330 gtk_option_menu_set_history(GTK_OPTION_MENU(product_om), 0);
331 select_product(rule_w, GUINT_TO_POINTER(0));
334 /* Set the current product. */
335 #define ADD_TO_FILTER_MENU(rt) \
336 menu_item = gtk_menu_item_new_with_label(name); \
337 SIGNAL_CONNECT(menu_item, "activate", select_filter, \
338 GUINT_TO_POINTER(rt)); \
339 OBJECT_SET_DATA(menu_item, WS_RULE_INFO_KEY, rule_info); \
340 gtk_menu_append(GTK_MENU(menu), menu_item); \
343 first_mi = menu_item; \
347 #define NAME_TCP_UDP (rule_info->ptype == PT_TCP ? "TCP" : "UDP")
349 select_product(GtkWidget *w, gpointer data)
351 guint prod = GPOINTER_TO_UINT(data);
352 rule_info_t *rule_info;
353 gchar name[MAX_RULE_LEN], addr_str[MAX_RULE_LEN];
355 GtkWidget *menu, *menu_item, *first_mi = NULL;
356 rule_type_t rule_type = RT_NONE;
357 gboolean rt_set = FALSE, sensitive = FALSE;
359 rule_info = OBJECT_GET_DATA(w, WS_RULE_INFO_KEY);
361 if (prod >= NUM_PRODS || !rule_info)
364 rule_info->product = prod;
367 gtk_option_menu_remove_menu(GTK_OPTION_MENU(rule_info->filter_om));
368 menu = gtk_menu_new();
369 gtk_option_menu_set_menu(GTK_OPTION_MENU(rule_info->filter_om), menu);
371 /* Fill in valid menu items. */
372 if (products[prod].mac_func && rule_info->dl_src.type == AT_ETHER) {
373 addr = &(rule_info->dl_src);
374 address_to_str_buf(addr, name, MAX_RULE_LEN);
375 ADD_TO_FILTER_MENU(RT_MAC_SRC);
377 addr = &(rule_info->dl_dst);
378 address_to_str_buf(addr, name, MAX_RULE_LEN);
379 ADD_TO_FILTER_MENU(RT_MAC_DST);
382 if (products[prod].ipv4_func && rule_info->net_src.type == AT_IPv4) {
383 addr = &(rule_info->net_src);
384 address_to_str_buf(addr, name, MAX_RULE_LEN);
385 ADD_TO_FILTER_MENU(RT_IPv4_SRC);
387 addr = &(rule_info->net_dst);
388 address_to_str_buf(addr, name, MAX_RULE_LEN);
389 ADD_TO_FILTER_MENU(RT_IPv4_DST);
392 if (products[prod].port_func && (rule_info->ptype == PT_TCP || rule_info->ptype == PT_UDP)) {
393 g_snprintf(name, MAX_RULE_LEN, "%s port %u", NAME_TCP_UDP,
395 ADD_TO_FILTER_MENU(RT_PORT_SRC);
396 if (rule_info->srcport != rule_info->destport) {
397 g_snprintf(name, MAX_RULE_LEN, "%s port %u", NAME_TCP_UDP,
398 rule_info->destport);
399 ADD_TO_FILTER_MENU(RT_PORT_DST);
403 if (products[prod].ipv4_port_func && rule_info->net_src.type == AT_IPv4 &&
404 (rule_info->ptype == PT_TCP || rule_info->ptype == PT_UDP)) {
405 addr = &(rule_info->net_src);
406 address_to_str_buf(addr, addr_str, MAX_RULE_LEN);
407 g_snprintf(name, MAX_RULE_LEN, "%s + %s port %u", addr_str,
408 NAME_TCP_UDP, rule_info->srcport);
409 ADD_TO_FILTER_MENU(RT_IPv4_PORT_SRC);
411 addr = &(rule_info->net_dst);
412 address_to_str_buf(addr, addr_str, MAX_RULE_LEN);
413 g_snprintf(name, MAX_RULE_LEN, "%s + %s port %u", addr_str,
414 NAME_TCP_UDP, rule_info->destport);
415 ADD_TO_FILTER_MENU(RT_IPv4_PORT_DST);
419 if (rule_type != RT_NONE) {
420 gtk_widget_show_all(rule_info->filter_om);
421 gtk_option_menu_set_history(GTK_OPTION_MENU(rule_info->filter_om), 0);
424 gtk_widget_set_sensitive(rule_info->filter_om, sensitive);
425 gtk_widget_set_sensitive(rule_info->inbound_cb,
426 products[prod].does_inbound && sensitive);
427 gtk_widget_set_sensitive(rule_info->deny_cb, sensitive);
429 select_filter(w, GUINT_TO_POINTER(rule_type));
432 /* Set the current product. */
434 select_filter(GtkWidget *w, gpointer data)
436 rule_type_t cur_type = GPOINTER_TO_UINT(data);
437 rule_info_t *rule_info;
439 rule_info = OBJECT_GET_DATA(w, WS_RULE_INFO_KEY);
441 if (cur_type >= NUM_RULE_TYPES || !rule_info)
444 rule_info->rule_type = cur_type;
446 set_rule_text(rule_info);
449 /* Set inbound/outbound */
451 toggle_inbound(GtkToggleButton *t, gpointer data)
453 rule_info_t *rule_info = (rule_info_t *) data;
455 rule_info->inbound = gtk_toggle_button_get_active(t);
457 set_rule_text(rule_info);
460 /* Set deny/allow. */
462 toggle_deny(GtkToggleButton *t, gpointer data)
464 rule_info_t *rule_info = (rule_info_t *) data;
466 rule_info->deny = gtk_toggle_button_get_active(t);
468 set_rule_text(rule_info);
471 /* Set the rule text */
472 #define DL_ADDR (rt == RT_MAC_SRC ? &(rule_info->dl_src) : &(rule_info->dl_dst))
473 #define NET_ADDR (rt == RT_IPv4_SRC ? &(rule_info->net_src) : &(rule_info->net_dst))
474 #define NET_PORT (rt == RT_PORT_SRC ? rule_info->srcport : rule_info->destport)
476 set_rule_text(rule_info_t *rule_info) {
477 GString *rtxt = g_string_new("");
478 gchar addr_str[MAX_RULE_LEN];
479 rule_type_t rt = rule_info->rule_type;
480 guint prod = rule_info->product;
481 address *addr = NULL;
483 syntax_func rt_func = NULL;
485 #if GTK_MAJOR_VERSION < 2
488 GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(rule_info->text));
491 if (prod < NUM_PRODS) {
492 g_string_sprintf(rtxt, "%s %s\n", products[prod].comment_pfx, products[prod].name);
495 g_string_sprintfa(rtxt, "%s Not supported", products[prod].comment_pfx);
501 address_to_str_buf(addr, addr_str, MAX_RULE_LEN);
502 rt_func = products[prod].mac_func;
507 address_to_str_buf(addr, addr_str, MAX_RULE_LEN);
508 rt_func = products[prod].ipv4_func;
513 rt_func = products[prod].port_func;
515 case RT_IPv4_PORT_SRC:
516 case RT_IPv4_PORT_DST:
518 address_to_str_buf(addr, addr_str, MAX_RULE_LEN);
520 rt_func = products[prod].ipv4_port_func;
528 rt_func(rtxt, addr_str, port, rule_info->ptype, rule_info->inbound, rule_info->deny);
530 g_string_sprintfa(rtxt, "ERROR: Unable to create rule");
533 #if GTK_MAJOR_VERSION < 2
534 txtlen = gtk_text_get_length(GTK_TEXT(rule_info->text));
536 gtk_text_set_point(GTK_TEXT(rule_info->text), 0);
537 gtk_text_forward_delete(GTK_TEXT(rule_info->text), txtlen);
539 gtk_text_insert(GTK_TEXT(rule_info->text), user_font_get_regular(),
540 NULL, NULL, rtxt->str, rtxt->len);
542 gtk_text_buffer_set_text(buf, rtxt->str, rtxt->len);
545 g_string_free(rtxt, TRUE);
549 /* Rule text functions */
551 static void sf_dummy(GString *rtxt _U_, gchar *addr _U_, guint32 port _U_, port_type ptype _U_, gboolean inbound _U_, gboolean deny _U_) {
555 #define IPFW_DENY (deny ? "deny" : "allow")
556 #define IPFW_IN (inbound ? "in" : "out")
557 static void sf_ipfw_mac(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
558 g_string_sprintfa(rtxt, "add %s MAC %s any %s",
559 IPFW_DENY, addr, IPFW_IN);
562 #define NF_DROP (deny ? "DROP" : "ACCEPT")
563 #define NF_INPUT (inbound ? "INPUT" : "OUTPUT")
564 static void sf_netfilter_mac(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
565 g_string_sprintfa(rtxt, "iptables -A %s --mac-source %s -j %s",
566 NF_INPUT, addr, NF_DROP);
570 #define IOS_DENY (deny ? "deny" : "permit")
571 static void sf_ios_std_ipv4(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound _U_, gboolean deny) {
572 g_string_sprintfa(rtxt, "access-list NUMBER %s host %s", IOS_DENY, addr);
575 static void sf_ios_ext_ipv4(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
577 g_string_sprintfa(rtxt, "access-list NUMBER %s ip host %s any", IOS_DENY, addr);
579 g_string_sprintfa(rtxt, "access-list NUMBER %s ip any host %s", IOS_DENY, addr);
582 #define IPFILTER_DENY (deny ? "block" : "pass")
583 #define IPFILTER_IN (inbound ? "in" : "out")
584 static void sf_ipfilter_ipv4(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
585 g_string_sprintfa(rtxt, "%s %s on le0 from %s to any",
586 IPFILTER_DENY, IPFILTER_IN, addr);
589 static void sf_ipfw_ipv4(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
590 g_string_sprintfa(rtxt, "add %s ip from %s to any %s",
591 IPFW_DENY, addr, IPFW_IN);
594 static void sf_netfilter_ipv4(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
595 g_string_sprintfa(rtxt, "iptables -A %s -i eth0 -d %s/32 -j %s",
596 NF_INPUT, addr, NF_DROP);
599 #define PF_DENY (deny ? "block" : "pass")
600 #define PF_IN (inbound ? "in" : "out")
601 static void sf_pf_ipv4(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
602 g_string_sprintfa(rtxt, "%s %s quick on $ext_if from %s to any",
603 PF_DENY, PF_IN, addr);
607 #define RT_TCP_UDP (ptype == PT_TCP ? "tcp" : "udp")
608 static void sf_ios_ext_port(GString *rtxt, gchar *addr _U_, guint32 port, port_type ptype, gboolean inbound _U_, gboolean deny) {
609 g_string_sprintfa(rtxt, "access-list NUMBER %s %s any any eq %u",
610 IOS_DENY, RT_TCP_UDP, port);
613 static void sf_ipfilter_port(GString *rtxt, gchar *addr _U_, guint32 port, port_type ptype _U_, gboolean inbound, gboolean deny) {
614 g_string_sprintfa(rtxt, "%s %s on le0 proto %s from any to any port = %u",
615 IPFILTER_DENY, IPFILTER_IN, RT_TCP_UDP, port);
618 static void sf_ipfw_port(GString *rtxt, gchar *addr _U_, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
619 g_string_sprintfa(rtxt, "add %s %s from any to any %u %s",
620 IPFW_DENY, RT_TCP_UDP, port, IPFW_IN);
623 static void sf_netfilter_port(GString *rtxt, gchar *addr _U_, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
624 g_string_sprintfa(rtxt, "iptables -A %s -p %s --destination-port %u -j %s",
625 NF_INPUT, RT_TCP_UDP, port, NF_DROP);
628 static void sf_pf_port(GString *rtxt, gchar *addr _U_, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
629 g_string_sprintfa(rtxt, "%s %s quick on $ext_if proto %s from any to any port %u",
630 PF_DENY, PF_IN, RT_TCP_UDP, port);
633 #define NETSH_DENY (deny ? "DISABLE" : "ENABLE")
634 static void sf_netsh_port(GString *rtxt, gchar *addr _U_, guint32 port, port_type ptype, gboolean inbound _U_, gboolean deny) {
635 g_string_sprintfa(rtxt, "add portopening %s %u Wireshark %s",
636 RT_TCP_UDP, port, NETSH_DENY);
640 static void sf_ios_ext_ipv4_port(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
642 g_string_sprintfa(rtxt, "access-list NUMBER %s %s host %s any eq %u", IOS_DENY, RT_TCP_UDP, addr, port);
644 g_string_sprintfa(rtxt, "access-list NUMBER %s %s any host %s eq %u", IOS_DENY, RT_TCP_UDP, addr, port);
647 static void sf_ipfilter_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
649 g_string_sprintfa(rtxt, "%s %s on le0 proto %s from %s to any port = %u",
650 IPFILTER_DENY, IPFILTER_IN, RT_TCP_UDP, addr, port);
652 g_string_sprintfa(rtxt, "%s %s on le0 proto %s from any to %s port = %u",
653 IPFILTER_DENY, IPFILTER_IN, RT_TCP_UDP, addr, port);
656 static void sf_ipfw_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
657 g_string_sprintfa(rtxt, "add %s %s from %s to any %u %s",
658 IPFW_DENY, RT_TCP_UDP, addr, port, IPFW_IN);
661 static void sf_pf_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
662 g_string_sprintfa(rtxt, "%s %s quick on $ext_if proto %s from %s to any port %u",
663 PF_DENY, PF_IN, RT_TCP_UDP, addr, port);
666 static void sf_netfilter_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
667 g_string_sprintfa(rtxt, "iptables -A %s -p %s -d %s/32 --destination-port %u -j %s",
668 NF_INPUT, RT_TCP_UDP, addr, port, NF_DROP);
671 static void sf_netsh_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound _U_, gboolean deny) {
672 g_string_sprintfa(rtxt, "add portopening %s %u Wireshark %s %s",
673 RT_TCP_UDP, port, NETSH_DENY, addr);
676 /* The destroy call back has the responsibility of
677 * unlinking the temporary file
678 * and freeing the filter_out_filter */
680 firewall_destroy_cb(GtkWidget *w, gpointer data _U_)
682 rule_info_t *rule_info;
684 rule_info = OBJECT_GET_DATA(w, WS_RULE_INFO_KEY);
685 forget_rule_info(rule_info);
691 firewall_copy_cmd_cb(GtkWidget *w _U_, gpointer data)
693 rule_info_t *rule_info = data;
695 #if GTK_MAJOR_VERSION >= 2
696 GtkTextIter start, end;
700 #if GTK_MAJOR_VERSION < 2
701 gtk_editable_select_region(GTK_EDITABLE(rule_info->text), 0, -1);
702 gtk_editable_copy_clipboard(GTK_EDITABLE(rule_info->text));
704 buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(rule_info->text));
705 gtk_text_buffer_get_start_iter(buf, &start);
706 gtk_text_buffer_get_end_iter(buf, &end);
707 gtk_text_buffer_move_mark_by_name(buf, "insert", &start);
708 gtk_text_buffer_move_mark_by_name(buf, "selection_bound", &end);
709 gtk_text_buffer_copy_clipboard(buf, gtk_clipboard_get(GDK_SELECTION_CLIPBOARD));
714 * Keep a static pointer to the current "Save SSL Follow Stream As" window, if
715 * any, so that if somebody tries to do "Save"
716 * while there's already a "Save SSL Follow Stream" window up, we just pop
717 * up the existing one, rather than creating a new one.
720 firewall_save_as_cmd_cb(GtkWidget *w _U_, gpointer data)
723 rule_info_t *rule_info = data;
725 if (rule_info->firewall_save_as_w != NULL) {
726 /* There's already a dialog box; reactivate it. */
727 reactivate_window(rule_info->firewall_save_as_w);
731 new_win = file_selection_new("Wireshark: Save Firewall ACL Rule",
732 FILE_SELECTION_SAVE);
733 rule_info->firewall_save_as_w = new_win;
735 /* Tuck away the rule_info object into the window */
736 OBJECT_SET_DATA(new_win, WS_RULE_INFO_KEY, rule_info);
738 SIGNAL_CONNECT(new_win, "destroy", firewall_save_as_destroy_cb, rule_info);
740 #if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2
741 if (gtk_dialog_run(GTK_DIALOG(new_win)) == GTK_RESPONSE_ACCEPT)
743 firewall_save_as_ok_cb(new_win, new_win);
745 window_destroy(new_win);
748 /* Connect the ok_button to file_save_as_ok_cb function and pass along a
749 pointer to the file selection box widget */
750 SIGNAL_CONNECT(GTK_FILE_SELECTION(new_win)->ok_button,
751 "clicked", firewall_save_as_ok_cb, new_win);
753 window_set_cancel_button(new_win,
754 GTK_FILE_SELECTION(new_win)->cancel_button, window_cancel_button_cb);
756 gtk_file_selection_set_filename(GTK_FILE_SELECTION(new_win), "");
758 SIGNAL_CONNECT(new_win, "delete_event", window_delete_event_cb, NULL);
760 gtk_widget_show_all(new_win);
761 window_present(new_win);
767 firewall_save_as_ok_cb(GtkWidget * w _U_, gpointer fs)
769 gchar *to_name, *rule;
770 rule_info_t *rule_info;
774 #if GTK_MAJOR_VERSION >= 2
775 GtkTextIter start, end;
779 #if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2
780 to_name = g_strdup(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fs)));
782 to_name = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(fs)));
785 /* Perhaps the user specified a directory instead of a file.
786 Check whether they did. */
787 if (test_for_directory(to_name) == EISDIR) {
788 /* It's a directory - set the file selection box to display that
789 directory, and leave the selection box displayed. */
790 set_last_open_dir(to_name);
792 file_selection_set_current_folder(fs, get_last_open_dir());
796 rule_info = OBJECT_GET_DATA(fs, WS_RULE_INFO_KEY);
797 fh = eth_fopen(to_name, "w");
799 open_failure_alert_box(to_name, errno, TRUE);
804 #if GTK_MAJOR_VERSION < 2
805 rule = gtk_editable_get_chars(GTK_EDITABLE(rule_info->text), 0, -1);
807 buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(rule_info->text));
808 gtk_text_buffer_get_start_iter(buf, &start);
809 gtk_text_buffer_get_end_iter(buf, &end);
810 rule = gtk_text_buffer_get_text(buf, &start, &end, FALSE);
815 #if GTK_MAJOR_VERSION < 2 /* XXX - Does this apply for gtk_text_buffer_get_text () as well? */
819 gtk_widget_hide(GTK_WIDGET(fs));
820 window_destroy(GTK_WIDGET(fs));
822 /* Save the directory name for future file dialogs. */
823 dirname = get_dirname(to_name); /* Overwrites to_name */
824 set_last_open_dir(dirname);
829 firewall_save_as_destroy_cb(GtkWidget * win _U_, gpointer data)
831 rule_info_t *rule_info = data;
833 /* Note that we no longer have a dialog box. */
834 rule_info->firewall_save_as_w = NULL;