1 /* firewall_rules_dlg.c
3 * SPDX-License-Identifier: GPL-2.0-or-later
7 * Generate firewall ACL rules based on packet addresses and ports.
8 * For directional rules, an outside interface is assumed.
10 * There may be better ways to present the information, e.g. all rules
11 * in one huge text window, or some sort of tree view.
15 * To add a new product, add syntax functions modify the products[] array.
17 * To add a new syntax function, add its prototype above the products[]
18 * array, and add the function below with all the others.
21 /* Copied from gtk/firewall_rules.c */
27 #include "epan/address.h"
29 #include "firewall_rules.h"
31 static void sf_ipfw_mac(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
32 static void sf_netfilter_mac(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
34 static void sf_ios_std_ipv4(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
35 static void sf_ios_ext_ipv4(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
36 static void sf_ipfilter_ipv4(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
37 static void sf_ipfw_ipv4(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
38 static void sf_netfilter_ipv4(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
39 static void sf_pf_ipv4(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
40 /* XXX - Can you addresses-only filters using WFW/netsh? */
42 static void sf_ios_ext_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
43 static void sf_ipfilter_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
44 static void sf_ipfw_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
45 static void sf_netfilter_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
46 static void sf_pf_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
47 static void sf_netsh_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
49 static void sf_ios_ext_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
50 static void sf_ipfilter_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
51 static void sf_ipfw_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
52 static void sf_netfilter_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
53 static void sf_pf_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
54 static void sf_netsh_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
56 typedef struct _fw_product_t {
58 const char *rule_hint;
59 const char *comment_pfx;
61 syntax_func ipv4_func;
62 syntax_func port_func;
63 syntax_func ipv4_port_func;
64 gboolean does_inbound;
67 static fw_product products[] = {
68 { "Cisco IOS (standard)", "Change NUMBER to a valid ACL number.", "!",
69 NULL, sf_ios_std_ipv4, NULL, NULL, FALSE },
70 { "Cisco IOS (extended)", "Change NUMBER to a valid ACL number.", "!",
71 NULL, sf_ios_ext_ipv4, sf_ios_ext_port, sf_ios_ext_ipv4_port, TRUE },
72 { "IP Filter (ipfilter)", "Change le0 to a valid interface if needed.", "#",
73 NULL, sf_ipfilter_ipv4, sf_ipfilter_port, sf_ipfilter_ipv4_port, TRUE },
74 { "IPFirewall (ipfw)", "", "#",
75 sf_ipfw_mac, sf_ipfw_ipv4, sf_ipfw_port, sf_ipfw_ipv4_port, TRUE },
76 { "Netfilter (iptables)", "Change eth0 to a valid interface if needed.", "#",
77 sf_netfilter_mac, sf_netfilter_ipv4, sf_netfilter_port,
78 sf_netfilter_ipv4_port, TRUE },
79 { "Packet Filter (pf)", "$ext_if should be set to a valid interface.", "#",
80 NULL, sf_pf_ipv4, sf_pf_port, sf_pf_ipv4_port, TRUE },
81 { "Windows Firewall (netsh)", "", "#",
82 NULL, NULL, sf_netsh_port, sf_netsh_ipv4_port, FALSE }
84 #define NUM_PRODS (sizeof(products) / sizeof(fw_product))
87 size_t firewall_product_count(void)
92 const char *firewall_product_name(size_t product_idx)
94 if (product_idx >= NUM_PRODS) return "Unknown";
95 return products[product_idx].name;
98 const char *firewall_product_rule_hint(size_t product_idx)
100 if (product_idx >= NUM_PRODS) return "";
101 return products[product_idx].rule_hint;
104 const char *firewall_product_comment_prefix(size_t product_idx)
106 if (product_idx >= NUM_PRODS) return "";
107 return products[product_idx].comment_pfx;
110 syntax_func firewall_product_mac_func(size_t product_idx)
112 if (product_idx >= NUM_PRODS) return NULL;
113 return products[product_idx].mac_func;
117 syntax_func firewall_product_ipv4_func(size_t product_idx)
119 if (product_idx >= NUM_PRODS) return NULL;
120 return products[product_idx].ipv4_func;
124 syntax_func firewall_product_port_func(size_t product_idx)
126 if (product_idx >= NUM_PRODS) return NULL;
127 return products[product_idx].port_func;
131 syntax_func firewall_product_ipv4_port_func(size_t product_idx)
133 if (product_idx >= NUM_PRODS) return NULL;
134 return products[product_idx].ipv4_port_func;
137 gboolean firewall_product_does_inbound(size_t product_idx)
139 if (product_idx >= NUM_PRODS) return FALSE;
140 return products[product_idx].does_inbound;
145 #define IPFW_RULE(deny) ((deny) ? "deny" : "allow")
146 #define IPFW_DIR(inbound) ((inbound) ? "in" : "out")
147 static void sf_ipfw_mac(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
148 g_string_append_printf(rtxt, "add %s MAC %s any %s",
149 IPFW_RULE(deny), addr, IPFW_DIR(inbound));
152 #define NF_RULE(deny) ((deny) ? "DROP" : "ACCEPT")
153 #define NF_DIR(inbound) ((inbound) ? "INPUT" : "OUTPUT")
154 static void sf_netfilter_mac(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
155 g_string_append_printf(rtxt, "iptables --append %s --in-interface eth0 --mac-source %s --jump %s",
156 NF_DIR(inbound), addr, NF_RULE(deny));
160 #define IOS_RULE(deny) ((deny) ? "deny" : "permit")
161 static void sf_ios_std_ipv4(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound _U_, gboolean deny) {
162 g_string_append_printf(rtxt, "access-list NUMBER %s host %s", IOS_RULE(deny), addr);
165 static void sf_ios_ext_ipv4(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
167 g_string_append_printf(rtxt, "access-list NUMBER %s ip host %s any", IOS_RULE(deny), addr);
169 g_string_append_printf(rtxt, "access-list NUMBER %s ip any host %s", IOS_RULE(deny), addr);
172 #define IPFILTER_RULE(deny) ((deny) ? "block" : "pass")
173 #define IPFILTER_DIR(inbound) ((inbound) ? "in" : "out")
175 static void sf_ipfilter_ipv4(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
176 g_string_append_printf(rtxt, "%s %s on le0 from %s to any",
177 IPFILTER_RULE(deny), IPFILTER_DIR(inbound), addr);
180 static void sf_ipfw_ipv4(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
181 g_string_append_printf(rtxt, "add %s ip from %s to any %s",
182 IPFW_RULE(deny), addr, IPFW_DIR(inbound));
185 #define NF_ADDR_DIR(inbound) ((inbound) ? "--source" : "--destination")
186 static void sf_netfilter_ipv4(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
187 g_string_append_printf(rtxt, "iptables --append %s --in-interface eth0 %s %s/32 --jump %s",
188 NF_DIR(inbound), NF_ADDR_DIR(inbound), addr, NF_RULE(deny));
191 #define PF_RULE(deny) ((deny) ? "block" : "pass")
192 #define PF_DIR(inbound) ((inbound) ? "in" : "out")
193 static void sf_pf_ipv4(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype _U_, gboolean inbound, gboolean deny) {
194 g_string_append_printf(rtxt, "%s %s quick on $ext_if from %s to any",
195 PF_RULE(deny), PF_DIR(inbound), addr);
199 #define RT_TCP_UDP(ptype) ((ptype) == PT_TCP ? "tcp" : "udp")
200 static void sf_ios_ext_port(GString *rtxt, gchar *addr _U_, guint32 port, port_type ptype, gboolean inbound _U_, gboolean deny) {
201 g_string_append_printf(rtxt, "access-list NUMBER %s %s any any eq %u",
202 IOS_RULE(deny), RT_TCP_UDP(ptype), port);
205 static void sf_ipfilter_port(GString *rtxt, gchar *addr _U_, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
206 g_string_append_printf(rtxt, "%s %s on le0 proto %s from any to any port = %u",
207 IPFILTER_RULE(deny), IPFILTER_DIR(inbound), RT_TCP_UDP(ptype), port);
210 static void sf_ipfw_port(GString *rtxt, gchar *addr _U_, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
211 g_string_append_printf(rtxt, "add %s %s from any to any %u %s",
212 IPFW_RULE(deny), RT_TCP_UDP(ptype), port, IPFW_DIR(inbound));
215 #define NF_PORT_DIR(inbound) ((inbound) ? "--source-port" : "--destination-port")
216 static void sf_netfilter_port(GString *rtxt, gchar *addr _U_, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
217 g_string_append_printf(rtxt, "iptables --append %s --in-interface eth0 --protocol %s %s %u --jump %s",
218 NF_DIR(inbound), RT_TCP_UDP(ptype), NF_PORT_DIR(inbound), port, NF_RULE(deny));
221 static void sf_pf_port(GString *rtxt, gchar *addr _U_, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
222 g_string_append_printf(rtxt, "%s %s quick on $ext_if proto %s from any to any port %u",
223 PF_RULE(deny), PF_DIR(inbound), RT_TCP_UDP(ptype), port);
226 #define NETSH_RULE(deny) ((deny) ? "DISABLE" : "ENABLE")
227 static void sf_netsh_port(GString *rtxt, gchar *addr _U_, guint32 port, port_type ptype, gboolean inbound _U_, gboolean deny) {
228 g_string_append_printf(rtxt, "add portopening %s %u Wireshark %s",
229 RT_TCP_UDP(ptype), port, NETSH_RULE(deny));
233 static void sf_ios_ext_ipv4_port(GString *rtxt, gchar *addr, guint32 port _U_, port_type ptype, gboolean inbound, gboolean deny) {
235 g_string_append_printf(rtxt, "access-list NUMBER %s %s host %s any eq %u", IOS_RULE(deny), RT_TCP_UDP(ptype), addr, port);
237 g_string_append_printf(rtxt, "access-list NUMBER %s %s any host %s eq %u", IOS_RULE(deny), RT_TCP_UDP(ptype), addr, port);
240 static void sf_ipfilter_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
242 g_string_append_printf(rtxt, "%s %s on le0 proto %s from %s to any port = %u",
243 IPFILTER_RULE(deny), IPFILTER_DIR(inbound), RT_TCP_UDP(ptype), addr, port);
245 g_string_append_printf(rtxt, "%s %s on le0 proto %s from any to %s port = %u",
246 IPFILTER_RULE(deny), IPFILTER_DIR(inbound), RT_TCP_UDP(ptype), addr, port);
249 static void sf_ipfw_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
250 g_string_append_printf(rtxt, "add %s %s from %s to any %u %s",
251 IPFW_RULE(deny), RT_TCP_UDP(ptype), addr, port, IPFW_DIR(inbound));
254 static void sf_pf_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
255 g_string_append_printf(rtxt, "%s %s quick on $ext_if proto %s from %s to any port %u",
256 PF_RULE(deny), PF_DIR(inbound), RT_TCP_UDP(ptype), addr, port);
259 static void sf_netfilter_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny) {
260 g_string_append_printf(rtxt, "iptables --append %s --in-interface eth0 --protocol %s %s %s/32 %s %u --jump %s",
261 NF_DIR(inbound), RT_TCP_UDP(ptype), NF_ADDR_DIR(inbound), addr, NF_PORT_DIR(inbound), port, NF_RULE(deny));
264 static void sf_netsh_ipv4_port(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound _U_, gboolean deny) {
265 g_string_append_printf(rtxt, "add portopening %s %u Wireshark %s %s",
266 RT_TCP_UDP(ptype), port, NETSH_RULE(deny), addr);
271 * Editor modelines - http://www.wireshark.org/tools/modelines.html
276 * indent-tabs-mode: nil
279 * vi: set shiftwidth=4 tabstop=8 expandtab:
280 * :indentSize=4:tabSize=8:noTabs=true: