1 /* firewall_rules_dlg.c
3 * SPDX-License-Identifier: GPL-2.0-or-later*/
6 * Generate firewall ACL rules based on packet addresses and ports.
7 * For directional rules, an outside interface is assumed.
9 * There may be better ways to present the information, e.g. all rules
10 * in one huge text window, or some sort of tree view.
14 * To add a new product, add syntax functions modify the products[] array.
16 * To add a new syntax function, add its prototype above the products[]
17 * array, and add the function below with all the others.
20 /* Copied from gtk/firewall_rules.c */
26 #include "epan/address.h"
28 #include "firewall_rules.h"
30 static void sf_ipfw_mac(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
31 static void sf_netfilter_mac(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
33 static void sf_ios_std_ipv4(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
34 static void sf_ios_ext_ipv4(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
35 static void sf_ipfilter_ipv4(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
36 static void sf_ipfw_ipv4(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
37 static void sf_netfilter_ipv4(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
38 static void sf_pf_ipv4(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
39 /* XXX - Can you addresses-only filters using WFW/netsh? */
41 static void sf_ios_ext_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
42 static void sf_ipfilter_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
43 static void sf_ipfw_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
44 static void sf_netfilter_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
45 static void sf_pf_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
46 static void sf_netsh_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
48 static void sf_ios_ext_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
49 static void sf_ipfilter_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
50 static void sf_ipfw_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
51 static void sf_netfilter_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
52 static void sf_pf_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
53 static void sf_netsh_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
55 typedef struct _fw_product_t {
57 const char *rule_hint;
58 const char *comment_pfx;
60 syntax_func ipv4_func;
61 syntax_func port_func;
62 syntax_func ipv4_port_func;
63 gboolean does_inbound;
66 static fw_product products[] = {
67 { "Cisco IOS (standard)", "Change NUMBER to a valid ACL number.", "!",
68 NULL, sf_ios_std_ipv4, NULL, NULL, FALSE },
69 { "Cisco IOS (extended)", "Change NUMBER to a valid ACL number.", "!",
70 NULL, sf_ios_ext_ipv4, sf_ios_ext_port, sf_ios_ext_ipv4_port, TRUE },
71 { "IP Filter (ipfilter)", "Change le0 to a valid interface if needed.", "#",
72 NULL, sf_ipfilter_ipv4, sf_ipfilter_port, sf_ipfilter_ipv4_port, TRUE },
73 { "IPFirewall (ipfw)", "", "#",
74 sf_ipfw_mac, sf_ipfw_ipv4, sf_ipfw_port, sf_ipfw_ipv4_port, TRUE },
75 { "Netfilter (iptables)", "Change eth0 to a valid interface if needed.", "#",
76 sf_netfilter_mac, sf_netfilter_ipv4, sf_netfilter_port,
77 sf_netfilter_ipv4_port, TRUE },
78 { "Packet Filter (pf)", "$ext_if should be set to a valid interface.", "#",
79 NULL, sf_pf_ipv4, sf_pf_port, sf_pf_ipv4_port, TRUE },
80 { "Windows Firewall (netsh)", "", "#",
81 NULL, NULL, sf_netsh_port, sf_netsh_ipv4_port, FALSE }
83 #define NUM_PRODS (sizeof(products) / sizeof(fw_product))
86 size_t firewall_product_count(void)
91 const char *firewall_product_name(size_t product_idx)
93 if (product_idx >= NUM_PRODS) return "Unknown";
94 return products[product_idx].name;
97 const char *firewall_product_rule_hint(size_t product_idx)
99 if (product_idx >= NUM_PRODS) return "";
100 return products[product_idx].rule_hint;
103 const char *firewall_product_comment_prefix(size_t product_idx)
105 if (product_idx >= NUM_PRODS) return "";
106 return products[product_idx].comment_pfx;
109 syntax_func firewall_product_mac_func(size_t product_idx)
111 if (product_idx >= NUM_PRODS) return NULL;
112 return products[product_idx].mac_func;
116 syntax_func firewall_product_ipv4_func(size_t product_idx)
118 if (product_idx >= NUM_PRODS) return NULL;
119 return products[product_idx].ipv4_func;
123 syntax_func firewall_product_port_func(size_t product_idx)
125 if (product_idx >= NUM_PRODS) return NULL;
126 return products[product_idx].port_func;
130 syntax_func firewall_product_ipv4_port_func(size_t product_idx)
132 if (product_idx >= NUM_PRODS) return NULL;
133 return products[product_idx].ipv4_port_func;
136 gboolean firewall_product_does_inbound(size_t product_idx)
138 if (product_idx >= NUM_PRODS) return FALSE;
139 return products[product_idx].does_inbound;
144 #define IPFW_RULE(deny) ((deny) ? "deny" : "allow")
145 #define IPFW_DIR(inbound) ((inbound) ? "in" : "out")
146 static void sf_ipfw_mac(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
147 g_string_append_printf(rtxt, "add %s MAC %s any %s",
148 IPFW_RULE(deny), addr, IPFW_DIR(inbound));
151 #define NF_RULE(deny) ((deny) ? "DROP" : "ACCEPT")
152 #define NF_DIR(inbound) ((inbound) ? "INPUT" : "OUTPUT")
153 static void sf_netfilter_mac(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
154 g_string_append_printf(rtxt, "iptables --append %s --in-interface eth0 --mac-source %s --jump %s",
155 NF_DIR(inbound), addr, NF_RULE(deny));
159 #define IOS_RULE(deny) ((deny) ? "deny" : "permit")
160 static void sf_ios_std_ipv4(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound _U_, gboolean deny) {
161 g_string_append_printf(rtxt, "access-list NUMBER %s host %s", IOS_RULE(deny), addr);
164 static void sf_ios_ext_ipv4(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
166 g_string_append_printf(rtxt, "access-list NUMBER %s ip host %s any", IOS_RULE(deny), addr);
168 g_string_append_printf(rtxt, "access-list NUMBER %s ip any host %s", IOS_RULE(deny), addr);
171 #define IPFILTER_RULE(deny) ((deny) ? "block" : "pass")
172 #define IPFILTER_DIR(inbound) ((inbound) ? "in" : "out")
174 static void sf_ipfilter_ipv4(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
175 g_string_append_printf(rtxt, "%s %s on le0 from %s to any",
176 IPFILTER_RULE(deny), IPFILTER_DIR(inbound), addr);
179 static void sf_ipfw_ipv4(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
180 g_string_append_printf(rtxt, "add %s ip from %s to any %s",
181 IPFW_RULE(deny), addr, IPFW_DIR(inbound));
184 #define NF_ADDR_DIR(inbound) ((inbound) ? "--source" : "--destination")
185 static void sf_netfilter_ipv4(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
186 g_string_append_printf(rtxt, "iptables --append %s --in-interface eth0 %s %s/32 --jump %s",
187 NF_DIR(inbound), NF_ADDR_DIR(inbound), addr, NF_RULE(deny));
190 #define PF_RULE(deny) ((deny) ? "block" : "pass")
191 #define PF_DIR(inbound) ((inbound) ? "in" : "out")
192 static void sf_pf_ipv4(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
193 g_string_append_printf(rtxt, "%s %s quick on $ext_if from %s to any",
194 PF_RULE(deny), PF_DIR(inbound), addr);
198 #define RT_TCP_UDP(ptype) ((ptype) == PT_TCP ? "tcp" : "udp")
199 static void sf_ios_ext_port(GString *rtxt, gchar *addr _U_, guint32 port, port_type ptype, gboolean inbound _U_, gboolean deny) {
200 g_string_append_printf(rtxt, "access-list NUMBER %s %s any any eq %u",
201 IOS_RULE(deny), RT_TCP_UDP(ptype), port);
204 static void sf_ipfilter_port(GString *rtxt, gchar *addr _U_, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
205 g_string_append_printf(rtxt, "%s %s on le0 proto %s from any to any port = %u",
206 IPFILTER_RULE(deny), IPFILTER_DIR(inbound), RT_TCP_UDP(ptype), port);
209 static void sf_ipfw_port(GString *rtxt, gchar *addr _U_, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
210 g_string_append_printf(rtxt, "add %s %s from any to any %u %s",
211 IPFW_RULE(deny), RT_TCP_UDP(ptype), port, IPFW_DIR(inbound));
214 #define NF_PORT_DIR(inbound) ((inbound) ? "--source-port" : "--destination-port")
215 static void sf_netfilter_port(GString *rtxt, gchar *addr _U_, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
216 g_string_append_printf(rtxt, "iptables --append %s --in-interface eth0 --protocol %s %s %u --jump %s",
217 NF_DIR(inbound), RT_TCP_UDP(ptype), NF_PORT_DIR(inbound), port, NF_RULE(deny));
220 static void sf_pf_port(GString *rtxt, gchar *addr _U_, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
221 g_string_append_printf(rtxt, "%s %s quick on $ext_if proto %s from any to any port %u",
222 PF_RULE(deny), PF_DIR(inbound), RT_TCP_UDP(ptype), port);
225 #define NETSH_RULE(deny) ((deny) ? "DISABLE" : "ENABLE")
226 static void sf_netsh_port(GString *rtxt, gchar *addr _U_, guint32 port, port_type ptype, gboolean inbound _U_, gboolean deny) {
227 g_string_append_printf(rtxt, "add portopening %s %u Wireshark %s",
228 RT_TCP_UDP(ptype), port, NETSH_RULE(deny));
232 static void sf_ios_ext_ipv4_port(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype, gboolean inbound, gboolean deny) {
234 g_string_append_printf(rtxt, "access-list NUMBER %s %s host %s any eq %u", IOS_RULE(deny), RT_TCP_UDP(ptype), addr, port);
236 g_string_append_printf(rtxt, "access-list NUMBER %s %s any host %s eq %u", IOS_RULE(deny), RT_TCP_UDP(ptype), addr, port);
239 static void sf_ipfilter_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
241 g_string_append_printf(rtxt, "%s %s on le0 proto %s from %s to any port = %u",
242 IPFILTER_RULE(deny), IPFILTER_DIR(inbound), RT_TCP_UDP(ptype), addr, port);
244 g_string_append_printf(rtxt, "%s %s on le0 proto %s from any to %s port = %u",
245 IPFILTER_RULE(deny), IPFILTER_DIR(inbound), RT_TCP_UDP(ptype), addr, port);
248 static void sf_ipfw_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
249 g_string_append_printf(rtxt, "add %s %s from %s to any %u %s",
250 IPFW_RULE(deny), RT_TCP_UDP(ptype), addr, port, IPFW_DIR(inbound));
253 static void sf_pf_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
254 g_string_append_printf(rtxt, "%s %s quick on $ext_if proto %s from %s to any port %u",
255 PF_RULE(deny), PF_DIR(inbound), RT_TCP_UDP(ptype), addr, port);
258 static void sf_netfilter_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
259 g_string_append_printf(rtxt, "iptables --append %s --in-interface eth0 --protocol %s %s %s/32 %s %u --jump %s",
260 NF_DIR(inbound), RT_TCP_UDP(ptype), NF_ADDR_DIR(inbound), addr, NF_PORT_DIR(inbound), port, NF_RULE(deny));
263 static void sf_netsh_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound _U_, gboolean deny) {
264 g_string_append_printf(rtxt, "add portopening %s %u Wireshark %s %s",
265 RT_TCP_UDP(ptype), port, NETSH_RULE(deny), addr);
270 * Editor modelines - http://www.wireshark.org/tools/modelines.html
275 * indent-tabs-mode: nil
278 * vi: set shiftwidth=4 tabstop=8 expandtab:
279 * :indentSize=4:tabSize=8:noTabs=true: