Deleted Added
full compact
ip_fw2.c (231852) ip_fw2.c (232865)
1/*-
2 * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25
26#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25
26#include <sys/cdefs.h>
27__FBSDID("$FreeBSD: head/sys/netinet/ipfw/ip_fw2.c 231852 2012-02-17 02:39:58Z bz $");
27__FBSDID("$FreeBSD: head/sys/netinet/ipfw/ip_fw2.c 232865 2012-03-12 14:07:57Z melifaro $");
28
29/*
30 * The FreeBSD IP packet firewall, main file
31 */
32
33#include "opt_ipfw.h"
34#include "opt_ipdivert.h"
35#include "opt_inet.h"
36#ifndef INET
37#error "IPFIREWALL requires INET"
38#endif /* INET */
39#include "opt_inet6.h"
40#include "opt_ipsec.h"
41
42#include <sys/param.h>
43#include <sys/systm.h>
44#include <sys/condvar.h>
45#include <sys/eventhandler.h>
46#include <sys/malloc.h>
47#include <sys/mbuf.h>
48#include <sys/kernel.h>
49#include <sys/lock.h>
50#include <sys/jail.h>
51#include <sys/module.h>
52#include <sys/priv.h>
53#include <sys/proc.h>
54#include <sys/rwlock.h>
55#include <sys/socket.h>
56#include <sys/socketvar.h>
57#include <sys/sysctl.h>
58#include <sys/syslog.h>
59#include <sys/ucred.h>
60#include <net/ethernet.h> /* for ETHERTYPE_IP */
61#include <net/if.h>
62#include <net/route.h>
63#include <net/pf_mtag.h>
64#include <net/vnet.h>
65
66#include <netinet/in.h>
67#include <netinet/in_var.h>
68#include <netinet/in_pcb.h>
69#include <netinet/ip.h>
70#include <netinet/ip_var.h>
71#include <netinet/ip_icmp.h>
72#include <netinet/ip_fw.h>
73#include <netinet/ipfw/ip_fw_private.h>
74#include <netinet/ip_carp.h>
75#include <netinet/pim.h>
76#include <netinet/tcp_var.h>
77#include <netinet/udp.h>
78#include <netinet/udp_var.h>
79#include <netinet/sctp.h>
80
81#include <netinet/ip6.h>
82#include <netinet/icmp6.h>
83#ifdef INET6
84#include <netinet6/in6_pcb.h>
85#include <netinet6/scope6_var.h>
86#include <netinet6/ip6_var.h>
87#endif
88
89#include <machine/in_cksum.h> /* XXX for in_cksum */
90
91#ifdef MAC
92#include <security/mac/mac_framework.h>
93#endif
94
95/*
96 * static variables followed by global ones.
97 * All ipfw global variables are here.
98 */
99
100/* ipfw_vnet_ready controls when we are open for business */
101static VNET_DEFINE(int, ipfw_vnet_ready) = 0;
102#define V_ipfw_vnet_ready VNET(ipfw_vnet_ready)
103
104static VNET_DEFINE(int, fw_deny_unknown_exthdrs);
105#define V_fw_deny_unknown_exthdrs VNET(fw_deny_unknown_exthdrs)
106
107static VNET_DEFINE(int, fw_permit_single_frag6) = 1;
108#define V_fw_permit_single_frag6 VNET(fw_permit_single_frag6)
109
110#ifdef IPFIREWALL_DEFAULT_TO_ACCEPT
111static int default_to_accept = 1;
112#else
113static int default_to_accept;
114#endif
115
116VNET_DEFINE(int, autoinc_step);
117VNET_DEFINE(int, fw_one_pass) = 1;
118
28
29/*
30 * The FreeBSD IP packet firewall, main file
31 */
32
33#include "opt_ipfw.h"
34#include "opt_ipdivert.h"
35#include "opt_inet.h"
36#ifndef INET
37#error "IPFIREWALL requires INET"
38#endif /* INET */
39#include "opt_inet6.h"
40#include "opt_ipsec.h"
41
42#include <sys/param.h>
43#include <sys/systm.h>
44#include <sys/condvar.h>
45#include <sys/eventhandler.h>
46#include <sys/malloc.h>
47#include <sys/mbuf.h>
48#include <sys/kernel.h>
49#include <sys/lock.h>
50#include <sys/jail.h>
51#include <sys/module.h>
52#include <sys/priv.h>
53#include <sys/proc.h>
54#include <sys/rwlock.h>
55#include <sys/socket.h>
56#include <sys/socketvar.h>
57#include <sys/sysctl.h>
58#include <sys/syslog.h>
59#include <sys/ucred.h>
60#include <net/ethernet.h> /* for ETHERTYPE_IP */
61#include <net/if.h>
62#include <net/route.h>
63#include <net/pf_mtag.h>
64#include <net/vnet.h>
65
66#include <netinet/in.h>
67#include <netinet/in_var.h>
68#include <netinet/in_pcb.h>
69#include <netinet/ip.h>
70#include <netinet/ip_var.h>
71#include <netinet/ip_icmp.h>
72#include <netinet/ip_fw.h>
73#include <netinet/ipfw/ip_fw_private.h>
74#include <netinet/ip_carp.h>
75#include <netinet/pim.h>
76#include <netinet/tcp_var.h>
77#include <netinet/udp.h>
78#include <netinet/udp_var.h>
79#include <netinet/sctp.h>
80
81#include <netinet/ip6.h>
82#include <netinet/icmp6.h>
83#ifdef INET6
84#include <netinet6/in6_pcb.h>
85#include <netinet6/scope6_var.h>
86#include <netinet6/ip6_var.h>
87#endif
88
89#include <machine/in_cksum.h> /* XXX for in_cksum */
90
91#ifdef MAC
92#include <security/mac/mac_framework.h>
93#endif
94
95/*
96 * static variables followed by global ones.
97 * All ipfw global variables are here.
98 */
99
100/* ipfw_vnet_ready controls when we are open for business */
101static VNET_DEFINE(int, ipfw_vnet_ready) = 0;
102#define V_ipfw_vnet_ready VNET(ipfw_vnet_ready)
103
104static VNET_DEFINE(int, fw_deny_unknown_exthdrs);
105#define V_fw_deny_unknown_exthdrs VNET(fw_deny_unknown_exthdrs)
106
107static VNET_DEFINE(int, fw_permit_single_frag6) = 1;
108#define V_fw_permit_single_frag6 VNET(fw_permit_single_frag6)
109
110#ifdef IPFIREWALL_DEFAULT_TO_ACCEPT
111static int default_to_accept = 1;
112#else
113static int default_to_accept;
114#endif
115
116VNET_DEFINE(int, autoinc_step);
117VNET_DEFINE(int, fw_one_pass) = 1;
118
119/* Use 128 tables by default */
120VNET_DEFINE(int, fw_tables_max) = IPFW_TABLES_MAX;
121
119/*
120 * Each rule belongs to one of 32 different sets (0..31).
121 * The variable set_disable contains one bit per set.
122 * If the bit is set, all rules in the corresponding set
123 * are disabled. Set RESVD_SET(31) is reserved for the default rule
124 * and rules that are not deleted by the flush command,
125 * and CANNOT be disabled.
126 * Rules in set RESVD_SET can only be deleted individually.
127 */
128VNET_DEFINE(u_int32_t, set_disable);
129#define V_set_disable VNET(set_disable)
130
131VNET_DEFINE(int, fw_verbose);
132/* counter for ipfw_log(NULL...) */
133VNET_DEFINE(u_int64_t, norule_counter);
134VNET_DEFINE(int, verbose_limit);
135
136/* layer3_chain contains the list of rules for layer 3 */
137VNET_DEFINE(struct ip_fw_chain, layer3_chain);
138
139ipfw_nat_t *ipfw_nat_ptr = NULL;
140struct cfg_nat *(*lookup_nat_ptr)(struct nat_list *, int);
141ipfw_nat_cfg_t *ipfw_nat_cfg_ptr;
142ipfw_nat_cfg_t *ipfw_nat_del_ptr;
143ipfw_nat_cfg_t *ipfw_nat_get_cfg_ptr;
144ipfw_nat_cfg_t *ipfw_nat_get_log_ptr;
145
146#ifdef SYSCTL_NODE
147uint32_t dummy_def = IPFW_DEFAULT_RULE;
122/*
123 * Each rule belongs to one of 32 different sets (0..31).
124 * The variable set_disable contains one bit per set.
125 * If the bit is set, all rules in the corresponding set
126 * are disabled. Set RESVD_SET(31) is reserved for the default rule
127 * and rules that are not deleted by the flush command,
128 * and CANNOT be disabled.
129 * Rules in set RESVD_SET can only be deleted individually.
130 */
131VNET_DEFINE(u_int32_t, set_disable);
132#define V_set_disable VNET(set_disable)
133
134VNET_DEFINE(int, fw_verbose);
135/* counter for ipfw_log(NULL...) */
136VNET_DEFINE(u_int64_t, norule_counter);
137VNET_DEFINE(int, verbose_limit);
138
139/* layer3_chain contains the list of rules for layer 3 */
140VNET_DEFINE(struct ip_fw_chain, layer3_chain);
141
142ipfw_nat_t *ipfw_nat_ptr = NULL;
143struct cfg_nat *(*lookup_nat_ptr)(struct nat_list *, int);
144ipfw_nat_cfg_t *ipfw_nat_cfg_ptr;
145ipfw_nat_cfg_t *ipfw_nat_del_ptr;
146ipfw_nat_cfg_t *ipfw_nat_get_cfg_ptr;
147ipfw_nat_cfg_t *ipfw_nat_get_log_ptr;
148
149#ifdef SYSCTL_NODE
150uint32_t dummy_def = IPFW_DEFAULT_RULE;
148uint32_t dummy_tables_max = IPFW_TABLES_MAX;
149
150SYSBEGIN(f3)
151
152SYSCTL_NODE(_net_inet_ip, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall");
153SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, one_pass,
154 CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_one_pass), 0,
155 "Only do a single pass through ipfw when using dummynet(4)");
156SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, autoinc_step,
157 CTLFLAG_RW, &VNET_NAME(autoinc_step), 0,
158 "Rule number auto-increment step");
159SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, verbose,
160 CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_verbose), 0,
161 "Log matches to ipfw rules");
162SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, verbose_limit,
163 CTLFLAG_RW, &VNET_NAME(verbose_limit), 0,
164 "Set upper limit of matches of ipfw rules logged");
165SYSCTL_UINT(_net_inet_ip_fw, OID_AUTO, default_rule, CTLFLAG_RD,
166 &dummy_def, 0,
167 "The default/max possible rule number.");
168SYSCTL_UINT(_net_inet_ip_fw, OID_AUTO, tables_max, CTLFLAG_RD,
151
152SYSBEGIN(f3)
153
154SYSCTL_NODE(_net_inet_ip, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall");
155SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, one_pass,
156 CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_one_pass), 0,
157 "Only do a single pass through ipfw when using dummynet(4)");
158SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, autoinc_step,
159 CTLFLAG_RW, &VNET_NAME(autoinc_step), 0,
160 "Rule number auto-increment step");
161SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, verbose,
162 CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_verbose), 0,
163 "Log matches to ipfw rules");
164SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, verbose_limit,
165 CTLFLAG_RW, &VNET_NAME(verbose_limit), 0,
166 "Set upper limit of matches of ipfw rules logged");
167SYSCTL_UINT(_net_inet_ip_fw, OID_AUTO, default_rule, CTLFLAG_RD,
168 &dummy_def, 0,
169 "The default/max possible rule number.");
170SYSCTL_UINT(_net_inet_ip_fw, OID_AUTO, tables_max, CTLFLAG_RD,
169 &dummy_tables_max, 0,
171 &V_fw_tables_max, 0,
170 "The maximum number of tables.");
171SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, default_to_accept, CTLFLAG_RDTUN,
172 &default_to_accept, 0,
173 "Make the default rule accept all packets.");
174TUNABLE_INT("net.inet.ip.fw.default_to_accept", &default_to_accept);
172 "The maximum number of tables.");
173SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, default_to_accept, CTLFLAG_RDTUN,
174 &default_to_accept, 0,
175 "Make the default rule accept all packets.");
176TUNABLE_INT("net.inet.ip.fw.default_to_accept", &default_to_accept);
177TUNABLE_INT("net.inet.ip.fw.tables_max", &V_fw_tables_max);
175SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, static_count,
176 CTLFLAG_RD, &VNET_NAME(layer3_chain.n_rules), 0,
177 "Number of static rules");
178
179#ifdef INET6
180SYSCTL_DECL(_net_inet6_ip6);
181SYSCTL_NODE(_net_inet6_ip6, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall");
182SYSCTL_VNET_INT(_net_inet6_ip6_fw, OID_AUTO, deny_unknown_exthdrs,
183 CTLFLAG_RW | CTLFLAG_SECURE, &VNET_NAME(fw_deny_unknown_exthdrs), 0,
184 "Deny packets with unknown IPv6 Extension Headers");
185SYSCTL_VNET_INT(_net_inet6_ip6_fw, OID_AUTO, permit_single_frag6,
186 CTLFLAG_RW | CTLFLAG_SECURE, &VNET_NAME(fw_permit_single_frag6), 0,
187 "Permit single packet IPv6 fragments");
188#endif /* INET6 */
189
190SYSEND
191
192#endif /* SYSCTL_NODE */
193
194
195/*
196 * Some macros used in the various matching options.
197 * L3HDR maps an ipv4 pointer into a layer3 header pointer of type T
198 * Other macros just cast void * into the appropriate type
199 */
200#define L3HDR(T, ip) ((T *)((u_int32_t *)(ip) + (ip)->ip_hl))
201#define TCP(p) ((struct tcphdr *)(p))
202#define SCTP(p) ((struct sctphdr *)(p))
203#define UDP(p) ((struct udphdr *)(p))
204#define ICMP(p) ((struct icmphdr *)(p))
205#define ICMP6(p) ((struct icmp6_hdr *)(p))
206
207static __inline int
208icmptype_match(struct icmphdr *icmp, ipfw_insn_u32 *cmd)
209{
210 int type = icmp->icmp_type;
211
212 return (type <= ICMP_MAXTYPE && (cmd->d[0] & (1<<type)) );
213}
214
215#define TT ( (1 << ICMP_ECHO) | (1 << ICMP_ROUTERSOLICIT) | \
216 (1 << ICMP_TSTAMP) | (1 << ICMP_IREQ) | (1 << ICMP_MASKREQ) )
217
218static int
219is_icmp_query(struct icmphdr *icmp)
220{
221 int type = icmp->icmp_type;
222
223 return (type <= ICMP_MAXTYPE && (TT & (1<<type)) );
224}
225#undef TT
226
227/*
228 * The following checks use two arrays of 8 or 16 bits to store the
229 * bits that we want set or clear, respectively. They are in the
230 * low and high half of cmd->arg1 or cmd->d[0].
231 *
232 * We scan options and store the bits we find set. We succeed if
233 *
234 * (want_set & ~bits) == 0 && (want_clear & ~bits) == want_clear
235 *
236 * The code is sometimes optimized not to store additional variables.
237 */
238
239static int
240flags_match(ipfw_insn *cmd, u_int8_t bits)
241{
242 u_char want_clear;
243 bits = ~bits;
244
245 if ( ((cmd->arg1 & 0xff) & bits) != 0)
246 return 0; /* some bits we want set were clear */
247 want_clear = (cmd->arg1 >> 8) & 0xff;
248 if ( (want_clear & bits) != want_clear)
249 return 0; /* some bits we want clear were set */
250 return 1;
251}
252
253static int
254ipopts_match(struct ip *ip, ipfw_insn *cmd)
255{
256 int optlen, bits = 0;
257 u_char *cp = (u_char *)(ip + 1);
258 int x = (ip->ip_hl << 2) - sizeof (struct ip);
259
260 for (; x > 0; x -= optlen, cp += optlen) {
261 int opt = cp[IPOPT_OPTVAL];
262
263 if (opt == IPOPT_EOL)
264 break;
265 if (opt == IPOPT_NOP)
266 optlen = 1;
267 else {
268 optlen = cp[IPOPT_OLEN];
269 if (optlen <= 0 || optlen > x)
270 return 0; /* invalid or truncated */
271 }
272 switch (opt) {
273
274 default:
275 break;
276
277 case IPOPT_LSRR:
278 bits |= IP_FW_IPOPT_LSRR;
279 break;
280
281 case IPOPT_SSRR:
282 bits |= IP_FW_IPOPT_SSRR;
283 break;
284
285 case IPOPT_RR:
286 bits |= IP_FW_IPOPT_RR;
287 break;
288
289 case IPOPT_TS:
290 bits |= IP_FW_IPOPT_TS;
291 break;
292 }
293 }
294 return (flags_match(cmd, bits));
295}
296
297static int
298tcpopts_match(struct tcphdr *tcp, ipfw_insn *cmd)
299{
300 int optlen, bits = 0;
301 u_char *cp = (u_char *)(tcp + 1);
302 int x = (tcp->th_off << 2) - sizeof(struct tcphdr);
303
304 for (; x > 0; x -= optlen, cp += optlen) {
305 int opt = cp[0];
306 if (opt == TCPOPT_EOL)
307 break;
308 if (opt == TCPOPT_NOP)
309 optlen = 1;
310 else {
311 optlen = cp[1];
312 if (optlen <= 0)
313 break;
314 }
315
316 switch (opt) {
317
318 default:
319 break;
320
321 case TCPOPT_MAXSEG:
322 bits |= IP_FW_TCPOPT_MSS;
323 break;
324
325 case TCPOPT_WINDOW:
326 bits |= IP_FW_TCPOPT_WINDOW;
327 break;
328
329 case TCPOPT_SACK_PERMITTED:
330 case TCPOPT_SACK:
331 bits |= IP_FW_TCPOPT_SACK;
332 break;
333
334 case TCPOPT_TIMESTAMP:
335 bits |= IP_FW_TCPOPT_TS;
336 break;
337
338 }
339 }
340 return (flags_match(cmd, bits));
341}
342
343static int
178SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, static_count,
179 CTLFLAG_RD, &VNET_NAME(layer3_chain.n_rules), 0,
180 "Number of static rules");
181
182#ifdef INET6
183SYSCTL_DECL(_net_inet6_ip6);
184SYSCTL_NODE(_net_inet6_ip6, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall");
185SYSCTL_VNET_INT(_net_inet6_ip6_fw, OID_AUTO, deny_unknown_exthdrs,
186 CTLFLAG_RW | CTLFLAG_SECURE, &VNET_NAME(fw_deny_unknown_exthdrs), 0,
187 "Deny packets with unknown IPv6 Extension Headers");
188SYSCTL_VNET_INT(_net_inet6_ip6_fw, OID_AUTO, permit_single_frag6,
189 CTLFLAG_RW | CTLFLAG_SECURE, &VNET_NAME(fw_permit_single_frag6), 0,
190 "Permit single packet IPv6 fragments");
191#endif /* INET6 */
192
193SYSEND
194
195#endif /* SYSCTL_NODE */
196
197
198/*
199 * Some macros used in the various matching options.
200 * L3HDR maps an ipv4 pointer into a layer3 header pointer of type T
201 * Other macros just cast void * into the appropriate type
202 */
203#define L3HDR(T, ip) ((T *)((u_int32_t *)(ip) + (ip)->ip_hl))
204#define TCP(p) ((struct tcphdr *)(p))
205#define SCTP(p) ((struct sctphdr *)(p))
206#define UDP(p) ((struct udphdr *)(p))
207#define ICMP(p) ((struct icmphdr *)(p))
208#define ICMP6(p) ((struct icmp6_hdr *)(p))
209
210static __inline int
211icmptype_match(struct icmphdr *icmp, ipfw_insn_u32 *cmd)
212{
213 int type = icmp->icmp_type;
214
215 return (type <= ICMP_MAXTYPE && (cmd->d[0] & (1<<type)) );
216}
217
218#define TT ( (1 << ICMP_ECHO) | (1 << ICMP_ROUTERSOLICIT) | \
219 (1 << ICMP_TSTAMP) | (1 << ICMP_IREQ) | (1 << ICMP_MASKREQ) )
220
221static int
222is_icmp_query(struct icmphdr *icmp)
223{
224 int type = icmp->icmp_type;
225
226 return (type <= ICMP_MAXTYPE && (TT & (1<<type)) );
227}
228#undef TT
229
230/*
231 * The following checks use two arrays of 8 or 16 bits to store the
232 * bits that we want set or clear, respectively. They are in the
233 * low and high half of cmd->arg1 or cmd->d[0].
234 *
235 * We scan options and store the bits we find set. We succeed if
236 *
237 * (want_set & ~bits) == 0 && (want_clear & ~bits) == want_clear
238 *
239 * The code is sometimes optimized not to store additional variables.
240 */
241
242static int
243flags_match(ipfw_insn *cmd, u_int8_t bits)
244{
245 u_char want_clear;
246 bits = ~bits;
247
248 if ( ((cmd->arg1 & 0xff) & bits) != 0)
249 return 0; /* some bits we want set were clear */
250 want_clear = (cmd->arg1 >> 8) & 0xff;
251 if ( (want_clear & bits) != want_clear)
252 return 0; /* some bits we want clear were set */
253 return 1;
254}
255
256static int
257ipopts_match(struct ip *ip, ipfw_insn *cmd)
258{
259 int optlen, bits = 0;
260 u_char *cp = (u_char *)(ip + 1);
261 int x = (ip->ip_hl << 2) - sizeof (struct ip);
262
263 for (; x > 0; x -= optlen, cp += optlen) {
264 int opt = cp[IPOPT_OPTVAL];
265
266 if (opt == IPOPT_EOL)
267 break;
268 if (opt == IPOPT_NOP)
269 optlen = 1;
270 else {
271 optlen = cp[IPOPT_OLEN];
272 if (optlen <= 0 || optlen > x)
273 return 0; /* invalid or truncated */
274 }
275 switch (opt) {
276
277 default:
278 break;
279
280 case IPOPT_LSRR:
281 bits |= IP_FW_IPOPT_LSRR;
282 break;
283
284 case IPOPT_SSRR:
285 bits |= IP_FW_IPOPT_SSRR;
286 break;
287
288 case IPOPT_RR:
289 bits |= IP_FW_IPOPT_RR;
290 break;
291
292 case IPOPT_TS:
293 bits |= IP_FW_IPOPT_TS;
294 break;
295 }
296 }
297 return (flags_match(cmd, bits));
298}
299
300static int
301tcpopts_match(struct tcphdr *tcp, ipfw_insn *cmd)
302{
303 int optlen, bits = 0;
304 u_char *cp = (u_char *)(tcp + 1);
305 int x = (tcp->th_off << 2) - sizeof(struct tcphdr);
306
307 for (; x > 0; x -= optlen, cp += optlen) {
308 int opt = cp[0];
309 if (opt == TCPOPT_EOL)
310 break;
311 if (opt == TCPOPT_NOP)
312 optlen = 1;
313 else {
314 optlen = cp[1];
315 if (optlen <= 0)
316 break;
317 }
318
319 switch (opt) {
320
321 default:
322 break;
323
324 case TCPOPT_MAXSEG:
325 bits |= IP_FW_TCPOPT_MSS;
326 break;
327
328 case TCPOPT_WINDOW:
329 bits |= IP_FW_TCPOPT_WINDOW;
330 break;
331
332 case TCPOPT_SACK_PERMITTED:
333 case TCPOPT_SACK:
334 bits |= IP_FW_TCPOPT_SACK;
335 break;
336
337 case TCPOPT_TIMESTAMP:
338 bits |= IP_FW_TCPOPT_TS;
339 break;
340
341 }
342 }
343 return (flags_match(cmd, bits));
344}
345
346static int
344iface_match(struct ifnet *ifp, ipfw_insn_if *cmd)
347iface_match(struct ifnet *ifp, ipfw_insn_if *cmd, struct ip_fw_chain *chain, uint32_t *tablearg)
345{
346 if (ifp == NULL) /* no iface with this packet, match fails */
347 return 0;
348 /* Check by name or by IP address */
349 if (cmd->name[0] != '\0') { /* match by name */
348{
349 if (ifp == NULL) /* no iface with this packet, match fails */
350 return 0;
351 /* Check by name or by IP address */
352 if (cmd->name[0] != '\0') { /* match by name */
353 if (cmd->name[0] == '\1') /* use tablearg to match */
354 return ipfw_lookup_table_extended(chain, cmd->p.glob,
355 ifp->if_xname, tablearg, IPFW_TABLE_INTERFACE);
350 /* Check name */
351 if (cmd->p.glob) {
352 if (fnmatch(cmd->name, ifp->if_xname, 0) == 0)
353 return(1);
354 } else {
355 if (strncmp(ifp->if_xname, cmd->name, IFNAMSIZ) == 0)
356 return(1);
357 }
358 } else {
359#ifdef __FreeBSD__ /* and OSX too ? */
360 struct ifaddr *ia;
361
362 if_addr_rlock(ifp);
363 TAILQ_FOREACH(ia, &ifp->if_addrhead, ifa_link) {
364 if (ia->ifa_addr->sa_family != AF_INET)
365 continue;
366 if (cmd->p.ip.s_addr == ((struct sockaddr_in *)
367 (ia->ifa_addr))->sin_addr.s_addr) {
368 if_addr_runlock(ifp);
369 return(1); /* match */
370 }
371 }
372 if_addr_runlock(ifp);
373#endif /* __FreeBSD__ */
374 }
375 return(0); /* no match, fail ... */
376}
377
378/*
379 * The verify_path function checks if a route to the src exists and
380 * if it is reachable via ifp (when provided).
381 *
382 * The 'verrevpath' option checks that the interface that an IP packet
383 * arrives on is the same interface that traffic destined for the
384 * packet's source address would be routed out of.
385 * The 'versrcreach' option just checks that the source address is
386 * reachable via any route (except default) in the routing table.
387 * These two are a measure to block forged packets. This is also
388 * commonly known as "anti-spoofing" or Unicast Reverse Path
389 * Forwarding (Unicast RFP) in Cisco-ese. The name of the knobs
390 * is purposely reminiscent of the Cisco IOS command,
391 *
392 * ip verify unicast reverse-path
393 * ip verify unicast source reachable-via any
394 *
395 * which implements the same functionality. But note that the syntax
396 * is misleading, and the check may be performed on all IP packets
397 * whether unicast, multicast, or broadcast.
398 */
399static int
400verify_path(struct in_addr src, struct ifnet *ifp, u_int fib)
401{
402#ifndef __FreeBSD__
403 return 0;
404#else
405 struct route ro;
406 struct sockaddr_in *dst;
407
408 bzero(&ro, sizeof(ro));
409
410 dst = (struct sockaddr_in *)&(ro.ro_dst);
411 dst->sin_family = AF_INET;
412 dst->sin_len = sizeof(*dst);
413 dst->sin_addr = src;
414 in_rtalloc_ign(&ro, 0, fib);
415
416 if (ro.ro_rt == NULL)
417 return 0;
418
419 /*
420 * If ifp is provided, check for equality with rtentry.
421 * We should use rt->rt_ifa->ifa_ifp, instead of rt->rt_ifp,
422 * in order to pass packets injected back by if_simloop():
423 * if useloopback == 1 routing entry (via lo0) for our own address
424 * may exist, so we need to handle routing assymetry.
425 */
426 if (ifp != NULL && ro.ro_rt->rt_ifa->ifa_ifp != ifp) {
427 RTFREE(ro.ro_rt);
428 return 0;
429 }
430
431 /* if no ifp provided, check if rtentry is not default route */
432 if (ifp == NULL &&
433 satosin(rt_key(ro.ro_rt))->sin_addr.s_addr == INADDR_ANY) {
434 RTFREE(ro.ro_rt);
435 return 0;
436 }
437
438 /* or if this is a blackhole/reject route */
439 if (ifp == NULL && ro.ro_rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
440 RTFREE(ro.ro_rt);
441 return 0;
442 }
443
444 /* found valid route */
445 RTFREE(ro.ro_rt);
446 return 1;
447#endif /* __FreeBSD__ */
448}
449
450#ifdef INET6
451/*
452 * ipv6 specific rules here...
453 */
454static __inline int
455icmp6type_match (int type, ipfw_insn_u32 *cmd)
456{
457 return (type <= ICMP6_MAXTYPE && (cmd->d[type/32] & (1<<(type%32)) ) );
458}
459
460static int
461flow6id_match( int curr_flow, ipfw_insn_u32 *cmd )
462{
463 int i;
464 for (i=0; i <= cmd->o.arg1; ++i )
465 if (curr_flow == cmd->d[i] )
466 return 1;
467 return 0;
468}
469
470/* support for IP6_*_ME opcodes */
471static int
472search_ip6_addr_net (struct in6_addr * ip6_addr)
473{
474 struct ifnet *mdc;
475 struct ifaddr *mdc2;
476 struct in6_ifaddr *fdm;
477 struct in6_addr copia;
478
479 TAILQ_FOREACH(mdc, &V_ifnet, if_link) {
480 if_addr_rlock(mdc);
481 TAILQ_FOREACH(mdc2, &mdc->if_addrhead, ifa_link) {
482 if (mdc2->ifa_addr->sa_family == AF_INET6) {
483 fdm = (struct in6_ifaddr *)mdc2;
484 copia = fdm->ia_addr.sin6_addr;
485 /* need for leaving scope_id in the sock_addr */
486 in6_clearscope(&copia);
487 if (IN6_ARE_ADDR_EQUAL(ip6_addr, &copia)) {
488 if_addr_runlock(mdc);
489 return 1;
490 }
491 }
492 }
493 if_addr_runlock(mdc);
494 }
495 return 0;
496}
497
498static int
499verify_path6(struct in6_addr *src, struct ifnet *ifp, u_int fib)
500{
501 struct route_in6 ro;
502 struct sockaddr_in6 *dst;
503
504 bzero(&ro, sizeof(ro));
505
506 dst = (struct sockaddr_in6 * )&(ro.ro_dst);
507 dst->sin6_family = AF_INET6;
508 dst->sin6_len = sizeof(*dst);
509 dst->sin6_addr = *src;
510
511 in6_rtalloc_ign(&ro, 0, fib);
512 if (ro.ro_rt == NULL)
513 return 0;
514
515 /*
516 * if ifp is provided, check for equality with rtentry
517 * We should use rt->rt_ifa->ifa_ifp, instead of rt->rt_ifp,
518 * to support the case of sending packets to an address of our own.
519 * (where the former interface is the first argument of if_simloop()
520 * (=ifp), the latter is lo0)
521 */
522 if (ifp != NULL && ro.ro_rt->rt_ifa->ifa_ifp != ifp) {
523 RTFREE(ro.ro_rt);
524 return 0;
525 }
526
527 /* if no ifp provided, check if rtentry is not default route */
528 if (ifp == NULL &&
529 IN6_IS_ADDR_UNSPECIFIED(&satosin6(rt_key(ro.ro_rt))->sin6_addr)) {
530 RTFREE(ro.ro_rt);
531 return 0;
532 }
533
534 /* or if this is a blackhole/reject route */
535 if (ifp == NULL && ro.ro_rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
536 RTFREE(ro.ro_rt);
537 return 0;
538 }
539
540 /* found valid route */
541 RTFREE(ro.ro_rt);
542 return 1;
543
544}
545
546static int
547is_icmp6_query(int icmp6_type)
548{
549 if ((icmp6_type <= ICMP6_MAXTYPE) &&
550 (icmp6_type == ICMP6_ECHO_REQUEST ||
551 icmp6_type == ICMP6_MEMBERSHIP_QUERY ||
552 icmp6_type == ICMP6_WRUREQUEST ||
553 icmp6_type == ICMP6_FQDN_QUERY ||
554 icmp6_type == ICMP6_NI_QUERY))
555 return (1);
556
557 return (0);
558}
559
560static void
561send_reject6(struct ip_fw_args *args, int code, u_int hlen, struct ip6_hdr *ip6)
562{
563 struct mbuf *m;
564
565 m = args->m;
566 if (code == ICMP6_UNREACH_RST && args->f_id.proto == IPPROTO_TCP) {
567 struct tcphdr *tcp;
568 tcp = (struct tcphdr *)((char *)ip6 + hlen);
569
570 if ((tcp->th_flags & TH_RST) == 0) {
571 struct mbuf *m0;
572 m0 = ipfw_send_pkt(args->m, &(args->f_id),
573 ntohl(tcp->th_seq), ntohl(tcp->th_ack),
574 tcp->th_flags | TH_RST);
575 if (m0 != NULL)
576 ip6_output(m0, NULL, NULL, 0, NULL, NULL,
577 NULL);
578 }
579 FREE_PKT(m);
580 } else if (code != ICMP6_UNREACH_RST) { /* Send an ICMPv6 unreach. */
581#if 0
582 /*
583 * Unlike above, the mbufs need to line up with the ip6 hdr,
584 * as the contents are read. We need to m_adj() the
585 * needed amount.
586 * The mbuf will however be thrown away so we can adjust it.
587 * Remember we did an m_pullup on it already so we
588 * can make some assumptions about contiguousness.
589 */
590 if (args->L3offset)
591 m_adj(m, args->L3offset);
592#endif
593 icmp6_error(m, ICMP6_DST_UNREACH, code, 0);
594 } else
595 FREE_PKT(m);
596
597 args->m = NULL;
598}
599
600#endif /* INET6 */
601
602
603/*
604 * sends a reject message, consuming the mbuf passed as an argument.
605 */
606static void
607send_reject(struct ip_fw_args *args, int code, int iplen, struct ip *ip)
608{
609
610#if 0
611 /* XXX When ip is not guaranteed to be at mtod() we will
612 * need to account for this */
613 * The mbuf will however be thrown away so we can adjust it.
614 * Remember we did an m_pullup on it already so we
615 * can make some assumptions about contiguousness.
616 */
617 if (args->L3offset)
618 m_adj(m, args->L3offset);
619#endif
620 if (code != ICMP_REJECT_RST) { /* Send an ICMP unreach */
621 /* We need the IP header in host order for icmp_error(). */
622 SET_HOST_IPLEN(ip);
623 icmp_error(args->m, ICMP_UNREACH, code, 0L, 0);
624 } else if (args->f_id.proto == IPPROTO_TCP) {
625 struct tcphdr *const tcp =
626 L3HDR(struct tcphdr, mtod(args->m, struct ip *));
627 if ( (tcp->th_flags & TH_RST) == 0) {
628 struct mbuf *m;
629 m = ipfw_send_pkt(args->m, &(args->f_id),
630 ntohl(tcp->th_seq), ntohl(tcp->th_ack),
631 tcp->th_flags | TH_RST);
632 if (m != NULL)
633 ip_output(m, NULL, NULL, 0, NULL, NULL);
634 }
635 FREE_PKT(args->m);
636 } else
637 FREE_PKT(args->m);
638 args->m = NULL;
639}
640
641/*
642 * Support for uid/gid/jail lookup. These tests are expensive
643 * (because we may need to look into the list of active sockets)
644 * so we cache the results. ugid_lookupp is 0 if we have not
645 * yet done a lookup, 1 if we succeeded, and -1 if we tried
646 * and failed. The function always returns the match value.
647 * We could actually spare the variable and use *uc, setting
648 * it to '(void *)check_uidgid if we have no info, NULL if
649 * we tried and failed, or any other value if successful.
650 */
651static int
652check_uidgid(ipfw_insn_u32 *insn, struct ip_fw_args *args, int *ugid_lookupp,
653 struct ucred **uc)
654{
655#ifndef __FreeBSD__
656 /* XXX */
657 return cred_check(insn, proto, oif,
658 dst_ip, dst_port, src_ip, src_port,
659 (struct bsd_ucred *)uc, ugid_lookupp, ((struct mbuf *)inp)->m_skb);
660#else /* FreeBSD */
661 struct in_addr src_ip, dst_ip;
662 struct inpcbinfo *pi;
663 struct ipfw_flow_id *id;
664 struct inpcb *pcb, *inp;
665 struct ifnet *oif;
666 int lookupflags;
667 int match;
668
669 id = &args->f_id;
670 inp = args->inp;
671 oif = args->oif;
672
673 /*
674 * Check to see if the UDP or TCP stack supplied us with
675 * the PCB. If so, rather then holding a lock and looking
676 * up the PCB, we can use the one that was supplied.
677 */
678 if (inp && *ugid_lookupp == 0) {
679 INP_LOCK_ASSERT(inp);
680 if (inp->inp_socket != NULL) {
681 *uc = crhold(inp->inp_cred);
682 *ugid_lookupp = 1;
683 } else
684 *ugid_lookupp = -1;
685 }
686 /*
687 * If we have already been here and the packet has no
688 * PCB entry associated with it, then we can safely
689 * assume that this is a no match.
690 */
691 if (*ugid_lookupp == -1)
692 return (0);
693 if (id->proto == IPPROTO_TCP) {
694 lookupflags = 0;
695 pi = &V_tcbinfo;
696 } else if (id->proto == IPPROTO_UDP) {
697 lookupflags = INPLOOKUP_WILDCARD;
698 pi = &V_udbinfo;
699 } else
700 return 0;
701 lookupflags |= INPLOOKUP_RLOCKPCB;
702 match = 0;
703 if (*ugid_lookupp == 0) {
704 if (id->addr_type == 6) {
705#ifdef INET6
706 if (oif == NULL)
707 pcb = in6_pcblookup_mbuf(pi,
708 &id->src_ip6, htons(id->src_port),
709 &id->dst_ip6, htons(id->dst_port),
710 lookupflags, oif, args->m);
711 else
712 pcb = in6_pcblookup_mbuf(pi,
713 &id->dst_ip6, htons(id->dst_port),
714 &id->src_ip6, htons(id->src_port),
715 lookupflags, oif, args->m);
716#else
717 *ugid_lookupp = -1;
718 return (0);
719#endif
720 } else {
721 src_ip.s_addr = htonl(id->src_ip);
722 dst_ip.s_addr = htonl(id->dst_ip);
723 if (oif == NULL)
724 pcb = in_pcblookup_mbuf(pi,
725 src_ip, htons(id->src_port),
726 dst_ip, htons(id->dst_port),
727 lookupflags, oif, args->m);
728 else
729 pcb = in_pcblookup_mbuf(pi,
730 dst_ip, htons(id->dst_port),
731 src_ip, htons(id->src_port),
732 lookupflags, oif, args->m);
733 }
734 if (pcb != NULL) {
735 INP_RLOCK_ASSERT(pcb);
736 *uc = crhold(pcb->inp_cred);
737 *ugid_lookupp = 1;
738 INP_RUNLOCK(pcb);
739 }
740 if (*ugid_lookupp == 0) {
741 /*
742 * We tried and failed, set the variable to -1
743 * so we will not try again on this packet.
744 */
745 *ugid_lookupp = -1;
746 return (0);
747 }
748 }
749 if (insn->o.opcode == O_UID)
750 match = ((*uc)->cr_uid == (uid_t)insn->d[0]);
751 else if (insn->o.opcode == O_GID)
752 match = groupmember((gid_t)insn->d[0], *uc);
753 else if (insn->o.opcode == O_JAIL)
754 match = ((*uc)->cr_prison->pr_id == (int)insn->d[0]);
755 return (match);
756#endif /* __FreeBSD__ */
757}
758
759/*
760 * Helper function to set args with info on the rule after the matching
761 * one. slot is precise, whereas we guess rule_id as they are
762 * assigned sequentially.
763 */
764static inline void
765set_match(struct ip_fw_args *args, int slot,
766 struct ip_fw_chain *chain)
767{
768 args->rule.chain_id = chain->id;
769 args->rule.slot = slot + 1; /* we use 0 as a marker */
770 args->rule.rule_id = 1 + chain->map[slot]->id;
771 args->rule.rulenum = chain->map[slot]->rulenum;
772}
773
774/*
775 * The main check routine for the firewall.
776 *
777 * All arguments are in args so we can modify them and return them
778 * back to the caller.
779 *
780 * Parameters:
781 *
782 * args->m (in/out) The packet; we set to NULL when/if we nuke it.
783 * Starts with the IP header.
784 * args->eh (in) Mac header if present, NULL for layer3 packet.
785 * args->L3offset Number of bytes bypassed if we came from L2.
786 * e.g. often sizeof(eh) ** NOTYET **
787 * args->oif Outgoing interface, NULL if packet is incoming.
788 * The incoming interface is in the mbuf. (in)
789 * args->divert_rule (in/out)
790 * Skip up to the first rule past this rule number;
791 * upon return, non-zero port number for divert or tee.
792 *
793 * args->rule Pointer to the last matching rule (in/out)
794 * args->next_hop Socket we are forwarding to (out).
795 * args->next_hop6 IPv6 next hop we are forwarding to (out).
796 * args->f_id Addresses grabbed from the packet (out)
797 * args->rule.info a cookie depending on rule action
798 *
799 * Return value:
800 *
801 * IP_FW_PASS the packet must be accepted
802 * IP_FW_DENY the packet must be dropped
803 * IP_FW_DIVERT divert packet, port in m_tag
804 * IP_FW_TEE tee packet, port in m_tag
805 * IP_FW_DUMMYNET to dummynet, pipe in args->cookie
806 * IP_FW_NETGRAPH into netgraph, cookie args->cookie
807 * args->rule contains the matching rule,
808 * args->rule.info has additional information.
809 *
810 */
811int
812ipfw_chk(struct ip_fw_args *args)
813{
814
815 /*
816 * Local variables holding state while processing a packet:
817 *
818 * IMPORTANT NOTE: to speed up the processing of rules, there
819 * are some assumption on the values of the variables, which
820 * are documented here. Should you change them, please check
821 * the implementation of the various instructions to make sure
822 * that they still work.
823 *
824 * args->eh The MAC header. It is non-null for a layer2
825 * packet, it is NULL for a layer-3 packet.
826 * **notyet**
827 * args->L3offset Offset in the packet to the L3 (IP or equiv.) header.
828 *
829 * m | args->m Pointer to the mbuf, as received from the caller.
830 * It may change if ipfw_chk() does an m_pullup, or if it
831 * consumes the packet because it calls send_reject().
832 * XXX This has to change, so that ipfw_chk() never modifies
833 * or consumes the buffer.
834 * ip is the beginning of the ip(4 or 6) header.
835 * Calculated by adding the L3offset to the start of data.
836 * (Until we start using L3offset, the packet is
837 * supposed to start with the ip header).
838 */
839 struct mbuf *m = args->m;
840 struct ip *ip = mtod(m, struct ip *);
841
842 /*
843 * For rules which contain uid/gid or jail constraints, cache
844 * a copy of the users credentials after the pcb lookup has been
845 * executed. This will speed up the processing of rules with
846 * these types of constraints, as well as decrease contention
847 * on pcb related locks.
848 */
849#ifndef __FreeBSD__
850 struct bsd_ucred ucred_cache;
851#else
852 struct ucred *ucred_cache = NULL;
853#endif
854 int ucred_lookup = 0;
855
856 /*
857 * oif | args->oif If NULL, ipfw_chk has been called on the
858 * inbound path (ether_input, ip_input).
859 * If non-NULL, ipfw_chk has been called on the outbound path
860 * (ether_output, ip_output).
861 */
862 struct ifnet *oif = args->oif;
863
864 int f_pos = 0; /* index of current rule in the array */
865 int retval = 0;
866
867 /*
868 * hlen The length of the IP header.
869 */
870 u_int hlen = 0; /* hlen >0 means we have an IP pkt */
871
872 /*
873 * offset The offset of a fragment. offset != 0 means that
874 * we have a fragment at this offset of an IPv4 packet.
875 * offset == 0 means that (if this is an IPv4 packet)
876 * this is the first or only fragment.
877 * For IPv6 offset|ip6f_mf == 0 means there is no Fragment Header
878 * or there is a single packet fragement (fragement header added
879 * without needed). We will treat a single packet fragment as if
880 * there was no fragment header (or log/block depending on the
881 * V_fw_permit_single_frag6 sysctl setting).
882 */
883 u_short offset = 0;
884 u_short ip6f_mf = 0;
885
886 /*
887 * Local copies of addresses. They are only valid if we have
888 * an IP packet.
889 *
890 * proto The protocol. Set to 0 for non-ip packets,
891 * or to the protocol read from the packet otherwise.
892 * proto != 0 means that we have an IPv4 packet.
893 *
894 * src_port, dst_port port numbers, in HOST format. Only
895 * valid for TCP and UDP packets.
896 *
897 * src_ip, dst_ip ip addresses, in NETWORK format.
898 * Only valid for IPv4 packets.
899 */
900 uint8_t proto;
901 uint16_t src_port = 0, dst_port = 0; /* NOTE: host format */
902 struct in_addr src_ip, dst_ip; /* NOTE: network format */
903 uint16_t iplen=0;
904 int pktlen;
905 uint16_t etype = 0; /* Host order stored ether type */
906
907 /*
908 * dyn_dir = MATCH_UNKNOWN when rules unchecked,
909 * MATCH_NONE when checked and not matched (q = NULL),
910 * MATCH_FORWARD or MATCH_REVERSE otherwise (q != NULL)
911 */
912 int dyn_dir = MATCH_UNKNOWN;
913 ipfw_dyn_rule *q = NULL;
914 struct ip_fw_chain *chain = &V_layer3_chain;
915
916 /*
917 * We store in ulp a pointer to the upper layer protocol header.
918 * In the ipv4 case this is easy to determine from the header,
919 * but for ipv6 we might have some additional headers in the middle.
920 * ulp is NULL if not found.
921 */
922 void *ulp = NULL; /* upper layer protocol pointer. */
923
924 /* XXX ipv6 variables */
925 int is_ipv6 = 0;
926 uint8_t icmp6_type = 0;
927 uint16_t ext_hd = 0; /* bits vector for extension header filtering */
928 /* end of ipv6 variables */
929
930 int is_ipv4 = 0;
931
932 int done = 0; /* flag to exit the outer loop */
933
934 if (m->m_flags & M_SKIP_FIREWALL || (! V_ipfw_vnet_ready))
935 return (IP_FW_PASS); /* accept */
936
937 dst_ip.s_addr = 0; /* make sure it is initialized */
938 src_ip.s_addr = 0; /* make sure it is initialized */
939 pktlen = m->m_pkthdr.len;
940 args->f_id.fib = M_GETFIB(m); /* note mbuf not altered) */
941 proto = args->f_id.proto = 0; /* mark f_id invalid */
942 /* XXX 0 is a valid proto: IP/IPv6 Hop-by-Hop Option */
943
944/*
945 * PULLUP_TO(len, p, T) makes sure that len + sizeof(T) is contiguous,
946 * then it sets p to point at the offset "len" in the mbuf. WARNING: the
947 * pointer might become stale after other pullups (but we never use it
948 * this way).
949 */
950#define PULLUP_TO(_len, p, T) PULLUP_LEN(_len, p, sizeof(T))
951#define PULLUP_LEN(_len, p, T) \
952do { \
953 int x = (_len) + T; \
954 if ((m)->m_len < x) { \
955 args->m = m = m_pullup(m, x); \
956 if (m == NULL) \
957 goto pullup_failed; \
958 } \
959 p = (mtod(m, char *) + (_len)); \
960} while (0)
961
962 /*
963 * if we have an ether header,
964 */
965 if (args->eh)
966 etype = ntohs(args->eh->ether_type);
967
968 /* Identify IP packets and fill up variables. */
969 if (pktlen >= sizeof(struct ip6_hdr) &&
970 (args->eh == NULL || etype == ETHERTYPE_IPV6) && ip->ip_v == 6) {
971 struct ip6_hdr *ip6 = (struct ip6_hdr *)ip;
972 is_ipv6 = 1;
973 args->f_id.addr_type = 6;
974 hlen = sizeof(struct ip6_hdr);
975 proto = ip6->ip6_nxt;
976
977 /* Search extension headers to find upper layer protocols */
978 while (ulp == NULL && offset == 0) {
979 switch (proto) {
980 case IPPROTO_ICMPV6:
981 PULLUP_TO(hlen, ulp, struct icmp6_hdr);
982 icmp6_type = ICMP6(ulp)->icmp6_type;
983 break;
984
985 case IPPROTO_TCP:
986 PULLUP_TO(hlen, ulp, struct tcphdr);
987 dst_port = TCP(ulp)->th_dport;
988 src_port = TCP(ulp)->th_sport;
989 /* save flags for dynamic rules */
990 args->f_id._flags = TCP(ulp)->th_flags;
991 break;
992
993 case IPPROTO_SCTP:
994 PULLUP_TO(hlen, ulp, struct sctphdr);
995 src_port = SCTP(ulp)->src_port;
996 dst_port = SCTP(ulp)->dest_port;
997 break;
998
999 case IPPROTO_UDP:
1000 PULLUP_TO(hlen, ulp, struct udphdr);
1001 dst_port = UDP(ulp)->uh_dport;
1002 src_port = UDP(ulp)->uh_sport;
1003 break;
1004
1005 case IPPROTO_HOPOPTS: /* RFC 2460 */
1006 PULLUP_TO(hlen, ulp, struct ip6_hbh);
1007 ext_hd |= EXT_HOPOPTS;
1008 hlen += (((struct ip6_hbh *)ulp)->ip6h_len + 1) << 3;
1009 proto = ((struct ip6_hbh *)ulp)->ip6h_nxt;
1010 ulp = NULL;
1011 break;
1012
1013 case IPPROTO_ROUTING: /* RFC 2460 */
1014 PULLUP_TO(hlen, ulp, struct ip6_rthdr);
1015 switch (((struct ip6_rthdr *)ulp)->ip6r_type) {
1016 case 0:
1017 ext_hd |= EXT_RTHDR0;
1018 break;
1019 case 2:
1020 ext_hd |= EXT_RTHDR2;
1021 break;
1022 default:
1023 if (V_fw_verbose)
1024 printf("IPFW2: IPV6 - Unknown "
1025 "Routing Header type(%d)\n",
1026 ((struct ip6_rthdr *)
1027 ulp)->ip6r_type);
1028 if (V_fw_deny_unknown_exthdrs)
1029 return (IP_FW_DENY);
1030 break;
1031 }
1032 ext_hd |= EXT_ROUTING;
1033 hlen += (((struct ip6_rthdr *)ulp)->ip6r_len + 1) << 3;
1034 proto = ((struct ip6_rthdr *)ulp)->ip6r_nxt;
1035 ulp = NULL;
1036 break;
1037
1038 case IPPROTO_FRAGMENT: /* RFC 2460 */
1039 PULLUP_TO(hlen, ulp, struct ip6_frag);
1040 ext_hd |= EXT_FRAGMENT;
1041 hlen += sizeof (struct ip6_frag);
1042 proto = ((struct ip6_frag *)ulp)->ip6f_nxt;
1043 offset = ((struct ip6_frag *)ulp)->ip6f_offlg &
1044 IP6F_OFF_MASK;
1045 ip6f_mf = ((struct ip6_frag *)ulp)->ip6f_offlg &
1046 IP6F_MORE_FRAG;
1047 if (V_fw_permit_single_frag6 == 0 &&
1048 offset == 0 && ip6f_mf == 0) {
1049 if (V_fw_verbose)
1050 printf("IPFW2: IPV6 - Invalid "
1051 "Fragment Header\n");
1052 if (V_fw_deny_unknown_exthdrs)
1053 return (IP_FW_DENY);
1054 break;
1055 }
1056 args->f_id.extra =
1057 ntohl(((struct ip6_frag *)ulp)->ip6f_ident);
1058 ulp = NULL;
1059 break;
1060
1061 case IPPROTO_DSTOPTS: /* RFC 2460 */
1062 PULLUP_TO(hlen, ulp, struct ip6_hbh);
1063 ext_hd |= EXT_DSTOPTS;
1064 hlen += (((struct ip6_hbh *)ulp)->ip6h_len + 1) << 3;
1065 proto = ((struct ip6_hbh *)ulp)->ip6h_nxt;
1066 ulp = NULL;
1067 break;
1068
1069 case IPPROTO_AH: /* RFC 2402 */
1070 PULLUP_TO(hlen, ulp, struct ip6_ext);
1071 ext_hd |= EXT_AH;
1072 hlen += (((struct ip6_ext *)ulp)->ip6e_len + 2) << 2;
1073 proto = ((struct ip6_ext *)ulp)->ip6e_nxt;
1074 ulp = NULL;
1075 break;
1076
1077 case IPPROTO_ESP: /* RFC 2406 */
1078 PULLUP_TO(hlen, ulp, uint32_t); /* SPI, Seq# */
1079 /* Anything past Seq# is variable length and
1080 * data past this ext. header is encrypted. */
1081 ext_hd |= EXT_ESP;
1082 break;
1083
1084 case IPPROTO_NONE: /* RFC 2460 */
1085 /*
1086 * Packet ends here, and IPv6 header has
1087 * already been pulled up. If ip6e_len!=0
1088 * then octets must be ignored.
1089 */
1090 ulp = ip; /* non-NULL to get out of loop. */
1091 break;
1092
1093 case IPPROTO_OSPFIGP:
1094 /* XXX OSPF header check? */
1095 PULLUP_TO(hlen, ulp, struct ip6_ext);
1096 break;
1097
1098 case IPPROTO_PIM:
1099 /* XXX PIM header check? */
1100 PULLUP_TO(hlen, ulp, struct pim);
1101 break;
1102
1103 case IPPROTO_CARP:
1104 PULLUP_TO(hlen, ulp, struct carp_header);
1105 if (((struct carp_header *)ulp)->carp_version !=
1106 CARP_VERSION)
1107 return (IP_FW_DENY);
1108 if (((struct carp_header *)ulp)->carp_type !=
1109 CARP_ADVERTISEMENT)
1110 return (IP_FW_DENY);
1111 break;
1112
1113 case IPPROTO_IPV6: /* RFC 2893 */
1114 PULLUP_TO(hlen, ulp, struct ip6_hdr);
1115 break;
1116
1117 case IPPROTO_IPV4: /* RFC 2893 */
1118 PULLUP_TO(hlen, ulp, struct ip);
1119 break;
1120
1121 default:
1122 if (V_fw_verbose)
1123 printf("IPFW2: IPV6 - Unknown "
1124 "Extension Header(%d), ext_hd=%x\n",
1125 proto, ext_hd);
1126 if (V_fw_deny_unknown_exthdrs)
1127 return (IP_FW_DENY);
1128 PULLUP_TO(hlen, ulp, struct ip6_ext);
1129 break;
1130 } /*switch */
1131 }
1132 ip = mtod(m, struct ip *);
1133 ip6 = (struct ip6_hdr *)ip;
1134 args->f_id.src_ip6 = ip6->ip6_src;
1135 args->f_id.dst_ip6 = ip6->ip6_dst;
1136 args->f_id.src_ip = 0;
1137 args->f_id.dst_ip = 0;
1138 args->f_id.flow_id6 = ntohl(ip6->ip6_flow);
1139 } else if (pktlen >= sizeof(struct ip) &&
1140 (args->eh == NULL || etype == ETHERTYPE_IP) && ip->ip_v == 4) {
1141 is_ipv4 = 1;
1142 hlen = ip->ip_hl << 2;
1143 args->f_id.addr_type = 4;
1144
1145 /*
1146 * Collect parameters into local variables for faster matching.
1147 */
1148 proto = ip->ip_p;
1149 src_ip = ip->ip_src;
1150 dst_ip = ip->ip_dst;
1151 offset = ntohs(ip->ip_off) & IP_OFFMASK;
1152 iplen = ntohs(ip->ip_len);
1153 pktlen = iplen < pktlen ? iplen : pktlen;
1154
1155 if (offset == 0) {
1156 switch (proto) {
1157 case IPPROTO_TCP:
1158 PULLUP_TO(hlen, ulp, struct tcphdr);
1159 dst_port = TCP(ulp)->th_dport;
1160 src_port = TCP(ulp)->th_sport;
1161 /* save flags for dynamic rules */
1162 args->f_id._flags = TCP(ulp)->th_flags;
1163 break;
1164
1165 case IPPROTO_SCTP:
1166 PULLUP_TO(hlen, ulp, struct sctphdr);
1167 src_port = SCTP(ulp)->src_port;
1168 dst_port = SCTP(ulp)->dest_port;
1169 break;
1170
1171 case IPPROTO_UDP:
1172 PULLUP_TO(hlen, ulp, struct udphdr);
1173 dst_port = UDP(ulp)->uh_dport;
1174 src_port = UDP(ulp)->uh_sport;
1175 break;
1176
1177 case IPPROTO_ICMP:
1178 PULLUP_TO(hlen, ulp, struct icmphdr);
1179 //args->f_id.flags = ICMP(ulp)->icmp_type;
1180 break;
1181
1182 default:
1183 break;
1184 }
1185 }
1186
1187 ip = mtod(m, struct ip *);
1188 args->f_id.src_ip = ntohl(src_ip.s_addr);
1189 args->f_id.dst_ip = ntohl(dst_ip.s_addr);
1190 }
1191#undef PULLUP_TO
1192 if (proto) { /* we may have port numbers, store them */
1193 args->f_id.proto = proto;
1194 args->f_id.src_port = src_port = ntohs(src_port);
1195 args->f_id.dst_port = dst_port = ntohs(dst_port);
1196 }
1197
1198 IPFW_RLOCK(chain);
1199 if (! V_ipfw_vnet_ready) { /* shutting down, leave NOW. */
1200 IPFW_RUNLOCK(chain);
1201 return (IP_FW_PASS); /* accept */
1202 }
1203 if (args->rule.slot) {
1204 /*
1205 * Packet has already been tagged as a result of a previous
1206 * match on rule args->rule aka args->rule_id (PIPE, QUEUE,
1207 * REASS, NETGRAPH, DIVERT/TEE...)
1208 * Validate the slot and continue from the next one
1209 * if still present, otherwise do a lookup.
1210 */
1211 f_pos = (args->rule.chain_id == chain->id) ?
1212 args->rule.slot :
1213 ipfw_find_rule(chain, args->rule.rulenum,
1214 args->rule.rule_id);
1215 } else {
1216 f_pos = 0;
1217 }
1218
1219 /*
1220 * Now scan the rules, and parse microinstructions for each rule.
1221 * We have two nested loops and an inner switch. Sometimes we
1222 * need to break out of one or both loops, or re-enter one of
1223 * the loops with updated variables. Loop variables are:
1224 *
1225 * f_pos (outer loop) points to the current rule.
1226 * On output it points to the matching rule.
1227 * done (outer loop) is used as a flag to break the loop.
1228 * l (inner loop) residual length of current rule.
1229 * cmd points to the current microinstruction.
1230 *
1231 * We break the inner loop by setting l=0 and possibly
1232 * cmdlen=0 if we don't want to advance cmd.
1233 * We break the outer loop by setting done=1
1234 * We can restart the inner loop by setting l>0 and f_pos, f, cmd
1235 * as needed.
1236 */
1237 for (; f_pos < chain->n_rules; f_pos++) {
1238 ipfw_insn *cmd;
1239 uint32_t tablearg = 0;
1240 int l, cmdlen, skip_or; /* skip rest of OR block */
1241 struct ip_fw *f;
1242
1243 f = chain->map[f_pos];
1244 if (V_set_disable & (1 << f->set) )
1245 continue;
1246
1247 skip_or = 0;
1248 for (l = f->cmd_len, cmd = f->cmd ; l > 0 ;
1249 l -= cmdlen, cmd += cmdlen) {
1250 int match;
1251
1252 /*
1253 * check_body is a jump target used when we find a
1254 * CHECK_STATE, and need to jump to the body of
1255 * the target rule.
1256 */
1257
1258/* check_body: */
1259 cmdlen = F_LEN(cmd);
1260 /*
1261 * An OR block (insn_1 || .. || insn_n) has the
1262 * F_OR bit set in all but the last instruction.
1263 * The first match will set "skip_or", and cause
1264 * the following instructions to be skipped until
1265 * past the one with the F_OR bit clear.
1266 */
1267 if (skip_or) { /* skip this instruction */
1268 if ((cmd->len & F_OR) == 0)
1269 skip_or = 0; /* next one is good */
1270 continue;
1271 }
1272 match = 0; /* set to 1 if we succeed */
1273
1274 switch (cmd->opcode) {
1275 /*
1276 * The first set of opcodes compares the packet's
1277 * fields with some pattern, setting 'match' if a
1278 * match is found. At the end of the loop there is
1279 * logic to deal with F_NOT and F_OR flags associated
1280 * with the opcode.
1281 */
1282 case O_NOP:
1283 match = 1;
1284 break;
1285
1286 case O_FORWARD_MAC:
1287 printf("ipfw: opcode %d unimplemented\n",
1288 cmd->opcode);
1289 break;
1290
1291 case O_GID:
1292 case O_UID:
1293 case O_JAIL:
1294 /*
1295 * We only check offset == 0 && proto != 0,
1296 * as this ensures that we have a
1297 * packet with the ports info.
1298 */
1299 if (offset != 0)
1300 break;
1301 if (proto == IPPROTO_TCP ||
1302 proto == IPPROTO_UDP)
1303 match = check_uidgid(
1304 (ipfw_insn_u32 *)cmd,
1305 args, &ucred_lookup,
1306#ifdef __FreeBSD__
1307 &ucred_cache);
1308#else
1309 (void *)&ucred_cache);
1310#endif
1311 break;
1312
1313 case O_RECV:
1314 match = iface_match(m->m_pkthdr.rcvif,
356 /* Check name */
357 if (cmd->p.glob) {
358 if (fnmatch(cmd->name, ifp->if_xname, 0) == 0)
359 return(1);
360 } else {
361 if (strncmp(ifp->if_xname, cmd->name, IFNAMSIZ) == 0)
362 return(1);
363 }
364 } else {
365#ifdef __FreeBSD__ /* and OSX too ? */
366 struct ifaddr *ia;
367
368 if_addr_rlock(ifp);
369 TAILQ_FOREACH(ia, &ifp->if_addrhead, ifa_link) {
370 if (ia->ifa_addr->sa_family != AF_INET)
371 continue;
372 if (cmd->p.ip.s_addr == ((struct sockaddr_in *)
373 (ia->ifa_addr))->sin_addr.s_addr) {
374 if_addr_runlock(ifp);
375 return(1); /* match */
376 }
377 }
378 if_addr_runlock(ifp);
379#endif /* __FreeBSD__ */
380 }
381 return(0); /* no match, fail ... */
382}
383
384/*
385 * The verify_path function checks if a route to the src exists and
386 * if it is reachable via ifp (when provided).
387 *
388 * The 'verrevpath' option checks that the interface that an IP packet
389 * arrives on is the same interface that traffic destined for the
390 * packet's source address would be routed out of.
391 * The 'versrcreach' option just checks that the source address is
392 * reachable via any route (except default) in the routing table.
393 * These two are a measure to block forged packets. This is also
394 * commonly known as "anti-spoofing" or Unicast Reverse Path
395 * Forwarding (Unicast RFP) in Cisco-ese. The name of the knobs
396 * is purposely reminiscent of the Cisco IOS command,
397 *
398 * ip verify unicast reverse-path
399 * ip verify unicast source reachable-via any
400 *
401 * which implements the same functionality. But note that the syntax
402 * is misleading, and the check may be performed on all IP packets
403 * whether unicast, multicast, or broadcast.
404 */
405static int
406verify_path(struct in_addr src, struct ifnet *ifp, u_int fib)
407{
408#ifndef __FreeBSD__
409 return 0;
410#else
411 struct route ro;
412 struct sockaddr_in *dst;
413
414 bzero(&ro, sizeof(ro));
415
416 dst = (struct sockaddr_in *)&(ro.ro_dst);
417 dst->sin_family = AF_INET;
418 dst->sin_len = sizeof(*dst);
419 dst->sin_addr = src;
420 in_rtalloc_ign(&ro, 0, fib);
421
422 if (ro.ro_rt == NULL)
423 return 0;
424
425 /*
426 * If ifp is provided, check for equality with rtentry.
427 * We should use rt->rt_ifa->ifa_ifp, instead of rt->rt_ifp,
428 * in order to pass packets injected back by if_simloop():
429 * if useloopback == 1 routing entry (via lo0) for our own address
430 * may exist, so we need to handle routing assymetry.
431 */
432 if (ifp != NULL && ro.ro_rt->rt_ifa->ifa_ifp != ifp) {
433 RTFREE(ro.ro_rt);
434 return 0;
435 }
436
437 /* if no ifp provided, check if rtentry is not default route */
438 if (ifp == NULL &&
439 satosin(rt_key(ro.ro_rt))->sin_addr.s_addr == INADDR_ANY) {
440 RTFREE(ro.ro_rt);
441 return 0;
442 }
443
444 /* or if this is a blackhole/reject route */
445 if (ifp == NULL && ro.ro_rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
446 RTFREE(ro.ro_rt);
447 return 0;
448 }
449
450 /* found valid route */
451 RTFREE(ro.ro_rt);
452 return 1;
453#endif /* __FreeBSD__ */
454}
455
456#ifdef INET6
457/*
458 * ipv6 specific rules here...
459 */
460static __inline int
461icmp6type_match (int type, ipfw_insn_u32 *cmd)
462{
463 return (type <= ICMP6_MAXTYPE && (cmd->d[type/32] & (1<<(type%32)) ) );
464}
465
466static int
467flow6id_match( int curr_flow, ipfw_insn_u32 *cmd )
468{
469 int i;
470 for (i=0; i <= cmd->o.arg1; ++i )
471 if (curr_flow == cmd->d[i] )
472 return 1;
473 return 0;
474}
475
476/* support for IP6_*_ME opcodes */
477static int
478search_ip6_addr_net (struct in6_addr * ip6_addr)
479{
480 struct ifnet *mdc;
481 struct ifaddr *mdc2;
482 struct in6_ifaddr *fdm;
483 struct in6_addr copia;
484
485 TAILQ_FOREACH(mdc, &V_ifnet, if_link) {
486 if_addr_rlock(mdc);
487 TAILQ_FOREACH(mdc2, &mdc->if_addrhead, ifa_link) {
488 if (mdc2->ifa_addr->sa_family == AF_INET6) {
489 fdm = (struct in6_ifaddr *)mdc2;
490 copia = fdm->ia_addr.sin6_addr;
491 /* need for leaving scope_id in the sock_addr */
492 in6_clearscope(&copia);
493 if (IN6_ARE_ADDR_EQUAL(ip6_addr, &copia)) {
494 if_addr_runlock(mdc);
495 return 1;
496 }
497 }
498 }
499 if_addr_runlock(mdc);
500 }
501 return 0;
502}
503
504static int
505verify_path6(struct in6_addr *src, struct ifnet *ifp, u_int fib)
506{
507 struct route_in6 ro;
508 struct sockaddr_in6 *dst;
509
510 bzero(&ro, sizeof(ro));
511
512 dst = (struct sockaddr_in6 * )&(ro.ro_dst);
513 dst->sin6_family = AF_INET6;
514 dst->sin6_len = sizeof(*dst);
515 dst->sin6_addr = *src;
516
517 in6_rtalloc_ign(&ro, 0, fib);
518 if (ro.ro_rt == NULL)
519 return 0;
520
521 /*
522 * if ifp is provided, check for equality with rtentry
523 * We should use rt->rt_ifa->ifa_ifp, instead of rt->rt_ifp,
524 * to support the case of sending packets to an address of our own.
525 * (where the former interface is the first argument of if_simloop()
526 * (=ifp), the latter is lo0)
527 */
528 if (ifp != NULL && ro.ro_rt->rt_ifa->ifa_ifp != ifp) {
529 RTFREE(ro.ro_rt);
530 return 0;
531 }
532
533 /* if no ifp provided, check if rtentry is not default route */
534 if (ifp == NULL &&
535 IN6_IS_ADDR_UNSPECIFIED(&satosin6(rt_key(ro.ro_rt))->sin6_addr)) {
536 RTFREE(ro.ro_rt);
537 return 0;
538 }
539
540 /* or if this is a blackhole/reject route */
541 if (ifp == NULL && ro.ro_rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
542 RTFREE(ro.ro_rt);
543 return 0;
544 }
545
546 /* found valid route */
547 RTFREE(ro.ro_rt);
548 return 1;
549
550}
551
552static int
553is_icmp6_query(int icmp6_type)
554{
555 if ((icmp6_type <= ICMP6_MAXTYPE) &&
556 (icmp6_type == ICMP6_ECHO_REQUEST ||
557 icmp6_type == ICMP6_MEMBERSHIP_QUERY ||
558 icmp6_type == ICMP6_WRUREQUEST ||
559 icmp6_type == ICMP6_FQDN_QUERY ||
560 icmp6_type == ICMP6_NI_QUERY))
561 return (1);
562
563 return (0);
564}
565
566static void
567send_reject6(struct ip_fw_args *args, int code, u_int hlen, struct ip6_hdr *ip6)
568{
569 struct mbuf *m;
570
571 m = args->m;
572 if (code == ICMP6_UNREACH_RST && args->f_id.proto == IPPROTO_TCP) {
573 struct tcphdr *tcp;
574 tcp = (struct tcphdr *)((char *)ip6 + hlen);
575
576 if ((tcp->th_flags & TH_RST) == 0) {
577 struct mbuf *m0;
578 m0 = ipfw_send_pkt(args->m, &(args->f_id),
579 ntohl(tcp->th_seq), ntohl(tcp->th_ack),
580 tcp->th_flags | TH_RST);
581 if (m0 != NULL)
582 ip6_output(m0, NULL, NULL, 0, NULL, NULL,
583 NULL);
584 }
585 FREE_PKT(m);
586 } else if (code != ICMP6_UNREACH_RST) { /* Send an ICMPv6 unreach. */
587#if 0
588 /*
589 * Unlike above, the mbufs need to line up with the ip6 hdr,
590 * as the contents are read. We need to m_adj() the
591 * needed amount.
592 * The mbuf will however be thrown away so we can adjust it.
593 * Remember we did an m_pullup on it already so we
594 * can make some assumptions about contiguousness.
595 */
596 if (args->L3offset)
597 m_adj(m, args->L3offset);
598#endif
599 icmp6_error(m, ICMP6_DST_UNREACH, code, 0);
600 } else
601 FREE_PKT(m);
602
603 args->m = NULL;
604}
605
606#endif /* INET6 */
607
608
609/*
610 * sends a reject message, consuming the mbuf passed as an argument.
611 */
612static void
613send_reject(struct ip_fw_args *args, int code, int iplen, struct ip *ip)
614{
615
616#if 0
617 /* XXX When ip is not guaranteed to be at mtod() we will
618 * need to account for this */
619 * The mbuf will however be thrown away so we can adjust it.
620 * Remember we did an m_pullup on it already so we
621 * can make some assumptions about contiguousness.
622 */
623 if (args->L3offset)
624 m_adj(m, args->L3offset);
625#endif
626 if (code != ICMP_REJECT_RST) { /* Send an ICMP unreach */
627 /* We need the IP header in host order for icmp_error(). */
628 SET_HOST_IPLEN(ip);
629 icmp_error(args->m, ICMP_UNREACH, code, 0L, 0);
630 } else if (args->f_id.proto == IPPROTO_TCP) {
631 struct tcphdr *const tcp =
632 L3HDR(struct tcphdr, mtod(args->m, struct ip *));
633 if ( (tcp->th_flags & TH_RST) == 0) {
634 struct mbuf *m;
635 m = ipfw_send_pkt(args->m, &(args->f_id),
636 ntohl(tcp->th_seq), ntohl(tcp->th_ack),
637 tcp->th_flags | TH_RST);
638 if (m != NULL)
639 ip_output(m, NULL, NULL, 0, NULL, NULL);
640 }
641 FREE_PKT(args->m);
642 } else
643 FREE_PKT(args->m);
644 args->m = NULL;
645}
646
647/*
648 * Support for uid/gid/jail lookup. These tests are expensive
649 * (because we may need to look into the list of active sockets)
650 * so we cache the results. ugid_lookupp is 0 if we have not
651 * yet done a lookup, 1 if we succeeded, and -1 if we tried
652 * and failed. The function always returns the match value.
653 * We could actually spare the variable and use *uc, setting
654 * it to '(void *)check_uidgid if we have no info, NULL if
655 * we tried and failed, or any other value if successful.
656 */
657static int
658check_uidgid(ipfw_insn_u32 *insn, struct ip_fw_args *args, int *ugid_lookupp,
659 struct ucred **uc)
660{
661#ifndef __FreeBSD__
662 /* XXX */
663 return cred_check(insn, proto, oif,
664 dst_ip, dst_port, src_ip, src_port,
665 (struct bsd_ucred *)uc, ugid_lookupp, ((struct mbuf *)inp)->m_skb);
666#else /* FreeBSD */
667 struct in_addr src_ip, dst_ip;
668 struct inpcbinfo *pi;
669 struct ipfw_flow_id *id;
670 struct inpcb *pcb, *inp;
671 struct ifnet *oif;
672 int lookupflags;
673 int match;
674
675 id = &args->f_id;
676 inp = args->inp;
677 oif = args->oif;
678
679 /*
680 * Check to see if the UDP or TCP stack supplied us with
681 * the PCB. If so, rather then holding a lock and looking
682 * up the PCB, we can use the one that was supplied.
683 */
684 if (inp && *ugid_lookupp == 0) {
685 INP_LOCK_ASSERT(inp);
686 if (inp->inp_socket != NULL) {
687 *uc = crhold(inp->inp_cred);
688 *ugid_lookupp = 1;
689 } else
690 *ugid_lookupp = -1;
691 }
692 /*
693 * If we have already been here and the packet has no
694 * PCB entry associated with it, then we can safely
695 * assume that this is a no match.
696 */
697 if (*ugid_lookupp == -1)
698 return (0);
699 if (id->proto == IPPROTO_TCP) {
700 lookupflags = 0;
701 pi = &V_tcbinfo;
702 } else if (id->proto == IPPROTO_UDP) {
703 lookupflags = INPLOOKUP_WILDCARD;
704 pi = &V_udbinfo;
705 } else
706 return 0;
707 lookupflags |= INPLOOKUP_RLOCKPCB;
708 match = 0;
709 if (*ugid_lookupp == 0) {
710 if (id->addr_type == 6) {
711#ifdef INET6
712 if (oif == NULL)
713 pcb = in6_pcblookup_mbuf(pi,
714 &id->src_ip6, htons(id->src_port),
715 &id->dst_ip6, htons(id->dst_port),
716 lookupflags, oif, args->m);
717 else
718 pcb = in6_pcblookup_mbuf(pi,
719 &id->dst_ip6, htons(id->dst_port),
720 &id->src_ip6, htons(id->src_port),
721 lookupflags, oif, args->m);
722#else
723 *ugid_lookupp = -1;
724 return (0);
725#endif
726 } else {
727 src_ip.s_addr = htonl(id->src_ip);
728 dst_ip.s_addr = htonl(id->dst_ip);
729 if (oif == NULL)
730 pcb = in_pcblookup_mbuf(pi,
731 src_ip, htons(id->src_port),
732 dst_ip, htons(id->dst_port),
733 lookupflags, oif, args->m);
734 else
735 pcb = in_pcblookup_mbuf(pi,
736 dst_ip, htons(id->dst_port),
737 src_ip, htons(id->src_port),
738 lookupflags, oif, args->m);
739 }
740 if (pcb != NULL) {
741 INP_RLOCK_ASSERT(pcb);
742 *uc = crhold(pcb->inp_cred);
743 *ugid_lookupp = 1;
744 INP_RUNLOCK(pcb);
745 }
746 if (*ugid_lookupp == 0) {
747 /*
748 * We tried and failed, set the variable to -1
749 * so we will not try again on this packet.
750 */
751 *ugid_lookupp = -1;
752 return (0);
753 }
754 }
755 if (insn->o.opcode == O_UID)
756 match = ((*uc)->cr_uid == (uid_t)insn->d[0]);
757 else if (insn->o.opcode == O_GID)
758 match = groupmember((gid_t)insn->d[0], *uc);
759 else if (insn->o.opcode == O_JAIL)
760 match = ((*uc)->cr_prison->pr_id == (int)insn->d[0]);
761 return (match);
762#endif /* __FreeBSD__ */
763}
764
765/*
766 * Helper function to set args with info on the rule after the matching
767 * one. slot is precise, whereas we guess rule_id as they are
768 * assigned sequentially.
769 */
770static inline void
771set_match(struct ip_fw_args *args, int slot,
772 struct ip_fw_chain *chain)
773{
774 args->rule.chain_id = chain->id;
775 args->rule.slot = slot + 1; /* we use 0 as a marker */
776 args->rule.rule_id = 1 + chain->map[slot]->id;
777 args->rule.rulenum = chain->map[slot]->rulenum;
778}
779
780/*
781 * The main check routine for the firewall.
782 *
783 * All arguments are in args so we can modify them and return them
784 * back to the caller.
785 *
786 * Parameters:
787 *
788 * args->m (in/out) The packet; we set to NULL when/if we nuke it.
789 * Starts with the IP header.
790 * args->eh (in) Mac header if present, NULL for layer3 packet.
791 * args->L3offset Number of bytes bypassed if we came from L2.
792 * e.g. often sizeof(eh) ** NOTYET **
793 * args->oif Outgoing interface, NULL if packet is incoming.
794 * The incoming interface is in the mbuf. (in)
795 * args->divert_rule (in/out)
796 * Skip up to the first rule past this rule number;
797 * upon return, non-zero port number for divert or tee.
798 *
799 * args->rule Pointer to the last matching rule (in/out)
800 * args->next_hop Socket we are forwarding to (out).
801 * args->next_hop6 IPv6 next hop we are forwarding to (out).
802 * args->f_id Addresses grabbed from the packet (out)
803 * args->rule.info a cookie depending on rule action
804 *
805 * Return value:
806 *
807 * IP_FW_PASS the packet must be accepted
808 * IP_FW_DENY the packet must be dropped
809 * IP_FW_DIVERT divert packet, port in m_tag
810 * IP_FW_TEE tee packet, port in m_tag
811 * IP_FW_DUMMYNET to dummynet, pipe in args->cookie
812 * IP_FW_NETGRAPH into netgraph, cookie args->cookie
813 * args->rule contains the matching rule,
814 * args->rule.info has additional information.
815 *
816 */
817int
818ipfw_chk(struct ip_fw_args *args)
819{
820
821 /*
822 * Local variables holding state while processing a packet:
823 *
824 * IMPORTANT NOTE: to speed up the processing of rules, there
825 * are some assumption on the values of the variables, which
826 * are documented here. Should you change them, please check
827 * the implementation of the various instructions to make sure
828 * that they still work.
829 *
830 * args->eh The MAC header. It is non-null for a layer2
831 * packet, it is NULL for a layer-3 packet.
832 * **notyet**
833 * args->L3offset Offset in the packet to the L3 (IP or equiv.) header.
834 *
835 * m | args->m Pointer to the mbuf, as received from the caller.
836 * It may change if ipfw_chk() does an m_pullup, or if it
837 * consumes the packet because it calls send_reject().
838 * XXX This has to change, so that ipfw_chk() never modifies
839 * or consumes the buffer.
840 * ip is the beginning of the ip(4 or 6) header.
841 * Calculated by adding the L3offset to the start of data.
842 * (Until we start using L3offset, the packet is
843 * supposed to start with the ip header).
844 */
845 struct mbuf *m = args->m;
846 struct ip *ip = mtod(m, struct ip *);
847
848 /*
849 * For rules which contain uid/gid or jail constraints, cache
850 * a copy of the users credentials after the pcb lookup has been
851 * executed. This will speed up the processing of rules with
852 * these types of constraints, as well as decrease contention
853 * on pcb related locks.
854 */
855#ifndef __FreeBSD__
856 struct bsd_ucred ucred_cache;
857#else
858 struct ucred *ucred_cache = NULL;
859#endif
860 int ucred_lookup = 0;
861
862 /*
863 * oif | args->oif If NULL, ipfw_chk has been called on the
864 * inbound path (ether_input, ip_input).
865 * If non-NULL, ipfw_chk has been called on the outbound path
866 * (ether_output, ip_output).
867 */
868 struct ifnet *oif = args->oif;
869
870 int f_pos = 0; /* index of current rule in the array */
871 int retval = 0;
872
873 /*
874 * hlen The length of the IP header.
875 */
876 u_int hlen = 0; /* hlen >0 means we have an IP pkt */
877
878 /*
879 * offset The offset of a fragment. offset != 0 means that
880 * we have a fragment at this offset of an IPv4 packet.
881 * offset == 0 means that (if this is an IPv4 packet)
882 * this is the first or only fragment.
883 * For IPv6 offset|ip6f_mf == 0 means there is no Fragment Header
884 * or there is a single packet fragement (fragement header added
885 * without needed). We will treat a single packet fragment as if
886 * there was no fragment header (or log/block depending on the
887 * V_fw_permit_single_frag6 sysctl setting).
888 */
889 u_short offset = 0;
890 u_short ip6f_mf = 0;
891
892 /*
893 * Local copies of addresses. They are only valid if we have
894 * an IP packet.
895 *
896 * proto The protocol. Set to 0 for non-ip packets,
897 * or to the protocol read from the packet otherwise.
898 * proto != 0 means that we have an IPv4 packet.
899 *
900 * src_port, dst_port port numbers, in HOST format. Only
901 * valid for TCP and UDP packets.
902 *
903 * src_ip, dst_ip ip addresses, in NETWORK format.
904 * Only valid for IPv4 packets.
905 */
906 uint8_t proto;
907 uint16_t src_port = 0, dst_port = 0; /* NOTE: host format */
908 struct in_addr src_ip, dst_ip; /* NOTE: network format */
909 uint16_t iplen=0;
910 int pktlen;
911 uint16_t etype = 0; /* Host order stored ether type */
912
913 /*
914 * dyn_dir = MATCH_UNKNOWN when rules unchecked,
915 * MATCH_NONE when checked and not matched (q = NULL),
916 * MATCH_FORWARD or MATCH_REVERSE otherwise (q != NULL)
917 */
918 int dyn_dir = MATCH_UNKNOWN;
919 ipfw_dyn_rule *q = NULL;
920 struct ip_fw_chain *chain = &V_layer3_chain;
921
922 /*
923 * We store in ulp a pointer to the upper layer protocol header.
924 * In the ipv4 case this is easy to determine from the header,
925 * but for ipv6 we might have some additional headers in the middle.
926 * ulp is NULL if not found.
927 */
928 void *ulp = NULL; /* upper layer protocol pointer. */
929
930 /* XXX ipv6 variables */
931 int is_ipv6 = 0;
932 uint8_t icmp6_type = 0;
933 uint16_t ext_hd = 0; /* bits vector for extension header filtering */
934 /* end of ipv6 variables */
935
936 int is_ipv4 = 0;
937
938 int done = 0; /* flag to exit the outer loop */
939
940 if (m->m_flags & M_SKIP_FIREWALL || (! V_ipfw_vnet_ready))
941 return (IP_FW_PASS); /* accept */
942
943 dst_ip.s_addr = 0; /* make sure it is initialized */
944 src_ip.s_addr = 0; /* make sure it is initialized */
945 pktlen = m->m_pkthdr.len;
946 args->f_id.fib = M_GETFIB(m); /* note mbuf not altered) */
947 proto = args->f_id.proto = 0; /* mark f_id invalid */
948 /* XXX 0 is a valid proto: IP/IPv6 Hop-by-Hop Option */
949
950/*
951 * PULLUP_TO(len, p, T) makes sure that len + sizeof(T) is contiguous,
952 * then it sets p to point at the offset "len" in the mbuf. WARNING: the
953 * pointer might become stale after other pullups (but we never use it
954 * this way).
955 */
956#define PULLUP_TO(_len, p, T) PULLUP_LEN(_len, p, sizeof(T))
957#define PULLUP_LEN(_len, p, T) \
958do { \
959 int x = (_len) + T; \
960 if ((m)->m_len < x) { \
961 args->m = m = m_pullup(m, x); \
962 if (m == NULL) \
963 goto pullup_failed; \
964 } \
965 p = (mtod(m, char *) + (_len)); \
966} while (0)
967
968 /*
969 * if we have an ether header,
970 */
971 if (args->eh)
972 etype = ntohs(args->eh->ether_type);
973
974 /* Identify IP packets and fill up variables. */
975 if (pktlen >= sizeof(struct ip6_hdr) &&
976 (args->eh == NULL || etype == ETHERTYPE_IPV6) && ip->ip_v == 6) {
977 struct ip6_hdr *ip6 = (struct ip6_hdr *)ip;
978 is_ipv6 = 1;
979 args->f_id.addr_type = 6;
980 hlen = sizeof(struct ip6_hdr);
981 proto = ip6->ip6_nxt;
982
983 /* Search extension headers to find upper layer protocols */
984 while (ulp == NULL && offset == 0) {
985 switch (proto) {
986 case IPPROTO_ICMPV6:
987 PULLUP_TO(hlen, ulp, struct icmp6_hdr);
988 icmp6_type = ICMP6(ulp)->icmp6_type;
989 break;
990
991 case IPPROTO_TCP:
992 PULLUP_TO(hlen, ulp, struct tcphdr);
993 dst_port = TCP(ulp)->th_dport;
994 src_port = TCP(ulp)->th_sport;
995 /* save flags for dynamic rules */
996 args->f_id._flags = TCP(ulp)->th_flags;
997 break;
998
999 case IPPROTO_SCTP:
1000 PULLUP_TO(hlen, ulp, struct sctphdr);
1001 src_port = SCTP(ulp)->src_port;
1002 dst_port = SCTP(ulp)->dest_port;
1003 break;
1004
1005 case IPPROTO_UDP:
1006 PULLUP_TO(hlen, ulp, struct udphdr);
1007 dst_port = UDP(ulp)->uh_dport;
1008 src_port = UDP(ulp)->uh_sport;
1009 break;
1010
1011 case IPPROTO_HOPOPTS: /* RFC 2460 */
1012 PULLUP_TO(hlen, ulp, struct ip6_hbh);
1013 ext_hd |= EXT_HOPOPTS;
1014 hlen += (((struct ip6_hbh *)ulp)->ip6h_len + 1) << 3;
1015 proto = ((struct ip6_hbh *)ulp)->ip6h_nxt;
1016 ulp = NULL;
1017 break;
1018
1019 case IPPROTO_ROUTING: /* RFC 2460 */
1020 PULLUP_TO(hlen, ulp, struct ip6_rthdr);
1021 switch (((struct ip6_rthdr *)ulp)->ip6r_type) {
1022 case 0:
1023 ext_hd |= EXT_RTHDR0;
1024 break;
1025 case 2:
1026 ext_hd |= EXT_RTHDR2;
1027 break;
1028 default:
1029 if (V_fw_verbose)
1030 printf("IPFW2: IPV6 - Unknown "
1031 "Routing Header type(%d)\n",
1032 ((struct ip6_rthdr *)
1033 ulp)->ip6r_type);
1034 if (V_fw_deny_unknown_exthdrs)
1035 return (IP_FW_DENY);
1036 break;
1037 }
1038 ext_hd |= EXT_ROUTING;
1039 hlen += (((struct ip6_rthdr *)ulp)->ip6r_len + 1) << 3;
1040 proto = ((struct ip6_rthdr *)ulp)->ip6r_nxt;
1041 ulp = NULL;
1042 break;
1043
1044 case IPPROTO_FRAGMENT: /* RFC 2460 */
1045 PULLUP_TO(hlen, ulp, struct ip6_frag);
1046 ext_hd |= EXT_FRAGMENT;
1047 hlen += sizeof (struct ip6_frag);
1048 proto = ((struct ip6_frag *)ulp)->ip6f_nxt;
1049 offset = ((struct ip6_frag *)ulp)->ip6f_offlg &
1050 IP6F_OFF_MASK;
1051 ip6f_mf = ((struct ip6_frag *)ulp)->ip6f_offlg &
1052 IP6F_MORE_FRAG;
1053 if (V_fw_permit_single_frag6 == 0 &&
1054 offset == 0 && ip6f_mf == 0) {
1055 if (V_fw_verbose)
1056 printf("IPFW2: IPV6 - Invalid "
1057 "Fragment Header\n");
1058 if (V_fw_deny_unknown_exthdrs)
1059 return (IP_FW_DENY);
1060 break;
1061 }
1062 args->f_id.extra =
1063 ntohl(((struct ip6_frag *)ulp)->ip6f_ident);
1064 ulp = NULL;
1065 break;
1066
1067 case IPPROTO_DSTOPTS: /* RFC 2460 */
1068 PULLUP_TO(hlen, ulp, struct ip6_hbh);
1069 ext_hd |= EXT_DSTOPTS;
1070 hlen += (((struct ip6_hbh *)ulp)->ip6h_len + 1) << 3;
1071 proto = ((struct ip6_hbh *)ulp)->ip6h_nxt;
1072 ulp = NULL;
1073 break;
1074
1075 case IPPROTO_AH: /* RFC 2402 */
1076 PULLUP_TO(hlen, ulp, struct ip6_ext);
1077 ext_hd |= EXT_AH;
1078 hlen += (((struct ip6_ext *)ulp)->ip6e_len + 2) << 2;
1079 proto = ((struct ip6_ext *)ulp)->ip6e_nxt;
1080 ulp = NULL;
1081 break;
1082
1083 case IPPROTO_ESP: /* RFC 2406 */
1084 PULLUP_TO(hlen, ulp, uint32_t); /* SPI, Seq# */
1085 /* Anything past Seq# is variable length and
1086 * data past this ext. header is encrypted. */
1087 ext_hd |= EXT_ESP;
1088 break;
1089
1090 case IPPROTO_NONE: /* RFC 2460 */
1091 /*
1092 * Packet ends here, and IPv6 header has
1093 * already been pulled up. If ip6e_len!=0
1094 * then octets must be ignored.
1095 */
1096 ulp = ip; /* non-NULL to get out of loop. */
1097 break;
1098
1099 case IPPROTO_OSPFIGP:
1100 /* XXX OSPF header check? */
1101 PULLUP_TO(hlen, ulp, struct ip6_ext);
1102 break;
1103
1104 case IPPROTO_PIM:
1105 /* XXX PIM header check? */
1106 PULLUP_TO(hlen, ulp, struct pim);
1107 break;
1108
1109 case IPPROTO_CARP:
1110 PULLUP_TO(hlen, ulp, struct carp_header);
1111 if (((struct carp_header *)ulp)->carp_version !=
1112 CARP_VERSION)
1113 return (IP_FW_DENY);
1114 if (((struct carp_header *)ulp)->carp_type !=
1115 CARP_ADVERTISEMENT)
1116 return (IP_FW_DENY);
1117 break;
1118
1119 case IPPROTO_IPV6: /* RFC 2893 */
1120 PULLUP_TO(hlen, ulp, struct ip6_hdr);
1121 break;
1122
1123 case IPPROTO_IPV4: /* RFC 2893 */
1124 PULLUP_TO(hlen, ulp, struct ip);
1125 break;
1126
1127 default:
1128 if (V_fw_verbose)
1129 printf("IPFW2: IPV6 - Unknown "
1130 "Extension Header(%d), ext_hd=%x\n",
1131 proto, ext_hd);
1132 if (V_fw_deny_unknown_exthdrs)
1133 return (IP_FW_DENY);
1134 PULLUP_TO(hlen, ulp, struct ip6_ext);
1135 break;
1136 } /*switch */
1137 }
1138 ip = mtod(m, struct ip *);
1139 ip6 = (struct ip6_hdr *)ip;
1140 args->f_id.src_ip6 = ip6->ip6_src;
1141 args->f_id.dst_ip6 = ip6->ip6_dst;
1142 args->f_id.src_ip = 0;
1143 args->f_id.dst_ip = 0;
1144 args->f_id.flow_id6 = ntohl(ip6->ip6_flow);
1145 } else if (pktlen >= sizeof(struct ip) &&
1146 (args->eh == NULL || etype == ETHERTYPE_IP) && ip->ip_v == 4) {
1147 is_ipv4 = 1;
1148 hlen = ip->ip_hl << 2;
1149 args->f_id.addr_type = 4;
1150
1151 /*
1152 * Collect parameters into local variables for faster matching.
1153 */
1154 proto = ip->ip_p;
1155 src_ip = ip->ip_src;
1156 dst_ip = ip->ip_dst;
1157 offset = ntohs(ip->ip_off) & IP_OFFMASK;
1158 iplen = ntohs(ip->ip_len);
1159 pktlen = iplen < pktlen ? iplen : pktlen;
1160
1161 if (offset == 0) {
1162 switch (proto) {
1163 case IPPROTO_TCP:
1164 PULLUP_TO(hlen, ulp, struct tcphdr);
1165 dst_port = TCP(ulp)->th_dport;
1166 src_port = TCP(ulp)->th_sport;
1167 /* save flags for dynamic rules */
1168 args->f_id._flags = TCP(ulp)->th_flags;
1169 break;
1170
1171 case IPPROTO_SCTP:
1172 PULLUP_TO(hlen, ulp, struct sctphdr);
1173 src_port = SCTP(ulp)->src_port;
1174 dst_port = SCTP(ulp)->dest_port;
1175 break;
1176
1177 case IPPROTO_UDP:
1178 PULLUP_TO(hlen, ulp, struct udphdr);
1179 dst_port = UDP(ulp)->uh_dport;
1180 src_port = UDP(ulp)->uh_sport;
1181 break;
1182
1183 case IPPROTO_ICMP:
1184 PULLUP_TO(hlen, ulp, struct icmphdr);
1185 //args->f_id.flags = ICMP(ulp)->icmp_type;
1186 break;
1187
1188 default:
1189 break;
1190 }
1191 }
1192
1193 ip = mtod(m, struct ip *);
1194 args->f_id.src_ip = ntohl(src_ip.s_addr);
1195 args->f_id.dst_ip = ntohl(dst_ip.s_addr);
1196 }
1197#undef PULLUP_TO
1198 if (proto) { /* we may have port numbers, store them */
1199 args->f_id.proto = proto;
1200 args->f_id.src_port = src_port = ntohs(src_port);
1201 args->f_id.dst_port = dst_port = ntohs(dst_port);
1202 }
1203
1204 IPFW_RLOCK(chain);
1205 if (! V_ipfw_vnet_ready) { /* shutting down, leave NOW. */
1206 IPFW_RUNLOCK(chain);
1207 return (IP_FW_PASS); /* accept */
1208 }
1209 if (args->rule.slot) {
1210 /*
1211 * Packet has already been tagged as a result of a previous
1212 * match on rule args->rule aka args->rule_id (PIPE, QUEUE,
1213 * REASS, NETGRAPH, DIVERT/TEE...)
1214 * Validate the slot and continue from the next one
1215 * if still present, otherwise do a lookup.
1216 */
1217 f_pos = (args->rule.chain_id == chain->id) ?
1218 args->rule.slot :
1219 ipfw_find_rule(chain, args->rule.rulenum,
1220 args->rule.rule_id);
1221 } else {
1222 f_pos = 0;
1223 }
1224
1225 /*
1226 * Now scan the rules, and parse microinstructions for each rule.
1227 * We have two nested loops and an inner switch. Sometimes we
1228 * need to break out of one or both loops, or re-enter one of
1229 * the loops with updated variables. Loop variables are:
1230 *
1231 * f_pos (outer loop) points to the current rule.
1232 * On output it points to the matching rule.
1233 * done (outer loop) is used as a flag to break the loop.
1234 * l (inner loop) residual length of current rule.
1235 * cmd points to the current microinstruction.
1236 *
1237 * We break the inner loop by setting l=0 and possibly
1238 * cmdlen=0 if we don't want to advance cmd.
1239 * We break the outer loop by setting done=1
1240 * We can restart the inner loop by setting l>0 and f_pos, f, cmd
1241 * as needed.
1242 */
1243 for (; f_pos < chain->n_rules; f_pos++) {
1244 ipfw_insn *cmd;
1245 uint32_t tablearg = 0;
1246 int l, cmdlen, skip_or; /* skip rest of OR block */
1247 struct ip_fw *f;
1248
1249 f = chain->map[f_pos];
1250 if (V_set_disable & (1 << f->set) )
1251 continue;
1252
1253 skip_or = 0;
1254 for (l = f->cmd_len, cmd = f->cmd ; l > 0 ;
1255 l -= cmdlen, cmd += cmdlen) {
1256 int match;
1257
1258 /*
1259 * check_body is a jump target used when we find a
1260 * CHECK_STATE, and need to jump to the body of
1261 * the target rule.
1262 */
1263
1264/* check_body: */
1265 cmdlen = F_LEN(cmd);
1266 /*
1267 * An OR block (insn_1 || .. || insn_n) has the
1268 * F_OR bit set in all but the last instruction.
1269 * The first match will set "skip_or", and cause
1270 * the following instructions to be skipped until
1271 * past the one with the F_OR bit clear.
1272 */
1273 if (skip_or) { /* skip this instruction */
1274 if ((cmd->len & F_OR) == 0)
1275 skip_or = 0; /* next one is good */
1276 continue;
1277 }
1278 match = 0; /* set to 1 if we succeed */
1279
1280 switch (cmd->opcode) {
1281 /*
1282 * The first set of opcodes compares the packet's
1283 * fields with some pattern, setting 'match' if a
1284 * match is found. At the end of the loop there is
1285 * logic to deal with F_NOT and F_OR flags associated
1286 * with the opcode.
1287 */
1288 case O_NOP:
1289 match = 1;
1290 break;
1291
1292 case O_FORWARD_MAC:
1293 printf("ipfw: opcode %d unimplemented\n",
1294 cmd->opcode);
1295 break;
1296
1297 case O_GID:
1298 case O_UID:
1299 case O_JAIL:
1300 /*
1301 * We only check offset == 0 && proto != 0,
1302 * as this ensures that we have a
1303 * packet with the ports info.
1304 */
1305 if (offset != 0)
1306 break;
1307 if (proto == IPPROTO_TCP ||
1308 proto == IPPROTO_UDP)
1309 match = check_uidgid(
1310 (ipfw_insn_u32 *)cmd,
1311 args, &ucred_lookup,
1312#ifdef __FreeBSD__
1313 &ucred_cache);
1314#else
1315 (void *)&ucred_cache);
1316#endif
1317 break;
1318
1319 case O_RECV:
1320 match = iface_match(m->m_pkthdr.rcvif,
1315 (ipfw_insn_if *)cmd);
1321 (ipfw_insn_if *)cmd, chain, &tablearg);
1316 break;
1317
1318 case O_XMIT:
1322 break;
1323
1324 case O_XMIT:
1319 match = iface_match(oif, (ipfw_insn_if *)cmd);
1325 match = iface_match(oif, (ipfw_insn_if *)cmd,
1326 chain, &tablearg);
1320 break;
1321
1322 case O_VIA:
1323 match = iface_match(oif ? oif :
1327 break;
1328
1329 case O_VIA:
1330 match = iface_match(oif ? oif :
1324 m->m_pkthdr.rcvif, (ipfw_insn_if *)cmd);
1331 m->m_pkthdr.rcvif, (ipfw_insn_if *)cmd,
1332 chain, &tablearg);
1325 break;
1326
1327 case O_MACADDR2:
1328 if (args->eh != NULL) { /* have MAC header */
1329 u_int32_t *want = (u_int32_t *)
1330 ((ipfw_insn_mac *)cmd)->addr;
1331 u_int32_t *mask = (u_int32_t *)
1332 ((ipfw_insn_mac *)cmd)->mask;
1333 u_int32_t *hdr = (u_int32_t *)args->eh;
1334
1335 match =
1336 ( want[0] == (hdr[0] & mask[0]) &&
1337 want[1] == (hdr[1] & mask[1]) &&
1338 want[2] == (hdr[2] & mask[2]) );
1339 }
1340 break;
1341
1342 case O_MAC_TYPE:
1343 if (args->eh != NULL) {
1344 u_int16_t *p =
1345 ((ipfw_insn_u16 *)cmd)->ports;
1346 int i;
1347
1348 for (i = cmdlen - 1; !match && i>0;
1349 i--, p += 2)
1350 match = (etype >= p[0] &&
1351 etype <= p[1]);
1352 }
1353 break;
1354
1355 case O_FRAG:
1356 match = (offset != 0);
1357 break;
1358
1359 case O_IN: /* "out" is "not in" */
1360 match = (oif == NULL);
1361 break;
1362
1363 case O_LAYER2:
1364 match = (args->eh != NULL);
1365 break;
1366
1367 case O_DIVERTED:
1368 {
1369 /* For diverted packets, args->rule.info
1370 * contains the divert port (in host format)
1371 * reason and direction.
1372 */
1373 uint32_t i = args->rule.info;
1374 match = (i&IPFW_IS_MASK) == IPFW_IS_DIVERT &&
1375 cmd->arg1 & ((i & IPFW_INFO_IN) ? 1 : 2);
1376 }
1377 break;
1378
1379 case O_PROTO:
1380 /*
1381 * We do not allow an arg of 0 so the
1382 * check of "proto" only suffices.
1383 */
1384 match = (proto == cmd->arg1);
1385 break;
1386
1387 case O_IP_SRC:
1388 match = is_ipv4 &&
1389 (((ipfw_insn_ip *)cmd)->addr.s_addr ==
1390 src_ip.s_addr);
1391 break;
1392
1393 case O_IP_SRC_LOOKUP:
1394 case O_IP_DST_LOOKUP:
1395 if (is_ipv4) {
1396 uint32_t key =
1397 (cmd->opcode == O_IP_DST_LOOKUP) ?
1398 dst_ip.s_addr : src_ip.s_addr;
1399 uint32_t v = 0;
1400
1401 if (cmdlen > F_INSN_SIZE(ipfw_insn_u32)) {
1402 /* generic lookup. The key must be
1403 * in 32bit big-endian format.
1404 */
1405 v = ((ipfw_insn_u32 *)cmd)->d[1];
1406 if (v == 0)
1407 key = dst_ip.s_addr;
1408 else if (v == 1)
1409 key = src_ip.s_addr;
1410 else if (v == 6) /* dscp */
1411 key = (ip->ip_tos >> 2) & 0x3f;
1412 else if (offset != 0)
1413 break;
1414 else if (proto != IPPROTO_TCP &&
1415 proto != IPPROTO_UDP)
1416 break;
1417 else if (v == 2)
1418 key = htonl(dst_port);
1419 else if (v == 3)
1420 key = htonl(src_port);
1421 else if (v == 4 || v == 5) {
1422 check_uidgid(
1423 (ipfw_insn_u32 *)cmd,
1424 args, &ucred_lookup,
1425#ifdef __FreeBSD__
1426 &ucred_cache);
1427 if (v == 4 /* O_UID */)
1428 key = ucred_cache->cr_uid;
1429 else if (v == 5 /* O_JAIL */)
1430 key = ucred_cache->cr_prison->pr_id;
1431#else /* !__FreeBSD__ */
1432 (void *)&ucred_cache);
1433 if (v ==4 /* O_UID */)
1434 key = ucred_cache.uid;
1435 else if (v == 5 /* O_JAIL */)
1436 key = ucred_cache.xid;
1437#endif /* !__FreeBSD__ */
1438 key = htonl(key);
1439 } else
1440 break;
1441 }
1442 match = ipfw_lookup_table(chain,
1443 cmd->arg1, key, &v);
1444 if (!match)
1445 break;
1446 if (cmdlen == F_INSN_SIZE(ipfw_insn_u32))
1447 match =
1448 ((ipfw_insn_u32 *)cmd)->d[0] == v;
1449 else
1450 tablearg = v;
1333 break;
1334
1335 case O_MACADDR2:
1336 if (args->eh != NULL) { /* have MAC header */
1337 u_int32_t *want = (u_int32_t *)
1338 ((ipfw_insn_mac *)cmd)->addr;
1339 u_int32_t *mask = (u_int32_t *)
1340 ((ipfw_insn_mac *)cmd)->mask;
1341 u_int32_t *hdr = (u_int32_t *)args->eh;
1342
1343 match =
1344 ( want[0] == (hdr[0] & mask[0]) &&
1345 want[1] == (hdr[1] & mask[1]) &&
1346 want[2] == (hdr[2] & mask[2]) );
1347 }
1348 break;
1349
1350 case O_MAC_TYPE:
1351 if (args->eh != NULL) {
1352 u_int16_t *p =
1353 ((ipfw_insn_u16 *)cmd)->ports;
1354 int i;
1355
1356 for (i = cmdlen - 1; !match && i>0;
1357 i--, p += 2)
1358 match = (etype >= p[0] &&
1359 etype <= p[1]);
1360 }
1361 break;
1362
1363 case O_FRAG:
1364 match = (offset != 0);
1365 break;
1366
1367 case O_IN: /* "out" is "not in" */
1368 match = (oif == NULL);
1369 break;
1370
1371 case O_LAYER2:
1372 match = (args->eh != NULL);
1373 break;
1374
1375 case O_DIVERTED:
1376 {
1377 /* For diverted packets, args->rule.info
1378 * contains the divert port (in host format)
1379 * reason and direction.
1380 */
1381 uint32_t i = args->rule.info;
1382 match = (i&IPFW_IS_MASK) == IPFW_IS_DIVERT &&
1383 cmd->arg1 & ((i & IPFW_INFO_IN) ? 1 : 2);
1384 }
1385 break;
1386
1387 case O_PROTO:
1388 /*
1389 * We do not allow an arg of 0 so the
1390 * check of "proto" only suffices.
1391 */
1392 match = (proto == cmd->arg1);
1393 break;
1394
1395 case O_IP_SRC:
1396 match = is_ipv4 &&
1397 (((ipfw_insn_ip *)cmd)->addr.s_addr ==
1398 src_ip.s_addr);
1399 break;
1400
1401 case O_IP_SRC_LOOKUP:
1402 case O_IP_DST_LOOKUP:
1403 if (is_ipv4) {
1404 uint32_t key =
1405 (cmd->opcode == O_IP_DST_LOOKUP) ?
1406 dst_ip.s_addr : src_ip.s_addr;
1407 uint32_t v = 0;
1408
1409 if (cmdlen > F_INSN_SIZE(ipfw_insn_u32)) {
1410 /* generic lookup. The key must be
1411 * in 32bit big-endian format.
1412 */
1413 v = ((ipfw_insn_u32 *)cmd)->d[1];
1414 if (v == 0)
1415 key = dst_ip.s_addr;
1416 else if (v == 1)
1417 key = src_ip.s_addr;
1418 else if (v == 6) /* dscp */
1419 key = (ip->ip_tos >> 2) & 0x3f;
1420 else if (offset != 0)
1421 break;
1422 else if (proto != IPPROTO_TCP &&
1423 proto != IPPROTO_UDP)
1424 break;
1425 else if (v == 2)
1426 key = htonl(dst_port);
1427 else if (v == 3)
1428 key = htonl(src_port);
1429 else if (v == 4 || v == 5) {
1430 check_uidgid(
1431 (ipfw_insn_u32 *)cmd,
1432 args, &ucred_lookup,
1433#ifdef __FreeBSD__
1434 &ucred_cache);
1435 if (v == 4 /* O_UID */)
1436 key = ucred_cache->cr_uid;
1437 else if (v == 5 /* O_JAIL */)
1438 key = ucred_cache->cr_prison->pr_id;
1439#else /* !__FreeBSD__ */
1440 (void *)&ucred_cache);
1441 if (v ==4 /* O_UID */)
1442 key = ucred_cache.uid;
1443 else if (v == 5 /* O_JAIL */)
1444 key = ucred_cache.xid;
1445#endif /* !__FreeBSD__ */
1446 key = htonl(key);
1447 } else
1448 break;
1449 }
1450 match = ipfw_lookup_table(chain,
1451 cmd->arg1, key, &v);
1452 if (!match)
1453 break;
1454 if (cmdlen == F_INSN_SIZE(ipfw_insn_u32))
1455 match =
1456 ((ipfw_insn_u32 *)cmd)->d[0] == v;
1457 else
1458 tablearg = v;
1459 } else if (is_ipv6) {
1460 uint32_t v = 0;
1461 void *pkey = (cmd->opcode == O_IP_DST_LOOKUP) ?
1462 &args->f_id.dst_ip6: &args->f_id.src_ip6;
1463 match = ipfw_lookup_table_extended(chain,
1464 cmd->arg1, pkey, &v,
1465 IPFW_TABLE_CIDR);
1466 if (cmdlen == F_INSN_SIZE(ipfw_insn_u32))
1467 match = ((ipfw_insn_u32 *)cmd)->d[0] == v;
1468 if (match)
1469 tablearg = v;
1451 }
1452 break;
1453
1454 case O_IP_SRC_MASK:
1455 case O_IP_DST_MASK:
1456 if (is_ipv4) {
1457 uint32_t a =
1458 (cmd->opcode == O_IP_DST_MASK) ?
1459 dst_ip.s_addr : src_ip.s_addr;
1460 uint32_t *p = ((ipfw_insn_u32 *)cmd)->d;
1461 int i = cmdlen-1;
1462
1463 for (; !match && i>0; i-= 2, p+= 2)
1464 match = (p[0] == (a & p[1]));
1465 }
1466 break;
1467
1468 case O_IP_SRC_ME:
1469 if (is_ipv4) {
1470 struct ifnet *tif;
1471
1472 INADDR_TO_IFP(src_ip, tif);
1473 match = (tif != NULL);
1474 break;
1475 }
1476#ifdef INET6
1477 /* FALLTHROUGH */
1478 case O_IP6_SRC_ME:
1479 match= is_ipv6 && search_ip6_addr_net(&args->f_id.src_ip6);
1480#endif
1481 break;
1482
1483 case O_IP_DST_SET:
1484 case O_IP_SRC_SET:
1485 if (is_ipv4) {
1486 u_int32_t *d = (u_int32_t *)(cmd+1);
1487 u_int32_t addr =
1488 cmd->opcode == O_IP_DST_SET ?
1489 args->f_id.dst_ip :
1490 args->f_id.src_ip;
1491
1492 if (addr < d[0])
1493 break;
1494 addr -= d[0]; /* subtract base */
1495 match = (addr < cmd->arg1) &&
1496 ( d[ 1 + (addr>>5)] &
1497 (1<<(addr & 0x1f)) );
1498 }
1499 break;
1500
1501 case O_IP_DST:
1502 match = is_ipv4 &&
1503 (((ipfw_insn_ip *)cmd)->addr.s_addr ==
1504 dst_ip.s_addr);
1505 break;
1506
1507 case O_IP_DST_ME:
1508 if (is_ipv4) {
1509 struct ifnet *tif;
1510
1511 INADDR_TO_IFP(dst_ip, tif);
1512 match = (tif != NULL);
1513 break;
1514 }
1515#ifdef INET6
1516 /* FALLTHROUGH */
1517 case O_IP6_DST_ME:
1518 match= is_ipv6 && search_ip6_addr_net(&args->f_id.dst_ip6);
1519#endif
1520 break;
1521
1522
1523 case O_IP_SRCPORT:
1524 case O_IP_DSTPORT:
1525 /*
1526 * offset == 0 && proto != 0 is enough
1527 * to guarantee that we have a
1528 * packet with port info.
1529 */
1530 if ((proto==IPPROTO_UDP || proto==IPPROTO_TCP)
1531 && offset == 0) {
1532 u_int16_t x =
1533 (cmd->opcode == O_IP_SRCPORT) ?
1534 src_port : dst_port ;
1535 u_int16_t *p =
1536 ((ipfw_insn_u16 *)cmd)->ports;
1537 int i;
1538
1539 for (i = cmdlen - 1; !match && i>0;
1540 i--, p += 2)
1541 match = (x>=p[0] && x<=p[1]);
1542 }
1543 break;
1544
1545 case O_ICMPTYPE:
1546 match = (offset == 0 && proto==IPPROTO_ICMP &&
1547 icmptype_match(ICMP(ulp), (ipfw_insn_u32 *)cmd) );
1548 break;
1549
1550#ifdef INET6
1551 case O_ICMP6TYPE:
1552 match = is_ipv6 && offset == 0 &&
1553 proto==IPPROTO_ICMPV6 &&
1554 icmp6type_match(
1555 ICMP6(ulp)->icmp6_type,
1556 (ipfw_insn_u32 *)cmd);
1557 break;
1558#endif /* INET6 */
1559
1560 case O_IPOPT:
1561 match = (is_ipv4 &&
1562 ipopts_match(ip, cmd) );
1563 break;
1564
1565 case O_IPVER:
1566 match = (is_ipv4 &&
1567 cmd->arg1 == ip->ip_v);
1568 break;
1569
1570 case O_IPID:
1571 case O_IPLEN:
1572 case O_IPTTL:
1573 if (is_ipv4) { /* only for IP packets */
1574 uint16_t x;
1575 uint16_t *p;
1576 int i;
1577
1578 if (cmd->opcode == O_IPLEN)
1579 x = iplen;
1580 else if (cmd->opcode == O_IPTTL)
1581 x = ip->ip_ttl;
1582 else /* must be IPID */
1583 x = ntohs(ip->ip_id);
1584 if (cmdlen == 1) {
1585 match = (cmd->arg1 == x);
1586 break;
1587 }
1588 /* otherwise we have ranges */
1589 p = ((ipfw_insn_u16 *)cmd)->ports;
1590 i = cmdlen - 1;
1591 for (; !match && i>0; i--, p += 2)
1592 match = (x >= p[0] && x <= p[1]);
1593 }
1594 break;
1595
1596 case O_IPPRECEDENCE:
1597 match = (is_ipv4 &&
1598 (cmd->arg1 == (ip->ip_tos & 0xe0)) );
1599 break;
1600
1601 case O_IPTOS:
1602 match = (is_ipv4 &&
1603 flags_match(cmd, ip->ip_tos));
1604 break;
1605
1606 case O_TCPDATALEN:
1607 if (proto == IPPROTO_TCP && offset == 0) {
1608 struct tcphdr *tcp;
1609 uint16_t x;
1610 uint16_t *p;
1611 int i;
1612
1613 tcp = TCP(ulp);
1614 x = iplen -
1615 ((ip->ip_hl + tcp->th_off) << 2);
1616 if (cmdlen == 1) {
1617 match = (cmd->arg1 == x);
1618 break;
1619 }
1620 /* otherwise we have ranges */
1621 p = ((ipfw_insn_u16 *)cmd)->ports;
1622 i = cmdlen - 1;
1623 for (; !match && i>0; i--, p += 2)
1624 match = (x >= p[0] && x <= p[1]);
1625 }
1626 break;
1627
1628 case O_TCPFLAGS:
1629 match = (proto == IPPROTO_TCP && offset == 0 &&
1630 flags_match(cmd, TCP(ulp)->th_flags));
1631 break;
1632
1633 case O_TCPOPTS:
1634 PULLUP_LEN(hlen, ulp, (TCP(ulp)->th_off << 2));
1635 match = (proto == IPPROTO_TCP && offset == 0 &&
1636 tcpopts_match(TCP(ulp), cmd));
1637 break;
1638
1639 case O_TCPSEQ:
1640 match = (proto == IPPROTO_TCP && offset == 0 &&
1641 ((ipfw_insn_u32 *)cmd)->d[0] ==
1642 TCP(ulp)->th_seq);
1643 break;
1644
1645 case O_TCPACK:
1646 match = (proto == IPPROTO_TCP && offset == 0 &&
1647 ((ipfw_insn_u32 *)cmd)->d[0] ==
1648 TCP(ulp)->th_ack);
1649 break;
1650
1651 case O_TCPWIN:
1652 if (proto == IPPROTO_TCP && offset == 0) {
1653 uint16_t x;
1654 uint16_t *p;
1655 int i;
1656
1657 x = ntohs(TCP(ulp)->th_win);
1658 if (cmdlen == 1) {
1659 match = (cmd->arg1 == x);
1660 break;
1661 }
1662 /* Otherwise we have ranges. */
1663 p = ((ipfw_insn_u16 *)cmd)->ports;
1664 i = cmdlen - 1;
1665 for (; !match && i > 0; i--, p += 2)
1666 match = (x >= p[0] && x <= p[1]);
1667 }
1668 break;
1669
1670 case O_ESTAB:
1671 /* reject packets which have SYN only */
1672 /* XXX should i also check for TH_ACK ? */
1673 match = (proto == IPPROTO_TCP && offset == 0 &&
1674 (TCP(ulp)->th_flags &
1675 (TH_RST | TH_ACK | TH_SYN)) != TH_SYN);
1676 break;
1677
1678 case O_ALTQ: {
1679 struct pf_mtag *at;
1680 ipfw_insn_altq *altq = (ipfw_insn_altq *)cmd;
1681
1682 match = 1;
1683 at = pf_find_mtag(m);
1684 if (at != NULL && at->qid != 0)
1685 break;
1686 at = pf_get_mtag(m);
1687 if (at == NULL) {
1688 /*
1689 * Let the packet fall back to the
1690 * default ALTQ.
1691 */
1692 break;
1693 }
1694 at->qid = altq->qid;
1695 at->hdr = ip;
1696 break;
1697 }
1698
1699 case O_LOG:
1700 ipfw_log(f, hlen, args, m,
1701 oif, offset | ip6f_mf, tablearg, ip);
1702 match = 1;
1703 break;
1704
1705 case O_PROB:
1706 match = (random()<((ipfw_insn_u32 *)cmd)->d[0]);
1707 break;
1708
1709 case O_VERREVPATH:
1710 /* Outgoing packets automatically pass/match */
1711 match = ((oif != NULL) ||
1712 (m->m_pkthdr.rcvif == NULL) ||
1713 (
1714#ifdef INET6
1715 is_ipv6 ?
1716 verify_path6(&(args->f_id.src_ip6),
1717 m->m_pkthdr.rcvif, args->f_id.fib) :
1718#endif
1719 verify_path(src_ip, m->m_pkthdr.rcvif,
1720 args->f_id.fib)));
1721 break;
1722
1723 case O_VERSRCREACH:
1724 /* Outgoing packets automatically pass/match */
1725 match = (hlen > 0 && ((oif != NULL) ||
1726#ifdef INET6
1727 is_ipv6 ?
1728 verify_path6(&(args->f_id.src_ip6),
1729 NULL, args->f_id.fib) :
1730#endif
1731 verify_path(src_ip, NULL, args->f_id.fib)));
1732 break;
1733
1734 case O_ANTISPOOF:
1735 /* Outgoing packets automatically pass/match */
1736 if (oif == NULL && hlen > 0 &&
1737 ( (is_ipv4 && in_localaddr(src_ip))
1738#ifdef INET6
1739 || (is_ipv6 &&
1740 in6_localaddr(&(args->f_id.src_ip6)))
1741#endif
1742 ))
1743 match =
1744#ifdef INET6
1745 is_ipv6 ? verify_path6(
1746 &(args->f_id.src_ip6),
1747 m->m_pkthdr.rcvif,
1748 args->f_id.fib) :
1749#endif
1750 verify_path(src_ip,
1751 m->m_pkthdr.rcvif,
1752 args->f_id.fib);
1753 else
1754 match = 1;
1755 break;
1756
1757 case O_IPSEC:
1758#ifdef IPSEC
1759 match = (m_tag_find(m,
1760 PACKET_TAG_IPSEC_IN_DONE, NULL) != NULL);
1761#endif
1762 /* otherwise no match */
1763 break;
1764
1765#ifdef INET6
1766 case O_IP6_SRC:
1767 match = is_ipv6 &&
1768 IN6_ARE_ADDR_EQUAL(&args->f_id.src_ip6,
1769 &((ipfw_insn_ip6 *)cmd)->addr6);
1770 break;
1771
1772 case O_IP6_DST:
1773 match = is_ipv6 &&
1774 IN6_ARE_ADDR_EQUAL(&args->f_id.dst_ip6,
1775 &((ipfw_insn_ip6 *)cmd)->addr6);
1776 break;
1777 case O_IP6_SRC_MASK:
1778 case O_IP6_DST_MASK:
1779 if (is_ipv6) {
1780 int i = cmdlen - 1;
1781 struct in6_addr p;
1782 struct in6_addr *d =
1783 &((ipfw_insn_ip6 *)cmd)->addr6;
1784
1785 for (; !match && i > 0; d += 2,
1786 i -= F_INSN_SIZE(struct in6_addr)
1787 * 2) {
1788 p = (cmd->opcode ==
1789 O_IP6_SRC_MASK) ?
1790 args->f_id.src_ip6:
1791 args->f_id.dst_ip6;
1792 APPLY_MASK(&p, &d[1]);
1793 match =
1794 IN6_ARE_ADDR_EQUAL(&d[0],
1795 &p);
1796 }
1797 }
1798 break;
1799
1800 case O_FLOW6ID:
1801 match = is_ipv6 &&
1802 flow6id_match(args->f_id.flow_id6,
1803 (ipfw_insn_u32 *) cmd);
1804 break;
1805
1806 case O_EXT_HDR:
1807 match = is_ipv6 &&
1808 (ext_hd & ((ipfw_insn *) cmd)->arg1);
1809 break;
1810
1811 case O_IP6:
1812 match = is_ipv6;
1813 break;
1814#endif
1815
1816 case O_IP4:
1817 match = is_ipv4;
1818 break;
1819
1820 case O_TAG: {
1821 struct m_tag *mtag;
1822 uint32_t tag = (cmd->arg1 == IP_FW_TABLEARG) ?
1823 tablearg : cmd->arg1;
1824
1825 /* Packet is already tagged with this tag? */
1826 mtag = m_tag_locate(m, MTAG_IPFW, tag, NULL);
1827
1828 /* We have `untag' action when F_NOT flag is
1829 * present. And we must remove this mtag from
1830 * mbuf and reset `match' to zero (`match' will
1831 * be inversed later).
1832 * Otherwise we should allocate new mtag and
1833 * push it into mbuf.
1834 */
1835 if (cmd->len & F_NOT) { /* `untag' action */
1836 if (mtag != NULL)
1837 m_tag_delete(m, mtag);
1838 match = 0;
1839 } else {
1840 if (mtag == NULL) {
1841 mtag = m_tag_alloc( MTAG_IPFW,
1842 tag, 0, M_NOWAIT);
1843 if (mtag != NULL)
1844 m_tag_prepend(m, mtag);
1845 }
1846 match = 1;
1847 }
1848 break;
1849 }
1850
1851 case O_FIB: /* try match the specified fib */
1852 if (args->f_id.fib == cmd->arg1)
1853 match = 1;
1854 break;
1855
1856 case O_SOCKARG: {
1857 struct inpcb *inp = args->inp;
1858 struct inpcbinfo *pi;
1859
1860 if (is_ipv6) /* XXX can we remove this ? */
1861 break;
1862
1863 if (proto == IPPROTO_TCP)
1864 pi = &V_tcbinfo;
1865 else if (proto == IPPROTO_UDP)
1866 pi = &V_udbinfo;
1867 else
1868 break;
1869
1870 /*
1871 * XXXRW: so_user_cookie should almost
1872 * certainly be inp_user_cookie?
1873 */
1874
1875 /* For incomming packet, lookup up the
1876 inpcb using the src/dest ip/port tuple */
1877 if (inp == NULL) {
1878 inp = in_pcblookup(pi,
1879 src_ip, htons(src_port),
1880 dst_ip, htons(dst_port),
1881 INPLOOKUP_RLOCKPCB, NULL);
1882 if (inp != NULL) {
1883 tablearg =
1884 inp->inp_socket->so_user_cookie;
1885 if (tablearg)
1886 match = 1;
1887 INP_RUNLOCK(inp);
1888 }
1889 } else {
1890 if (inp->inp_socket) {
1891 tablearg =
1892 inp->inp_socket->so_user_cookie;
1893 if (tablearg)
1894 match = 1;
1895 }
1896 }
1897 break;
1898 }
1899
1900 case O_TAGGED: {
1901 struct m_tag *mtag;
1902 uint32_t tag = (cmd->arg1 == IP_FW_TABLEARG) ?
1903 tablearg : cmd->arg1;
1904
1905 if (cmdlen == 1) {
1906 match = m_tag_locate(m, MTAG_IPFW,
1907 tag, NULL) != NULL;
1908 break;
1909 }
1910
1911 /* we have ranges */
1912 for (mtag = m_tag_first(m);
1913 mtag != NULL && !match;
1914 mtag = m_tag_next(m, mtag)) {
1915 uint16_t *p;
1916 int i;
1917
1918 if (mtag->m_tag_cookie != MTAG_IPFW)
1919 continue;
1920
1921 p = ((ipfw_insn_u16 *)cmd)->ports;
1922 i = cmdlen - 1;
1923 for(; !match && i > 0; i--, p += 2)
1924 match =
1925 mtag->m_tag_id >= p[0] &&
1926 mtag->m_tag_id <= p[1];
1927 }
1928 break;
1929 }
1930
1931 /*
1932 * The second set of opcodes represents 'actions',
1933 * i.e. the terminal part of a rule once the packet
1934 * matches all previous patterns.
1935 * Typically there is only one action for each rule,
1936 * and the opcode is stored at the end of the rule
1937 * (but there are exceptions -- see below).
1938 *
1939 * In general, here we set retval and terminate the
1940 * outer loop (would be a 'break 3' in some language,
1941 * but we need to set l=0, done=1)
1942 *
1943 * Exceptions:
1944 * O_COUNT and O_SKIPTO actions:
1945 * instead of terminating, we jump to the next rule
1946 * (setting l=0), or to the SKIPTO target (setting
1947 * f/f_len, cmd and l as needed), respectively.
1948 *
1949 * O_TAG, O_LOG and O_ALTQ action parameters:
1950 * perform some action and set match = 1;
1951 *
1952 * O_LIMIT and O_KEEP_STATE: these opcodes are
1953 * not real 'actions', and are stored right
1954 * before the 'action' part of the rule.
1955 * These opcodes try to install an entry in the
1956 * state tables; if successful, we continue with
1957 * the next opcode (match=1; break;), otherwise
1958 * the packet must be dropped (set retval,
1959 * break loops with l=0, done=1)
1960 *
1961 * O_PROBE_STATE and O_CHECK_STATE: these opcodes
1962 * cause a lookup of the state table, and a jump
1963 * to the 'action' part of the parent rule
1964 * if an entry is found, or
1965 * (CHECK_STATE only) a jump to the next rule if
1966 * the entry is not found.
1967 * The result of the lookup is cached so that
1968 * further instances of these opcodes become NOPs.
1969 * The jump to the next rule is done by setting
1970 * l=0, cmdlen=0.
1971 */
1972 case O_LIMIT:
1973 case O_KEEP_STATE:
1974 if (ipfw_install_state(f,
1975 (ipfw_insn_limit *)cmd, args, tablearg)) {
1976 /* error or limit violation */
1977 retval = IP_FW_DENY;
1978 l = 0; /* exit inner loop */
1979 done = 1; /* exit outer loop */
1980 }
1981 match = 1;
1982 break;
1983
1984 case O_PROBE_STATE:
1985 case O_CHECK_STATE:
1986 /*
1987 * dynamic rules are checked at the first
1988 * keep-state or check-state occurrence,
1989 * with the result being stored in dyn_dir.
1990 * The compiler introduces a PROBE_STATE
1991 * instruction for us when we have a
1992 * KEEP_STATE (because PROBE_STATE needs
1993 * to be run first).
1994 */
1995 if (dyn_dir == MATCH_UNKNOWN &&
1996 (q = ipfw_lookup_dyn_rule(&args->f_id,
1997 &dyn_dir, proto == IPPROTO_TCP ?
1998 TCP(ulp) : NULL))
1999 != NULL) {
2000 /*
2001 * Found dynamic entry, update stats
2002 * and jump to the 'action' part of
2003 * the parent rule by setting
2004 * f, cmd, l and clearing cmdlen.
2005 */
2006 q->pcnt++;
2007 q->bcnt += pktlen;
2008 /* XXX we would like to have f_pos
2009 * readily accessible in the dynamic
2010 * rule, instead of having to
2011 * lookup q->rule.
2012 */
2013 f = q->rule;
2014 f_pos = ipfw_find_rule(chain,
2015 f->rulenum, f->id);
2016 cmd = ACTION_PTR(f);
2017 l = f->cmd_len - f->act_ofs;
2018 ipfw_dyn_unlock();
2019 cmdlen = 0;
2020 match = 1;
2021 break;
2022 }
2023 /*
2024 * Dynamic entry not found. If CHECK_STATE,
2025 * skip to next rule, if PROBE_STATE just
2026 * ignore and continue with next opcode.
2027 */
2028 if (cmd->opcode == O_CHECK_STATE)
2029 l = 0; /* exit inner loop */
2030 match = 1;
2031 break;
2032
2033 case O_ACCEPT:
2034 retval = 0; /* accept */
2035 l = 0; /* exit inner loop */
2036 done = 1; /* exit outer loop */
2037 break;
2038
2039 case O_PIPE:
2040 case O_QUEUE:
2041 set_match(args, f_pos, chain);
2042 args->rule.info = (cmd->arg1 == IP_FW_TABLEARG) ?
2043 tablearg : cmd->arg1;
2044 if (cmd->opcode == O_PIPE)
2045 args->rule.info |= IPFW_IS_PIPE;
2046 if (V_fw_one_pass)
2047 args->rule.info |= IPFW_ONEPASS;
2048 retval = IP_FW_DUMMYNET;
2049 l = 0; /* exit inner loop */
2050 done = 1; /* exit outer loop */
2051 break;
2052
2053 case O_DIVERT:
2054 case O_TEE:
2055 if (args->eh) /* not on layer 2 */
2056 break;
2057 /* otherwise this is terminal */
2058 l = 0; /* exit inner loop */
2059 done = 1; /* exit outer loop */
2060 retval = (cmd->opcode == O_DIVERT) ?
2061 IP_FW_DIVERT : IP_FW_TEE;
2062 set_match(args, f_pos, chain);
2063 args->rule.info = (cmd->arg1 == IP_FW_TABLEARG) ?
2064 tablearg : cmd->arg1;
2065 break;
2066
2067 case O_COUNT:
2068 f->pcnt++; /* update stats */
2069 f->bcnt += pktlen;
2070 f->timestamp = time_uptime;
2071 l = 0; /* exit inner loop */
2072 break;
2073
2074 case O_SKIPTO:
2075 f->pcnt++; /* update stats */
2076 f->bcnt += pktlen;
2077 f->timestamp = time_uptime;
2078 /* If possible use cached f_pos (in f->next_rule),
2079 * whose version is written in f->next_rule
2080 * (horrible hacks to avoid changing the ABI).
2081 */
2082 if (cmd->arg1 != IP_FW_TABLEARG &&
2083 (uintptr_t)f->x_next == chain->id) {
2084 f_pos = (uintptr_t)f->next_rule;
2085 } else {
2086 int i = (cmd->arg1 == IP_FW_TABLEARG) ?
2087 tablearg : cmd->arg1;
2088 /* make sure we do not jump backward */
2089 if (i <= f->rulenum)
2090 i = f->rulenum + 1;
2091 f_pos = ipfw_find_rule(chain, i, 0);
2092 /* update the cache */
2093 if (cmd->arg1 != IP_FW_TABLEARG) {
2094 f->next_rule =
2095 (void *)(uintptr_t)f_pos;
2096 f->x_next =
2097 (void *)(uintptr_t)chain->id;
2098 }
2099 }
2100 /*
2101 * Skip disabled rules, and re-enter
2102 * the inner loop with the correct
2103 * f_pos, f, l and cmd.
2104 * Also clear cmdlen and skip_or
2105 */
2106 for (; f_pos < chain->n_rules - 1 &&
2107 (V_set_disable &
2108 (1 << chain->map[f_pos]->set));
2109 f_pos++)
2110 ;
2111 /* Re-enter the inner loop at the skipto rule. */
2112 f = chain->map[f_pos];
2113 l = f->cmd_len;
2114 cmd = f->cmd;
2115 match = 1;
2116 cmdlen = 0;
2117 skip_or = 0;
2118 continue;
2119 break; /* not reached */
2120
2121 case O_CALLRETURN: {
2122 /*
2123 * Implementation of `subroutine' call/return,
2124 * in the stack carried in an mbuf tag. This
2125 * is different from `skipto' in that any call
2126 * address is possible (`skipto' must prevent
2127 * backward jumps to avoid endless loops).
2128 * We have `return' action when F_NOT flag is
2129 * present. The `m_tag_id' field is used as
2130 * stack pointer.
2131 */
2132 struct m_tag *mtag;
2133 uint16_t jmpto, *stack;
2134
2135#define IS_CALL ((cmd->len & F_NOT) == 0)
2136#define IS_RETURN ((cmd->len & F_NOT) != 0)
2137 /*
2138 * Hand-rolled version of m_tag_locate() with
2139 * wildcard `type'.
2140 * If not already tagged, allocate new tag.
2141 */
2142 mtag = m_tag_first(m);
2143 while (mtag != NULL) {
2144 if (mtag->m_tag_cookie ==
2145 MTAG_IPFW_CALL)
2146 break;
2147 mtag = m_tag_next(m, mtag);
2148 }
2149 if (mtag == NULL && IS_CALL) {
2150 mtag = m_tag_alloc(MTAG_IPFW_CALL, 0,
2151 IPFW_CALLSTACK_SIZE *
2152 sizeof(uint16_t), M_NOWAIT);
2153 if (mtag != NULL)
2154 m_tag_prepend(m, mtag);
2155 }
2156
2157 /*
2158 * On error both `call' and `return' just
2159 * continue with next rule.
2160 */
2161 if (IS_RETURN && (mtag == NULL ||
2162 mtag->m_tag_id == 0)) {
2163 l = 0; /* exit inner loop */
2164 break;
2165 }
2166 if (IS_CALL && (mtag == NULL ||
2167 mtag->m_tag_id >= IPFW_CALLSTACK_SIZE)) {
2168 printf("ipfw: call stack error, "
2169 "go to next rule\n");
2170 l = 0; /* exit inner loop */
2171 break;
2172 }
2173
2174 f->pcnt++; /* update stats */
2175 f->bcnt += pktlen;
2176 f->timestamp = time_uptime;
2177 stack = (uint16_t *)(mtag + 1);
2178
2179 /*
2180 * The `call' action may use cached f_pos
2181 * (in f->next_rule), whose version is written
2182 * in f->next_rule.
2183 * The `return' action, however, doesn't have
2184 * fixed jump address in cmd->arg1 and can't use
2185 * cache.
2186 */
2187 if (IS_CALL) {
2188 stack[mtag->m_tag_id] = f->rulenum;
2189 mtag->m_tag_id++;
2190 if (cmd->arg1 != IP_FW_TABLEARG &&
2191 (uintptr_t)f->x_next == chain->id) {
2192 f_pos = (uintptr_t)f->next_rule;
2193 } else {
2194 jmpto = (cmd->arg1 ==
2195 IP_FW_TABLEARG) ? tablearg:
2196 cmd->arg1;
2197 f_pos = ipfw_find_rule(chain,
2198 jmpto, 0);
2199 /* update the cache */
2200 if (cmd->arg1 !=
2201 IP_FW_TABLEARG) {
2202 f->next_rule =
2203 (void *)(uintptr_t)
2204 f_pos;
2205 f->x_next =
2206 (void *)(uintptr_t)
2207 chain->id;
2208 }
2209 }
2210 } else { /* `return' action */
2211 mtag->m_tag_id--;
2212 jmpto = stack[mtag->m_tag_id] + 1;
2213 f_pos = ipfw_find_rule(chain, jmpto, 0);
2214 }
2215
2216 /*
2217 * Skip disabled rules, and re-enter
2218 * the inner loop with the correct
2219 * f_pos, f, l and cmd.
2220 * Also clear cmdlen and skip_or
2221 */
2222 for (; f_pos < chain->n_rules - 1 &&
2223 (V_set_disable &
2224 (1 << chain->map[f_pos]->set)); f_pos++)
2225 ;
2226 /* Re-enter the inner loop at the dest rule. */
2227 f = chain->map[f_pos];
2228 l = f->cmd_len;
2229 cmd = f->cmd;
2230 cmdlen = 0;
2231 skip_or = 0;
2232 continue;
2233 break; /* NOTREACHED */
2234 }
2235#undef IS_CALL
2236#undef IS_RETURN
2237
2238 case O_REJECT:
2239 /*
2240 * Drop the packet and send a reject notice
2241 * if the packet is not ICMP (or is an ICMP
2242 * query), and it is not multicast/broadcast.
2243 */
2244 if (hlen > 0 && is_ipv4 && offset == 0 &&
2245 (proto != IPPROTO_ICMP ||
2246 is_icmp_query(ICMP(ulp))) &&
2247 !(m->m_flags & (M_BCAST|M_MCAST)) &&
2248 !IN_MULTICAST(ntohl(dst_ip.s_addr))) {
2249 send_reject(args, cmd->arg1, iplen, ip);
2250 m = args->m;
2251 }
2252 /* FALLTHROUGH */
2253#ifdef INET6
2254 case O_UNREACH6:
2255 if (hlen > 0 && is_ipv6 &&
2256 ((offset & IP6F_OFF_MASK) == 0) &&
2257 (proto != IPPROTO_ICMPV6 ||
2258 (is_icmp6_query(icmp6_type) == 1)) &&
2259 !(m->m_flags & (M_BCAST|M_MCAST)) &&
2260 !IN6_IS_ADDR_MULTICAST(&args->f_id.dst_ip6)) {
2261 send_reject6(
2262 args, cmd->arg1, hlen,
2263 (struct ip6_hdr *)ip);
2264 m = args->m;
2265 }
2266 /* FALLTHROUGH */
2267#endif
2268 case O_DENY:
2269 retval = IP_FW_DENY;
2270 l = 0; /* exit inner loop */
2271 done = 1; /* exit outer loop */
2272 break;
2273
2274 case O_FORWARD_IP:
2275 if (args->eh) /* not valid on layer2 pkts */
2276 break;
2277 if (q == NULL || q->rule != f ||
2278 dyn_dir == MATCH_FORWARD) {
2279 struct sockaddr_in *sa;
2280 sa = &(((ipfw_insn_sa *)cmd)->sa);
2281 if (sa->sin_addr.s_addr == INADDR_ANY) {
2282 bcopy(sa, &args->hopstore,
2283 sizeof(*sa));
2284 args->hopstore.sin_addr.s_addr =
2285 htonl(tablearg);
2286 args->next_hop = &args->hopstore;
2287 } else {
2288 args->next_hop = sa;
2289 }
2290 }
2291 retval = IP_FW_PASS;
2292 l = 0; /* exit inner loop */
2293 done = 1; /* exit outer loop */
2294 break;
2295
2296#ifdef INET6
2297 case O_FORWARD_IP6:
2298 if (args->eh) /* not valid on layer2 pkts */
2299 break;
2300 if (q == NULL || q->rule != f ||
2301 dyn_dir == MATCH_FORWARD) {
2302 struct sockaddr_in6 *sin6;
2303
2304 sin6 = &(((ipfw_insn_sa6 *)cmd)->sa);
2305 args->next_hop6 = sin6;
2306 }
2307 retval = IP_FW_PASS;
2308 l = 0; /* exit inner loop */
2309 done = 1; /* exit outer loop */
2310 break;
2311#endif
2312
2313 case O_NETGRAPH:
2314 case O_NGTEE:
2315 set_match(args, f_pos, chain);
2316 args->rule.info = (cmd->arg1 == IP_FW_TABLEARG) ?
2317 tablearg : cmd->arg1;
2318 if (V_fw_one_pass)
2319 args->rule.info |= IPFW_ONEPASS;
2320 retval = (cmd->opcode == O_NETGRAPH) ?
2321 IP_FW_NETGRAPH : IP_FW_NGTEE;
2322 l = 0; /* exit inner loop */
2323 done = 1; /* exit outer loop */
2324 break;
2325
2326 case O_SETFIB: {
2327 uint32_t fib;
2328
2329 f->pcnt++; /* update stats */
2330 f->bcnt += pktlen;
2331 f->timestamp = time_uptime;
2332 fib = (cmd->arg1 == IP_FW_TABLEARG) ? tablearg:
2333 cmd->arg1;
2334 if (fib >= rt_numfibs)
2335 fib = 0;
2336 M_SETFIB(m, fib);
2337 args->f_id.fib = fib;
2338 l = 0; /* exit inner loop */
2339 break;
2340 }
2341
2342 case O_NAT:
2343 if (!IPFW_NAT_LOADED) {
2344 retval = IP_FW_DENY;
2345 } else {
2346 struct cfg_nat *t;
2347 int nat_id;
2348
2349 set_match(args, f_pos, chain);
2350 /* Check if this is 'global' nat rule */
2351 if (cmd->arg1 == 0) {
2352 retval = ipfw_nat_ptr(args, NULL, m);
2353 l = 0;
2354 done = 1;
2355 break;
2356 }
2357 t = ((ipfw_insn_nat *)cmd)->nat;
2358 if (t == NULL) {
2359 nat_id = (cmd->arg1 == IP_FW_TABLEARG) ?
2360 tablearg : cmd->arg1;
2361 t = (*lookup_nat_ptr)(&chain->nat, nat_id);
2362
2363 if (t == NULL) {
2364 retval = IP_FW_DENY;
2365 l = 0; /* exit inner loop */
2366 done = 1; /* exit outer loop */
2367 break;
2368 }
2369 if (cmd->arg1 != IP_FW_TABLEARG)
2370 ((ipfw_insn_nat *)cmd)->nat = t;
2371 }
2372 retval = ipfw_nat_ptr(args, t, m);
2373 }
2374 l = 0; /* exit inner loop */
2375 done = 1; /* exit outer loop */
2376 break;
2377
2378 case O_REASS: {
2379 int ip_off;
2380
2381 f->pcnt++;
2382 f->bcnt += pktlen;
2383 l = 0; /* in any case exit inner loop */
2384 ip_off = ntohs(ip->ip_off);
2385
2386 /* if not fragmented, go to next rule */
2387 if ((ip_off & (IP_MF | IP_OFFMASK)) == 0)
2388 break;
2389 /*
2390 * ip_reass() expects len & off in host
2391 * byte order.
2392 */
2393 SET_HOST_IPLEN(ip);
2394
2395 args->m = m = ip_reass(m);
2396
2397 /*
2398 * do IP header checksum fixup.
2399 */
2400 if (m == NULL) { /* fragment got swallowed */
2401 retval = IP_FW_DENY;
2402 } else { /* good, packet complete */
2403 int hlen;
2404
2405 ip = mtod(m, struct ip *);
2406 hlen = ip->ip_hl << 2;
2407 SET_NET_IPLEN(ip);
2408 ip->ip_sum = 0;
2409 if (hlen == sizeof(struct ip))
2410 ip->ip_sum = in_cksum_hdr(ip);
2411 else
2412 ip->ip_sum = in_cksum(m, hlen);
2413 retval = IP_FW_REASS;
2414 set_match(args, f_pos, chain);
2415 }
2416 done = 1; /* exit outer loop */
2417 break;
2418 }
2419
2420 default:
2421 panic("-- unknown opcode %d\n", cmd->opcode);
2422 } /* end of switch() on opcodes */
2423 /*
2424 * if we get here with l=0, then match is irrelevant.
2425 */
2426
2427 if (cmd->len & F_NOT)
2428 match = !match;
2429
2430 if (match) {
2431 if (cmd->len & F_OR)
2432 skip_or = 1;
2433 } else {
2434 if (!(cmd->len & F_OR)) /* not an OR block, */
2435 break; /* try next rule */
2436 }
2437
2438 } /* end of inner loop, scan opcodes */
2439#undef PULLUP_LEN
2440
2441 if (done)
2442 break;
2443
2444/* next_rule:; */ /* try next rule */
2445
2446 } /* end of outer for, scan rules */
2447
2448 if (done) {
2449 struct ip_fw *rule = chain->map[f_pos];
2450 /* Update statistics */
2451 rule->pcnt++;
2452 rule->bcnt += pktlen;
2453 rule->timestamp = time_uptime;
2454 } else {
2455 retval = IP_FW_DENY;
2456 printf("ipfw: ouch!, skip past end of rules, denying packet\n");
2457 }
2458 IPFW_RUNLOCK(chain);
2459#ifdef __FreeBSD__
2460 if (ucred_cache != NULL)
2461 crfree(ucred_cache);
2462#endif
2463 return (retval);
2464
2465pullup_failed:
2466 if (V_fw_verbose)
2467 printf("ipfw: pullup failed\n");
2468 return (IP_FW_DENY);
2469}
2470
2471/*
2472 * Module and VNET glue
2473 */
2474
2475/*
2476 * Stuff that must be initialised only on boot or module load
2477 */
2478static int
2479ipfw_init(void)
2480{
2481 int error = 0;
2482
2483 ipfw_dyn_attach();
2484 /*
2485 * Only print out this stuff the first time around,
2486 * when called from the sysinit code.
2487 */
2488 printf("ipfw2 "
2489#ifdef INET6
2490 "(+ipv6) "
2491#endif
2492 "initialized, divert %s, nat %s, "
2493 "rule-based forwarding "
2494#ifdef IPFIREWALL_FORWARD
2495 "enabled, "
2496#else
2497 "disabled, "
2498#endif
2499 "default to %s, logging ",
2500#ifdef IPDIVERT
2501 "enabled",
2502#else
2503 "loadable",
2504#endif
2505#ifdef IPFIREWALL_NAT
2506 "enabled",
2507#else
2508 "loadable",
2509#endif
2510 default_to_accept ? "accept" : "deny");
2511
2512 /*
2513 * Note: V_xxx variables can be accessed here but the vnet specific
2514 * initializer may not have been called yet for the VIMAGE case.
2515 * Tuneables will have been processed. We will print out values for
2516 * the default vnet.
2517 * XXX This should all be rationalized AFTER 8.0
2518 */
2519 if (V_fw_verbose == 0)
2520 printf("disabled\n");
2521 else if (V_verbose_limit == 0)
2522 printf("unlimited\n");
2523 else
2524 printf("limited to %d packets/entry by default\n",
2525 V_verbose_limit);
2526
2527 ipfw_log_bpf(1); /* init */
2528 return (error);
2529}
2530
2531/*
2532 * Called for the removal of the last instance only on module unload.
2533 */
2534static void
2535ipfw_destroy(void)
2536{
2537
2538 ipfw_log_bpf(0); /* uninit */
2539 ipfw_dyn_detach();
2540 printf("IP firewall unloaded\n");
2541}
2542
2543/*
2544 * Stuff that must be initialized for every instance
2545 * (including the first of course).
2546 */
2547static int
2548vnet_ipfw_init(const void *unused)
2549{
2550 int error;
2551 struct ip_fw *rule = NULL;
2552 struct ip_fw_chain *chain;
2553
2554 chain = &V_layer3_chain;
2555
2556 /* First set up some values that are compile time options */
2557 V_autoinc_step = 100; /* bounded to 1..1000 in add_rule() */
2558 V_fw_deny_unknown_exthdrs = 1;
2559#ifdef IPFIREWALL_VERBOSE
2560 V_fw_verbose = 1;
2561#endif
2562#ifdef IPFIREWALL_VERBOSE_LIMIT
2563 V_verbose_limit = IPFIREWALL_VERBOSE_LIMIT;
2564#endif
2565#ifdef IPFIREWALL_NAT
2566 LIST_INIT(&chain->nat);
2567#endif
2568
1470 }
1471 break;
1472
1473 case O_IP_SRC_MASK:
1474 case O_IP_DST_MASK:
1475 if (is_ipv4) {
1476 uint32_t a =
1477 (cmd->opcode == O_IP_DST_MASK) ?
1478 dst_ip.s_addr : src_ip.s_addr;
1479 uint32_t *p = ((ipfw_insn_u32 *)cmd)->d;
1480 int i = cmdlen-1;
1481
1482 for (; !match && i>0; i-= 2, p+= 2)
1483 match = (p[0] == (a & p[1]));
1484 }
1485 break;
1486
1487 case O_IP_SRC_ME:
1488 if (is_ipv4) {
1489 struct ifnet *tif;
1490
1491 INADDR_TO_IFP(src_ip, tif);
1492 match = (tif != NULL);
1493 break;
1494 }
1495#ifdef INET6
1496 /* FALLTHROUGH */
1497 case O_IP6_SRC_ME:
1498 match= is_ipv6 && search_ip6_addr_net(&args->f_id.src_ip6);
1499#endif
1500 break;
1501
1502 case O_IP_DST_SET:
1503 case O_IP_SRC_SET:
1504 if (is_ipv4) {
1505 u_int32_t *d = (u_int32_t *)(cmd+1);
1506 u_int32_t addr =
1507 cmd->opcode == O_IP_DST_SET ?
1508 args->f_id.dst_ip :
1509 args->f_id.src_ip;
1510
1511 if (addr < d[0])
1512 break;
1513 addr -= d[0]; /* subtract base */
1514 match = (addr < cmd->arg1) &&
1515 ( d[ 1 + (addr>>5)] &
1516 (1<<(addr & 0x1f)) );
1517 }
1518 break;
1519
1520 case O_IP_DST:
1521 match = is_ipv4 &&
1522 (((ipfw_insn_ip *)cmd)->addr.s_addr ==
1523 dst_ip.s_addr);
1524 break;
1525
1526 case O_IP_DST_ME:
1527 if (is_ipv4) {
1528 struct ifnet *tif;
1529
1530 INADDR_TO_IFP(dst_ip, tif);
1531 match = (tif != NULL);
1532 break;
1533 }
1534#ifdef INET6
1535 /* FALLTHROUGH */
1536 case O_IP6_DST_ME:
1537 match= is_ipv6 && search_ip6_addr_net(&args->f_id.dst_ip6);
1538#endif
1539 break;
1540
1541
1542 case O_IP_SRCPORT:
1543 case O_IP_DSTPORT:
1544 /*
1545 * offset == 0 && proto != 0 is enough
1546 * to guarantee that we have a
1547 * packet with port info.
1548 */
1549 if ((proto==IPPROTO_UDP || proto==IPPROTO_TCP)
1550 && offset == 0) {
1551 u_int16_t x =
1552 (cmd->opcode == O_IP_SRCPORT) ?
1553 src_port : dst_port ;
1554 u_int16_t *p =
1555 ((ipfw_insn_u16 *)cmd)->ports;
1556 int i;
1557
1558 for (i = cmdlen - 1; !match && i>0;
1559 i--, p += 2)
1560 match = (x>=p[0] && x<=p[1]);
1561 }
1562 break;
1563
1564 case O_ICMPTYPE:
1565 match = (offset == 0 && proto==IPPROTO_ICMP &&
1566 icmptype_match(ICMP(ulp), (ipfw_insn_u32 *)cmd) );
1567 break;
1568
1569#ifdef INET6
1570 case O_ICMP6TYPE:
1571 match = is_ipv6 && offset == 0 &&
1572 proto==IPPROTO_ICMPV6 &&
1573 icmp6type_match(
1574 ICMP6(ulp)->icmp6_type,
1575 (ipfw_insn_u32 *)cmd);
1576 break;
1577#endif /* INET6 */
1578
1579 case O_IPOPT:
1580 match = (is_ipv4 &&
1581 ipopts_match(ip, cmd) );
1582 break;
1583
1584 case O_IPVER:
1585 match = (is_ipv4 &&
1586 cmd->arg1 == ip->ip_v);
1587 break;
1588
1589 case O_IPID:
1590 case O_IPLEN:
1591 case O_IPTTL:
1592 if (is_ipv4) { /* only for IP packets */
1593 uint16_t x;
1594 uint16_t *p;
1595 int i;
1596
1597 if (cmd->opcode == O_IPLEN)
1598 x = iplen;
1599 else if (cmd->opcode == O_IPTTL)
1600 x = ip->ip_ttl;
1601 else /* must be IPID */
1602 x = ntohs(ip->ip_id);
1603 if (cmdlen == 1) {
1604 match = (cmd->arg1 == x);
1605 break;
1606 }
1607 /* otherwise we have ranges */
1608 p = ((ipfw_insn_u16 *)cmd)->ports;
1609 i = cmdlen - 1;
1610 for (; !match && i>0; i--, p += 2)
1611 match = (x >= p[0] && x <= p[1]);
1612 }
1613 break;
1614
1615 case O_IPPRECEDENCE:
1616 match = (is_ipv4 &&
1617 (cmd->arg1 == (ip->ip_tos & 0xe0)) );
1618 break;
1619
1620 case O_IPTOS:
1621 match = (is_ipv4 &&
1622 flags_match(cmd, ip->ip_tos));
1623 break;
1624
1625 case O_TCPDATALEN:
1626 if (proto == IPPROTO_TCP && offset == 0) {
1627 struct tcphdr *tcp;
1628 uint16_t x;
1629 uint16_t *p;
1630 int i;
1631
1632 tcp = TCP(ulp);
1633 x = iplen -
1634 ((ip->ip_hl + tcp->th_off) << 2);
1635 if (cmdlen == 1) {
1636 match = (cmd->arg1 == x);
1637 break;
1638 }
1639 /* otherwise we have ranges */
1640 p = ((ipfw_insn_u16 *)cmd)->ports;
1641 i = cmdlen - 1;
1642 for (; !match && i>0; i--, p += 2)
1643 match = (x >= p[0] && x <= p[1]);
1644 }
1645 break;
1646
1647 case O_TCPFLAGS:
1648 match = (proto == IPPROTO_TCP && offset == 0 &&
1649 flags_match(cmd, TCP(ulp)->th_flags));
1650 break;
1651
1652 case O_TCPOPTS:
1653 PULLUP_LEN(hlen, ulp, (TCP(ulp)->th_off << 2));
1654 match = (proto == IPPROTO_TCP && offset == 0 &&
1655 tcpopts_match(TCP(ulp), cmd));
1656 break;
1657
1658 case O_TCPSEQ:
1659 match = (proto == IPPROTO_TCP && offset == 0 &&
1660 ((ipfw_insn_u32 *)cmd)->d[0] ==
1661 TCP(ulp)->th_seq);
1662 break;
1663
1664 case O_TCPACK:
1665 match = (proto == IPPROTO_TCP && offset == 0 &&
1666 ((ipfw_insn_u32 *)cmd)->d[0] ==
1667 TCP(ulp)->th_ack);
1668 break;
1669
1670 case O_TCPWIN:
1671 if (proto == IPPROTO_TCP && offset == 0) {
1672 uint16_t x;
1673 uint16_t *p;
1674 int i;
1675
1676 x = ntohs(TCP(ulp)->th_win);
1677 if (cmdlen == 1) {
1678 match = (cmd->arg1 == x);
1679 break;
1680 }
1681 /* Otherwise we have ranges. */
1682 p = ((ipfw_insn_u16 *)cmd)->ports;
1683 i = cmdlen - 1;
1684 for (; !match && i > 0; i--, p += 2)
1685 match = (x >= p[0] && x <= p[1]);
1686 }
1687 break;
1688
1689 case O_ESTAB:
1690 /* reject packets which have SYN only */
1691 /* XXX should i also check for TH_ACK ? */
1692 match = (proto == IPPROTO_TCP && offset == 0 &&
1693 (TCP(ulp)->th_flags &
1694 (TH_RST | TH_ACK | TH_SYN)) != TH_SYN);
1695 break;
1696
1697 case O_ALTQ: {
1698 struct pf_mtag *at;
1699 ipfw_insn_altq *altq = (ipfw_insn_altq *)cmd;
1700
1701 match = 1;
1702 at = pf_find_mtag(m);
1703 if (at != NULL && at->qid != 0)
1704 break;
1705 at = pf_get_mtag(m);
1706 if (at == NULL) {
1707 /*
1708 * Let the packet fall back to the
1709 * default ALTQ.
1710 */
1711 break;
1712 }
1713 at->qid = altq->qid;
1714 at->hdr = ip;
1715 break;
1716 }
1717
1718 case O_LOG:
1719 ipfw_log(f, hlen, args, m,
1720 oif, offset | ip6f_mf, tablearg, ip);
1721 match = 1;
1722 break;
1723
1724 case O_PROB:
1725 match = (random()<((ipfw_insn_u32 *)cmd)->d[0]);
1726 break;
1727
1728 case O_VERREVPATH:
1729 /* Outgoing packets automatically pass/match */
1730 match = ((oif != NULL) ||
1731 (m->m_pkthdr.rcvif == NULL) ||
1732 (
1733#ifdef INET6
1734 is_ipv6 ?
1735 verify_path6(&(args->f_id.src_ip6),
1736 m->m_pkthdr.rcvif, args->f_id.fib) :
1737#endif
1738 verify_path(src_ip, m->m_pkthdr.rcvif,
1739 args->f_id.fib)));
1740 break;
1741
1742 case O_VERSRCREACH:
1743 /* Outgoing packets automatically pass/match */
1744 match = (hlen > 0 && ((oif != NULL) ||
1745#ifdef INET6
1746 is_ipv6 ?
1747 verify_path6(&(args->f_id.src_ip6),
1748 NULL, args->f_id.fib) :
1749#endif
1750 verify_path(src_ip, NULL, args->f_id.fib)));
1751 break;
1752
1753 case O_ANTISPOOF:
1754 /* Outgoing packets automatically pass/match */
1755 if (oif == NULL && hlen > 0 &&
1756 ( (is_ipv4 && in_localaddr(src_ip))
1757#ifdef INET6
1758 || (is_ipv6 &&
1759 in6_localaddr(&(args->f_id.src_ip6)))
1760#endif
1761 ))
1762 match =
1763#ifdef INET6
1764 is_ipv6 ? verify_path6(
1765 &(args->f_id.src_ip6),
1766 m->m_pkthdr.rcvif,
1767 args->f_id.fib) :
1768#endif
1769 verify_path(src_ip,
1770 m->m_pkthdr.rcvif,
1771 args->f_id.fib);
1772 else
1773 match = 1;
1774 break;
1775
1776 case O_IPSEC:
1777#ifdef IPSEC
1778 match = (m_tag_find(m,
1779 PACKET_TAG_IPSEC_IN_DONE, NULL) != NULL);
1780#endif
1781 /* otherwise no match */
1782 break;
1783
1784#ifdef INET6
1785 case O_IP6_SRC:
1786 match = is_ipv6 &&
1787 IN6_ARE_ADDR_EQUAL(&args->f_id.src_ip6,
1788 &((ipfw_insn_ip6 *)cmd)->addr6);
1789 break;
1790
1791 case O_IP6_DST:
1792 match = is_ipv6 &&
1793 IN6_ARE_ADDR_EQUAL(&args->f_id.dst_ip6,
1794 &((ipfw_insn_ip6 *)cmd)->addr6);
1795 break;
1796 case O_IP6_SRC_MASK:
1797 case O_IP6_DST_MASK:
1798 if (is_ipv6) {
1799 int i = cmdlen - 1;
1800 struct in6_addr p;
1801 struct in6_addr *d =
1802 &((ipfw_insn_ip6 *)cmd)->addr6;
1803
1804 for (; !match && i > 0; d += 2,
1805 i -= F_INSN_SIZE(struct in6_addr)
1806 * 2) {
1807 p = (cmd->opcode ==
1808 O_IP6_SRC_MASK) ?
1809 args->f_id.src_ip6:
1810 args->f_id.dst_ip6;
1811 APPLY_MASK(&p, &d[1]);
1812 match =
1813 IN6_ARE_ADDR_EQUAL(&d[0],
1814 &p);
1815 }
1816 }
1817 break;
1818
1819 case O_FLOW6ID:
1820 match = is_ipv6 &&
1821 flow6id_match(args->f_id.flow_id6,
1822 (ipfw_insn_u32 *) cmd);
1823 break;
1824
1825 case O_EXT_HDR:
1826 match = is_ipv6 &&
1827 (ext_hd & ((ipfw_insn *) cmd)->arg1);
1828 break;
1829
1830 case O_IP6:
1831 match = is_ipv6;
1832 break;
1833#endif
1834
1835 case O_IP4:
1836 match = is_ipv4;
1837 break;
1838
1839 case O_TAG: {
1840 struct m_tag *mtag;
1841 uint32_t tag = (cmd->arg1 == IP_FW_TABLEARG) ?
1842 tablearg : cmd->arg1;
1843
1844 /* Packet is already tagged with this tag? */
1845 mtag = m_tag_locate(m, MTAG_IPFW, tag, NULL);
1846
1847 /* We have `untag' action when F_NOT flag is
1848 * present. And we must remove this mtag from
1849 * mbuf and reset `match' to zero (`match' will
1850 * be inversed later).
1851 * Otherwise we should allocate new mtag and
1852 * push it into mbuf.
1853 */
1854 if (cmd->len & F_NOT) { /* `untag' action */
1855 if (mtag != NULL)
1856 m_tag_delete(m, mtag);
1857 match = 0;
1858 } else {
1859 if (mtag == NULL) {
1860 mtag = m_tag_alloc( MTAG_IPFW,
1861 tag, 0, M_NOWAIT);
1862 if (mtag != NULL)
1863 m_tag_prepend(m, mtag);
1864 }
1865 match = 1;
1866 }
1867 break;
1868 }
1869
1870 case O_FIB: /* try match the specified fib */
1871 if (args->f_id.fib == cmd->arg1)
1872 match = 1;
1873 break;
1874
1875 case O_SOCKARG: {
1876 struct inpcb *inp = args->inp;
1877 struct inpcbinfo *pi;
1878
1879 if (is_ipv6) /* XXX can we remove this ? */
1880 break;
1881
1882 if (proto == IPPROTO_TCP)
1883 pi = &V_tcbinfo;
1884 else if (proto == IPPROTO_UDP)
1885 pi = &V_udbinfo;
1886 else
1887 break;
1888
1889 /*
1890 * XXXRW: so_user_cookie should almost
1891 * certainly be inp_user_cookie?
1892 */
1893
1894 /* For incomming packet, lookup up the
1895 inpcb using the src/dest ip/port tuple */
1896 if (inp == NULL) {
1897 inp = in_pcblookup(pi,
1898 src_ip, htons(src_port),
1899 dst_ip, htons(dst_port),
1900 INPLOOKUP_RLOCKPCB, NULL);
1901 if (inp != NULL) {
1902 tablearg =
1903 inp->inp_socket->so_user_cookie;
1904 if (tablearg)
1905 match = 1;
1906 INP_RUNLOCK(inp);
1907 }
1908 } else {
1909 if (inp->inp_socket) {
1910 tablearg =
1911 inp->inp_socket->so_user_cookie;
1912 if (tablearg)
1913 match = 1;
1914 }
1915 }
1916 break;
1917 }
1918
1919 case O_TAGGED: {
1920 struct m_tag *mtag;
1921 uint32_t tag = (cmd->arg1 == IP_FW_TABLEARG) ?
1922 tablearg : cmd->arg1;
1923
1924 if (cmdlen == 1) {
1925 match = m_tag_locate(m, MTAG_IPFW,
1926 tag, NULL) != NULL;
1927 break;
1928 }
1929
1930 /* we have ranges */
1931 for (mtag = m_tag_first(m);
1932 mtag != NULL && !match;
1933 mtag = m_tag_next(m, mtag)) {
1934 uint16_t *p;
1935 int i;
1936
1937 if (mtag->m_tag_cookie != MTAG_IPFW)
1938 continue;
1939
1940 p = ((ipfw_insn_u16 *)cmd)->ports;
1941 i = cmdlen - 1;
1942 for(; !match && i > 0; i--, p += 2)
1943 match =
1944 mtag->m_tag_id >= p[0] &&
1945 mtag->m_tag_id <= p[1];
1946 }
1947 break;
1948 }
1949
1950 /*
1951 * The second set of opcodes represents 'actions',
1952 * i.e. the terminal part of a rule once the packet
1953 * matches all previous patterns.
1954 * Typically there is only one action for each rule,
1955 * and the opcode is stored at the end of the rule
1956 * (but there are exceptions -- see below).
1957 *
1958 * In general, here we set retval and terminate the
1959 * outer loop (would be a 'break 3' in some language,
1960 * but we need to set l=0, done=1)
1961 *
1962 * Exceptions:
1963 * O_COUNT and O_SKIPTO actions:
1964 * instead of terminating, we jump to the next rule
1965 * (setting l=0), or to the SKIPTO target (setting
1966 * f/f_len, cmd and l as needed), respectively.
1967 *
1968 * O_TAG, O_LOG and O_ALTQ action parameters:
1969 * perform some action and set match = 1;
1970 *
1971 * O_LIMIT and O_KEEP_STATE: these opcodes are
1972 * not real 'actions', and are stored right
1973 * before the 'action' part of the rule.
1974 * These opcodes try to install an entry in the
1975 * state tables; if successful, we continue with
1976 * the next opcode (match=1; break;), otherwise
1977 * the packet must be dropped (set retval,
1978 * break loops with l=0, done=1)
1979 *
1980 * O_PROBE_STATE and O_CHECK_STATE: these opcodes
1981 * cause a lookup of the state table, and a jump
1982 * to the 'action' part of the parent rule
1983 * if an entry is found, or
1984 * (CHECK_STATE only) a jump to the next rule if
1985 * the entry is not found.
1986 * The result of the lookup is cached so that
1987 * further instances of these opcodes become NOPs.
1988 * The jump to the next rule is done by setting
1989 * l=0, cmdlen=0.
1990 */
1991 case O_LIMIT:
1992 case O_KEEP_STATE:
1993 if (ipfw_install_state(f,
1994 (ipfw_insn_limit *)cmd, args, tablearg)) {
1995 /* error or limit violation */
1996 retval = IP_FW_DENY;
1997 l = 0; /* exit inner loop */
1998 done = 1; /* exit outer loop */
1999 }
2000 match = 1;
2001 break;
2002
2003 case O_PROBE_STATE:
2004 case O_CHECK_STATE:
2005 /*
2006 * dynamic rules are checked at the first
2007 * keep-state or check-state occurrence,
2008 * with the result being stored in dyn_dir.
2009 * The compiler introduces a PROBE_STATE
2010 * instruction for us when we have a
2011 * KEEP_STATE (because PROBE_STATE needs
2012 * to be run first).
2013 */
2014 if (dyn_dir == MATCH_UNKNOWN &&
2015 (q = ipfw_lookup_dyn_rule(&args->f_id,
2016 &dyn_dir, proto == IPPROTO_TCP ?
2017 TCP(ulp) : NULL))
2018 != NULL) {
2019 /*
2020 * Found dynamic entry, update stats
2021 * and jump to the 'action' part of
2022 * the parent rule by setting
2023 * f, cmd, l and clearing cmdlen.
2024 */
2025 q->pcnt++;
2026 q->bcnt += pktlen;
2027 /* XXX we would like to have f_pos
2028 * readily accessible in the dynamic
2029 * rule, instead of having to
2030 * lookup q->rule.
2031 */
2032 f = q->rule;
2033 f_pos = ipfw_find_rule(chain,
2034 f->rulenum, f->id);
2035 cmd = ACTION_PTR(f);
2036 l = f->cmd_len - f->act_ofs;
2037 ipfw_dyn_unlock();
2038 cmdlen = 0;
2039 match = 1;
2040 break;
2041 }
2042 /*
2043 * Dynamic entry not found. If CHECK_STATE,
2044 * skip to next rule, if PROBE_STATE just
2045 * ignore and continue with next opcode.
2046 */
2047 if (cmd->opcode == O_CHECK_STATE)
2048 l = 0; /* exit inner loop */
2049 match = 1;
2050 break;
2051
2052 case O_ACCEPT:
2053 retval = 0; /* accept */
2054 l = 0; /* exit inner loop */
2055 done = 1; /* exit outer loop */
2056 break;
2057
2058 case O_PIPE:
2059 case O_QUEUE:
2060 set_match(args, f_pos, chain);
2061 args->rule.info = (cmd->arg1 == IP_FW_TABLEARG) ?
2062 tablearg : cmd->arg1;
2063 if (cmd->opcode == O_PIPE)
2064 args->rule.info |= IPFW_IS_PIPE;
2065 if (V_fw_one_pass)
2066 args->rule.info |= IPFW_ONEPASS;
2067 retval = IP_FW_DUMMYNET;
2068 l = 0; /* exit inner loop */
2069 done = 1; /* exit outer loop */
2070 break;
2071
2072 case O_DIVERT:
2073 case O_TEE:
2074 if (args->eh) /* not on layer 2 */
2075 break;
2076 /* otherwise this is terminal */
2077 l = 0; /* exit inner loop */
2078 done = 1; /* exit outer loop */
2079 retval = (cmd->opcode == O_DIVERT) ?
2080 IP_FW_DIVERT : IP_FW_TEE;
2081 set_match(args, f_pos, chain);
2082 args->rule.info = (cmd->arg1 == IP_FW_TABLEARG) ?
2083 tablearg : cmd->arg1;
2084 break;
2085
2086 case O_COUNT:
2087 f->pcnt++; /* update stats */
2088 f->bcnt += pktlen;
2089 f->timestamp = time_uptime;
2090 l = 0; /* exit inner loop */
2091 break;
2092
2093 case O_SKIPTO:
2094 f->pcnt++; /* update stats */
2095 f->bcnt += pktlen;
2096 f->timestamp = time_uptime;
2097 /* If possible use cached f_pos (in f->next_rule),
2098 * whose version is written in f->next_rule
2099 * (horrible hacks to avoid changing the ABI).
2100 */
2101 if (cmd->arg1 != IP_FW_TABLEARG &&
2102 (uintptr_t)f->x_next == chain->id) {
2103 f_pos = (uintptr_t)f->next_rule;
2104 } else {
2105 int i = (cmd->arg1 == IP_FW_TABLEARG) ?
2106 tablearg : cmd->arg1;
2107 /* make sure we do not jump backward */
2108 if (i <= f->rulenum)
2109 i = f->rulenum + 1;
2110 f_pos = ipfw_find_rule(chain, i, 0);
2111 /* update the cache */
2112 if (cmd->arg1 != IP_FW_TABLEARG) {
2113 f->next_rule =
2114 (void *)(uintptr_t)f_pos;
2115 f->x_next =
2116 (void *)(uintptr_t)chain->id;
2117 }
2118 }
2119 /*
2120 * Skip disabled rules, and re-enter
2121 * the inner loop with the correct
2122 * f_pos, f, l and cmd.
2123 * Also clear cmdlen and skip_or
2124 */
2125 for (; f_pos < chain->n_rules - 1 &&
2126 (V_set_disable &
2127 (1 << chain->map[f_pos]->set));
2128 f_pos++)
2129 ;
2130 /* Re-enter the inner loop at the skipto rule. */
2131 f = chain->map[f_pos];
2132 l = f->cmd_len;
2133 cmd = f->cmd;
2134 match = 1;
2135 cmdlen = 0;
2136 skip_or = 0;
2137 continue;
2138 break; /* not reached */
2139
2140 case O_CALLRETURN: {
2141 /*
2142 * Implementation of `subroutine' call/return,
2143 * in the stack carried in an mbuf tag. This
2144 * is different from `skipto' in that any call
2145 * address is possible (`skipto' must prevent
2146 * backward jumps to avoid endless loops).
2147 * We have `return' action when F_NOT flag is
2148 * present. The `m_tag_id' field is used as
2149 * stack pointer.
2150 */
2151 struct m_tag *mtag;
2152 uint16_t jmpto, *stack;
2153
2154#define IS_CALL ((cmd->len & F_NOT) == 0)
2155#define IS_RETURN ((cmd->len & F_NOT) != 0)
2156 /*
2157 * Hand-rolled version of m_tag_locate() with
2158 * wildcard `type'.
2159 * If not already tagged, allocate new tag.
2160 */
2161 mtag = m_tag_first(m);
2162 while (mtag != NULL) {
2163 if (mtag->m_tag_cookie ==
2164 MTAG_IPFW_CALL)
2165 break;
2166 mtag = m_tag_next(m, mtag);
2167 }
2168 if (mtag == NULL && IS_CALL) {
2169 mtag = m_tag_alloc(MTAG_IPFW_CALL, 0,
2170 IPFW_CALLSTACK_SIZE *
2171 sizeof(uint16_t), M_NOWAIT);
2172 if (mtag != NULL)
2173 m_tag_prepend(m, mtag);
2174 }
2175
2176 /*
2177 * On error both `call' and `return' just
2178 * continue with next rule.
2179 */
2180 if (IS_RETURN && (mtag == NULL ||
2181 mtag->m_tag_id == 0)) {
2182 l = 0; /* exit inner loop */
2183 break;
2184 }
2185 if (IS_CALL && (mtag == NULL ||
2186 mtag->m_tag_id >= IPFW_CALLSTACK_SIZE)) {
2187 printf("ipfw: call stack error, "
2188 "go to next rule\n");
2189 l = 0; /* exit inner loop */
2190 break;
2191 }
2192
2193 f->pcnt++; /* update stats */
2194 f->bcnt += pktlen;
2195 f->timestamp = time_uptime;
2196 stack = (uint16_t *)(mtag + 1);
2197
2198 /*
2199 * The `call' action may use cached f_pos
2200 * (in f->next_rule), whose version is written
2201 * in f->next_rule.
2202 * The `return' action, however, doesn't have
2203 * fixed jump address in cmd->arg1 and can't use
2204 * cache.
2205 */
2206 if (IS_CALL) {
2207 stack[mtag->m_tag_id] = f->rulenum;
2208 mtag->m_tag_id++;
2209 if (cmd->arg1 != IP_FW_TABLEARG &&
2210 (uintptr_t)f->x_next == chain->id) {
2211 f_pos = (uintptr_t)f->next_rule;
2212 } else {
2213 jmpto = (cmd->arg1 ==
2214 IP_FW_TABLEARG) ? tablearg:
2215 cmd->arg1;
2216 f_pos = ipfw_find_rule(chain,
2217 jmpto, 0);
2218 /* update the cache */
2219 if (cmd->arg1 !=
2220 IP_FW_TABLEARG) {
2221 f->next_rule =
2222 (void *)(uintptr_t)
2223 f_pos;
2224 f->x_next =
2225 (void *)(uintptr_t)
2226 chain->id;
2227 }
2228 }
2229 } else { /* `return' action */
2230 mtag->m_tag_id--;
2231 jmpto = stack[mtag->m_tag_id] + 1;
2232 f_pos = ipfw_find_rule(chain, jmpto, 0);
2233 }
2234
2235 /*
2236 * Skip disabled rules, and re-enter
2237 * the inner loop with the correct
2238 * f_pos, f, l and cmd.
2239 * Also clear cmdlen and skip_or
2240 */
2241 for (; f_pos < chain->n_rules - 1 &&
2242 (V_set_disable &
2243 (1 << chain->map[f_pos]->set)); f_pos++)
2244 ;
2245 /* Re-enter the inner loop at the dest rule. */
2246 f = chain->map[f_pos];
2247 l = f->cmd_len;
2248 cmd = f->cmd;
2249 cmdlen = 0;
2250 skip_or = 0;
2251 continue;
2252 break; /* NOTREACHED */
2253 }
2254#undef IS_CALL
2255#undef IS_RETURN
2256
2257 case O_REJECT:
2258 /*
2259 * Drop the packet and send a reject notice
2260 * if the packet is not ICMP (or is an ICMP
2261 * query), and it is not multicast/broadcast.
2262 */
2263 if (hlen > 0 && is_ipv4 && offset == 0 &&
2264 (proto != IPPROTO_ICMP ||
2265 is_icmp_query(ICMP(ulp))) &&
2266 !(m->m_flags & (M_BCAST|M_MCAST)) &&
2267 !IN_MULTICAST(ntohl(dst_ip.s_addr))) {
2268 send_reject(args, cmd->arg1, iplen, ip);
2269 m = args->m;
2270 }
2271 /* FALLTHROUGH */
2272#ifdef INET6
2273 case O_UNREACH6:
2274 if (hlen > 0 && is_ipv6 &&
2275 ((offset & IP6F_OFF_MASK) == 0) &&
2276 (proto != IPPROTO_ICMPV6 ||
2277 (is_icmp6_query(icmp6_type) == 1)) &&
2278 !(m->m_flags & (M_BCAST|M_MCAST)) &&
2279 !IN6_IS_ADDR_MULTICAST(&args->f_id.dst_ip6)) {
2280 send_reject6(
2281 args, cmd->arg1, hlen,
2282 (struct ip6_hdr *)ip);
2283 m = args->m;
2284 }
2285 /* FALLTHROUGH */
2286#endif
2287 case O_DENY:
2288 retval = IP_FW_DENY;
2289 l = 0; /* exit inner loop */
2290 done = 1; /* exit outer loop */
2291 break;
2292
2293 case O_FORWARD_IP:
2294 if (args->eh) /* not valid on layer2 pkts */
2295 break;
2296 if (q == NULL || q->rule != f ||
2297 dyn_dir == MATCH_FORWARD) {
2298 struct sockaddr_in *sa;
2299 sa = &(((ipfw_insn_sa *)cmd)->sa);
2300 if (sa->sin_addr.s_addr == INADDR_ANY) {
2301 bcopy(sa, &args->hopstore,
2302 sizeof(*sa));
2303 args->hopstore.sin_addr.s_addr =
2304 htonl(tablearg);
2305 args->next_hop = &args->hopstore;
2306 } else {
2307 args->next_hop = sa;
2308 }
2309 }
2310 retval = IP_FW_PASS;
2311 l = 0; /* exit inner loop */
2312 done = 1; /* exit outer loop */
2313 break;
2314
2315#ifdef INET6
2316 case O_FORWARD_IP6:
2317 if (args->eh) /* not valid on layer2 pkts */
2318 break;
2319 if (q == NULL || q->rule != f ||
2320 dyn_dir == MATCH_FORWARD) {
2321 struct sockaddr_in6 *sin6;
2322
2323 sin6 = &(((ipfw_insn_sa6 *)cmd)->sa);
2324 args->next_hop6 = sin6;
2325 }
2326 retval = IP_FW_PASS;
2327 l = 0; /* exit inner loop */
2328 done = 1; /* exit outer loop */
2329 break;
2330#endif
2331
2332 case O_NETGRAPH:
2333 case O_NGTEE:
2334 set_match(args, f_pos, chain);
2335 args->rule.info = (cmd->arg1 == IP_FW_TABLEARG) ?
2336 tablearg : cmd->arg1;
2337 if (V_fw_one_pass)
2338 args->rule.info |= IPFW_ONEPASS;
2339 retval = (cmd->opcode == O_NETGRAPH) ?
2340 IP_FW_NETGRAPH : IP_FW_NGTEE;
2341 l = 0; /* exit inner loop */
2342 done = 1; /* exit outer loop */
2343 break;
2344
2345 case O_SETFIB: {
2346 uint32_t fib;
2347
2348 f->pcnt++; /* update stats */
2349 f->bcnt += pktlen;
2350 f->timestamp = time_uptime;
2351 fib = (cmd->arg1 == IP_FW_TABLEARG) ? tablearg:
2352 cmd->arg1;
2353 if (fib >= rt_numfibs)
2354 fib = 0;
2355 M_SETFIB(m, fib);
2356 args->f_id.fib = fib;
2357 l = 0; /* exit inner loop */
2358 break;
2359 }
2360
2361 case O_NAT:
2362 if (!IPFW_NAT_LOADED) {
2363 retval = IP_FW_DENY;
2364 } else {
2365 struct cfg_nat *t;
2366 int nat_id;
2367
2368 set_match(args, f_pos, chain);
2369 /* Check if this is 'global' nat rule */
2370 if (cmd->arg1 == 0) {
2371 retval = ipfw_nat_ptr(args, NULL, m);
2372 l = 0;
2373 done = 1;
2374 break;
2375 }
2376 t = ((ipfw_insn_nat *)cmd)->nat;
2377 if (t == NULL) {
2378 nat_id = (cmd->arg1 == IP_FW_TABLEARG) ?
2379 tablearg : cmd->arg1;
2380 t = (*lookup_nat_ptr)(&chain->nat, nat_id);
2381
2382 if (t == NULL) {
2383 retval = IP_FW_DENY;
2384 l = 0; /* exit inner loop */
2385 done = 1; /* exit outer loop */
2386 break;
2387 }
2388 if (cmd->arg1 != IP_FW_TABLEARG)
2389 ((ipfw_insn_nat *)cmd)->nat = t;
2390 }
2391 retval = ipfw_nat_ptr(args, t, m);
2392 }
2393 l = 0; /* exit inner loop */
2394 done = 1; /* exit outer loop */
2395 break;
2396
2397 case O_REASS: {
2398 int ip_off;
2399
2400 f->pcnt++;
2401 f->bcnt += pktlen;
2402 l = 0; /* in any case exit inner loop */
2403 ip_off = ntohs(ip->ip_off);
2404
2405 /* if not fragmented, go to next rule */
2406 if ((ip_off & (IP_MF | IP_OFFMASK)) == 0)
2407 break;
2408 /*
2409 * ip_reass() expects len & off in host
2410 * byte order.
2411 */
2412 SET_HOST_IPLEN(ip);
2413
2414 args->m = m = ip_reass(m);
2415
2416 /*
2417 * do IP header checksum fixup.
2418 */
2419 if (m == NULL) { /* fragment got swallowed */
2420 retval = IP_FW_DENY;
2421 } else { /* good, packet complete */
2422 int hlen;
2423
2424 ip = mtod(m, struct ip *);
2425 hlen = ip->ip_hl << 2;
2426 SET_NET_IPLEN(ip);
2427 ip->ip_sum = 0;
2428 if (hlen == sizeof(struct ip))
2429 ip->ip_sum = in_cksum_hdr(ip);
2430 else
2431 ip->ip_sum = in_cksum(m, hlen);
2432 retval = IP_FW_REASS;
2433 set_match(args, f_pos, chain);
2434 }
2435 done = 1; /* exit outer loop */
2436 break;
2437 }
2438
2439 default:
2440 panic("-- unknown opcode %d\n", cmd->opcode);
2441 } /* end of switch() on opcodes */
2442 /*
2443 * if we get here with l=0, then match is irrelevant.
2444 */
2445
2446 if (cmd->len & F_NOT)
2447 match = !match;
2448
2449 if (match) {
2450 if (cmd->len & F_OR)
2451 skip_or = 1;
2452 } else {
2453 if (!(cmd->len & F_OR)) /* not an OR block, */
2454 break; /* try next rule */
2455 }
2456
2457 } /* end of inner loop, scan opcodes */
2458#undef PULLUP_LEN
2459
2460 if (done)
2461 break;
2462
2463/* next_rule:; */ /* try next rule */
2464
2465 } /* end of outer for, scan rules */
2466
2467 if (done) {
2468 struct ip_fw *rule = chain->map[f_pos];
2469 /* Update statistics */
2470 rule->pcnt++;
2471 rule->bcnt += pktlen;
2472 rule->timestamp = time_uptime;
2473 } else {
2474 retval = IP_FW_DENY;
2475 printf("ipfw: ouch!, skip past end of rules, denying packet\n");
2476 }
2477 IPFW_RUNLOCK(chain);
2478#ifdef __FreeBSD__
2479 if (ucred_cache != NULL)
2480 crfree(ucred_cache);
2481#endif
2482 return (retval);
2483
2484pullup_failed:
2485 if (V_fw_verbose)
2486 printf("ipfw: pullup failed\n");
2487 return (IP_FW_DENY);
2488}
2489
2490/*
2491 * Module and VNET glue
2492 */
2493
2494/*
2495 * Stuff that must be initialised only on boot or module load
2496 */
2497static int
2498ipfw_init(void)
2499{
2500 int error = 0;
2501
2502 ipfw_dyn_attach();
2503 /*
2504 * Only print out this stuff the first time around,
2505 * when called from the sysinit code.
2506 */
2507 printf("ipfw2 "
2508#ifdef INET6
2509 "(+ipv6) "
2510#endif
2511 "initialized, divert %s, nat %s, "
2512 "rule-based forwarding "
2513#ifdef IPFIREWALL_FORWARD
2514 "enabled, "
2515#else
2516 "disabled, "
2517#endif
2518 "default to %s, logging ",
2519#ifdef IPDIVERT
2520 "enabled",
2521#else
2522 "loadable",
2523#endif
2524#ifdef IPFIREWALL_NAT
2525 "enabled",
2526#else
2527 "loadable",
2528#endif
2529 default_to_accept ? "accept" : "deny");
2530
2531 /*
2532 * Note: V_xxx variables can be accessed here but the vnet specific
2533 * initializer may not have been called yet for the VIMAGE case.
2534 * Tuneables will have been processed. We will print out values for
2535 * the default vnet.
2536 * XXX This should all be rationalized AFTER 8.0
2537 */
2538 if (V_fw_verbose == 0)
2539 printf("disabled\n");
2540 else if (V_verbose_limit == 0)
2541 printf("unlimited\n");
2542 else
2543 printf("limited to %d packets/entry by default\n",
2544 V_verbose_limit);
2545
2546 ipfw_log_bpf(1); /* init */
2547 return (error);
2548}
2549
2550/*
2551 * Called for the removal of the last instance only on module unload.
2552 */
2553static void
2554ipfw_destroy(void)
2555{
2556
2557 ipfw_log_bpf(0); /* uninit */
2558 ipfw_dyn_detach();
2559 printf("IP firewall unloaded\n");
2560}
2561
2562/*
2563 * Stuff that must be initialized for every instance
2564 * (including the first of course).
2565 */
2566static int
2567vnet_ipfw_init(const void *unused)
2568{
2569 int error;
2570 struct ip_fw *rule = NULL;
2571 struct ip_fw_chain *chain;
2572
2573 chain = &V_layer3_chain;
2574
2575 /* First set up some values that are compile time options */
2576 V_autoinc_step = 100; /* bounded to 1..1000 in add_rule() */
2577 V_fw_deny_unknown_exthdrs = 1;
2578#ifdef IPFIREWALL_VERBOSE
2579 V_fw_verbose = 1;
2580#endif
2581#ifdef IPFIREWALL_VERBOSE_LIMIT
2582 V_verbose_limit = IPFIREWALL_VERBOSE_LIMIT;
2583#endif
2584#ifdef IPFIREWALL_NAT
2585 LIST_INIT(&chain->nat);
2586#endif
2587
2588 /* Check user-supplied number for validness */
2589 if (V_fw_tables_max < 0)
2590 V_fw_tables_max = IPFW_TABLES_MAX;
2591 if (V_fw_tables_max > 65534)
2592 V_fw_tables_max = 65534;
2593
2569 /* insert the default rule and create the initial map */
2570 chain->n_rules = 1;
2571 chain->static_len = sizeof(struct ip_fw);
2594 /* insert the default rule and create the initial map */
2595 chain->n_rules = 1;
2596 chain->static_len = sizeof(struct ip_fw);
2572 chain->map = malloc(sizeof(struct ip_fw *), M_IPFW, M_NOWAIT | M_ZERO);
2597 chain->map = malloc(sizeof(struct ip_fw *), M_IPFW, M_WAITOK | M_ZERO);
2573 if (chain->map)
2598 if (chain->map)
2574 rule = malloc(chain->static_len, M_IPFW, M_NOWAIT | M_ZERO);
2575 if (rule == NULL) {
2576 if (chain->map)
2577 free(chain->map, M_IPFW);
2578 printf("ipfw2: ENOSPC initializing default rule "
2579 "(support disabled)\n");
2580 return (ENOSPC);
2581 }
2599 rule = malloc(chain->static_len, M_IPFW, M_WAITOK | M_ZERO);
2582 error = ipfw_init_tables(chain);
2583 if (error) {
2600 error = ipfw_init_tables(chain);
2601 if (error) {
2584 panic("init_tables"); /* XXX Marko fix this ! */
2602 printf("ipfw2: setting up tables failed\n");
2603 free(chain->map, M_IPFW);
2604 free(rule, M_IPFW);
2605 return (ENOSPC);
2585 }
2586
2587 /* fill and insert the default rule */
2588 rule->act_ofs = 0;
2589 rule->rulenum = IPFW_DEFAULT_RULE;
2590 rule->cmd_len = 1;
2591 rule->set = RESVD_SET;
2592 rule->cmd[0].len = 1;
2593 rule->cmd[0].opcode = default_to_accept ? O_ACCEPT : O_DENY;
2594 chain->rules = chain->default_rule = chain->map[0] = rule;
2595 chain->id = rule->id = 1;
2596
2597 IPFW_LOCK_INIT(chain);
2598 ipfw_dyn_init();
2599
2600 /* First set up some values that are compile time options */
2601 V_ipfw_vnet_ready = 1; /* Open for business */
2602
2603 /*
2604 * Hook the sockopt handler, and the layer2 (V_ip_fw_chk_ptr)
2605 * and pfil hooks for ipv4 and ipv6. Even if the latter two fail
2606 * we still keep the module alive because the sockopt and
2607 * layer2 paths are still useful.
2608 * ipfw[6]_hook return 0 on success, ENOENT on failure,
2609 * so we can ignore the exact return value and just set a flag.
2610 *
2611 * Note that V_fw[6]_enable are manipulated by a SYSCTL_PROC so
2612 * changes in the underlying (per-vnet) variables trigger
2613 * immediate hook()/unhook() calls.
2614 * In layer2 we have the same behaviour, except that V_ether_ipfw
2615 * is checked on each packet because there are no pfil hooks.
2616 */
2617 V_ip_fw_ctl_ptr = ipfw_ctl;
2618 V_ip_fw_chk_ptr = ipfw_chk;
2619 error = ipfw_attach_hooks(1);
2620 return (error);
2621}
2622
2623/*
2624 * Called for the removal of each instance.
2625 */
2626static int
2627vnet_ipfw_uninit(const void *unused)
2628{
2629 struct ip_fw *reap, *rule;
2630 struct ip_fw_chain *chain = &V_layer3_chain;
2631 int i;
2632
2633 V_ipfw_vnet_ready = 0; /* tell new callers to go away */
2634 /*
2635 * disconnect from ipv4, ipv6, layer2 and sockopt.
2636 * Then grab, release and grab again the WLOCK so we make
2637 * sure the update is propagated and nobody will be in.
2638 */
2639 (void)ipfw_attach_hooks(0 /* detach */);
2640 V_ip_fw_chk_ptr = NULL;
2641 V_ip_fw_ctl_ptr = NULL;
2642 IPFW_UH_WLOCK(chain);
2643 IPFW_UH_WUNLOCK(chain);
2644 IPFW_UH_WLOCK(chain);
2645
2646 IPFW_WLOCK(chain);
2606 }
2607
2608 /* fill and insert the default rule */
2609 rule->act_ofs = 0;
2610 rule->rulenum = IPFW_DEFAULT_RULE;
2611 rule->cmd_len = 1;
2612 rule->set = RESVD_SET;
2613 rule->cmd[0].len = 1;
2614 rule->cmd[0].opcode = default_to_accept ? O_ACCEPT : O_DENY;
2615 chain->rules = chain->default_rule = chain->map[0] = rule;
2616 chain->id = rule->id = 1;
2617
2618 IPFW_LOCK_INIT(chain);
2619 ipfw_dyn_init();
2620
2621 /* First set up some values that are compile time options */
2622 V_ipfw_vnet_ready = 1; /* Open for business */
2623
2624 /*
2625 * Hook the sockopt handler, and the layer2 (V_ip_fw_chk_ptr)
2626 * and pfil hooks for ipv4 and ipv6. Even if the latter two fail
2627 * we still keep the module alive because the sockopt and
2628 * layer2 paths are still useful.
2629 * ipfw[6]_hook return 0 on success, ENOENT on failure,
2630 * so we can ignore the exact return value and just set a flag.
2631 *
2632 * Note that V_fw[6]_enable are manipulated by a SYSCTL_PROC so
2633 * changes in the underlying (per-vnet) variables trigger
2634 * immediate hook()/unhook() calls.
2635 * In layer2 we have the same behaviour, except that V_ether_ipfw
2636 * is checked on each packet because there are no pfil hooks.
2637 */
2638 V_ip_fw_ctl_ptr = ipfw_ctl;
2639 V_ip_fw_chk_ptr = ipfw_chk;
2640 error = ipfw_attach_hooks(1);
2641 return (error);
2642}
2643
2644/*
2645 * Called for the removal of each instance.
2646 */
2647static int
2648vnet_ipfw_uninit(const void *unused)
2649{
2650 struct ip_fw *reap, *rule;
2651 struct ip_fw_chain *chain = &V_layer3_chain;
2652 int i;
2653
2654 V_ipfw_vnet_ready = 0; /* tell new callers to go away */
2655 /*
2656 * disconnect from ipv4, ipv6, layer2 and sockopt.
2657 * Then grab, release and grab again the WLOCK so we make
2658 * sure the update is propagated and nobody will be in.
2659 */
2660 (void)ipfw_attach_hooks(0 /* detach */);
2661 V_ip_fw_chk_ptr = NULL;
2662 V_ip_fw_ctl_ptr = NULL;
2663 IPFW_UH_WLOCK(chain);
2664 IPFW_UH_WUNLOCK(chain);
2665 IPFW_UH_WLOCK(chain);
2666
2667 IPFW_WLOCK(chain);
2668 ipfw_dyn_uninit(0); /* run the callout_drain */
2647 IPFW_WUNLOCK(chain);
2669 IPFW_WUNLOCK(chain);
2648 IPFW_WLOCK(chain);
2649
2670
2650 ipfw_dyn_uninit(0); /* run the callout_drain */
2651 ipfw_destroy_tables(chain);
2652 reap = NULL;
2671 ipfw_destroy_tables(chain);
2672 reap = NULL;
2673 IPFW_WLOCK(chain);
2653 for (i = 0; i < chain->n_rules; i++) {
2654 rule = chain->map[i];
2655 rule->x_next = reap;
2656 reap = rule;
2657 }
2658 if (chain->map)
2659 free(chain->map, M_IPFW);
2660 IPFW_WUNLOCK(chain);
2661 IPFW_UH_WUNLOCK(chain);
2662 if (reap != NULL)
2663 ipfw_reap_rules(reap);
2664 IPFW_LOCK_DESTROY(chain);
2665 ipfw_dyn_uninit(1); /* free the remaining parts */
2666 return 0;
2667}
2668
2669/*
2670 * Module event handler.
2671 * In general we have the choice of handling most of these events by the
2672 * event handler or by the (VNET_)SYS(UN)INIT handlers. I have chosen to
2673 * use the SYSINIT handlers as they are more capable of expressing the
2674 * flow of control during module and vnet operations, so this is just
2675 * a skeleton. Note there is no SYSINIT equivalent of the module
2676 * SHUTDOWN handler, but we don't have anything to do in that case anyhow.
2677 */
2678static int
2679ipfw_modevent(module_t mod, int type, void *unused)
2680{
2681 int err = 0;
2682
2683 switch (type) {
2684 case MOD_LOAD:
2685 /* Called once at module load or
2686 * system boot if compiled in. */
2687 break;
2688 case MOD_QUIESCE:
2689 /* Called before unload. May veto unloading. */
2690 break;
2691 case MOD_UNLOAD:
2692 /* Called during unload. */
2693 break;
2694 case MOD_SHUTDOWN:
2695 /* Called during system shutdown. */
2696 break;
2697 default:
2698 err = EOPNOTSUPP;
2699 break;
2700 }
2701 return err;
2702}
2703
2704static moduledata_t ipfwmod = {
2705 "ipfw",
2706 ipfw_modevent,
2707 0
2708};
2709
2710/* Define startup order. */
2711#define IPFW_SI_SUB_FIREWALL SI_SUB_PROTO_IFATTACHDOMAIN
2712#define IPFW_MODEVENT_ORDER (SI_ORDER_ANY - 255) /* On boot slot in here. */
2713#define IPFW_MODULE_ORDER (IPFW_MODEVENT_ORDER + 1) /* A little later. */
2714#define IPFW_VNET_ORDER (IPFW_MODEVENT_ORDER + 2) /* Later still. */
2715
2716DECLARE_MODULE(ipfw, ipfwmod, IPFW_SI_SUB_FIREWALL, IPFW_MODEVENT_ORDER);
2717MODULE_VERSION(ipfw, 2);
2718/* should declare some dependencies here */
2719
2720/*
2721 * Starting up. Done in order after ipfwmod() has been called.
2722 * VNET_SYSINIT is also called for each existing vnet and each new vnet.
2723 */
2724SYSINIT(ipfw_init, IPFW_SI_SUB_FIREWALL, IPFW_MODULE_ORDER,
2725 ipfw_init, NULL);
2726VNET_SYSINIT(vnet_ipfw_init, IPFW_SI_SUB_FIREWALL, IPFW_VNET_ORDER,
2727 vnet_ipfw_init, NULL);
2728
2729/*
2730 * Closing up shop. These are done in REVERSE ORDER, but still
2731 * after ipfwmod() has been called. Not called on reboot.
2732 * VNET_SYSUNINIT is also called for each exiting vnet as it exits.
2733 * or when the module is unloaded.
2734 */
2735SYSUNINIT(ipfw_destroy, IPFW_SI_SUB_FIREWALL, IPFW_MODULE_ORDER,
2736 ipfw_destroy, NULL);
2737VNET_SYSUNINIT(vnet_ipfw_uninit, IPFW_SI_SUB_FIREWALL, IPFW_VNET_ORDER,
2738 vnet_ipfw_uninit, NULL);
2739/* end of file */
2674 for (i = 0; i < chain->n_rules; i++) {
2675 rule = chain->map[i];
2676 rule->x_next = reap;
2677 reap = rule;
2678 }
2679 if (chain->map)
2680 free(chain->map, M_IPFW);
2681 IPFW_WUNLOCK(chain);
2682 IPFW_UH_WUNLOCK(chain);
2683 if (reap != NULL)
2684 ipfw_reap_rules(reap);
2685 IPFW_LOCK_DESTROY(chain);
2686 ipfw_dyn_uninit(1); /* free the remaining parts */
2687 return 0;
2688}
2689
2690/*
2691 * Module event handler.
2692 * In general we have the choice of handling most of these events by the
2693 * event handler or by the (VNET_)SYS(UN)INIT handlers. I have chosen to
2694 * use the SYSINIT handlers as they are more capable of expressing the
2695 * flow of control during module and vnet operations, so this is just
2696 * a skeleton. Note there is no SYSINIT equivalent of the module
2697 * SHUTDOWN handler, but we don't have anything to do in that case anyhow.
2698 */
2699static int
2700ipfw_modevent(module_t mod, int type, void *unused)
2701{
2702 int err = 0;
2703
2704 switch (type) {
2705 case MOD_LOAD:
2706 /* Called once at module load or
2707 * system boot if compiled in. */
2708 break;
2709 case MOD_QUIESCE:
2710 /* Called before unload. May veto unloading. */
2711 break;
2712 case MOD_UNLOAD:
2713 /* Called during unload. */
2714 break;
2715 case MOD_SHUTDOWN:
2716 /* Called during system shutdown. */
2717 break;
2718 default:
2719 err = EOPNOTSUPP;
2720 break;
2721 }
2722 return err;
2723}
2724
2725static moduledata_t ipfwmod = {
2726 "ipfw",
2727 ipfw_modevent,
2728 0
2729};
2730
2731/* Define startup order. */
2732#define IPFW_SI_SUB_FIREWALL SI_SUB_PROTO_IFATTACHDOMAIN
2733#define IPFW_MODEVENT_ORDER (SI_ORDER_ANY - 255) /* On boot slot in here. */
2734#define IPFW_MODULE_ORDER (IPFW_MODEVENT_ORDER + 1) /* A little later. */
2735#define IPFW_VNET_ORDER (IPFW_MODEVENT_ORDER + 2) /* Later still. */
2736
2737DECLARE_MODULE(ipfw, ipfwmod, IPFW_SI_SUB_FIREWALL, IPFW_MODEVENT_ORDER);
2738MODULE_VERSION(ipfw, 2);
2739/* should declare some dependencies here */
2740
2741/*
2742 * Starting up. Done in order after ipfwmod() has been called.
2743 * VNET_SYSINIT is also called for each existing vnet and each new vnet.
2744 */
2745SYSINIT(ipfw_init, IPFW_SI_SUB_FIREWALL, IPFW_MODULE_ORDER,
2746 ipfw_init, NULL);
2747VNET_SYSINIT(vnet_ipfw_init, IPFW_SI_SUB_FIREWALL, IPFW_VNET_ORDER,
2748 vnet_ipfw_init, NULL);
2749
2750/*
2751 * Closing up shop. These are done in REVERSE ORDER, but still
2752 * after ipfwmod() has been called. Not called on reboot.
2753 * VNET_SYSUNINIT is also called for each exiting vnet as it exits.
2754 * or when the module is unloaded.
2755 */
2756SYSUNINIT(ipfw_destroy, IPFW_SI_SUB_FIREWALL, IPFW_MODULE_ORDER,
2757 ipfw_destroy, NULL);
2758VNET_SYSUNINIT(vnet_ipfw_uninit, IPFW_SI_SUB_FIREWALL, IPFW_VNET_ORDER,
2759 vnet_ipfw_uninit, NULL);
2760/* end of file */