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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 */
52 #include <epan/packet.h>
53 #include <epan/addr_resolv.h>
54 #include <epan/epan_dissect.h>
55 #include <epan/filesystem.h>
56 #include <epan/dissectors/packet-ipv6.h>
58 #include <ui/alert_box.h>
59 #include <ui/last_open_dir.h>
61 #include <wsutil/file_util.h>
63 #include "ui/gtk/main.h"
64 #include "ui/gtk/dlg_utils.h"
65 #include "ui/gtk/file_dlg.h"
66 #include "ui/gtk/help_dlg.h"
67 #include "ui/gtk/gui_utils.h"
68 #include "ui/gtk/old-gtk-compat.h"
69 #include "ui/gtk/firewall_dlg.h"
71 #define MAX_RULE_LEN 200
88 /* Copied from packet_info struct */
89 typedef struct _rule_info_t
{
99 GtkWidget
*filter_combo_box
;
101 GtkWidget
*inbound_cb
;
104 rule_type_t rule_type
;
107 /* Syntax function prototypes */
108 typedef void (*syntax_func
)(GString
*rtxt
, gchar
*addr
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
);
110 static void sf_dummy(GString
*rtxt
, gchar
*addr
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
);
112 static void sf_ipfw_mac(GString
*rtxt
, gchar
*addr
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
);
113 static void sf_netfilter_mac(GString
*rtxt
, gchar
*addr
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
);
115 static void sf_ios_std_ipv4(GString
*rtxt
, gchar
*addr
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
);
116 static void sf_ios_ext_ipv4(GString
*rtxt
, gchar
*addr
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
);
117 static void sf_ipfilter_ipv4(GString
*rtxt
, gchar
*addr
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
);
118 static void sf_ipfw_ipv4(GString
*rtxt
, gchar
*addr
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
);
119 static void sf_netfilter_ipv4(GString
*rtxt
, gchar
*addr
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
);
120 static void sf_pf_ipv4(GString
*rtxt
, gchar
*addr
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
);
121 /* XXX - Can you addresses-only filters using WFW/netsh? */
123 static void sf_ios_ext_port(GString
*rtxt
, gchar
*addr
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
);
124 static void sf_ipfilter_port(GString
*rtxt
, gchar
*addr
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
);
125 static void sf_ipfw_port(GString
*rtxt
, gchar
*addr
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
);
126 static void sf_netfilter_port(GString
*rtxt
, gchar
*addr
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
);
127 static void sf_pf_port(GString
*rtxt
, gchar
*addr
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
);
128 static void sf_netsh_port(GString
*rtxt
, gchar
*addr
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
);
130 static void sf_ios_ext_ipv4_port(GString
*rtxt
, gchar
*addr
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
);
131 static void sf_ipfilter_ipv4_port(GString
*rtxt
, gchar
*addr
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
);
132 static void sf_ipfw_ipv4_port(GString
*rtxt
, gchar
*addr
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
);
133 static void sf_netfilter_ipv4_port(GString
*rtxt
, gchar
*addr
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
);
134 static void sf_pf_ipv4_port(GString
*rtxt
, gchar
*addr
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
);
135 static void sf_netsh_ipv4_port(GString
*rtxt
, gchar
*addr
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
);
137 typedef struct _fw_product_t
{
139 const gchar
*comment_pfx
;
140 syntax_func mac_func
;
141 syntax_func ipv4_func
;
142 syntax_func port_func
;
143 syntax_func ipv4_port_func
;
144 gboolean does_inbound
;
147 static fw_product products
[] = {
148 { "Cisco IOS (standard)", "!", NULL
, sf_ios_std_ipv4
, NULL
, NULL
, FALSE
},
149 { "Cisco IOS (extended)", "!",
150 NULL
, sf_ios_ext_ipv4
, sf_ios_ext_port
, sf_ios_ext_ipv4_port
, TRUE
},
151 { "IP Filter (ipfilter)", "#",
152 NULL
, sf_ipfilter_ipv4
, sf_ipfilter_port
, sf_ipfilter_ipv4_port
, TRUE
},
153 { "IPFirewall (ipfw)", "#",
154 sf_ipfw_mac
, sf_ipfw_ipv4
, sf_ipfw_port
, sf_ipfw_ipv4_port
, TRUE
},
155 { "Netfilter (iptables)", "#",
156 sf_netfilter_mac
, sf_netfilter_ipv4
, sf_netfilter_port
,
157 sf_netfilter_ipv4_port
, TRUE
},
158 { "Packet Filter (pf)", "#",
159 NULL
, sf_pf_ipv4
, sf_pf_port
, sf_pf_ipv4_port
, TRUE
},
160 { "Windows Firewall (netsh)", "#",
161 NULL
, NULL
, sf_netsh_port
, sf_netsh_ipv4_port
, FALSE
}
163 #define NUM_PRODS (sizeof(products) / sizeof(fw_product))
166 static void select_product(GtkWidget
* win
, gpointer data
);
167 static void select_filter(GtkWidget
* win
, gpointer data
);
168 static void toggle_inbound(GtkToggleButton
*t
, gpointer data
);
169 static void toggle_deny(GtkToggleButton
*t
, gpointer data
);
170 static void set_rule_text(rule_info_t
*rule_info
);
171 static void firewall_destroy_cb(GtkWidget
* win
, gpointer data
);
172 static void firewall_copy_cmd_cb(GtkWidget
* w
, gpointer data
);
173 static void firewall_save_as_cmd_cb(GtkWidget
* w
, gpointer data
);
175 #define WS_RULE_INFO_KEY "rule_info_key"
178 /* List of "rule_info_t" structures for all rule windows. */
179 static GList
*rule_infos
;
181 /* Remove a "rule_info_t" structure from the list. */
183 forget_rule_info(rule_info_t
*rule_info
)
185 rule_infos
= g_list_remove(rule_infos
, rule_info
);
190 firewall_rule_cb(GtkWidget
*w _U_
, gpointer data _U_
)
192 GtkWidget
*rule_w
, *vbox
, *txt_scrollw
, *text
;
193 GtkWidget
*label
, *product_combo_box
;
194 GtkWidget
*hbox
, *button_hbox
, *button
;
195 rule_info_t
*rule_info
;
196 packet_info
*pinfo
= &cfile
.edt
->pi
;
199 rule_info
= g_new0(rule_info_t
, 1);
200 COPY_ADDRESS(&(rule_info
->dl_src
), &(pinfo
->dl_src
));
201 COPY_ADDRESS(&(rule_info
->dl_dst
), &(pinfo
->dl_dst
));
202 COPY_ADDRESS(&(rule_info
->net_src
), &(pinfo
->net_src
));
203 COPY_ADDRESS(&(rule_info
->net_dst
), &(pinfo
->net_dst
));
204 rule_info
->ptype
= pinfo
->ptype
;
205 rule_info
->srcport
= pinfo
->srcport
;
206 rule_info
->destport
= pinfo
->destport
;
207 rule_info
->inbound
= TRUE
;
208 rule_info
->deny
= TRUE
;
209 rule_info
->product
= 0;
211 rule_w
= dlg_window_new("Firewall ACL Rules");
213 gtk_widget_set_name(rule_w
, "Firewall ACL rule window");
214 gtk_container_set_border_width(GTK_CONTAINER(rule_w
), 6);
216 /* setup the container */
217 vbox
= ws_gtk_box_new(GTK_ORIENTATION_VERTICAL
, 6, FALSE
);
218 gtk_container_add(GTK_CONTAINER(rule_w
), vbox
);
220 /* rule type selectors hbox */
221 hbox
= ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 1, FALSE
);
222 gtk_box_pack_start(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
224 /* product selector */
225 label
= gtk_label_new("Product");
226 gtk_box_pack_start(GTK_BOX(hbox
), label
, FALSE
, FALSE
, 0);
228 product_combo_box
= gtk_combo_box_text_new();
229 for (i
= 0; i
< NUM_PRODS
; i
++) {
230 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(product_combo_box
), products
[i
].name
);
232 g_object_set_data(G_OBJECT(product_combo_box
), WS_RULE_INFO_KEY
, rule_info
);
233 g_signal_connect(product_combo_box
, "changed", G_CALLBACK(select_product
), NULL
);
234 gtk_box_pack_start(GTK_BOX(hbox
), product_combo_box
, FALSE
, FALSE
, 5);
237 label
= gtk_label_new("Filter");
238 gtk_box_pack_start(GTK_BOX(hbox
), label
, FALSE
, FALSE
, 10);
240 rule_info
->filter_combo_box
= ws_combo_box_new_text_and_pointer();
241 g_object_set_data(G_OBJECT(rule_info
->filter_combo_box
), WS_RULE_INFO_KEY
, rule_info
); \
242 g_signal_connect(rule_info
->filter_combo_box
, "changed", G_CALLBACK(select_filter
), NULL
);
243 gtk_box_pack_start(GTK_BOX(hbox
), rule_info
->filter_combo_box
, FALSE
, FALSE
, 5);
245 /* inbound selector */
246 rule_info
->inbound_cb
= gtk_check_button_new_with_label("Inbound");
247 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rule_info
->inbound_cb
),
249 gtk_box_pack_start(GTK_BOX(hbox
), rule_info
->inbound_cb
, FALSE
, FALSE
, 10);
250 g_signal_connect(rule_info
->inbound_cb
, "toggled", G_CALLBACK(toggle_inbound
), rule_info
);
253 rule_info
->deny_cb
= gtk_check_button_new_with_label("Deny");
254 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rule_info
->deny_cb
),
256 gtk_box_pack_start(GTK_BOX(hbox
), rule_info
->deny_cb
, FALSE
, FALSE
, 10);
257 g_signal_connect(rule_info
->deny_cb
, "toggled", G_CALLBACK(toggle_deny
), rule_info
);
259 /* create a scrolled window for the text */
260 txt_scrollw
= scrolled_window_new(NULL
, NULL
);
261 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(txt_scrollw
),
263 gtk_box_pack_start(GTK_BOX(vbox
), txt_scrollw
, TRUE
, TRUE
, 0);
265 /* create a text box */
266 text
= gtk_text_view_new();
267 gtk_text_view_set_editable(GTK_TEXT_VIEW(text
), FALSE
);
268 gtk_container_add(GTK_CONTAINER(txt_scrollw
), text
);
269 rule_info
->text
= text
;
272 button_hbox
= dlg_button_row_new(GTK_STOCK_HELP
, GTK_STOCK_COPY
, GTK_STOCK_SAVE
, GTK_STOCK_CANCEL
, NULL
);
273 gtk_box_pack_start(GTK_BOX(vbox
), button_hbox
, FALSE
, FALSE
, 0);
275 /* Create Copy Button */
276 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(button_hbox
), GTK_STOCK_COPY
);
277 g_signal_connect(button
, "clicked", G_CALLBACK(firewall_copy_cmd_cb
), rule_info
);
278 gtk_widget_set_tooltip_text(button
, "Copy rule to clipboard");
280 /* Create Save Button */
281 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(button_hbox
), GTK_STOCK_SAVE
);
282 g_signal_connect(button
, "clicked", G_CALLBACK(firewall_save_as_cmd_cb
), rule_info
);
283 gtk_widget_set_tooltip_text(button
, "Save the rule as currently displayed");
285 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(button_hbox
), GTK_STOCK_CANCEL
);
286 gtk_widget_set_tooltip_text(button
, "Cancel the dialog");
287 window_set_cancel_button(rule_w
, button
, window_cancel_button_cb
);
289 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(button_hbox
), GTK_STOCK_HELP
);
290 g_signal_connect(button
, "clicked", G_CALLBACK(topic_cb
), (gpointer
)HELP_FIREWALL_DIALOG
);
292 /* Tuck away the rule_info object into the window */
293 g_object_set_data(G_OBJECT(rule_w
), WS_RULE_INFO_KEY
, rule_info
);
295 g_signal_connect(rule_w
, "delete_event", G_CALLBACK(window_delete_event_cb
), NULL
);
296 g_signal_connect(rule_w
, "destroy", G_CALLBACK(firewall_destroy_cb
), NULL
);
298 /* Make sure this widget gets destroyed if we quit the main loop,
299 so that if we exit, we clean up any temporary files we have
300 for "Follow SSL Stream" windows.
301 gtk_quit_add_destroy is deprecated and should not be used in newly-written code. This function is going to be removed in GTK+ 3.0
303 gtk_quit_add_destroy(gtk_main_level(), GTK_OBJECT(rule_w));
307 gtk_combo_box_set_active(GTK_COMBO_BOX(product_combo_box
), 0); /* invokes select_product callback */
308 gtk_widget_show_all(rule_w
);
309 window_present(rule_w
);
312 /* Set the current product. */
313 #define ADD_TO_FILTER_MENU(rt) \
314 ws_combo_box_append_text_and_pointer(GTK_COMBO_BOX(rule_info->filter_combo_box), name, GUINT_TO_POINTER(rt)); \
315 if (rule_type == RT_NONE) { \
319 #define NAME_TCP_UDP (rule_info->ptype == PT_TCP ? "TCP" : "UDP")
322 select_product(GtkWidget
*w
, gpointer data _U_
)
324 guint prod
= gtk_combo_box_get_active(GTK_COMBO_BOX(w
));
325 rule_info_t
*rule_info
;
326 gchar name
[MAX_RULE_LEN
], addr_str
[MAX_RULE_LEN
];
328 rule_type_t rule_type
= RT_NONE
;
329 gboolean sensitive
= FALSE
;
331 rule_info
=(rule_info_t
*)g_object_get_data(G_OBJECT(w
), WS_RULE_INFO_KEY
);
333 if (prod
>= NUM_PRODS
|| !rule_info
)
336 rule_info
->product
= prod
;
338 /* Clear the list store (ie: the como_box list items) */
339 ws_combo_box_clear_text_and_pointer(GTK_COMBO_BOX(rule_info
->filter_combo_box
));
341 /* Fill in valid combo_box list items (in the list store). */
342 if (products
[prod
].mac_func
&& rule_info
->dl_src
.type
== AT_ETHER
) {
343 addr
= &(rule_info
->dl_src
);
344 address_to_str_buf(addr
, name
, MAX_RULE_LEN
);
345 ADD_TO_FILTER_MENU(RT_MAC_SRC
);
347 addr
= &(rule_info
->dl_dst
);
348 address_to_str_buf(addr
, name
, MAX_RULE_LEN
);
349 ADD_TO_FILTER_MENU(RT_MAC_DST
);
352 if (products
[prod
].ipv4_func
&& rule_info
->net_src
.type
== AT_IPv4
) {
353 addr
= &(rule_info
->net_src
);
354 address_to_str_buf(addr
, name
, MAX_RULE_LEN
);
355 ADD_TO_FILTER_MENU(RT_IPv4_SRC
);
357 addr
= &(rule_info
->net_dst
);
358 address_to_str_buf(addr
, name
, MAX_RULE_LEN
);
359 ADD_TO_FILTER_MENU(RT_IPv4_DST
);
362 if (products
[prod
].port_func
&& (rule_info
->ptype
== PT_TCP
|| rule_info
->ptype
== PT_UDP
)) {
363 g_snprintf(name
, MAX_RULE_LEN
, "%s port %u", NAME_TCP_UDP
,
365 ADD_TO_FILTER_MENU(RT_PORT_SRC
);
366 if (rule_info
->srcport
!= rule_info
->destport
) {
367 g_snprintf(name
, MAX_RULE_LEN
, "%s port %u", NAME_TCP_UDP
,
368 rule_info
->destport
);
369 ADD_TO_FILTER_MENU(RT_PORT_DST
);
373 if (products
[prod
].ipv4_port_func
&& rule_info
->net_src
.type
== AT_IPv4
&&
374 (rule_info
->ptype
== PT_TCP
|| rule_info
->ptype
== PT_UDP
)) {
375 addr
= &(rule_info
->net_src
);
376 address_to_str_buf(addr
, addr_str
, MAX_RULE_LEN
);
377 g_snprintf(name
, MAX_RULE_LEN
, "%s + %s port %u", addr_str
,
378 NAME_TCP_UDP
, rule_info
->srcport
);
379 ADD_TO_FILTER_MENU(RT_IPv4_PORT_SRC
);
381 addr
= &(rule_info
->net_dst
);
382 address_to_str_buf(addr
, addr_str
, MAX_RULE_LEN
);
383 g_snprintf(name
, MAX_RULE_LEN
, "%s + %s port %u", addr_str
,
384 NAME_TCP_UDP
, rule_info
->destport
);
385 ADD_TO_FILTER_MENU(RT_IPv4_PORT_DST
);
388 if (rule_type
!= RT_NONE
) {
389 gtk_combo_box_set_active(GTK_COMBO_BOX(rule_info
->filter_combo_box
), 0); /* invokes select_filter callback */
392 select_filter(rule_info
->filter_combo_box
, NULL
); /* Call if RT_NONE [with nothing selected] */
395 gtk_widget_set_sensitive(rule_info
->filter_combo_box
, sensitive
);
396 gtk_widget_set_sensitive(rule_info
->inbound_cb
, products
[prod
].does_inbound
&& sensitive
);
397 gtk_widget_set_sensitive(rule_info
->deny_cb
, sensitive
);
400 /* Set the rule text based upon the current product and current filter. */
402 select_filter(GtkWidget
*w
, gpointer data _U_
)
404 rule_type_t cur_type
;
405 rule_info_t
*rule_info
;
408 rule_info
= (rule_info_t
*)g_object_get_data(G_OBJECT(w
), WS_RULE_INFO_KEY
);
413 if (ws_combo_box_get_active_pointer(GTK_COMBO_BOX(w
), &ptr
))
414 cur_type
= (rule_type_t
)GPOINTER_TO_UINT(ptr
);
416 cur_type
= RT_NONE
; /* If nothing selected (eg: nothing in filter list) */
418 if (cur_type
>= NUM_RULE_TYPES
)
421 rule_info
->rule_type
= cur_type
;
423 set_rule_text(rule_info
);
426 /* Set inbound/outbound */
428 toggle_inbound(GtkToggleButton
*t
, gpointer data
)
430 rule_info_t
*rule_info
= (rule_info_t
*) data
;
432 rule_info
->inbound
= gtk_toggle_button_get_active(t
);
434 set_rule_text(rule_info
);
437 /* Set deny/allow. */
439 toggle_deny(GtkToggleButton
*t
, gpointer data
)
441 rule_info_t
*rule_info
= (rule_info_t
*) data
;
443 rule_info
->deny
= gtk_toggle_button_get_active(t
);
445 set_rule_text(rule_info
);
448 /* Set the rule text */
449 #define DL_ADDR (rt == RT_MAC_SRC ? &(rule_info->dl_src) : &(rule_info->dl_dst))
450 #define NET_ADDR (rt == RT_IPv4_SRC ? &(rule_info->net_src) : &(rule_info->net_dst))
451 #define NET_PORT (rt == RT_PORT_SRC ? rule_info->srcport : rule_info->destport)
453 set_rule_text(rule_info_t
*rule_info
) {
454 GString
*rtxt
= g_string_new("");
455 gchar addr_str
[MAX_RULE_LEN
];
456 rule_type_t rt
= rule_info
->rule_type
;
457 guint prod
= rule_info
->product
;
458 address
*addr
= NULL
;
460 syntax_func rt_func
= NULL
;
462 GtkTextBuffer
*buf
= gtk_text_view_get_buffer(GTK_TEXT_VIEW(rule_info
->text
));
464 if (prod
< NUM_PRODS
) {
465 g_string_printf(rtxt
, "%s %s\n", products
[prod
].comment_pfx
, products
[prod
].name
);
468 g_string_append_printf(rtxt
, "%s Not supported", products
[prod
].comment_pfx
);
474 address_to_str_buf(addr
, addr_str
, MAX_RULE_LEN
);
475 rt_func
= products
[prod
].mac_func
;
480 address_to_str_buf(addr
, addr_str
, MAX_RULE_LEN
);
481 rt_func
= products
[prod
].ipv4_func
;
486 rt_func
= products
[prod
].port_func
;
488 case RT_IPv4_PORT_SRC
:
489 case RT_IPv4_PORT_DST
:
491 address_to_str_buf(addr
, addr_str
, MAX_RULE_LEN
);
493 rt_func
= products
[prod
].ipv4_port_func
;
501 rt_func(rtxt
, addr_str
, port
, rule_info
->ptype
, rule_info
->inbound
, rule_info
->deny
);
503 g_string_append_printf(rtxt
, "ERROR: Unable to create rule");
506 gtk_text_buffer_set_text(buf
, rtxt
->str
, (gint
) rtxt
->len
);
508 g_string_free(rtxt
, TRUE
);
512 /* Rule text functions */
514 static void sf_dummy(GString
*rtxt _U_
, gchar
*addr _U_
, guint32 port _U_
, port_type ptype _U_
, gboolean inbound _U_
, gboolean deny _U_
) {
518 #define IPFW_DENY (deny ? "deny" : "allow")
519 #define IPFW_IN (inbound ? "in" : "out")
520 static void sf_ipfw_mac(GString
*rtxt
, gchar
*addr
, guint32 port _U_
, port_type ptype _U_
, gboolean inbound
, gboolean deny
) {
521 g_string_append_printf(rtxt
, "add %s MAC %s any %s",
522 IPFW_DENY
, addr
, IPFW_IN
);
525 #define NF_DROP (deny ? "DROP" : "ACCEPT")
526 #define NF_INPUT (inbound ? "INPUT" : "OUTPUT")
527 static void sf_netfilter_mac(GString
*rtxt
, gchar
*addr
, guint32 port _U_
, port_type ptype _U_
, gboolean inbound
, gboolean deny
) {
528 g_string_append_printf(rtxt
, "iptables -A %s --mac-source %s -j %s",
529 NF_INPUT
, addr
, NF_DROP
);
533 #define IOS_DENY (deny ? "deny" : "permit")
534 static void sf_ios_std_ipv4(GString
*rtxt
, gchar
*addr
, guint32 port _U_
, port_type ptype _U_
, gboolean inbound _U_
, gboolean deny
) {
535 g_string_append_printf(rtxt
, "access-list NUMBER %s host %s", IOS_DENY
, addr
);
538 static void sf_ios_ext_ipv4(GString
*rtxt
, gchar
*addr
, guint32 port _U_
, port_type ptype _U_
, gboolean inbound
, gboolean deny
) {
540 g_string_append_printf(rtxt
, "access-list NUMBER %s ip host %s any", IOS_DENY
, addr
);
542 g_string_append_printf(rtxt
, "access-list NUMBER %s ip any host %s", IOS_DENY
, addr
);
545 #define IPFILTER_DENY (deny ? "block" : "pass")
546 #define IPFILTER_IN (inbound ? "in" : "out")
547 static void sf_ipfilter_ipv4(GString
*rtxt
, gchar
*addr
, guint32 port _U_
, port_type ptype _U_
, gboolean inbound
, gboolean deny
) {
548 g_string_append_printf(rtxt
, "%s %s on le0 from %s to any",
549 IPFILTER_DENY
, IPFILTER_IN
, addr
);
552 static void sf_ipfw_ipv4(GString
*rtxt
, gchar
*addr
, guint32 port _U_
, port_type ptype _U_
, gboolean inbound
, gboolean deny
) {
553 g_string_append_printf(rtxt
, "add %s ip from %s to any %s",
554 IPFW_DENY
, addr
, IPFW_IN
);
557 static void sf_netfilter_ipv4(GString
*rtxt
, gchar
*addr
, guint32 port _U_
, port_type ptype _U_
, gboolean inbound
, gboolean deny
) {
558 g_string_append_printf(rtxt
, "iptables -A %s -i eth0 -d %s/32 -j %s",
559 NF_INPUT
, addr
, NF_DROP
);
562 #define PF_DENY (deny ? "block" : "pass")
563 #define PF_IN (inbound ? "in" : "out")
564 static void sf_pf_ipv4(GString
*rtxt
, gchar
*addr
, guint32 port _U_
, port_type ptype _U_
, gboolean inbound
, gboolean deny
) {
565 g_string_append_printf(rtxt
, "%s %s quick on $ext_if from %s to any",
566 PF_DENY
, PF_IN
, addr
);
570 #define RT_TCP_UDP (ptype == PT_TCP ? "tcp" : "udp")
571 static void sf_ios_ext_port(GString
*rtxt
, gchar
*addr _U_
, guint32 port
, port_type ptype
, gboolean inbound _U_
, gboolean deny
) {
572 g_string_append_printf(rtxt
, "access-list NUMBER %s %s any any eq %u",
573 IOS_DENY
, RT_TCP_UDP
, port
);
576 static void sf_ipfilter_port(GString
*rtxt
, gchar
*addr _U_
, guint32 port
, port_type ptype _U_
, gboolean inbound
, gboolean deny
) {
577 g_string_append_printf(rtxt
, "%s %s on le0 proto %s from any to any port = %u",
578 IPFILTER_DENY
, IPFILTER_IN
, RT_TCP_UDP
, port
);
581 static void sf_ipfw_port(GString
*rtxt
, gchar
*addr _U_
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
) {
582 g_string_append_printf(rtxt
, "add %s %s from any to any %u %s",
583 IPFW_DENY
, RT_TCP_UDP
, port
, IPFW_IN
);
586 static void sf_netfilter_port(GString
*rtxt
, gchar
*addr _U_
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
) {
587 g_string_append_printf(rtxt
, "iptables -A %s -p %s --destination-port %u -j %s",
588 NF_INPUT
, RT_TCP_UDP
, port
, NF_DROP
);
591 static void sf_pf_port(GString
*rtxt
, gchar
*addr _U_
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
) {
592 g_string_append_printf(rtxt
, "%s %s quick on $ext_if proto %s from any to any port %u",
593 PF_DENY
, PF_IN
, RT_TCP_UDP
, port
);
596 #define NETSH_DENY (deny ? "DISABLE" : "ENABLE")
597 static void sf_netsh_port(GString
*rtxt
, gchar
*addr _U_
, guint32 port
, port_type ptype
, gboolean inbound _U_
, gboolean deny
) {
598 g_string_append_printf(rtxt
, "add portopening %s %u Wireshark %s",
599 RT_TCP_UDP
, port
, NETSH_DENY
);
603 static void sf_ios_ext_ipv4_port(GString
*rtxt
, gchar
*addr
, guint32 port _U_
, port_type ptype _U_
, gboolean inbound
, gboolean deny
) {
605 g_string_append_printf(rtxt
, "access-list NUMBER %s %s host %s any eq %u", IOS_DENY
, RT_TCP_UDP
, addr
, port
);
607 g_string_append_printf(rtxt
, "access-list NUMBER %s %s any host %s eq %u", IOS_DENY
, RT_TCP_UDP
, addr
, port
);
610 static void sf_ipfilter_ipv4_port(GString
*rtxt
, gchar
*addr
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
) {
612 g_string_append_printf(rtxt
, "%s %s on le0 proto %s from %s to any port = %u",
613 IPFILTER_DENY
, IPFILTER_IN
, RT_TCP_UDP
, addr
, port
);
615 g_string_append_printf(rtxt
, "%s %s on le0 proto %s from any to %s port = %u",
616 IPFILTER_DENY
, IPFILTER_IN
, RT_TCP_UDP
, addr
, port
);
619 static void sf_ipfw_ipv4_port(GString
*rtxt
, gchar
*addr
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
) {
620 g_string_append_printf(rtxt
, "add %s %s from %s to any %u %s",
621 IPFW_DENY
, RT_TCP_UDP
, addr
, port
, IPFW_IN
);
624 static void sf_pf_ipv4_port(GString
*rtxt
, gchar
*addr
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
) {
625 g_string_append_printf(rtxt
, "%s %s quick on $ext_if proto %s from %s to any port %u",
626 PF_DENY
, PF_IN
, RT_TCP_UDP
, addr
, port
);
629 static void sf_netfilter_ipv4_port(GString
*rtxt
, gchar
*addr
, guint32 port
, port_type ptype
, gboolean inbound
, gboolean deny
) {
630 g_string_append_printf(rtxt
, "iptables -A %s -p %s -d %s/32 --destination-port %u -j %s",
631 NF_INPUT
, RT_TCP_UDP
, addr
, port
, NF_DROP
);
634 static void sf_netsh_ipv4_port(GString
*rtxt
, gchar
*addr
, guint32 port
, port_type ptype
, gboolean inbound _U_
, gboolean deny
) {
635 g_string_append_printf(rtxt
, "add portopening %s %u Wireshark %s %s",
636 RT_TCP_UDP
, port
, NETSH_DENY
, addr
);
639 /* The destroy call back has the responsibility of
640 * unlinking the temporary file
641 * and freeing the filter_out_filter */
643 firewall_destroy_cb(GtkWidget
*w
, gpointer data _U_
)
645 rule_info_t
*rule_info
;
647 rule_info
= (rule_info_t
*)g_object_get_data(G_OBJECT(w
), WS_RULE_INFO_KEY
);
649 forget_rule_info(rule_info
);
652 gtk_widget_destroy(w
);
656 firewall_copy_cmd_cb(GtkWidget
*w _U_
, gpointer data
)
658 rule_info_t
*rule_info
= (rule_info_t
*)data
;
660 GtkTextIter start
, end
;
663 buf
= gtk_text_view_get_buffer(GTK_TEXT_VIEW(rule_info
->text
));
664 gtk_text_buffer_get_start_iter(buf
, &start
);
665 gtk_text_buffer_get_end_iter(buf
, &end
);
666 gtk_text_buffer_select_range(buf
, &start
, &end
);
667 gtk_text_buffer_copy_clipboard(buf
, gtk_clipboard_get(GDK_SELECTION_CLIPBOARD
));
671 firewall_save_as_ok_cb(char *to_name
, rule_info_t
*rule_info
)
676 GtkTextIter start
, end
;
679 fh
= ws_fopen(to_name
, "w");
681 open_failure_alert_box(to_name
, errno
, TRUE
);
686 buf
= gtk_text_view_get_buffer(GTK_TEXT_VIEW(rule_info
->text
));
687 gtk_text_buffer_get_start_iter(buf
, &start
);
688 gtk_text_buffer_get_end_iter(buf
, &end
);
689 rule
= gtk_text_buffer_get_text(buf
, &start
, &end
, FALSE
);
698 gtk_firewall_save_as_file(GtkWidget
*caller
)
703 new_win
= file_selection_new("Wireshark: Save Firewall ACL Rule",
705 FILE_SELECTION_SAVE
);
707 pathname
= file_selection_run(new_win
);
708 if (pathname
== NULL
) {
709 /* User cancelled or closed the dialog. */
713 /* We've crosed the Rubicon; get rid of the dialog box. */
714 window_destroy(new_win
);
720 firewall_save_as_cmd_cb(GtkWidget
*w
, gpointer data
)
722 GtkWidget
*caller
= gtk_widget_get_toplevel(w
);
723 rule_info_t
*rule_info
= (rule_info_t
*)data
;
727 * Loop until the user either selects a file or gives up.
730 pathname
= gtk_firewall_save_as_file(caller
);
731 if (pathname
== NULL
) {
735 if (firewall_save_as_ok_cb(pathname
, rule_info
)) {
740 /* Dump failed; let the user select another file or give up. */