Grab the lock before reading uid/gid related structure, this will
[ipfw.git] / dummynet / ip_fw2.c
1 /*-
2  * Copyright (c) 2002 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: src/sys/netinet/ip_fw2.c,v 1.175.2.13 2008/10/30 16:29:04 bz Exp $");
28
29 #define        DEB(x)
30 #define        DDB(x) x
31
32 /*
33  * Implement IP packet firewall (new version)
34  */
35
36 #if !defined(KLD_MODULE)
37 #include "opt_ipfw.h"
38 #include "opt_ipdivert.h"
39 #include "opt_ipdn.h"
40 #include "opt_inet.h"
41 #ifndef INET
42 #error IPFIREWALL requires INET.
43 #endif /* INET */
44 #endif
45 #include "opt_inet6.h"
46 #include "opt_ipsec.h"
47 #include "opt_mac.h"
48
49 #include <sys/param.h>
50 #include <sys/systm.h>
51 #include <sys/malloc.h>
52 #include <sys/mbuf.h>
53 #include <sys/kernel.h>
54 #include <sys/lock.h>
55 #include <sys/jail.h>
56 #include <sys/module.h>
57 #include <sys/priv.h>
58 #include <sys/proc.h>
59 #include <sys/socket.h>
60 #include <sys/socketvar.h>
61 #include <sys/sysctl.h>
62 #include <sys/syslog.h>
63 #include <sys/ucred.h>
64 #include <net/ethernet.h> /* for ETHERTYPE_IP */
65 #include <net/if.h>
66 #include <net/radix.h>
67 #include <net/route.h>
68 #include <net/pf_mtag.h>
69 #include <net/vnet.h>
70
71 #define IPFW_INTERNAL   /* Access to protected data structures in ip_fw.h. */
72
73 #include <netinet/in.h>
74 #include <netinet/in_var.h>
75 #include <netinet/in_pcb.h>
76 #include <netinet/ip.h>
77 #include <netinet/ip_var.h>
78 #include <netinet/ip_icmp.h>
79 #include <netinet/ip_fw.h>
80 #include <netinet/ip_divert.h>
81 #include <netinet/ip_dummynet.h>
82 #include <netinet/ip_carp.h>
83 #include <netinet/pim.h>
84 #include <netinet/tcp_var.h>
85 #include <netinet/udp.h>
86 #include <netinet/udp_var.h>
87 #include <netinet/sctp.h>
88
89 #include <netgraph/ng_ipfw.h>
90
91 #include <netinet/ip6.h>
92 #include <netinet/icmp6.h>
93 #ifdef INET6
94 #include <netinet6/scope6_var.h>
95 #endif
96
97 #include <machine/in_cksum.h>   /* XXX for in_cksum */
98
99 #ifdef MAC
100 #include <security/mac/mac_framework.h>
101 #endif
102
103 #ifdef linux
104 //#include <linux/netdevice.h>    /* XXX dev_net() is used in linux 2.6.30.5 */
105 #define INP_LOCK_ASSERT         /* define before missing.h otherwise ? */
106 #include "missing.h"
107 #define _IPV6_H         /* prevent ipv6 inclusion from hashtables and udp.h */
108 #include <net/sock.h>   /* linux - struct sock and sock_put() */
109 #endif
110
111 static VNET_DEFINE(int, ipfw_vnet_ready) = 0;
112 #define        V_ipfw_vnet_ready       VNET(ipfw_vnet_ready)
113 /*
114  * set_disable contains one bit per set value (0..31).
115  * If the bit is set, all rules with the corresponding set
116  * are disabled. Set RESVD_SET(31) is reserved for the default rule
117  * and rules that are not deleted by the flush command,
118  * and CANNOT be disabled.
119  * Rules in set RESVD_SET can only be deleted explicitly.
120  */
121 static VNET_DEFINE(u_int32_t, set_disable);
122 static VNET_DEFINE(int, fw_verbose);
123 static VNET_DEFINE(struct callout, ipfw_timeout);
124 static VNET_DEFINE(int, verbose_limit);
125
126 #define V_set_disable           VNET(set_disable)
127 #define V_fw_verbose            VNET(fw_verbose)
128 #define V_ipfw_timeout          VNET(ipfw_timeout)
129 #define V_verbose_limit         VNET(verbose_limit)
130
131 #ifdef IPFIREWALL_DEFAULT_TO_ACCEPT
132 static int default_to_accept = 1;
133 #else
134 static int default_to_accept;
135 #endif
136 static uma_zone_t ipfw_dyn_rule_zone;
137
138 struct ip_fw *ip_fw_default_rule;
139
140 /*
141  * Data structure to cache our ucred related
142  * information. This structure only gets used if
143  * the user specified UID/GID based constraints in
144  * a firewall rule.
145  */
146 struct ip_fw_ugid {
147         gid_t           fw_groups[NGROUPS];
148         int             fw_ngroups;
149         uid_t           fw_uid;
150         int             fw_prid;
151 };
152
153 /*
154  * list of rules for layer 3
155  */
156 VNET_DEFINE(struct ip_fw_chain, layer3_chain);
157
158 MALLOC_DEFINE(M_IPFW, "IpFw/IpAcct", "IpFw/IpAcct chain's");
159 MALLOC_DEFINE(M_IPFW_TBL, "ipfw_tbl", "IpFw tables");
160 #define IPFW_NAT_LOADED (ipfw_nat_ptr != NULL)
161 ipfw_nat_t *ipfw_nat_ptr = NULL;
162 ipfw_nat_cfg_t *ipfw_nat_cfg_ptr;
163 ipfw_nat_cfg_t *ipfw_nat_del_ptr;
164 ipfw_nat_cfg_t *ipfw_nat_get_cfg_ptr;
165 ipfw_nat_cfg_t *ipfw_nat_get_log_ptr;
166
167 struct table_entry {
168         struct radix_node       rn[2];
169         struct sockaddr_in      addr, mask;
170         u_int32_t               value;
171 };
172
173 static  VNET_DEFINE(int, autoinc_step);
174 #define V_autoinc_step                  VNET(autoinc_step)
175 static  VNET_DEFINE(int, fw_deny_unknown_exthdrs);
176 #define V_fw_deny_unknown_exthdrs       VNET(fw_deny_unknown_exthdrs)
177
178 extern int ipfw_chg_hook(SYSCTL_HANDLER_ARGS);
179
180 #ifdef SYSCTL_NODE
181 SYSCTL_NODE(_net_inet_ip, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall");
182 SYSCTL_VNET_PROC(_net_inet_ip_fw, OID_AUTO, enable,
183     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_enable), 0,
184     ipfw_chg_hook, "I", "Enable ipfw");
185 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, autoinc_step,
186     CTLFLAG_RW,  &VNET_NAME(autoinc_step), 0,
187     "Rule number auto-increment step");
188 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, one_pass,
189     CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_one_pass), 0,
190     "Only do a single pass through ipfw when using dummynet(4)");
191 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, verbose,
192     CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_verbose), 0,
193     "Log matches to ipfw rules");
194 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, verbose_limit,
195     CTLFLAG_RW, &VNET_NAME(verbose_limit), 0,
196     "Set upper limit of matches of ipfw rules logged");
197 SYSCTL_UINT(_net_inet_ip_fw, OID_AUTO, default_rule, CTLFLAG_RD,
198     NULL, IPFW_DEFAULT_RULE,
199     "The default/max possible rule number.");
200 SYSCTL_UINT(_net_inet_ip_fw, OID_AUTO, tables_max, CTLFLAG_RD,
201     NULL, IPFW_TABLES_MAX,
202     "The maximum number of tables.");
203 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, default_to_accept, CTLFLAG_RDTUN,
204     &default_to_accept, 0,
205     "Make the default rule accept all packets.");
206 TUNABLE_INT("net.inet.ip.fw.default_to_accept", &default_to_accept);
207
208 #ifdef INET6
209 SYSCTL_DECL(_net_inet6_ip6);
210 SYSCTL_NODE(_net_inet6_ip6, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall");
211 SYSCTL_VNET_PROC(_net_inet6_ip6_fw, OID_AUTO, enable,
212     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw6_enable), 0,
213     ipfw_chg_hook, "I", "Enable ipfw+6");
214 SYSCTL_VNET_INT(_net_inet6_ip6_fw, OID_AUTO, deny_unknown_exthdrs,
215     CTLFLAG_RW | CTLFLAG_SECURE, &VNET_NAME(fw_deny_unknown_exthdrs), 0,
216     "Deny packets with unknown IPv6 Extension Headers");
217 #endif /* INET6 */
218
219 #endif /* SYSCTL_NODE */
220
221 /*
222  * Description of dynamic rules.
223  *
224  * Dynamic rules are stored in lists accessed through a hash table
225  * (ipfw_dyn_v) whose size is curr_dyn_buckets. This value can
226  * be modified through the sysctl variable dyn_buckets which is
227  * updated when the table becomes empty.
228  *
229  * XXX currently there is only one list, ipfw_dyn.
230  *
231  * When a packet is received, its address fields are first masked
232  * with the mask defined for the rule, then hashed, then matched
233  * against the entries in the corresponding list.
234  * Dynamic rules can be used for different purposes:
235  *  + stateful rules;
236  *  + enforcing limits on the number of sessions;
237  *  + in-kernel NAT (not implemented yet)
238  *
239  * The lifetime of dynamic rules is regulated by dyn_*_lifetime,
240  * measured in seconds and depending on the flags.
241  *
242  * The total number of dynamic rules is stored in dyn_count.
243  * The max number of dynamic rules is dyn_max. When we reach
244  * the maximum number of rules we do not create anymore. This is
245  * done to avoid consuming too much memory, but also too much
246  * time when searching on each packet (ideally, we should try instead
247  * to put a limit on the length of the list on each bucket...).
248  *
249  * Each dynamic rule holds a pointer to the parent ipfw rule so
250  * we know what action to perform. Dynamic rules are removed when
251  * the parent rule is deleted. XXX we should make them survive.
252  *
253  * There are some limitations with dynamic rules -- we do not
254  * obey the 'randomized match', and we do not do multiple
255  * passes through the firewall. XXX check the latter!!!
256  */
257 static VNET_DEFINE(ipfw_dyn_rule **, ipfw_dyn_v);
258 static VNET_DEFINE(u_int32_t, dyn_buckets);
259 static VNET_DEFINE(u_int32_t, curr_dyn_buckets);
260
261 #define V_ipfw_dyn_v                    VNET(ipfw_dyn_v)
262 #define V_dyn_buckets                   VNET(dyn_buckets)
263 #define V_curr_dyn_buckets              VNET(curr_dyn_buckets)
264
265 #if defined( __linux__ ) || defined( _WIN32 )
266 DEFINE_SPINLOCK(ipfw_dyn_mtx);
267 #else
268 static struct mtx ipfw_dyn_mtx;         /* mutex guarding dynamic rules */
269 #endif /* !__linux__ */
270 #define IPFW_DYN_LOCK_INIT() \
271         mtx_init(&ipfw_dyn_mtx, "IPFW dynamic rules", NULL, MTX_DEF)
272 #define IPFW_DYN_LOCK_DESTROY() mtx_destroy(&ipfw_dyn_mtx)
273 #define IPFW_DYN_LOCK()         mtx_lock(&ipfw_dyn_mtx)
274 #define IPFW_DYN_UNLOCK()       mtx_unlock(&ipfw_dyn_mtx)
275 #define IPFW_DYN_LOCK_ASSERT()  mtx_assert(&ipfw_dyn_mtx, MA_OWNED)
276
277 static struct mbuf *send_pkt(struct mbuf *, struct ipfw_flow_id *,
278     u_int32_t, u_int32_t, int);
279
280
281 /*
282  * Timeouts for various events in handing dynamic rules.
283  */
284 static VNET_DEFINE(u_int32_t, dyn_ack_lifetime);
285 static VNET_DEFINE(u_int32_t, dyn_syn_lifetime);
286 static VNET_DEFINE(u_int32_t, dyn_fin_lifetime);
287 static VNET_DEFINE(u_int32_t, dyn_rst_lifetime);
288 static VNET_DEFINE(u_int32_t, dyn_udp_lifetime);
289 static VNET_DEFINE(u_int32_t, dyn_short_lifetime);
290     
291 #define V_dyn_ack_lifetime              VNET(dyn_ack_lifetime)
292 #define V_dyn_syn_lifetime              VNET(dyn_syn_lifetime)
293 #define V_dyn_fin_lifetime              VNET(dyn_fin_lifetime)
294 #define V_dyn_rst_lifetime              VNET(dyn_rst_lifetime)
295 #define V_dyn_udp_lifetime              VNET(dyn_udp_lifetime)
296 #define V_dyn_short_lifetime            VNET(dyn_short_lifetime)
297
298 /*
299  * Keepalives are sent if dyn_keepalive is set. They are sent every
300  * dyn_keepalive_period seconds, in the last dyn_keepalive_interval
301  * seconds of lifetime of a rule.
302  * dyn_rst_lifetime and dyn_fin_lifetime should be strictly lower
303  * than dyn_keepalive_period.
304  */
305
306 static VNET_DEFINE(u_int32_t, dyn_keepalive_interval);
307 static VNET_DEFINE(u_int32_t, dyn_keepalive_period);
308 static VNET_DEFINE(u_int32_t, dyn_keepalive);
309
310 #define V_dyn_keepalive_interval        VNET(dyn_keepalive_interval)
311 #define V_dyn_keepalive_period          VNET(dyn_keepalive_period)
312 #define V_dyn_keepalive                 VNET(dyn_keepalive)
313
314 static VNET_DEFINE(u_int32_t, static_count);    /* # of static rules */
315 static VNET_DEFINE(u_int32_t, static_len);      /* bytes of static rules */
316 static VNET_DEFINE(u_int32_t, dyn_count);       /* # of dynamic rules */
317 static VNET_DEFINE(u_int32_t, dyn_max);         /* max # of dynamic rules */
318
319 #define V_static_count          VNET(static_count)
320 #define V_static_len            VNET(static_len)
321 #define V_dyn_count             VNET(dyn_count)
322 #define V_dyn_max               VNET(dyn_max)
323
324 #ifdef SYSCTL_NODE
325 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_buckets,
326     CTLFLAG_RW, &VNET_NAME(dyn_buckets), 0,
327     "Number of dyn. buckets");
328 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, curr_dyn_buckets,
329     CTLFLAG_RD, &VNET_NAME(curr_dyn_buckets), 0,
330     "Current Number of dyn. buckets");
331 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_count,
332     CTLFLAG_RD, &VNET_NAME(dyn_count), 0,
333     "Number of dyn. rules");
334 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_max,
335     CTLFLAG_RW, &VNET_NAME(dyn_max), 0,
336     "Max number of dyn. rules");
337 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, static_count,
338     CTLFLAG_RD, &VNET_NAME(static_count), 0,
339     "Number of static rules");
340 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_ack_lifetime,
341     CTLFLAG_RW, &VNET_NAME(dyn_ack_lifetime), 0,
342     "Lifetime of dyn. rules for acks");
343 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_syn_lifetime,
344     CTLFLAG_RW, &VNET_NAME(dyn_syn_lifetime), 0,
345     "Lifetime of dyn. rules for syn");
346 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_fin_lifetime,
347     CTLFLAG_RW, &VNET_NAME(dyn_fin_lifetime), 0,
348     "Lifetime of dyn. rules for fin");
349 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_rst_lifetime,
350     CTLFLAG_RW, &VNET_NAME(dyn_rst_lifetime), 0,
351     "Lifetime of dyn. rules for rst");
352 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_udp_lifetime,
353     CTLFLAG_RW, &VNET_NAME(dyn_udp_lifetime), 0,
354     "Lifetime of dyn. rules for UDP");
355 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_short_lifetime,
356     CTLFLAG_RW, &VNET_NAME(dyn_short_lifetime), 0,
357     "Lifetime of dyn. rules for other situations");
358 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_keepalive,
359     CTLFLAG_RW, &VNET_NAME(dyn_keepalive), 0,
360     "Enable keepalives for dyn. rules");
361 #endif /* SYSCTL_NODE */
362
363 /*
364  * L3HDR maps an ipv4 pointer into a layer3 header pointer of type T
365  * Other macros just cast void * into the appropriate type
366  */
367 #define L3HDR(T, ip)    ((T *)((u_int32_t *)(ip) + (ip)->ip_hl))
368 #define TCP(p)          ((struct tcphdr *)(p))
369 #define SCTP(p)         ((struct sctphdr *)(p))
370 #define UDP(p)          ((struct udphdr *)(p))
371 #define ICMP(p)         ((struct icmphdr *)(p))
372 #define ICMP6(p)        ((struct icmp6_hdr *)(p))
373
374 static __inline int
375 icmptype_match(struct icmphdr *icmp, ipfw_insn_u32 *cmd)
376 {
377         int type = icmp->icmp_type;
378
379         return (type <= ICMP_MAXTYPE && (cmd->d[0] & (1<<type)) );
380 }
381
382 #define TT      ( (1 << ICMP_ECHO) | (1 << ICMP_ROUTERSOLICIT) | \
383     (1 << ICMP_TSTAMP) | (1 << ICMP_IREQ) | (1 << ICMP_MASKREQ) )
384
385 static int
386 is_icmp_query(struct icmphdr *icmp)
387 {
388         int type = icmp->icmp_type;
389
390         return (type <= ICMP_MAXTYPE && (TT & (1<<type)) );
391 }
392 #undef TT
393
394 /*
395  * The following checks use two arrays of 8 or 16 bits to store the
396  * bits that we want set or clear, respectively. They are in the
397  * low and high half of cmd->arg1 or cmd->d[0].
398  *
399  * We scan options and store the bits we find set. We succeed if
400  *
401  *      (want_set & ~bits) == 0 && (want_clear & ~bits) == want_clear
402  *
403  * The code is sometimes optimized not to store additional variables.
404  */
405
406 static int
407 flags_match(ipfw_insn *cmd, u_int8_t bits)
408 {
409         u_char want_clear;
410         bits = ~bits;
411
412         if ( ((cmd->arg1 & 0xff) & bits) != 0)
413                 return 0; /* some bits we want set were clear */
414         want_clear = (cmd->arg1 >> 8) & 0xff;
415         if ( (want_clear & bits) != want_clear)
416                 return 0; /* some bits we want clear were set */
417         return 1;
418 }
419
420 static int
421 ipopts_match(struct ip *ip, ipfw_insn *cmd)
422 {
423         int optlen, bits = 0;
424         u_char *cp = (u_char *)(ip + 1);
425         int x = (ip->ip_hl << 2) - sizeof (struct ip);
426
427         for (; x > 0; x -= optlen, cp += optlen) {
428                 int opt = cp[IPOPT_OPTVAL];
429
430                 if (opt == IPOPT_EOL)
431                         break;
432                 if (opt == IPOPT_NOP)
433                         optlen = 1;
434                 else {
435                         optlen = cp[IPOPT_OLEN];
436                         if (optlen <= 0 || optlen > x)
437                                 return 0; /* invalid or truncated */
438                 }
439                 switch (opt) {
440
441                 default:
442                         break;
443
444                 case IPOPT_LSRR:
445                         bits |= IP_FW_IPOPT_LSRR;
446                         break;
447
448                 case IPOPT_SSRR:
449                         bits |= IP_FW_IPOPT_SSRR;
450                         break;
451
452                 case IPOPT_RR:
453                         bits |= IP_FW_IPOPT_RR;
454                         break;
455
456                 case IPOPT_TS:
457                         bits |= IP_FW_IPOPT_TS;
458                         break;
459                 }
460         }
461         return (flags_match(cmd, bits));
462 }
463
464 static int
465 tcpopts_match(struct tcphdr *tcp, ipfw_insn *cmd)
466 {
467         int optlen, bits = 0;
468         u_char *cp = (u_char *)(tcp + 1);
469         int x = (tcp->th_off << 2) - sizeof(struct tcphdr);
470
471         for (; x > 0; x -= optlen, cp += optlen) {
472                 int opt = cp[0];
473                 if (opt == TCPOPT_EOL)
474                         break;
475                 if (opt == TCPOPT_NOP)
476                         optlen = 1;
477                 else {
478                         optlen = cp[1];
479                         if (optlen <= 0)
480                                 break;
481                 }
482
483                 switch (opt) {
484
485                 default:
486                         break;
487
488                 case TCPOPT_MAXSEG:
489                         bits |= IP_FW_TCPOPT_MSS;
490                         break;
491
492                 case TCPOPT_WINDOW:
493                         bits |= IP_FW_TCPOPT_WINDOW;
494                         break;
495
496                 case TCPOPT_SACK_PERMITTED:
497                 case TCPOPT_SACK:
498                         bits |= IP_FW_TCPOPT_SACK;
499                         break;
500
501                 case TCPOPT_TIMESTAMP:
502                         bits |= IP_FW_TCPOPT_TS;
503                         break;
504
505                 }
506         }
507         return (flags_match(cmd, bits));
508 }
509
510 static int
511 iface_match(struct ifnet *ifp, ipfw_insn_if *cmd)
512 {
513         if (ifp == NULL)        /* no iface with this packet, match fails */
514                 return 0;
515         /* Check by name or by IP address */
516         if (cmd->name[0] != '\0') { /* match by name */
517                 /* Check name */
518                 if (cmd->p.glob) {
519                         if (fnmatch(cmd->name, ifp->if_xname, 0) == 0)
520                                 return(1);
521                 } else {
522                         if (strncmp(ifp->if_xname, cmd->name, IFNAMSIZ) == 0)
523                                 return(1);
524                 }
525         } else {
526 #if !defined( __linux__ ) && !defined( _WIN32 )
527                 struct ifaddr *ia;
528
529                 if_addr_rlock(ifp);
530                 TAILQ_FOREACH(ia, &ifp->if_addrhead, ifa_link) {
531                         if (ia->ifa_addr->sa_family != AF_INET)
532                                 continue;
533                         if (cmd->p.ip.s_addr == ((struct sockaddr_in *)
534                             (ia->ifa_addr))->sin_addr.s_addr) {
535                                 if_addr_runlock(ifp);
536                                 return(1);      /* match */
537                         }
538                 }
539                 if_addr_runlock(ifp);
540 #endif
541         }
542         return(0);      /* no match, fail ... */
543 }
544
545 #if !defined( __linux__ ) && !defined( _WIN32 )
546 /*
547  * The verify_path function checks if a route to the src exists and
548  * if it is reachable via ifp (when provided).
549  * 
550  * The 'verrevpath' option checks that the interface that an IP packet
551  * arrives on is the same interface that traffic destined for the
552  * packet's source address would be routed out of.  The 'versrcreach'
553  * option just checks that the source address is reachable via any route
554  * (except default) in the routing table.  These two are a measure to block
555  * forged packets.  This is also commonly known as "anti-spoofing" or Unicast
556  * Reverse Path Forwarding (Unicast RFP) in Cisco-ese. The name of the knobs
557  * is purposely reminiscent of the Cisco IOS command,
558  *
559  *   ip verify unicast reverse-path
560  *   ip verify unicast source reachable-via any
561  *
562  * which implements the same functionality. But note that syntax is
563  * misleading. The check may be performed on all IP packets whether unicast,
564  * multicast, or broadcast.
565  */
566 static int
567 verify_path(struct in_addr src, struct ifnet *ifp, u_int fib)
568 {
569         struct route ro;
570         struct sockaddr_in *dst;
571
572         bzero(&ro, sizeof(ro));
573
574         dst = (struct sockaddr_in *)&(ro.ro_dst);
575         dst->sin_family = AF_INET;
576         dst->sin_len = sizeof(*dst);
577         dst->sin_addr = src;
578         in_rtalloc_ign(&ro, 0, fib);
579
580         if (ro.ro_rt == NULL)
581                 return 0;
582
583         /*
584          * If ifp is provided, check for equality with rtentry.
585          * We should use rt->rt_ifa->ifa_ifp, instead of rt->rt_ifp,
586          * in order to pass packets injected back by if_simloop():
587          * if useloopback == 1 routing entry (via lo0) for our own address
588          * may exist, so we need to handle routing assymetry.
589          */
590         if (ifp != NULL && ro.ro_rt->rt_ifa->ifa_ifp != ifp) {
591                 RTFREE(ro.ro_rt);
592                 return 0;
593         }
594
595         /* if no ifp provided, check if rtentry is not default route */
596         if (ifp == NULL &&
597              satosin(rt_key(ro.ro_rt))->sin_addr.s_addr == INADDR_ANY) {
598                 RTFREE(ro.ro_rt);
599                 return 0;
600         }
601
602         /* or if this is a blackhole/reject route */
603         if (ifp == NULL && ro.ro_rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
604                 RTFREE(ro.ro_rt);
605                 return 0;
606         }
607
608         /* found valid route */
609         RTFREE(ro.ro_rt);
610         return 1;
611 }
612 #endif
613
614 #ifdef INET6
615 /*
616  * ipv6 specific rules here...
617  */
618 static __inline int
619 icmp6type_match (int type, ipfw_insn_u32 *cmd)
620 {
621         return (type <= ICMP6_MAXTYPE && (cmd->d[type/32] & (1<<(type%32)) ) );
622 }
623
624 static int
625 flow6id_match( int curr_flow, ipfw_insn_u32 *cmd )
626 {
627         int i;
628         for (i=0; i <= cmd->o.arg1; ++i )
629                 if (curr_flow == cmd->d[i] )
630                         return 1;
631         return 0;
632 }
633
634 /* support for IP6_*_ME opcodes */
635 static int
636 search_ip6_addr_net (struct in6_addr * ip6_addr)
637 {
638         struct ifnet *mdc;
639         struct ifaddr *mdc2;
640         struct in6_ifaddr *fdm;
641         struct in6_addr copia;
642
643         TAILQ_FOREACH(mdc, &V_ifnet, if_link) {
644                 if_addr_rlock(mdc);
645                 TAILQ_FOREACH(mdc2, &mdc->if_addrhead, ifa_link) {
646                         if (mdc2->ifa_addr->sa_family == AF_INET6) {
647                                 fdm = (struct in6_ifaddr *)mdc2;
648                                 copia = fdm->ia_addr.sin6_addr;
649                                 /* need for leaving scope_id in the sock_addr */
650                                 in6_clearscope(&copia);
651                                 if (IN6_ARE_ADDR_EQUAL(ip6_addr, &copia)) {
652                                         if_addr_runlock(mdc);
653                                         return 1;
654                                 }
655                         }
656                 }
657                 if_addr_runlock(mdc);
658         }
659         return 0;
660 }
661
662 static int
663 verify_path6(struct in6_addr *src, struct ifnet *ifp)
664 {
665         struct route_in6 ro;
666         struct sockaddr_in6 *dst;
667
668         bzero(&ro, sizeof(ro));
669
670         dst = (struct sockaddr_in6 * )&(ro.ro_dst);
671         dst->sin6_family = AF_INET6;
672         dst->sin6_len = sizeof(*dst);
673         dst->sin6_addr = *src;
674         /* XXX MRT 0 for ipv6 at this time */
675         rtalloc_ign((struct route *)&ro, 0);
676
677         if (ro.ro_rt == NULL)
678                 return 0;
679
680         /* 
681          * if ifp is provided, check for equality with rtentry
682          * We should use rt->rt_ifa->ifa_ifp, instead of rt->rt_ifp,
683          * to support the case of sending packets to an address of our own.
684          * (where the former interface is the first argument of if_simloop()
685          *  (=ifp), the latter is lo0)
686          */
687         if (ifp != NULL && ro.ro_rt->rt_ifa->ifa_ifp != ifp) {
688                 RTFREE(ro.ro_rt);
689                 return 0;
690         }
691
692         /* if no ifp provided, check if rtentry is not default route */
693         if (ifp == NULL &&
694             IN6_IS_ADDR_UNSPECIFIED(&satosin6(rt_key(ro.ro_rt))->sin6_addr)) {
695                 RTFREE(ro.ro_rt);
696                 return 0;
697         }
698
699         /* or if this is a blackhole/reject route */
700         if (ifp == NULL && ro.ro_rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
701                 RTFREE(ro.ro_rt);
702                 return 0;
703         }
704
705         /* found valid route */
706         RTFREE(ro.ro_rt);
707         return 1;
708
709 }
710 static __inline int
711 hash_packet6(struct ipfw_flow_id *id)
712 {
713         u_int32_t i;
714         i = (id->dst_ip6.__u6_addr.__u6_addr32[2]) ^
715             (id->dst_ip6.__u6_addr.__u6_addr32[3]) ^
716             (id->src_ip6.__u6_addr.__u6_addr32[2]) ^
717             (id->src_ip6.__u6_addr.__u6_addr32[3]) ^
718             (id->dst_port) ^ (id->src_port);
719         return i;
720 }
721
722 static int
723 is_icmp6_query(int icmp6_type)
724 {
725         if ((icmp6_type <= ICMP6_MAXTYPE) &&
726             (icmp6_type == ICMP6_ECHO_REQUEST ||
727             icmp6_type == ICMP6_MEMBERSHIP_QUERY ||
728             icmp6_type == ICMP6_WRUREQUEST ||
729             icmp6_type == ICMP6_FQDN_QUERY ||
730             icmp6_type == ICMP6_NI_QUERY))
731                 return (1);
732
733         return (0);
734 }
735
736 static void
737 send_reject6(struct ip_fw_args *args, int code, u_int hlen, struct ip6_hdr *ip6)
738 {
739         struct mbuf *m;
740
741         m = args->m;
742         if (code == ICMP6_UNREACH_RST && args->f_id.proto == IPPROTO_TCP) {
743                 struct tcphdr *tcp;
744                 tcp = (struct tcphdr *)((char *)ip6 + hlen);
745
746                 if ((tcp->th_flags & TH_RST) == 0) {
747                         struct mbuf *m0;
748                         m0 = send_pkt(args->m, &(args->f_id),
749                             ntohl(tcp->th_seq), ntohl(tcp->th_ack),
750                             tcp->th_flags | TH_RST);
751                         if (m0 != NULL)
752                                 ip6_output(m0, NULL, NULL, 0, NULL, NULL,
753                                     NULL);
754                 }
755                 m_freem(m);
756         } else if (code != ICMP6_UNREACH_RST) { /* Send an ICMPv6 unreach. */
757 #if 0
758                 /*
759                  * Unlike above, the mbufs need to line up with the ip6 hdr,
760                  * as the contents are read. We need to m_adj() the
761                  * needed amount.
762                  * The mbuf will however be thrown away so we can adjust it.
763                  * Remember we did an m_pullup on it already so we
764                  * can make some assumptions about contiguousness.
765                  */
766                 if (args->L3offset)
767                         m_adj(m, args->L3offset);
768 #endif
769                 icmp6_error(m, ICMP6_DST_UNREACH, code, 0);
770         } else
771                 m_freem(m);
772
773         args->m = NULL;
774 }
775
776 #endif /* INET6 */
777
778 /* counter for ipfw_log(NULL...) */
779 static VNET_DEFINE(u_int64_t, norule_counter);
780 #define V_norule_counter                VNET(norule_counter)
781
782 #define SNPARGS(buf, len) buf + len, sizeof(buf) > len ? sizeof(buf) - len : 0
783 #define SNP(buf) buf, sizeof(buf)
784
785 /*
786  * We enter here when we have a rule with O_LOG.
787  * XXX this function alone takes about 2Kbytes of code!
788  */
789 static void
790 ipfw_log(struct ip_fw *f, u_int hlen, struct ip_fw_args *args,
791     struct mbuf *m, struct ifnet *oif, u_short offset, uint32_t tablearg,
792     struct ip *ip)
793 {
794         struct ether_header *eh = args->eh;
795         char *action;
796         int limit_reached = 0;
797         char action2[40], proto[128], fragment[32];
798
799         fragment[0] = '\0';
800         proto[0] = '\0';
801
802         if (f == NULL) {        /* bogus pkt */
803                 if (V_verbose_limit != 0 && V_norule_counter >= V_verbose_limit)
804                         return;
805                 V_norule_counter++;
806                 if (V_norule_counter == V_verbose_limit)
807                         limit_reached = V_verbose_limit;
808                 action = "Refuse";
809         } else {        /* O_LOG is the first action, find the real one */
810                 ipfw_insn *cmd = ACTION_PTR(f);
811                 ipfw_insn_log *l = (ipfw_insn_log *)cmd;
812
813                 if (l->max_log != 0 && l->log_left == 0)
814                         return;
815                 l->log_left--;
816                 if (l->log_left == 0)
817                         limit_reached = l->max_log;
818                 cmd += F_LEN(cmd);      /* point to first action */
819                 if (cmd->opcode == O_ALTQ) {
820                         ipfw_insn_altq *altq = (ipfw_insn_altq *)cmd;
821
822                         snprintf(SNPARGS(action2, 0), "Altq %d",
823                                 altq->qid);
824                         cmd += F_LEN(cmd);
825                 }
826                 if (cmd->opcode == O_PROB)
827                         cmd += F_LEN(cmd);
828
829                 if (cmd->opcode == O_TAG)
830                         cmd += F_LEN(cmd);
831
832                 action = action2;
833                 switch (cmd->opcode) {
834                 case O_DENY:
835                         action = "Deny";
836                         break;
837
838                 case O_REJECT:
839                         if (cmd->arg1==ICMP_REJECT_RST)
840                                 action = "Reset";
841                         else if (cmd->arg1==ICMP_UNREACH_HOST)
842                                 action = "Reject";
843                         else
844                                 snprintf(SNPARGS(action2, 0), "Unreach %d",
845                                         cmd->arg1);
846                         break;
847
848                 case O_UNREACH6:
849                         if (cmd->arg1==ICMP6_UNREACH_RST)
850                                 action = "Reset";
851                         else
852                                 snprintf(SNPARGS(action2, 0), "Unreach %d",
853                                         cmd->arg1);
854                         break;
855
856                 case O_ACCEPT:
857                         action = "Accept";
858                         break;
859                 case O_COUNT:
860                         action = "Count";
861                         break;
862                 case O_DIVERT:
863                         snprintf(SNPARGS(action2, 0), "Divert %d",
864                                 cmd->arg1);
865                         break;
866                 case O_TEE:
867                         snprintf(SNPARGS(action2, 0), "Tee %d",
868                                 cmd->arg1);
869                         break;
870                 case O_SETFIB:
871                         snprintf(SNPARGS(action2, 0), "SetFib %d",
872                                 cmd->arg1);
873                         break;
874                 case O_SKIPTO:
875                         snprintf(SNPARGS(action2, 0), "SkipTo %d",
876                                 cmd->arg1);
877                         break;
878                 case O_PIPE:
879                         snprintf(SNPARGS(action2, 0), "Pipe %d",
880                                 cmd->arg1);
881                         break;
882                 case O_QUEUE:
883                         snprintf(SNPARGS(action2, 0), "Queue %d",
884                                 cmd->arg1);
885                         break;
886                 case O_FORWARD_IP: {
887                         ipfw_insn_sa *sa = (ipfw_insn_sa *)cmd;
888                         int len;
889                         struct in_addr dummyaddr;
890                         if (sa->sa.sin_addr.s_addr == INADDR_ANY)
891                                 dummyaddr.s_addr = htonl(tablearg);
892                         else
893                                 dummyaddr.s_addr = sa->sa.sin_addr.s_addr;
894
895                         len = snprintf(SNPARGS(action2, 0), "Forward to %s",
896                                 inet_ntoa(dummyaddr));
897
898                         if (sa->sa.sin_port)
899                                 snprintf(SNPARGS(action2, len), ":%d",
900                                     sa->sa.sin_port);
901                         }
902                         break;
903                 case O_NETGRAPH:
904                         snprintf(SNPARGS(action2, 0), "Netgraph %d",
905                                 cmd->arg1);
906                         break;
907                 case O_NGTEE:
908                         snprintf(SNPARGS(action2, 0), "Ngtee %d",
909                                 cmd->arg1);
910                         break;
911                 case O_NAT:
912                         action = "Nat";
913                         break;
914                 case O_REASS:
915                         action = "Reass";
916                         break;
917                 default:
918                         action = "UNKNOWN";
919                         break;
920                 }
921         }
922
923         if (hlen == 0) {        /* non-ip */
924                 snprintf(SNPARGS(proto, 0), "MAC");
925
926         } else {
927                 int len;
928 #ifdef INET6
929                 char src[INET6_ADDRSTRLEN + 2], dst[INET6_ADDRSTRLEN + 2];
930 #else
931                 char src[INET_ADDRSTRLEN], dst[INET_ADDRSTRLEN];
932 #endif
933                 struct icmphdr *icmp;
934                 struct tcphdr *tcp;
935                 struct udphdr *udp;
936 #ifdef INET6
937                 struct ip6_hdr *ip6 = NULL;
938                 struct icmp6_hdr *icmp6;
939 #endif
940                 src[0] = '\0';
941                 dst[0] = '\0';
942 #ifdef INET6
943                 if (IS_IP6_FLOW_ID(&(args->f_id))) {
944                         char ip6buf[INET6_ADDRSTRLEN];
945                         snprintf(src, sizeof(src), "[%s]",
946                             ip6_sprintf(ip6buf, &args->f_id.src_ip6));
947                         snprintf(dst, sizeof(dst), "[%s]",
948                             ip6_sprintf(ip6buf, &args->f_id.dst_ip6));
949
950                         ip6 = (struct ip6_hdr *)ip;
951                         tcp = (struct tcphdr *)(((char *)ip) + hlen);
952                         udp = (struct udphdr *)(((char *)ip) + hlen);
953                 } else
954 #endif
955                 {
956                         tcp = L3HDR(struct tcphdr, ip);
957                         udp = L3HDR(struct udphdr, ip);
958
959                         inet_ntoa_r(ip->ip_src, src);
960                         inet_ntoa_r(ip->ip_dst, dst);
961                 }
962
963                 switch (args->f_id.proto) {
964                 case IPPROTO_TCP:
965                         len = snprintf(SNPARGS(proto, 0), "TCP %s", src);
966                         if (offset == 0)
967                                 snprintf(SNPARGS(proto, len), ":%d %s:%d",
968                                     ntohs(tcp->th_sport),
969                                     dst,
970                                     ntohs(tcp->th_dport));
971                         else
972                                 snprintf(SNPARGS(proto, len), " %s", dst);
973                         break;
974
975                 case IPPROTO_UDP:
976                         len = snprintf(SNPARGS(proto, 0), "UDP %s", src);
977                         if (offset == 0)
978                                 snprintf(SNPARGS(proto, len), ":%d %s:%d",
979                                     ntohs(udp->uh_sport),
980                                     dst,
981                                     ntohs(udp->uh_dport));
982                         else
983                                 snprintf(SNPARGS(proto, len), " %s", dst);
984                         break;
985
986                 case IPPROTO_ICMP:
987                         icmp = L3HDR(struct icmphdr, ip);
988                         if (offset == 0)
989                                 len = snprintf(SNPARGS(proto, 0),
990                                     "ICMP:%u.%u ",
991                                     icmp->icmp_type, icmp->icmp_code);
992                         else
993                                 len = snprintf(SNPARGS(proto, 0), "ICMP ");
994                         len += snprintf(SNPARGS(proto, len), "%s", src);
995                         snprintf(SNPARGS(proto, len), " %s", dst);
996                         break;
997 #ifdef INET6
998                 case IPPROTO_ICMPV6:
999                         icmp6 = (struct icmp6_hdr *)(((char *)ip) + hlen);
1000                         if (offset == 0)
1001                                 len = snprintf(SNPARGS(proto, 0),
1002                                     "ICMPv6:%u.%u ",
1003                                     icmp6->icmp6_type, icmp6->icmp6_code);
1004                         else
1005                                 len = snprintf(SNPARGS(proto, 0), "ICMPv6 ");
1006                         len += snprintf(SNPARGS(proto, len), "%s", src);
1007                         snprintf(SNPARGS(proto, len), " %s", dst);
1008                         break;
1009 #endif
1010                 default:
1011                         len = snprintf(SNPARGS(proto, 0), "P:%d %s",
1012                             args->f_id.proto, src);
1013                         snprintf(SNPARGS(proto, len), " %s", dst);
1014                         break;
1015                 }
1016
1017 #ifdef INET6
1018                 if (IS_IP6_FLOW_ID(&(args->f_id))) {
1019                         if (offset & (IP6F_OFF_MASK | IP6F_MORE_FRAG))
1020                                 snprintf(SNPARGS(fragment, 0),
1021                                     " (frag %08x:%d@%d%s)",
1022                                     args->f_id.frag_id6,
1023                                     ntohs(ip6->ip6_plen) - hlen,
1024                                     ntohs(offset & IP6F_OFF_MASK) << 3,
1025                                     (offset & IP6F_MORE_FRAG) ? "+" : "");
1026                 } else
1027 #endif
1028                 {
1029                         int ip_off, ip_len;
1030                         if (1 || eh != NULL) { /* layer 2 packets are as on the wire */
1031                                 ip_off = ntohs(ip->ip_off);
1032                                 ip_len = ntohs(ip->ip_len);
1033                         } else {
1034                                 ip_off = ip->ip_off;
1035                                 ip_len = ip->ip_len;
1036                         }
1037                         if (ip_off & (IP_MF | IP_OFFMASK))
1038                                 snprintf(SNPARGS(fragment, 0),
1039                                     " (frag %d:%d@%d%s)",
1040                                     ntohs(ip->ip_id), ip_len - (ip->ip_hl << 2),
1041                                     offset << 3,
1042                                     (ip_off & IP_MF) ? "+" : "");
1043                 }
1044         }
1045         if (oif || m->m_pkthdr.rcvif)
1046                 log(LOG_SECURITY | LOG_INFO,
1047                     "ipfw: %d %s %s %s via %s%s\n",
1048                     f ? f->rulenum : -1,
1049                     action, proto, oif ? "out" : "in",
1050                     oif ? oif->if_xname : m->m_pkthdr.rcvif->if_xname,
1051                     fragment);
1052         else
1053                 log(LOG_SECURITY | LOG_INFO,
1054                     "ipfw: %d %s %s [no if info]%s\n",
1055                     f ? f->rulenum : -1,
1056                     action, proto, fragment);
1057         if (limit_reached)
1058                 log(LOG_SECURITY | LOG_NOTICE,
1059                     "ipfw: limit %d reached on entry %d\n",
1060                     limit_reached, f ? f->rulenum : -1);
1061 }
1062
1063 /*
1064  * IMPORTANT: the hash function for dynamic rules must be commutative
1065  * in source and destination (ip,port), because rules are bidirectional
1066  * and we want to find both in the same bucket.
1067  */
1068 static __inline int
1069 hash_packet(struct ipfw_flow_id *id)
1070 {
1071         u_int32_t i;
1072
1073 #ifdef INET6
1074         if (IS_IP6_FLOW_ID(id)) 
1075                 i = hash_packet6(id);
1076         else
1077 #endif /* INET6 */
1078         i = (id->dst_ip) ^ (id->src_ip) ^ (id->dst_port) ^ (id->src_port);
1079         i &= (V_curr_dyn_buckets - 1);
1080         return i;
1081 }
1082
1083 static __inline void
1084 unlink_dyn_rule_print(struct ipfw_flow_id *id)
1085 {
1086         struct in_addr da;
1087 #ifdef INET6
1088         char src[INET6_ADDRSTRLEN], dst[INET6_ADDRSTRLEN];
1089 #else
1090         char src[INET_ADDRSTRLEN], dst[INET_ADDRSTRLEN];
1091 #endif
1092
1093 #ifdef INET6
1094         if (IS_IP6_FLOW_ID(id)) {
1095                 ip6_sprintf(src, &id->src_ip6);
1096                 ip6_sprintf(dst, &id->dst_ip6);
1097         } else
1098 #endif
1099         {
1100                 da.s_addr = htonl(id->src_ip);
1101                 inet_ntoa_r(da, src);
1102                 da.s_addr = htonl(id->dst_ip);
1103                 inet_ntoa_r(da, dst);
1104         }
1105         printf("ipfw: unlink entry %s %d -> %s %d, %d left\n",
1106             src, id->src_port, dst, id->dst_port, V_dyn_count - 1);
1107 }
1108
1109 /**
1110  * unlink a dynamic rule from a chain. prev is a pointer to
1111  * the previous one, q is a pointer to the rule to delete,
1112  * head is a pointer to the head of the queue.
1113  * Modifies q and potentially also head.
1114  */
1115 #define UNLINK_DYN_RULE(prev, head, q) {                                \
1116         ipfw_dyn_rule *old_q = q;                                       \
1117                                                                         \
1118         /* remove a refcount to the parent */                           \
1119         if (q->dyn_type == O_LIMIT)                                     \
1120                 q->parent->count--;                                     \
1121         DEB(unlink_dyn_rule_print(&q->id);)                             \
1122         if (prev != NULL)                                               \
1123                 prev->next = q = q->next;                               \
1124         else                                                            \
1125                 head = q = q->next;                                     \
1126         V_dyn_count--;                                                  \
1127         uma_zfree(ipfw_dyn_rule_zone, old_q); }
1128
1129 #define TIME_LEQ(a,b)       ((int)((a)-(b)) <= 0)
1130
1131 /**
1132  * Remove dynamic rules pointing to "rule", or all of them if rule == NULL.
1133  *
1134  * If keep_me == NULL, rules are deleted even if not expired,
1135  * otherwise only expired rules are removed.
1136  *
1137  * The value of the second parameter is also used to point to identify
1138  * a rule we absolutely do not want to remove (e.g. because we are
1139  * holding a reference to it -- this is the case with O_LIMIT_PARENT
1140  * rules). The pointer is only used for comparison, so any non-null
1141  * value will do.
1142  */
1143 static void
1144 remove_dyn_rule(struct ip_fw *rule, ipfw_dyn_rule *keep_me)
1145 {
1146         static u_int32_t last_remove = 0;
1147
1148 #define FORCE (keep_me == NULL)
1149
1150         ipfw_dyn_rule *prev, *q;
1151         int i, pass = 0, max_pass = 0;
1152
1153         IPFW_DYN_LOCK_ASSERT();
1154
1155         if (V_ipfw_dyn_v == NULL || V_dyn_count == 0)
1156                 return;
1157         /* do not expire more than once per second, it is useless */
1158         if (!FORCE && last_remove == time_uptime)
1159                 return;
1160         last_remove = time_uptime;
1161
1162         /*
1163          * because O_LIMIT refer to parent rules, during the first pass only
1164          * remove child and mark any pending LIMIT_PARENT, and remove
1165          * them in a second pass.
1166          */
1167 next_pass:
1168         for (i = 0 ; i < V_curr_dyn_buckets ; i++) {
1169                 for (prev=NULL, q = V_ipfw_dyn_v[i] ; q ; ) {
1170                         /*
1171                          * Logic can become complex here, so we split tests.
1172                          */
1173                         if (q == keep_me)
1174                                 goto next;
1175                         if (rule != NULL && rule != q->rule)
1176                                 goto next; /* not the one we are looking for */
1177                         if (q->dyn_type == O_LIMIT_PARENT) {
1178                                 /*
1179                                  * handle parent in the second pass,
1180                                  * record we need one.
1181                                  */
1182                                 max_pass = 1;
1183                                 if (pass == 0)
1184                                         goto next;
1185                                 if (FORCE && q->count != 0 ) {
1186                                         /* XXX should not happen! */
1187                                         printf("ipfw: OUCH! cannot remove rule,"
1188                                              " count %d\n", q->count);
1189                                 }
1190                         } else {
1191                                 if (!FORCE &&
1192                                     !TIME_LEQ( q->expire, time_uptime ))
1193                                         goto next;
1194                         }
1195              if (q->dyn_type != O_LIMIT_PARENT || !q->count) {
1196                      UNLINK_DYN_RULE(prev, V_ipfw_dyn_v[i], q);
1197                      continue;
1198              }
1199 next:
1200                         prev=q;
1201                         q=q->next;
1202                 }
1203         }
1204         if (pass++ < max_pass)
1205                 goto next_pass;
1206 }
1207
1208
1209 /**
1210  * lookup a dynamic rule.
1211  */
1212 static ipfw_dyn_rule *
1213 lookup_dyn_rule_locked(struct ipfw_flow_id *pkt, int *match_direction,
1214     struct tcphdr *tcp)
1215 {
1216         /*
1217          * stateful ipfw extensions.
1218          * Lookup into dynamic session queue
1219          */
1220 #define MATCH_REVERSE   0
1221 #define MATCH_FORWARD   1
1222 #define MATCH_NONE      2
1223 #define MATCH_UNKNOWN   3
1224         int i, dir = MATCH_NONE;
1225         ipfw_dyn_rule *prev, *q=NULL;
1226
1227         IPFW_DYN_LOCK_ASSERT();
1228
1229         if (V_ipfw_dyn_v == NULL)
1230                 goto done;      /* not found */
1231         i = hash_packet( pkt );
1232         for (prev=NULL, q = V_ipfw_dyn_v[i] ; q != NULL ; ) {
1233                 if (q->dyn_type == O_LIMIT_PARENT && q->count)
1234                         goto next;
1235                 if (TIME_LEQ( q->expire, time_uptime)) { /* expire entry */
1236                         UNLINK_DYN_RULE(prev, V_ipfw_dyn_v[i], q);
1237                         continue;
1238                 }
1239                 if (pkt->proto == q->id.proto &&
1240                     q->dyn_type != O_LIMIT_PARENT) {
1241                         if (IS_IP6_FLOW_ID(pkt)) {
1242                             if (IN6_ARE_ADDR_EQUAL(&(pkt->src_ip6),
1243                                 &(q->id.src_ip6)) &&
1244                             IN6_ARE_ADDR_EQUAL(&(pkt->dst_ip6),
1245                                 &(q->id.dst_ip6)) &&
1246                             pkt->src_port == q->id.src_port &&
1247                             pkt->dst_port == q->id.dst_port ) {
1248                                 dir = MATCH_FORWARD;
1249                                 break;
1250                             }
1251                             if (IN6_ARE_ADDR_EQUAL(&(pkt->src_ip6),
1252                                     &(q->id.dst_ip6)) &&
1253                                 IN6_ARE_ADDR_EQUAL(&(pkt->dst_ip6),
1254                                     &(q->id.src_ip6)) &&
1255                                 pkt->src_port == q->id.dst_port &&
1256                                 pkt->dst_port == q->id.src_port ) {
1257                                     dir = MATCH_REVERSE;
1258                                     break;
1259                             }
1260                         } else {
1261                             if (pkt->src_ip == q->id.src_ip &&
1262                                 pkt->dst_ip == q->id.dst_ip &&
1263                                 pkt->src_port == q->id.src_port &&
1264                                 pkt->dst_port == q->id.dst_port ) {
1265                                     dir = MATCH_FORWARD;
1266                                     break;
1267                             }
1268                             if (pkt->src_ip == q->id.dst_ip &&
1269                                 pkt->dst_ip == q->id.src_ip &&
1270                                 pkt->src_port == q->id.dst_port &&
1271                                 pkt->dst_port == q->id.src_port ) {
1272                                     dir = MATCH_REVERSE;
1273                                     break;
1274                             }
1275                         }
1276                 }
1277 next:
1278                 prev = q;
1279                 q = q->next;
1280         }
1281         if (q == NULL)
1282                 goto done; /* q = NULL, not found */
1283
1284         if ( prev != NULL) { /* found and not in front */
1285                 prev->next = q->next;
1286                 q->next = V_ipfw_dyn_v[i];
1287                 V_ipfw_dyn_v[i] = q;
1288         }
1289         if (pkt->proto == IPPROTO_TCP) { /* update state according to flags */
1290                 u_char flags = pkt->flags & (TH_FIN|TH_SYN|TH_RST);
1291
1292 #define BOTH_SYN        (TH_SYN | (TH_SYN << 8))
1293 #define BOTH_FIN        (TH_FIN | (TH_FIN << 8))
1294                 q->state |= (dir == MATCH_FORWARD ) ? flags : (flags << 8);
1295                 switch (q->state) {
1296                 case TH_SYN:                            /* opening */
1297                         q->expire = time_uptime + V_dyn_syn_lifetime;
1298                         break;
1299
1300                 case BOTH_SYN:                  /* move to established */
1301                 case BOTH_SYN | TH_FIN :        /* one side tries to close */
1302                 case BOTH_SYN | (TH_FIN << 8) :
1303                         if (tcp) {
1304 #define _SEQ_GE(a,b) ((int)(a) - (int)(b) >= 0)
1305                             u_int32_t ack = ntohl(tcp->th_ack);
1306                             if (dir == MATCH_FORWARD) {
1307                                 if (q->ack_fwd == 0 || _SEQ_GE(ack, q->ack_fwd))
1308                                     q->ack_fwd = ack;
1309                                 else { /* ignore out-of-sequence */
1310                                     break;
1311                                 }
1312                             } else {
1313                                 if (q->ack_rev == 0 || _SEQ_GE(ack, q->ack_rev))
1314                                     q->ack_rev = ack;
1315                                 else { /* ignore out-of-sequence */
1316                                     break;
1317                                 }
1318                             }
1319                         }
1320                         q->expire = time_uptime + V_dyn_ack_lifetime;
1321                         break;
1322
1323                 case BOTH_SYN | BOTH_FIN:       /* both sides closed */
1324                         if (V_dyn_fin_lifetime >= V_dyn_keepalive_period)
1325                                 V_dyn_fin_lifetime = V_dyn_keepalive_period - 1;
1326                         q->expire = time_uptime + V_dyn_fin_lifetime;
1327                         break;
1328
1329                 default:
1330 #if 0
1331                         /*
1332                          * reset or some invalid combination, but can also
1333                          * occur if we use keep-state the wrong way.
1334                          */
1335                         if ( (q->state & ((TH_RST << 8)|TH_RST)) == 0)
1336                                 printf("invalid state: 0x%x\n", q->state);
1337 #endif
1338                         if (V_dyn_rst_lifetime >= V_dyn_keepalive_period)
1339                                 V_dyn_rst_lifetime = V_dyn_keepalive_period - 1;
1340                         q->expire = time_uptime + V_dyn_rst_lifetime;
1341                         break;
1342                 }
1343         } else if (pkt->proto == IPPROTO_UDP) {
1344                 q->expire = time_uptime + V_dyn_udp_lifetime;
1345         } else {
1346                 /* other protocols */
1347                 q->expire = time_uptime + V_dyn_short_lifetime;
1348         }
1349 done:
1350         if (match_direction)
1351                 *match_direction = dir;
1352         return q;
1353 }
1354
1355 static ipfw_dyn_rule *
1356 lookup_dyn_rule(struct ipfw_flow_id *pkt, int *match_direction,
1357     struct tcphdr *tcp)
1358 {
1359         ipfw_dyn_rule *q;
1360
1361         IPFW_DYN_LOCK();
1362         q = lookup_dyn_rule_locked(pkt, match_direction, tcp);
1363         if (q == NULL)
1364                 IPFW_DYN_UNLOCK();
1365         /* NB: return table locked when q is not NULL */
1366         return q;
1367 }
1368
1369 static void
1370 realloc_dynamic_table(void)
1371 {
1372         IPFW_DYN_LOCK_ASSERT();
1373
1374         /*
1375          * Try reallocation, make sure we have a power of 2 and do
1376          * not allow more than 64k entries. In case of overflow,
1377          * default to 1024.
1378          */
1379
1380         if (V_dyn_buckets > 65536)
1381                 V_dyn_buckets = 1024;
1382         if ((V_dyn_buckets & (V_dyn_buckets-1)) != 0) { /* not a power of 2 */
1383                 V_dyn_buckets = V_curr_dyn_buckets; /* reset */
1384                 return;
1385         }
1386         V_curr_dyn_buckets = V_dyn_buckets;
1387         if (V_ipfw_dyn_v != NULL)
1388                 free(V_ipfw_dyn_v, M_IPFW);
1389         for (;;) {
1390                 V_ipfw_dyn_v = malloc(V_curr_dyn_buckets * sizeof(ipfw_dyn_rule *),
1391                        M_IPFW, M_NOWAIT | M_ZERO);
1392                 if (V_ipfw_dyn_v != NULL || V_curr_dyn_buckets <= 2)
1393                         break;
1394                 V_curr_dyn_buckets /= 2;
1395         }
1396 }
1397
1398 /**
1399  * Install state of type 'type' for a dynamic session.
1400  * The hash table contains two type of rules:
1401  * - regular rules (O_KEEP_STATE)
1402  * - rules for sessions with limited number of sess per user
1403  *   (O_LIMIT). When they are created, the parent is
1404  *   increased by 1, and decreased on delete. In this case,
1405  *   the third parameter is the parent rule and not the chain.
1406  * - "parent" rules for the above (O_LIMIT_PARENT).
1407  */
1408 static ipfw_dyn_rule *
1409 add_dyn_rule(struct ipfw_flow_id *id, u_int8_t dyn_type, struct ip_fw *rule)
1410 {
1411         ipfw_dyn_rule *r;
1412         int i;
1413
1414         IPFW_DYN_LOCK_ASSERT();
1415
1416         if (V_ipfw_dyn_v == NULL ||
1417             (V_dyn_count == 0 && V_dyn_buckets != V_curr_dyn_buckets)) {
1418                 realloc_dynamic_table();
1419                 if (V_ipfw_dyn_v == NULL)
1420                         return NULL; /* failed ! */
1421         }
1422         i = hash_packet(id);
1423
1424         r = uma_zalloc(ipfw_dyn_rule_zone, M_NOWAIT | M_ZERO);
1425         if (r == NULL) {
1426                 printf ("ipfw: sorry cannot allocate state\n");
1427                 return NULL;
1428         }
1429
1430         /* increase refcount on parent, and set pointer */
1431         if (dyn_type == O_LIMIT) {
1432                 ipfw_dyn_rule *parent = (ipfw_dyn_rule *)rule;
1433                 if ( parent->dyn_type != O_LIMIT_PARENT)
1434                         panic("invalid parent");
1435                 parent->count++;
1436                 r->parent = parent;
1437                 rule = parent->rule;
1438         }
1439
1440         r->id = *id;
1441         r->expire = time_uptime + V_dyn_syn_lifetime;
1442         r->rule = rule;
1443         r->dyn_type = dyn_type;
1444         r->pcnt = r->bcnt = 0;
1445         r->count = 0;
1446
1447         r->bucket = i;
1448         r->next = V_ipfw_dyn_v[i];
1449         V_ipfw_dyn_v[i] = r;
1450         V_dyn_count++;
1451         DEB({
1452                 struct in_addr da;
1453 #ifdef INET6
1454                 char src[INET6_ADDRSTRLEN];
1455                 char dst[INET6_ADDRSTRLEN];
1456 #else
1457                 char src[INET_ADDRSTRLEN];
1458                 char dst[INET_ADDRSTRLEN];
1459 #endif
1460
1461 #ifdef INET6
1462                 if (IS_IP6_FLOW_ID(&(r->id))) {
1463                         ip6_sprintf(src, &r->id.src_ip6);
1464                         ip6_sprintf(dst, &r->id.dst_ip6);
1465                 } else
1466 #endif
1467                 {
1468                         da.s_addr = htonl(r->id.src_ip);
1469                         inet_ntoa_r(da, src);
1470                         da.s_addr = htonl(r->id.dst_ip);
1471                         inet_ntoa_r(da, dst);
1472                 }
1473                 printf("ipfw: add dyn entry ty %d %s %d -> %s %d, total %d\n",
1474                     dyn_type, src, r->id.src_port, dst, r->id.dst_port,
1475                     V_dyn_count);
1476         })
1477         return r;
1478 }
1479
1480 /**
1481  * lookup dynamic parent rule using pkt and rule as search keys.
1482  * If the lookup fails, then install one.
1483  */
1484 static ipfw_dyn_rule *
1485 lookup_dyn_parent(struct ipfw_flow_id *pkt, struct ip_fw *rule)
1486 {
1487         ipfw_dyn_rule *q;
1488         int i;
1489
1490         IPFW_DYN_LOCK_ASSERT();
1491
1492         if (V_ipfw_dyn_v) {
1493                 int is_v6 = IS_IP6_FLOW_ID(pkt);
1494                 i = hash_packet( pkt );
1495                 for (q = V_ipfw_dyn_v[i] ; q != NULL ; q=q->next)
1496                         if (q->dyn_type == O_LIMIT_PARENT &&
1497                             rule== q->rule &&
1498                             pkt->proto == q->id.proto &&
1499                             pkt->src_port == q->id.src_port &&
1500                             pkt->dst_port == q->id.dst_port &&
1501                             (
1502                                 (is_v6 &&
1503                                  IN6_ARE_ADDR_EQUAL(&(pkt->src_ip6),
1504                                         &(q->id.src_ip6)) &&
1505                                  IN6_ARE_ADDR_EQUAL(&(pkt->dst_ip6),
1506                                         &(q->id.dst_ip6))) ||
1507                                 (!is_v6 &&
1508                                  pkt->src_ip == q->id.src_ip &&
1509                                  pkt->dst_ip == q->id.dst_ip)
1510                             )
1511                         ) {
1512                                 q->expire = time_uptime + V_dyn_short_lifetime;
1513                                 DEB(printf("ipfw: lookup_dyn_parent found 0x%p\n",q);)
1514                                 return q;
1515                         }
1516         }
1517         return add_dyn_rule(pkt, O_LIMIT_PARENT, rule);
1518 }
1519
1520 /**
1521  * Install dynamic state for rule type cmd->o.opcode
1522  *
1523  * Returns 1 (failure) if state is not installed because of errors or because
1524  * session limitations are enforced.
1525  */
1526 static int
1527 install_state(struct ip_fw *rule, ipfw_insn_limit *cmd,
1528     struct ip_fw_args *args, uint32_t tablearg)
1529 {
1530         static int last_log;
1531         ipfw_dyn_rule *q;
1532         struct in_addr da;
1533 #ifdef INET6
1534         char src[INET6_ADDRSTRLEN + 2], dst[INET6_ADDRSTRLEN + 2];
1535 #else
1536         char src[INET_ADDRSTRLEN], dst[INET_ADDRSTRLEN];
1537 #endif
1538
1539         src[0] = '\0';
1540         dst[0] = '\0';
1541
1542         IPFW_DYN_LOCK();
1543
1544         DEB(
1545 #ifdef INET6
1546         if (IS_IP6_FLOW_ID(&(args->f_id))) {
1547                 ip6_sprintf(src, &args->f_id.src_ip6);
1548                 ip6_sprintf(dst, &args->f_id.dst_ip6);
1549         } else
1550 #endif
1551         {
1552                 da.s_addr = htonl(args->f_id.src_ip);
1553                 inet_ntoa_r(da, src);
1554                 da.s_addr = htonl(args->f_id.dst_ip);
1555                 inet_ntoa_r(da, dst);
1556         }
1557         printf("ipfw: %s: type %d %s %u -> %s %u\n",
1558             __func__, cmd->o.opcode, src, args->f_id.src_port,
1559             dst, args->f_id.dst_port);
1560         src[0] = '\0';
1561         dst[0] = '\0';
1562         )
1563
1564         q = lookup_dyn_rule_locked(&args->f_id, NULL, NULL);
1565
1566         if (q != NULL) {        /* should never occur */
1567                 if (last_log != time_uptime) {
1568                         last_log = time_uptime;
1569                         printf("ipfw: %s: entry already present, done\n",
1570                             __func__);
1571                 }
1572                 IPFW_DYN_UNLOCK();
1573                 return (0);
1574         }
1575
1576         if (V_dyn_count >= V_dyn_max)
1577                 /* Run out of slots, try to remove any expired rule. */
1578                 remove_dyn_rule(NULL, (ipfw_dyn_rule *)1);
1579
1580         if (V_dyn_count >= V_dyn_max) {
1581                 if (last_log != time_uptime) {
1582                         last_log = time_uptime;
1583                         printf("ipfw: %s: Too many dynamic rules\n", __func__);
1584                 }
1585                 IPFW_DYN_UNLOCK();
1586                 return (1);     /* cannot install, notify caller */
1587         }
1588
1589         switch (cmd->o.opcode) {
1590         case O_KEEP_STATE:      /* bidir rule */
1591                 add_dyn_rule(&args->f_id, O_KEEP_STATE, rule);
1592                 break;
1593
1594         case O_LIMIT: {         /* limit number of sessions */
1595                 struct ipfw_flow_id id;
1596                 ipfw_dyn_rule *parent;
1597                 uint32_t conn_limit;
1598                 uint16_t limit_mask = cmd->limit_mask;
1599
1600                 conn_limit = (cmd->conn_limit == IP_FW_TABLEARG) ?
1601                     tablearg : cmd->conn_limit;
1602                   
1603                 DEB(
1604                 if (cmd->conn_limit == IP_FW_TABLEARG)
1605                         printf("ipfw: %s: O_LIMIT rule, conn_limit: %u "
1606                             "(tablearg)\n", __func__, conn_limit);
1607                 else
1608                         printf("ipfw: %s: O_LIMIT rule, conn_limit: %u\n",
1609                             __func__, conn_limit);
1610                 )
1611
1612                 id.dst_ip = id.src_ip = id.dst_port = id.src_port = 0;
1613                 id.proto = args->f_id.proto;
1614                 id.addr_type = args->f_id.addr_type;
1615                 id.fib = M_GETFIB(args->m);
1616
1617                 if (IS_IP6_FLOW_ID (&(args->f_id))) {
1618                         if (limit_mask & DYN_SRC_ADDR)
1619                                 id.src_ip6 = args->f_id.src_ip6;
1620                         if (limit_mask & DYN_DST_ADDR)
1621                                 id.dst_ip6 = args->f_id.dst_ip6;
1622                 } else {
1623                         if (limit_mask & DYN_SRC_ADDR)
1624                                 id.src_ip = args->f_id.src_ip;
1625                         if (limit_mask & DYN_DST_ADDR)
1626                                 id.dst_ip = args->f_id.dst_ip;
1627                 }
1628                 if (limit_mask & DYN_SRC_PORT)
1629                         id.src_port = args->f_id.src_port;
1630                 if (limit_mask & DYN_DST_PORT)
1631                         id.dst_port = args->f_id.dst_port;
1632                 if ((parent = lookup_dyn_parent(&id, rule)) == NULL) {
1633                         printf("ipfw: %s: add parent failed\n", __func__);
1634                         IPFW_DYN_UNLOCK();
1635                         return (1);
1636                 }
1637
1638                 if (parent->count >= conn_limit) {
1639                         /* See if we can remove some expired rule. */
1640                         remove_dyn_rule(rule, parent);
1641                         if (parent->count >= conn_limit) {
1642                                 if (V_fw_verbose && last_log != time_uptime) {
1643                                         last_log = time_uptime;
1644 #ifdef INET6
1645                                         /*
1646                                          * XXX IPv6 flows are not
1647                                          * supported yet.
1648                                          */
1649                                         if (IS_IP6_FLOW_ID(&(args->f_id))) {
1650                                                 char ip6buf[INET6_ADDRSTRLEN];
1651                                                 snprintf(src, sizeof(src),
1652                                                     "[%s]", ip6_sprintf(ip6buf,
1653                                                         &args->f_id.src_ip6));
1654                                                 snprintf(dst, sizeof(dst),
1655                                                     "[%s]", ip6_sprintf(ip6buf,
1656                                                         &args->f_id.dst_ip6));
1657                                         } else
1658 #endif
1659                                         {
1660                                                 da.s_addr =
1661                                                     htonl(args->f_id.src_ip);
1662                                                 inet_ntoa_r(da, src);
1663                                                 da.s_addr =
1664                                                     htonl(args->f_id.dst_ip);
1665                                                 inet_ntoa_r(da, dst);
1666                                         }
1667                                         log(LOG_SECURITY | LOG_DEBUG,
1668                                             "ipfw: %d %s %s:%u -> %s:%u, %s\n",
1669                                             parent->rule->rulenum,
1670                                             "drop session",
1671                                             src, (args->f_id.src_port),
1672                                             dst, (args->f_id.dst_port),
1673                                             "too many entries");
1674                                 }
1675                                 IPFW_DYN_UNLOCK();
1676                                 return (1);
1677                         }
1678                 }
1679                 add_dyn_rule(&args->f_id, O_LIMIT, (struct ip_fw *)parent);
1680                 break;
1681         }
1682         default:
1683                 printf("ipfw: %s: unknown dynamic rule type %u\n",
1684                     __func__, cmd->o.opcode);
1685                 IPFW_DYN_UNLOCK();
1686                 return (1);
1687         }
1688
1689         /* XXX just set lifetime */
1690         lookup_dyn_rule_locked(&args->f_id, NULL, NULL);
1691
1692         IPFW_DYN_UNLOCK();
1693         return (0);
1694 }
1695
1696 /*
1697  * Generate a TCP packet, containing either a RST or a keepalive.
1698  * When flags & TH_RST, we are sending a RST packet, because of a
1699  * "reset" action matched the packet.
1700  * Otherwise we are sending a keepalive, and flags & TH_
1701  * The 'replyto' mbuf is the mbuf being replied to, if any, and is required
1702  * so that MAC can label the reply appropriately.
1703  */
1704 static struct mbuf *
1705 send_pkt(struct mbuf *replyto, struct ipfw_flow_id *id, u_int32_t seq,
1706     u_int32_t ack, int flags)
1707 {
1708 #if defined( __linux__ ) || defined( _WIN32 )
1709         return NULL;
1710 #else
1711         struct mbuf *m;
1712         int len, dir;
1713         struct ip *h = NULL;            /* stupid compiler */
1714 #ifdef INET6
1715         struct ip6_hdr *h6 = NULL;
1716 #endif
1717         struct tcphdr *th = NULL;
1718
1719         MGETHDR(m, M_DONTWAIT, MT_DATA);
1720         if (m == NULL)
1721                 return (NULL);
1722
1723         M_SETFIB(m, id->fib);
1724 #ifdef MAC
1725         if (replyto != NULL)
1726                 mac_netinet_firewall_reply(replyto, m);
1727         else
1728                 mac_netinet_firewall_send(m);
1729 #else
1730         (void)replyto;          /* don't warn about unused arg */
1731 #endif
1732
1733         switch (id->addr_type) {
1734         case 4:
1735                 len = sizeof(struct ip) + sizeof(struct tcphdr);
1736                 break;
1737 #ifdef INET6
1738         case 6:
1739                 len = sizeof(struct ip6_hdr) + sizeof(struct tcphdr);
1740                 break;
1741 #endif
1742         default:
1743                 /* XXX: log me?!? */
1744                 m_freem(m);
1745                 return (NULL);
1746         }
1747         dir = ((flags & (TH_SYN | TH_RST)) == TH_SYN);
1748
1749         m->m_data += max_linkhdr;
1750         m->m_flags |= M_SKIP_FIREWALL;
1751         m->m_pkthdr.len = m->m_len = len;
1752         m->m_pkthdr.rcvif = NULL;
1753         bzero(m->m_data, len);
1754
1755         switch (id->addr_type) {
1756         case 4:
1757                 h = mtod(m, struct ip *);
1758
1759                 /* prepare for checksum */
1760                 h->ip_p = IPPROTO_TCP;
1761                 h->ip_len = htons(sizeof(struct tcphdr));
1762                 if (dir) {
1763                         h->ip_src.s_addr = htonl(id->src_ip);
1764                         h->ip_dst.s_addr = htonl(id->dst_ip);
1765                 } else {
1766                         h->ip_src.s_addr = htonl(id->dst_ip);
1767                         h->ip_dst.s_addr = htonl(id->src_ip);
1768                 }
1769
1770                 th = (struct tcphdr *)(h + 1);
1771                 break;
1772 #ifdef INET6
1773         case 6:
1774                 h6 = mtod(m, struct ip6_hdr *);
1775
1776                 /* prepare for checksum */
1777                 h6->ip6_nxt = IPPROTO_TCP;
1778                 h6->ip6_plen = htons(sizeof(struct tcphdr));
1779                 if (dir) {
1780                         h6->ip6_src = id->src_ip6;
1781                         h6->ip6_dst = id->dst_ip6;
1782                 } else {
1783                         h6->ip6_src = id->dst_ip6;
1784                         h6->ip6_dst = id->src_ip6;
1785                 }
1786
1787                 th = (struct tcphdr *)(h6 + 1);
1788                 break;
1789 #endif
1790         }
1791
1792         if (dir) {
1793                 th->th_sport = htons(id->src_port);
1794                 th->th_dport = htons(id->dst_port);
1795         } else {
1796                 th->th_sport = htons(id->dst_port);
1797                 th->th_dport = htons(id->src_port);
1798         }
1799         th->th_off = sizeof(struct tcphdr) >> 2;
1800
1801         if (flags & TH_RST) {
1802                 if (flags & TH_ACK) {
1803                         th->th_seq = htonl(ack);
1804                         // XXX th->th_ack = htonl(0);
1805                         th->th_flags = TH_RST;
1806                 } else {
1807                         if (flags & TH_SYN)
1808                                 seq++;
1809                         // XXX th->th_seq = htonl(0);
1810                         th->th_ack = htonl(seq);
1811                         th->th_flags = TH_RST | TH_ACK;
1812                 }
1813         } else {
1814                 /*
1815                  * Keepalive - use caller provided sequence numbers
1816                  */
1817                 th->th_seq = htonl(seq);
1818                 th->th_ack = htonl(ack);
1819                 th->th_flags = TH_ACK;
1820         }
1821
1822         switch (id->addr_type) {
1823         case 4:
1824                 th->th_sum = in_cksum(m, len);
1825
1826                 /* finish the ip header */
1827                 h->ip_v = 4;
1828                 h->ip_hl = sizeof(*h) >> 2;
1829                 h->ip_tos = IPTOS_LOWDELAY;
1830                 h->ip_off = 0;
1831                 h->ip_len = len;
1832                 h->ip_ttl = V_ip_defttl;
1833                 h->ip_sum = 0;
1834                 break;
1835 #ifdef INET6
1836         case 6:
1837                 th->th_sum = in6_cksum(m, IPPROTO_TCP, sizeof(*h6),
1838                     sizeof(struct tcphdr));
1839
1840                 /* finish the ip6 header */
1841                 h6->ip6_vfc |= IPV6_VERSION;
1842                 h6->ip6_hlim = IPV6_DEFHLIM;
1843                 break;
1844 #endif
1845         }
1846
1847         return (m);
1848 #endif /* !__linux__ */
1849 }
1850
1851 /*
1852  * sends a reject message, consuming the mbuf passed as an argument.
1853  */
1854 static void
1855 send_reject(struct ip_fw_args *args, int code, int ip_len, struct ip *ip)
1856 {
1857
1858 #if 0
1859         /* XXX When ip is not guaranteed to be at mtod() we will
1860          * need to account for this */
1861          * The mbuf will however be thrown away so we can adjust it.
1862          * Remember we did an m_pullup on it already so we
1863          * can make some assumptions about contiguousness.
1864          */
1865         if (args->L3offset)
1866                 m_adj(m, args->L3offset);
1867 #endif
1868         if (code != ICMP_REJECT_RST) { /* Send an ICMP unreach */
1869                 /* We need the IP header in host order for icmp_error(). */
1870 #if !defined( __linux__ ) && !defined( _WIN32 )
1871                 if (args->eh != NULL) {
1872                         ip->ip_len = ntohs(ip->ip_len);
1873                         ip->ip_off = ntohs(ip->ip_off);
1874                 }
1875 #endif
1876                 icmp_error(args->m, ICMP_UNREACH, code, 0L, 0);
1877         } else if (args->f_id.proto == IPPROTO_TCP) {
1878                 struct tcphdr *const tcp =
1879                     L3HDR(struct tcphdr, mtod(args->m, struct ip *));
1880                 if ( (tcp->th_flags & TH_RST) == 0) {
1881                         struct mbuf *m;
1882                         m = send_pkt(args->m, &(args->f_id),
1883                                 ntohl(tcp->th_seq), ntohl(tcp->th_ack),
1884                                 tcp->th_flags | TH_RST);
1885                         if (m != NULL)
1886                                 ip_output(m, NULL, NULL, 0, NULL, NULL);
1887                 }
1888                 m_freem(args->m);
1889         } else
1890                 m_freem(args->m);
1891         args->m = NULL;
1892 }
1893
1894 /**
1895  *
1896  * Given an ip_fw *, lookup_next_rule will return a pointer
1897  * to the next rule, which can be either the jump
1898  * target (for skipto instructions) or the next one in the list (in
1899  * all other cases including a missing jump target).
1900  * The result is also written in the "next_rule" field of the rule.
1901  * Backward jumps are not allowed, so start looking from the next
1902  * rule...
1903  *
1904  * This never returns NULL -- in case we do not have an exact match,
1905  * the next rule is returned. When the ruleset is changed,
1906  * pointers are flushed so we are always correct.
1907  */
1908
1909 static struct ip_fw *
1910 lookup_next_rule(struct ip_fw *me, u_int32_t tablearg)
1911 {
1912         struct ip_fw *rule = NULL;
1913         ipfw_insn *cmd;
1914         u_int16_t       rulenum;
1915
1916         /* look for action, in case it is a skipto */
1917         cmd = ACTION_PTR(me);
1918         if (cmd->opcode == O_LOG)
1919                 cmd += F_LEN(cmd);
1920         if (cmd->opcode == O_ALTQ)
1921                 cmd += F_LEN(cmd);
1922         if (cmd->opcode == O_TAG)
1923                 cmd += F_LEN(cmd);
1924         if (cmd->opcode == O_SKIPTO ) {
1925                 if (tablearg != 0) {
1926                         rulenum = (u_int16_t)tablearg;
1927                 } else {
1928                         rulenum = cmd->arg1;
1929                 }
1930                 for (rule = me->next; rule ; rule = rule->next) {
1931                         if (rule->rulenum >= rulenum) {
1932                                 break;
1933                         }
1934                 }
1935         }
1936         if (rule == NULL)                       /* failure or not a skipto */
1937                 rule = me->next;
1938         me->next_rule = rule;
1939         return rule;
1940 }
1941
1942 #ifdef radix
1943 static int
1944 add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
1945     uint8_t mlen, uint32_t value)
1946 {
1947         struct radix_node_head *rnh;
1948         struct table_entry *ent;
1949         struct radix_node *rn;
1950
1951         if (tbl >= IPFW_TABLES_MAX)
1952                 return (EINVAL);
1953         rnh = ch->tables[tbl];
1954         ent = malloc(sizeof(*ent), M_IPFW_TBL, M_NOWAIT | M_ZERO);
1955         if (ent == NULL)
1956                 return (ENOMEM);
1957         ent->value = value;
1958         ent->addr.sin_len = ent->mask.sin_len = 8;
1959         ent->mask.sin_addr.s_addr = htonl(mlen ? ~((1 << (32 - mlen)) - 1) : 0);
1960         ent->addr.sin_addr.s_addr = addr & ent->mask.sin_addr.s_addr;
1961         IPFW_WLOCK(ch);
1962         rn = rnh->rnh_addaddr(&ent->addr, &ent->mask, rnh, (void *)ent);
1963         if (rn == NULL) {
1964                 IPFW_WUNLOCK(ch);
1965                 free(ent, M_IPFW_TBL);
1966                 return (EEXIST);
1967         }
1968         IPFW_WUNLOCK(ch);
1969         return (0);
1970 }
1971
1972 static int
1973 del_table_entry(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
1974     uint8_t mlen)
1975 {
1976         struct radix_node_head *rnh;
1977         struct table_entry *ent;
1978         struct sockaddr_in sa, mask;
1979
1980         if (tbl >= IPFW_TABLES_MAX)
1981                 return (EINVAL);
1982         rnh = ch->tables[tbl];
1983         sa.sin_len = mask.sin_len = 8;
1984         mask.sin_addr.s_addr = htonl(mlen ? ~((1 << (32 - mlen)) - 1) : 0);
1985         sa.sin_addr.s_addr = addr & mask.sin_addr.s_addr;
1986         IPFW_WLOCK(ch);
1987         ent = (struct table_entry *)rnh->rnh_deladdr(&sa, &mask, rnh);
1988         if (ent == NULL) {
1989                 IPFW_WUNLOCK(ch);
1990                 return (ESRCH);
1991         }
1992         IPFW_WUNLOCK(ch);
1993         free(ent, M_IPFW_TBL);
1994         return (0);
1995 }
1996
1997 static int
1998 flush_table_entry(struct radix_node *rn, void *arg)
1999 {
2000         struct radix_node_head * const rnh = arg;
2001         struct table_entry *ent;
2002
2003         ent = (struct table_entry *)
2004             rnh->rnh_deladdr(rn->rn_key, rn->rn_mask, rnh);
2005         if (ent != NULL)
2006                 free(ent, M_IPFW_TBL);
2007         return (0);
2008 }
2009
2010 static int
2011 flush_table(struct ip_fw_chain *ch, uint16_t tbl)
2012 {
2013         struct radix_node_head *rnh;
2014
2015         IPFW_WLOCK_ASSERT(ch);
2016
2017         if (tbl >= IPFW_TABLES_MAX)
2018                 return (EINVAL);
2019         rnh = ch->tables[tbl];
2020         KASSERT(rnh != NULL, ("NULL IPFW table"));
2021         rnh->rnh_walktree(rnh, flush_table_entry, rnh);
2022         return (0);
2023 }
2024 #else
2025 extern int add_table_entry(struct ip_fw_chain *ch, uint16_t tbl,
2026     in_addr_t addr, uint8_t mlen, uint32_t value);
2027 extern int del_table_entry(struct ip_fw_chain *ch, uint16_t tbl,
2028     in_addr_t addr, uint8_t mlen);
2029 extern int flush_table(struct ip_fw_chain *ch, uint16_t tbl);
2030 extern int count_table(struct ip_fw_chain *ch, uint32_t tbl, uint32_t *cnt);
2031 extern int dump_table(struct ip_fw_chain *ch, ipfw_table *tbl);
2032 #endif
2033
2034 static void
2035 flush_tables(struct ip_fw_chain *ch)
2036 {
2037         uint16_t tbl;
2038
2039         IPFW_WLOCK_ASSERT(ch);
2040
2041         for (tbl = 0; tbl < IPFW_TABLES_MAX; tbl++)
2042                 flush_table(ch, tbl);
2043 }
2044
2045 static int
2046 init_tables(struct ip_fw_chain *ch)
2047
2048 #ifdef radix
2049         int i;
2050         uint16_t j;
2051
2052         for (i = 0; i < IPFW_TABLES_MAX; i++) {
2053                 if (!rn_inithead((void **)&ch->tables[i], 32)) {
2054                         for (j = 0; j < i; j++) {
2055                                 (void) flush_table(ch, j);
2056                         }
2057                         return (ENOMEM);
2058                 }
2059         }
2060 #endif
2061         return (0);
2062 }
2063
2064 static int
2065 lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
2066     uint32_t *val)
2067 {
2068 #ifdef radix
2069         struct radix_node_head *rnh;
2070         struct table_entry *ent;
2071         struct sockaddr_in sa;
2072
2073         if (tbl >= IPFW_TABLES_MAX)
2074                 return (0);
2075         rnh = ch->tables[tbl];
2076         sa.sin_len = 8;
2077         sa.sin_addr.s_addr = addr;
2078         ent = (struct table_entry *)(rnh->rnh_lookup(&sa, NULL, rnh));
2079         if (ent != NULL) {
2080                 *val = ent->value;
2081                 return (1);
2082         }
2083 #endif
2084         return (0);
2085 }
2086
2087 #ifdef radix
2088 static int
2089 count_table_entry(struct radix_node *rn, void *arg)
2090 {
2091         u_int32_t * const cnt = arg;
2092
2093         (*cnt)++;
2094         return (0);
2095 }
2096
2097 static int
2098 count_table(struct ip_fw_chain *ch, uint32_t tbl, uint32_t *cnt)
2099 {
2100         struct radix_node_head *rnh;
2101
2102         if (tbl >= IPFW_TABLES_MAX)
2103                 return (EINVAL);
2104         rnh = ch->tables[tbl];
2105         *cnt = 0;
2106         rnh->rnh_walktree(rnh, count_table_entry, cnt);
2107         return (0);
2108 }
2109
2110 static int
2111 dump_table_entry(struct radix_node *rn, void *arg)
2112 {
2113         struct table_entry * const n = (struct table_entry *)rn;
2114         ipfw_table * const tbl = arg;
2115         ipfw_table_entry *ent;
2116
2117         if (tbl->cnt == tbl->size)
2118                 return (1);
2119         ent = &tbl->ent[tbl->cnt];
2120         ent->tbl = tbl->tbl;
2121         if (in_nullhost(n->mask.sin_addr))
2122                 ent->masklen = 0;
2123         else
2124                 ent->masklen = 33 - ffs(ntohl(n->mask.sin_addr.s_addr));
2125         ent->addr = n->addr.sin_addr.s_addr;
2126         ent->value = n->value;
2127         tbl->cnt++;
2128         return (0);
2129 }
2130
2131 static int
2132 dump_table(struct ip_fw_chain *ch, ipfw_table *tbl)
2133 {
2134         struct radix_node_head *rnh;
2135
2136         if (tbl->tbl >= IPFW_TABLES_MAX)
2137                 return (EINVAL);
2138         rnh = ch->tables[tbl->tbl];
2139         tbl->cnt = 0;
2140         rnh->rnh_walktree(rnh, dump_table_entry, tbl);
2141         return (0);
2142 }
2143 #endif
2144
2145 #ifndef linux /* FreeBSD */
2146 static void
2147 fill_ugid_cache(struct inpcb *inp, struct ip_fw_ugid *ugp)
2148 {
2149         struct ucred *cr;
2150
2151         cr = inp->inp_cred;
2152         ugp->fw_prid = jailed(cr) ? cr->cr_prison->pr_id : -1;
2153         ugp->fw_uid = cr->cr_uid;
2154         ugp->fw_ngroups = cr->cr_ngroups;
2155         bcopy(cr->cr_groups, ugp->fw_groups, sizeof(ugp->fw_groups));
2156 }
2157 #endif
2158
2159 static int
2160 check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif,
2161     struct in_addr dst_ip, u_int16_t dst_port, struct in_addr src_ip,
2162     u_int16_t src_port, struct ip_fw_ugid *ugp, int *ugid_lookupp,
2163     struct inpcb *inp)
2164 {
2165 #ifdef linux
2166         int match = 0;
2167         struct sk_buff *skb = ((struct mbuf *)inp)->m_skb;
2168
2169         if (*ugid_lookupp == 0) {       /* actively lookup and copy in cache */
2170
2171                 /* returns null if any element of the chain up to file is null.
2172                  * if sk != NULL then we also have a reference 
2173                  */
2174                 *ugid_lookupp = linux_lookup(proto,
2175                         src_ip.s_addr, htons(src_port),
2176                         dst_ip.s_addr, htons(dst_port),
2177                         skb, oif ? 1 : 0, ugp);
2178
2179         }
2180         if (*ugid_lookupp < 0)
2181                 return 0;
2182
2183         if (insn->o.opcode == O_UID)
2184                 match = (ugp->fw_uid == (uid_t)insn->d[0]);
2185         else if (insn->o.opcode == O_JAIL)
2186                 match = (ugp->fw_groups[1] == (uid_t)insn->d[0]);
2187         else if (insn->o.opcode == O_GID)
2188                 match = (ugp->fw_groups[0] == (uid_t)insn->d[0]);
2189
2190         return match;
2191
2192 #else   /* FreeBSD */
2193
2194         struct inpcbinfo *pi;
2195         int wildcard;
2196         struct inpcb *pcb;
2197         int match;
2198         gid_t *gp;
2199
2200         /*
2201          * Check to see if the UDP or TCP stack supplied us with
2202          * the PCB. If so, rather then holding a lock and looking
2203          * up the PCB, we can use the one that was supplied.
2204          */
2205         if (inp && *ugid_lookupp == 0) {
2206                 INP_LOCK_ASSERT(inp);
2207                 if (inp->inp_socket != NULL) {
2208                         fill_ugid_cache(inp, ugp);
2209                         *ugid_lookupp = 1;
2210                 } else
2211                         *ugid_lookupp = -1;
2212         }
2213         /*
2214          * If we have already been here and the packet has no
2215          * PCB entry associated with it, then we can safely
2216          * assume that this is a no match.
2217          */
2218         if (*ugid_lookupp == -1)
2219                 return (0);
2220         if (proto == IPPROTO_TCP) {
2221                 wildcard = 0;
2222                 pi = &V_tcbinfo;
2223         } else if (proto == IPPROTO_UDP) {
2224                 wildcard = INPLOOKUP_WILDCARD;
2225                 pi = &V_udbinfo;
2226         } else
2227                 return 0;
2228         match = 0;
2229         if (*ugid_lookupp == 0) {
2230                 INP_INFO_RLOCK(pi);
2231                 pcb =  (oif) ?
2232                         in_pcblookup_hash(pi,
2233                                 dst_ip, htons(dst_port),
2234                                 src_ip, htons(src_port),
2235                                 wildcard, oif) :
2236                         in_pcblookup_hash(pi,
2237                                 src_ip, htons(src_port),
2238                                 dst_ip, htons(dst_port),
2239                                 wildcard, NULL);
2240                 if (pcb != NULL) {
2241                         fill_ugid_cache(pcb, ugp);
2242                         *ugid_lookupp = 1;
2243                 }
2244                 INP_INFO_RUNLOCK(pi);
2245                 if (*ugid_lookupp == 0) {
2246                         /*
2247                          * If the lookup did not yield any results, there
2248                          * is no sense in coming back and trying again. So
2249                          * we can set lookup to -1 and ensure that we wont
2250                          * bother the pcb system again.
2251                          */
2252                         *ugid_lookupp = -1;
2253                         return (0);
2254                 }
2255         } 
2256         if (insn->o.opcode == O_UID)
2257                 match = (ugp->fw_uid == (uid_t)insn->d[0]);
2258         else if (insn->o.opcode == O_GID) {
2259                 for (gp = ugp->fw_groups;
2260                         gp < &ugp->fw_groups[ugp->fw_ngroups]; gp++)
2261                         if (*gp == (gid_t)insn->d[0]) {
2262                                 match = 1;
2263                                 break;
2264                         }
2265         } else if (insn->o.opcode == O_JAIL)
2266                 match = (ugp->fw_prid == (int)insn->d[0]);
2267         return match;
2268 #endif
2269 }
2270
2271 /*
2272  * The main check routine for the firewall.
2273  *
2274  * All arguments are in args so we can modify them and return them
2275  * back to the caller.
2276  *
2277  * Parameters:
2278  *
2279  *      args->m (in/out) The packet; we set to NULL when/if we nuke it.
2280  *              Starts with the IP header.
2281  *      args->eh (in)   Mac header if present, or NULL for layer3 packet.
2282  *      args->L3offset  Number of bytes bypassed if we came from L2.
2283  *                      e.g. often sizeof(eh)  ** NOTYET **
2284  *      args->oif       Outgoing interface, or NULL if packet is incoming.
2285  *              The incoming interface is in the mbuf. (in)
2286  *      args->divert_rule (in/out)
2287  *              Skip up to the first rule past this rule number;
2288  *              upon return, non-zero port number for divert or tee.
2289  *
2290  *      args->rule      Pointer to the last matching rule (in/out)
2291  *      args->next_hop  Socket we are forwarding to (out).
2292  *      args->f_id      Addresses grabbed from the packet (out)
2293  *      args->cookie    a cookie depending on rule action
2294  *
2295  * Return value:
2296  *
2297  *      IP_FW_PASS      the packet must be accepted
2298  *      IP_FW_DENY      the packet must be dropped
2299  *      IP_FW_DIVERT    divert packet, port in m_tag
2300  *      IP_FW_TEE       tee packet, port in m_tag
2301  *      IP_FW_DUMMYNET  to dummynet, pipe in args->cookie
2302  *      IP_FW_NETGRAPH  into netgraph, cookie args->cookie
2303  *
2304  */
2305 int
2306 ipfw_chk(struct ip_fw_args *args)
2307 {
2308
2309         /*
2310          * Local variables holding state during the processing of a packet:
2311          *
2312          * IMPORTANT NOTE: to speed up the processing of rules, there
2313          * are some assumption on the values of the variables, which
2314          * are documented here. Should you change them, please check
2315          * the implementation of the various instructions to make sure
2316          * that they still work.
2317          *
2318          * args->eh     The MAC header. It is non-null for a layer2
2319          *      packet, it is NULL for a layer-3 packet.
2320          * **notyet**
2321          * args->L3offset Offset in the packet to the L3 (IP or equiv.) header.
2322          *
2323          * m | args->m  Pointer to the mbuf, as received from the caller.
2324          *      It may change if ipfw_chk() does an m_pullup, or if it
2325          *      consumes the packet because it calls send_reject().
2326          *      XXX This has to change, so that ipfw_chk() never modifies
2327          *      or consumes the buffer.
2328          * ip   is the beginning of the ip(4 or 6) header.
2329          *      Calculated by adding the L3offset to the start of data.
2330          *      (Until we start using L3offset, the packet is
2331          *      supposed to start with the ip header).
2332          */
2333         struct mbuf *m = args->m;
2334         struct ip *ip = mtod(m, struct ip *);
2335
2336         /*
2337          * For rules which contain uid/gid or jail constraints, cache
2338          * a copy of the users credentials after the pcb lookup has been
2339          * executed. This will speed up the processing of rules with
2340          * these types of constraints, as well as decrease contention
2341          * on pcb related locks.
2342          */
2343         struct ip_fw_ugid fw_ugid_cache;
2344         int ugid_lookup = 0;
2345
2346         /*
2347          * divinput_flags       If non-zero, set to the IP_FW_DIVERT_*_FLAG
2348          *      associated with a packet input on a divert socket.  This
2349          *      will allow to distinguish traffic and its direction when
2350          *      it originates from a divert socket.
2351          */
2352         u_int divinput_flags = 0;
2353
2354         /*
2355          * oif | args->oif      If NULL, ipfw_chk has been called on the
2356          *      inbound path (ether_input, ip_input).
2357          *      If non-NULL, ipfw_chk has been called on the outbound path
2358          *      (ether_output, ip_output).
2359          */
2360         struct ifnet *oif = args->oif;
2361
2362         struct ip_fw *f = NULL;         /* matching rule */
2363         int retval = 0;
2364
2365         /*
2366          * hlen The length of the IP header.
2367          */
2368         u_int hlen = 0;         /* hlen >0 means we have an IP pkt */
2369
2370         /*
2371          * offset       The offset of a fragment. offset != 0 means that
2372          *      we have a fragment at this offset of an IPv4 packet.
2373          *      offset == 0 means that (if this is an IPv4 packet)
2374          *      this is the first or only fragment.
2375          *      For IPv6 offset == 0 means there is no Fragment Header. 
2376          *      If offset != 0 for IPv6 always use correct mask to
2377          *      get the correct offset because we add IP6F_MORE_FRAG
2378          *      to be able to dectect the first fragment which would
2379          *      otherwise have offset = 0.
2380          */
2381         u_short offset = 0;
2382
2383         /*
2384          * Local copies of addresses. They are only valid if we have
2385          * an IP packet.
2386          *
2387          * proto        The protocol. Set to 0 for non-ip packets,
2388          *      or to the protocol read from the packet otherwise.
2389          *      proto != 0 means that we have an IPv4 packet.
2390          *
2391          * src_port, dst_port   port numbers, in HOST format. Only
2392          *      valid for TCP and UDP packets.
2393          *
2394          * src_ip, dst_ip       ip addresses, in NETWORK format.
2395          *      Only valid for IPv4 packets.
2396          */
2397         u_int8_t proto;
2398         u_int16_t src_port = 0, dst_port = 0;   /* NOTE: host format    */
2399         struct in_addr src_ip, dst_ip;          /* NOTE: network format */
2400         u_int16_t ip_len=0;
2401         int pktlen;
2402         u_int16_t       etype = 0;      /* Host order stored ether type */
2403
2404         /*
2405          * dyn_dir = MATCH_UNKNOWN when rules unchecked,
2406          *      MATCH_NONE when checked and not matched (q = NULL),
2407          *      MATCH_FORWARD or MATCH_REVERSE otherwise (q != NULL)
2408          */
2409         int dyn_dir = MATCH_UNKNOWN;
2410         ipfw_dyn_rule *q = NULL;
2411         struct ip_fw_chain *chain = &V_layer3_chain;
2412         struct m_tag *mtag;
2413
2414         /*
2415          * We store in ulp a pointer to the upper layer protocol header.
2416          * In the ipv4 case this is easy to determine from the header,
2417          * but for ipv6 we might have some additional headers in the middle.
2418          * ulp is NULL if not found.
2419          */
2420         void *ulp = NULL;               /* upper layer protocol pointer. */
2421         /* XXX ipv6 variables */
2422         int is_ipv6 = 0;
2423         u_int16_t ext_hd = 0;   /* bits vector for extension header filtering */
2424         /* end of ipv6 variables */
2425         int is_ipv4 = 0;
2426
2427         int done = 0;           /* flag to exit the outer loop */
2428
2429         if (m->m_flags & M_SKIP_FIREWALL || (! V_ipfw_vnet_ready))
2430                 return (IP_FW_PASS);    /* accept */
2431
2432         dst_ip.s_addr = 0;      /* make sure it is initialized */
2433         src_ip.s_addr = 0;      /* make sure it is initialized */
2434         pktlen = m->m_pkthdr.len;
2435         args->f_id.fib = M_GETFIB(m); /* note mbuf not altered) */
2436         proto = args->f_id.proto = 0;   /* mark f_id invalid */
2437                 /* XXX 0 is a valid proto: IP/IPv6 Hop-by-Hop Option */
2438
2439 /*
2440  * PULLUP_TO(len, p, T) makes sure that len + sizeof(T) is contiguous,
2441  * then it sets p to point at the offset "len" in the mbuf. WARNING: the
2442  * pointer might become stale after other pullups (but we never use it
2443  * this way).
2444  */
2445 #define PULLUP_TO(_len, p, T)                                           \
2446 do {                                                                    \
2447         int x = (_len) + sizeof(T);                                     \
2448         if ((m)->m_len < x) {                                           \
2449                         goto pullup_failed;                             \
2450         }                                                               \
2451         p = (mtod(m, char *) + (_len));                                 \
2452 } while (0)
2453
2454         /*
2455          * if we have an ether header,
2456          */
2457         if (args->eh)
2458                 etype = ntohs(args->eh->ether_type);
2459
2460         /* Identify IP packets and fill up variables. */
2461         if (pktlen >= sizeof(struct ip6_hdr) &&
2462             (args->eh == NULL || etype == ETHERTYPE_IPV6) && ip->ip_v == 6) {
2463                 struct ip6_hdr *ip6 = (struct ip6_hdr *)ip;
2464                 is_ipv6 = 1;
2465                 args->f_id.addr_type = 6;
2466                 hlen = sizeof(struct ip6_hdr);
2467                 proto = ip6->ip6_nxt;
2468
2469                 /* Search extension headers to find upper layer protocols */
2470                 while (ulp == NULL) {
2471                         switch (proto) {
2472                         case IPPROTO_ICMPV6:
2473                                 PULLUP_TO(hlen, ulp, struct icmp6_hdr);
2474                                 args->f_id.flags = ICMP6(ulp)->icmp6_type;
2475                                 break;
2476
2477                         case IPPROTO_TCP:
2478                                 PULLUP_TO(hlen, ulp, struct tcphdr);
2479                                 dst_port = TCP(ulp)->th_dport;
2480                                 src_port = TCP(ulp)->th_sport;
2481                                 args->f_id.flags = TCP(ulp)->th_flags;
2482                                 break;
2483
2484                         case IPPROTO_SCTP:
2485                                 PULLUP_TO(hlen, ulp, struct sctphdr);
2486                                 src_port = SCTP(ulp)->src_port;
2487                                 dst_port = SCTP(ulp)->dest_port;
2488                                 break;
2489
2490                         case IPPROTO_UDP:
2491                                 PULLUP_TO(hlen, ulp, struct udphdr);
2492                                 dst_port = UDP(ulp)->uh_dport;
2493                                 src_port = UDP(ulp)->uh_sport;
2494                                 break;
2495
2496                         case IPPROTO_HOPOPTS:   /* RFC 2460 */
2497                                 PULLUP_TO(hlen, ulp, struct ip6_hbh);
2498                                 ext_hd |= EXT_HOPOPTS;
2499                                 hlen += (((struct ip6_hbh *)ulp)->ip6h_len + 1) << 3;
2500                                 proto = ((struct ip6_hbh *)ulp)->ip6h_nxt;
2501                                 ulp = NULL;
2502                                 break;
2503
2504                         case IPPROTO_ROUTING:   /* RFC 2460 */
2505                                 PULLUP_TO(hlen, ulp, struct ip6_rthdr);
2506                                 switch (((struct ip6_rthdr *)ulp)->ip6r_type) {
2507                                 case 0:
2508                                         ext_hd |= EXT_RTHDR0;
2509                                         break;
2510                                 case 2:
2511                                         ext_hd |= EXT_RTHDR2;
2512                                         break;
2513                                 default:
2514                                         printf("IPFW2: IPV6 - Unknown Routing "
2515                                             "Header type(%d)\n",
2516                                             ((struct ip6_rthdr *)ulp)->ip6r_type);
2517                                         if (V_fw_deny_unknown_exthdrs)
2518                                             return (IP_FW_DENY);
2519                                         break;
2520                                 }
2521                                 ext_hd |= EXT_ROUTING;
2522                                 hlen += (((struct ip6_rthdr *)ulp)->ip6r_len + 1) << 3;
2523                                 proto = ((struct ip6_rthdr *)ulp)->ip6r_nxt;
2524                                 ulp = NULL;
2525                                 break;
2526
2527                         case IPPROTO_FRAGMENT:  /* RFC 2460 */
2528                                 PULLUP_TO(hlen, ulp, struct ip6_frag);
2529                                 ext_hd |= EXT_FRAGMENT;
2530                                 hlen += sizeof (struct ip6_frag);
2531                                 proto = ((struct ip6_frag *)ulp)->ip6f_nxt;
2532                                 offset = ((struct ip6_frag *)ulp)->ip6f_offlg &
2533                                         IP6F_OFF_MASK;
2534                                 /* Add IP6F_MORE_FRAG for offset of first
2535                                  * fragment to be != 0. */
2536                                 offset |= ((struct ip6_frag *)ulp)->ip6f_offlg &
2537                                         IP6F_MORE_FRAG;
2538                                 if (offset == 0) {
2539                                         printf("IPFW2: IPV6 - Invalid Fragment "
2540                                             "Header\n");
2541                                         if (V_fw_deny_unknown_exthdrs)
2542                                             return (IP_FW_DENY);
2543                                         break;
2544                                 }
2545                                 args->f_id.frag_id6 =
2546                                     ntohl(((struct ip6_frag *)ulp)->ip6f_ident);
2547                                 ulp = NULL;
2548                                 break;
2549
2550                         case IPPROTO_DSTOPTS:   /* RFC 2460 */
2551                                 PULLUP_TO(hlen, ulp, struct ip6_hbh);
2552                                 ext_hd |= EXT_DSTOPTS;
2553                                 hlen += (((struct ip6_hbh *)ulp)->ip6h_len + 1) << 3;
2554                                 proto = ((struct ip6_hbh *)ulp)->ip6h_nxt;
2555                                 ulp = NULL;
2556                                 break;
2557
2558                         case IPPROTO_AH:        /* RFC 2402 */
2559                                 PULLUP_TO(hlen, ulp, struct ip6_ext);
2560                                 ext_hd |= EXT_AH;
2561                                 hlen += (((struct ip6_ext *)ulp)->ip6e_len + 2) << 2;
2562                                 proto = ((struct ip6_ext *)ulp)->ip6e_nxt;
2563                                 ulp = NULL;
2564                                 break;
2565
2566                         case IPPROTO_ESP:       /* RFC 2406 */
2567                                 PULLUP_TO(hlen, ulp, uint32_t); /* SPI, Seq# */
2568                                 /* Anything past Seq# is variable length and
2569                                  * data past this ext. header is encrypted. */
2570                                 ext_hd |= EXT_ESP;
2571                                 break;
2572
2573                         case IPPROTO_NONE:      /* RFC 2460 */
2574                                 /*
2575                                  * Packet ends here, and IPv6 header has
2576                                  * already been pulled up. If ip6e_len!=0
2577                                  * then octets must be ignored.
2578                                  */
2579                                 ulp = ip; /* non-NULL to get out of loop. */
2580                                 break;
2581
2582                         case IPPROTO_OSPFIGP:
2583                                 /* XXX OSPF header check? */
2584                                 PULLUP_TO(hlen, ulp, struct ip6_ext);
2585                                 break;
2586
2587                         case IPPROTO_PIM:
2588                                 /* XXX PIM header check? */
2589                                 PULLUP_TO(hlen, ulp, struct pim);
2590                                 break;
2591
2592                         case IPPROTO_CARP:
2593                                 PULLUP_TO(hlen, ulp, struct carp_header);
2594                                 if (((struct carp_header *)ulp)->carp_version !=
2595                                     CARP_VERSION) 
2596                                         return (IP_FW_DENY);
2597                                 if (((struct carp_header *)ulp)->carp_type !=
2598                                     CARP_ADVERTISEMENT) 
2599                                         return (IP_FW_DENY);
2600                                 break;
2601
2602                         case IPPROTO_IPV6:      /* RFC 2893 */
2603                                 PULLUP_TO(hlen, ulp, struct ip6_hdr);
2604                                 break;
2605
2606                         case IPPROTO_IPV4:      /* RFC 2893 */
2607                                 PULLUP_TO(hlen, ulp, struct ip);
2608                                 break;
2609
2610                         default:
2611                                 printf("IPFW2: IPV6 - Unknown Extension "
2612                                     "Header(%d), ext_hd=%x\n", proto, ext_hd);
2613                                 if (V_fw_deny_unknown_exthdrs)
2614                                     return (IP_FW_DENY);
2615                                 PULLUP_TO(hlen, ulp, struct ip6_ext);
2616                                 break;
2617                         } /*switch */
2618                 }
2619                 ip = mtod(m, struct ip *);
2620                 ip6 = (struct ip6_hdr *)ip;
2621                 args->f_id.src_ip6 = ip6->ip6_src;
2622                 args->f_id.dst_ip6 = ip6->ip6_dst;
2623                 args->f_id.src_ip = 0;
2624                 args->f_id.dst_ip = 0;
2625                 args->f_id.flow_id6 = ntohl(ip6->ip6_flow);
2626         } else if (pktlen >= sizeof(struct ip) &&
2627             (args->eh == NULL || etype == ETHERTYPE_IP) && ip->ip_v == 4) {
2628                 is_ipv4 = 1;
2629                 hlen = ip->ip_hl << 2;
2630                 args->f_id.addr_type = 4;
2631
2632                 /*
2633                  * Collect parameters into local variables for faster matching.
2634                  */
2635                 proto = ip->ip_p;
2636                 src_ip = ip->ip_src;
2637                 dst_ip = ip->ip_dst;
2638
2639                 if (1 || args->eh != NULL) { /* layer 2 packets are as on the wire */
2640                         offset = ntohs(ip->ip_off) & IP_OFFMASK;
2641                         ip_len = ntohs(ip->ip_len);
2642                 } else {
2643                         offset = ip->ip_off & IP_OFFMASK;
2644                         ip_len = ip->ip_len;
2645                 }
2646                 pktlen = ip_len < pktlen ? ip_len : pktlen;
2647
2648                 if (offset == 0) {
2649                         switch (proto) {
2650                         case IPPROTO_TCP:
2651                                 PULLUP_TO(hlen, ulp, struct tcphdr);
2652                                 dst_port = TCP(ulp)->th_dport;
2653                                 src_port = TCP(ulp)->th_sport;
2654                                 args->f_id.flags = TCP(ulp)->th_flags;
2655                                 break;
2656
2657                         case IPPROTO_UDP:
2658                                 PULLUP_TO(hlen, ulp, struct udphdr);
2659                                 dst_port = UDP(ulp)->uh_dport;
2660                                 src_port = UDP(ulp)->uh_sport;
2661                                 break;
2662
2663                         case IPPROTO_ICMP:
2664                                 PULLUP_TO(hlen, ulp, struct icmphdr);
2665                                 args->f_id.flags = ICMP(ulp)->icmp_type;
2666                                 break;
2667
2668                         default:
2669                                 break;
2670                         }
2671                 }
2672
2673                 ip = mtod(m, struct ip *);
2674                 args->f_id.src_ip = ntohl(src_ip.s_addr);
2675                 args->f_id.dst_ip = ntohl(dst_ip.s_addr);
2676         }
2677 #undef PULLUP_TO
2678         if (proto) { /* we may have port numbers, store them */
2679                 args->f_id.proto = proto;
2680                 args->f_id.src_port = src_port = ntohs(src_port);
2681                 args->f_id.dst_port = dst_port = ntohs(dst_port);
2682         }
2683
2684         IPFW_RLOCK(chain);
2685         if (! V_ipfw_vnet_ready) { /* shutting down, leave NOW. */
2686                 IPFW_RUNLOCK(chain);
2687                 return (IP_FW_PASS);    /* accept */
2688         }
2689         mtag = m_tag_find(m, PACKET_TAG_DIVERT, NULL);
2690         if (args->rule) {
2691                 /*
2692                  * Packet has already been tagged. Look for the next rule
2693                  * to restart processing. Make sure that args->rule still
2694                  * exists and not changed.
2695                  * If fw_one_pass != 0 then just accept it.
2696                  * XXX should not happen here, but optimized out in
2697                  * the caller.
2698                  */
2699                 if (V_fw_one_pass) {
2700                         IPFW_RUNLOCK(chain);
2701                         return (IP_FW_PASS);
2702                 }
2703
2704                 f = args->rule->next_rule;
2705
2706                 if (f == NULL)
2707                         f = lookup_next_rule(args->rule, 0);
2708         } else {
2709                 /*
2710                  * Find the starting rule. It can be either the first
2711                  * one, or the one after divert_rule if asked so.
2712                  */
2713                 int skipto = mtag ? divert_cookie(mtag) : 0;
2714
2715                 f = chain->rules;
2716                 if (args->eh == NULL && skipto != 0) {
2717                         if (skipto >= IPFW_DEFAULT_RULE) {
2718                                 IPFW_RUNLOCK(chain);
2719                                 return (IP_FW_DENY); /* invalid */
2720                         }
2721                         while (f && f->rulenum <= skipto)
2722                                 f = f->next;
2723                         if (f == NULL) {        /* drop packet */
2724                                 IPFW_RUNLOCK(chain);
2725                                 return (IP_FW_DENY);
2726                         }
2727                 }
2728         }
2729         /* reset divert rule to avoid confusion later */
2730         if (mtag) {
2731                 divinput_flags = divert_info(mtag) &
2732                     (IP_FW_DIVERT_OUTPUT_FLAG | IP_FW_DIVERT_LOOPBACK_FLAG);
2733                 m_tag_delete(m, mtag);
2734         }
2735
2736         /*
2737          * Now scan the rules, and parse microinstructions for each rule.
2738          * We have two nested loops and an inner switch. Sometimes we
2739          * need to break out of one or both loops, or re-enter one of
2740          * the loops with updated variables. Loop variables are:
2741          *
2742          *      f (outer loop) points to the current rule.
2743          *              On output it points to the matching rule.
2744          *      done (outer loop) is used as a flag to break the loop.
2745          *      l (inner loop)  residual length of current rule.
2746          *      cmd points to the current microinstruction.
2747          *
2748          * We break the inner loop by setting l=0 and possibly
2749          * cmdlen=0 if we don't want to advance cmd.
2750          * We break the outer loop by setting done=1
2751          * We can restart the inner loop by setting l>0 and f, cmd
2752          * as needed.
2753          */
2754         for (; f; f = f->next) {
2755                 ipfw_insn *cmd;
2756                 uint32_t tablearg = 0;
2757                 int l, cmdlen, skip_or; /* skip rest of OR block */
2758
2759 /* again: */
2760                 if (V_set_disable & (1 << f->set) )
2761                         continue;
2762
2763                 skip_or = 0;
2764                 for (l = f->cmd_len, cmd = f->cmd ; l > 0 ;
2765                     l -= cmdlen, cmd += cmdlen) {
2766                         int match;
2767
2768                         /*
2769                          * check_body is a jump target used when we find a
2770                          * CHECK_STATE, and need to jump to the body of
2771                          * the target rule.
2772                          */
2773
2774 /* check_body: */
2775                         cmdlen = F_LEN(cmd);
2776                         /*
2777                          * An OR block (insn_1 || .. || insn_n) has the
2778                          * F_OR bit set in all but the last instruction.
2779                          * The first match will set "skip_or", and cause
2780                          * the following instructions to be skipped until
2781                          * past the one with the F_OR bit clear.
2782                          */
2783                         if (skip_or) {          /* skip this instruction */
2784                                 if ((cmd->len & F_OR) == 0)
2785                                         skip_or = 0;    /* next one is good */
2786                                 continue;
2787                         }
2788                         match = 0; /* set to 1 if we succeed */
2789
2790                         switch (cmd->opcode) {
2791                         /*
2792                          * The first set of opcodes compares the packet's
2793                          * fields with some pattern, setting 'match' if a
2794                          * match is found. At the end of the loop there is
2795                          * logic to deal with F_NOT and F_OR flags associated
2796                          * with the opcode.
2797                          */
2798                         case O_NOP:
2799                                 match = 1;
2800                                 break;
2801
2802                         case O_FORWARD_MAC:
2803                                 printf("ipfw: opcode %d unimplemented\n",
2804                                     cmd->opcode);
2805                                 break;
2806
2807                         case O_GID:
2808                         case O_UID:
2809                         case O_JAIL:
2810                                 /*
2811                                  * We only check offset == 0 && proto != 0,
2812                                  * as this ensures that we have a
2813                                  * packet with the ports info.
2814                                  */
2815                                 if (offset!=0)
2816                                         break;
2817                                 if (is_ipv6) /* XXX to be fixed later */
2818                                         break;
2819                                 if (proto == IPPROTO_TCP ||
2820                                     proto == IPPROTO_UDP)
2821                                         match = check_uidgid(
2822                                                     (ipfw_insn_u32 *)cmd,
2823                                                     proto, oif,
2824                                                     dst_ip, dst_port,
2825                                                     src_ip, src_port, &fw_ugid_cache,
2826                                                     &ugid_lookup, (struct inpcb *)args->m);
2827                                 break;
2828
2829                         case O_RECV:
2830                                 match = iface_match(m->m_pkthdr.rcvif,
2831                                     (ipfw_insn_if *)cmd);
2832                                 break;
2833
2834                         case O_XMIT:
2835                                 match = iface_match(oif, (ipfw_insn_if *)cmd);
2836                                 break;
2837
2838                         case O_VIA:
2839                                 match = iface_match(oif ? oif :
2840                                     m->m_pkthdr.rcvif, (ipfw_insn_if *)cmd);
2841                                 break;
2842
2843                         case O_MACADDR2:
2844                                 if (args->eh != NULL) { /* have MAC header */
2845                                         u_int32_t *want = (u_int32_t *)
2846                                                 ((ipfw_insn_mac *)cmd)->addr;
2847                                         u_int32_t *mask = (u_int32_t *)
2848                                                 ((ipfw_insn_mac *)cmd)->mask;
2849                                         u_int32_t *hdr = (u_int32_t *)args->eh;
2850
2851                                         match =
2852                                             ( want[0] == (hdr[0] & mask[0]) &&
2853                                               want[1] == (hdr[1] & mask[1]) &&
2854                                               want[2] == (hdr[2] & mask[2]) );
2855                                 }
2856                                 break;
2857
2858                         case O_MAC_TYPE:
2859                                 if (args->eh != NULL) {
2860                                         u_int16_t *p =
2861                                             ((ipfw_insn_u16 *)cmd)->ports;
2862                                         int i;
2863
2864                                         for (i = cmdlen - 1; !match && i>0;
2865                                             i--, p += 2)
2866                                                 match = (etype >= p[0] &&
2867                                                     etype <= p[1]);
2868                                 }
2869                                 break;
2870
2871                         case O_FRAG:
2872                                 match = (offset != 0);
2873                                 break;
2874
2875                         case O_IN:      /* "out" is "not in" */
2876                                 match = (oif == NULL);
2877                                 break;
2878
2879                         case O_LAYER2:
2880                                 match = (args->eh != NULL);
2881                                 break;
2882
2883                         case O_DIVERTED:
2884                                 match = (cmd->arg1 & 1 && divinput_flags &
2885                                     IP_FW_DIVERT_LOOPBACK_FLAG) ||
2886                                         (cmd->arg1 & 2 && divinput_flags &
2887                                     IP_FW_DIVERT_OUTPUT_FLAG);
2888                                 break;
2889
2890                         case O_PROTO:
2891                                 /*
2892                                  * We do not allow an arg of 0 so the
2893                                  * check of "proto" only suffices.
2894                                  */
2895                                 match = (proto == cmd->arg1);
2896                                 break;
2897
2898                         case O_IP_SRC:
2899                                 match = is_ipv4 &&
2900                                     (((ipfw_insn_ip *)cmd)->addr.s_addr ==
2901                                     src_ip.s_addr);
2902                                 break;
2903
2904                         case O_IP_SRC_LOOKUP:
2905                         case O_IP_DST_LOOKUP:
2906                                 if (is_ipv4) {
2907                                     uint32_t a =
2908                                         (cmd->opcode == O_IP_DST_LOOKUP) ?
2909                                             dst_ip.s_addr : src_ip.s_addr;
2910                                     uint32_t v = 0;
2911
2912                                     match = lookup_table(chain, cmd->arg1, a,
2913                                         &v);
2914                                     if (!match)
2915                                         break;
2916                                     if (cmdlen == F_INSN_SIZE(ipfw_insn_u32))
2917                                         match =
2918                                             ((ipfw_insn_u32 *)cmd)->d[0] == v;
2919                                     else
2920                                         tablearg = v;
2921                                 }
2922                                 break;
2923
2924                         case O_IP_SRC_MASK:
2925                         case O_IP_DST_MASK:
2926                                 if (is_ipv4) {
2927                                     uint32_t a =
2928                                         (cmd->opcode == O_IP_DST_MASK) ?
2929                                             dst_ip.s_addr : src_ip.s_addr;
2930                                     uint32_t *p = ((ipfw_insn_u32 *)cmd)->d;
2931                                     int i = cmdlen-1;
2932
2933                                     for (; !match && i>0; i-= 2, p+= 2)
2934                                         match = (p[0] == (a & p[1]));
2935                                 }
2936                                 break;
2937
2938                         case O_IP_SRC_ME:
2939                                 if (is_ipv4) {
2940                                         struct ifnet *tif;
2941
2942                                         INADDR_TO_IFP(src_ip, tif);
2943                                         match = (tif != NULL);
2944                                 }
2945                                 break;
2946
2947                         case O_IP_DST_SET:
2948                         case O_IP_SRC_SET:
2949                                 if (is_ipv4) {
2950                                         u_int32_t *d = (u_int32_t *)(cmd+1);
2951                                         u_int32_t addr =
2952                                             cmd->opcode == O_IP_DST_SET ?
2953                                                 args->f_id.dst_ip :
2954                                                 args->f_id.src_ip;
2955
2956                                             if (addr < d[0])
2957                                                     break;
2958                                             addr -= d[0]; /* subtract base */
2959                                             match = (addr < cmd->arg1) &&
2960                                                 ( d[ 1 + (addr>>5)] &
2961                                                   (1<<(addr & 0x1f)) );
2962                                 }
2963                                 break;
2964
2965                         case O_IP_DST:
2966                                 match = is_ipv4 &&
2967                                     (((ipfw_insn_ip *)cmd)->addr.s_addr ==
2968                                     dst_ip.s_addr);
2969                                 break;
2970
2971                         case O_IP_DST_ME:
2972                                 if (is_ipv4) {
2973                                         struct ifnet *tif;
2974
2975                                         INADDR_TO_IFP(dst_ip, tif);
2976                                         match = (tif != NULL);
2977                                 }
2978                                 break;
2979
2980                         case O_IP_SRCPORT:
2981                         case O_IP_DSTPORT:
2982                                 /*
2983                                  * offset == 0 && proto != 0 is enough
2984                                  * to guarantee that we have a
2985                                  * packet with port info.
2986                                  */
2987                                 if ((proto==IPPROTO_UDP || proto==IPPROTO_TCP)
2988                                     && offset == 0) {
2989                                         u_int16_t x =
2990                                             (cmd->opcode == O_IP_SRCPORT) ?
2991                                                 src_port : dst_port ;
2992                                         u_int16_t *p =
2993                                             ((ipfw_insn_u16 *)cmd)->ports;
2994                                         int i;
2995
2996                                         for (i = cmdlen - 1; !match && i>0;
2997                                             i--, p += 2)
2998                                                 match = (x>=p[0] && x<=p[1]);
2999                                 }
3000                                 break;
3001
3002                         case O_ICMPTYPE:
3003                                 match = (offset == 0 && proto==IPPROTO_ICMP &&
3004                                     icmptype_match(ICMP(ulp), (ipfw_insn_u32 *)cmd) );
3005                                 break;
3006
3007 #ifdef INET6
3008                         case O_ICMP6TYPE:
3009                                 match = is_ipv6 && offset == 0 &&
3010                                     proto==IPPROTO_ICMPV6 &&
3011                                     icmp6type_match(
3012                                         ICMP6(ulp)->icmp6_type,
3013                                         (ipfw_insn_u32 *)cmd);
3014                                 break;
3015 #endif /* INET6 */
3016
3017                         case O_IPOPT:
3018                                 match = (is_ipv4 &&
3019                                     ipopts_match(ip, cmd) );
3020                                 break;
3021
3022                         case O_IPVER:
3023                                 match = (is_ipv4 &&
3024                                     cmd->arg1 == ip->ip_v);
3025                                 break;
3026
3027                         case O_IPID:
3028                         case O_IPLEN:
3029                         case O_IPTTL:
3030                                 if (is_ipv4) {  /* only for IP packets */
3031                                     uint16_t x;
3032                                     uint16_t *p;
3033                                     int i;
3034
3035                                     if (cmd->opcode == O_IPLEN)
3036                                         x = ip_len;
3037                                     else if (cmd->opcode == O_IPTTL)
3038                                         x = ip->ip_ttl;
3039                                     else /* must be IPID */
3040                                         x = ntohs(ip->ip_id);
3041                                     if (cmdlen == 1) {
3042                                         match = (cmd->arg1 == x);
3043                                         break;
3044                                     }
3045                                     /* otherwise we have ranges */
3046                                     p = ((ipfw_insn_u16 *)cmd)->ports;
3047                                     i = cmdlen - 1;
3048                                     for (; !match && i>0; i--, p += 2)
3049                                         match = (x >= p[0] && x <= p[1]);
3050                                 }
3051                                 break;
3052
3053                         case O_IPPRECEDENCE:
3054                                 match = (is_ipv4 &&
3055                                     (cmd->arg1 == (ip->ip_tos & 0xe0)) );
3056                                 break;
3057
3058                         case O_IPTOS:
3059                                 match = (is_ipv4 &&
3060                                     flags_match(cmd, ip->ip_tos));
3061                                 break;
3062
3063                         case O_TCPDATALEN:
3064                                 if (proto == IPPROTO_TCP && offset == 0) {
3065                                     struct tcphdr *tcp;
3066                                     uint16_t x;
3067                                     uint16_t *p;
3068                                     int i;
3069
3070                                     tcp = TCP(ulp);
3071                                     x = ip_len -
3072                                         ((ip->ip_hl + tcp->th_off) << 2);
3073                                     if (cmdlen == 1) {
3074                                         match = (cmd->arg1 == x);
3075                                         break;
3076                                     }
3077                                     /* otherwise we have ranges */
3078                                     p = ((ipfw_insn_u16 *)cmd)->ports;
3079                                     i = cmdlen - 1;
3080                                     for (; !match && i>0; i--, p += 2)
3081                                         match = (x >= p[0] && x <= p[1]);
3082                                 }
3083                                 break;
3084
3085                         case O_TCPFLAGS:
3086                                 match = (proto == IPPROTO_TCP && offset == 0 &&
3087                                     flags_match(cmd, TCP(ulp)->th_flags));
3088                                 break;
3089
3090                         case O_TCPOPTS:
3091                                 match = (proto == IPPROTO_TCP && offset == 0 &&
3092                                     tcpopts_match(TCP(ulp), cmd));
3093                                 break;
3094
3095                         case O_TCPSEQ:
3096                                 match = (proto == IPPROTO_TCP && offset == 0 &&
3097                                     ((ipfw_insn_u32 *)cmd)->d[0] ==
3098                                         TCP(ulp)->th_seq);
3099                                 break;
3100
3101                         case O_TCPACK:
3102                                 match = (proto == IPPROTO_TCP && offset == 0 &&
3103                                     ((ipfw_insn_u32 *)cmd)->d[0] ==
3104                                         TCP(ulp)->th_ack);
3105                                 break;
3106
3107                         case O_TCPWIN:
3108                                 match = (proto == IPPROTO_TCP && offset == 0 &&
3109                                     cmd->arg1 == TCP(ulp)->th_win);
3110                                 break;
3111
3112                         case O_ESTAB:
3113                                 /* reject packets which have SYN only */
3114                                 /* XXX should i also check for TH_ACK ? */
3115                                 match = (proto == IPPROTO_TCP && offset == 0 &&
3116                                     (TCP(ulp)->th_flags &
3117                                      (TH_RST | TH_ACK | TH_SYN)) != TH_SYN);
3118                                 break;
3119
3120                         case O_ALTQ: {
3121                                 struct pf_mtag *at;
3122                                 ipfw_insn_altq *altq = (ipfw_insn_altq *)cmd;
3123
3124                                 match = 1;
3125                                 at = pf_find_mtag(m);
3126                                 if (at != NULL && at->qid != 0)
3127                                         break;
3128                                 at = pf_get_mtag(m);
3129                                 if (at == NULL) {
3130                                         /*
3131                                          * Let the packet fall back to the
3132                                          * default ALTQ.
3133                                          */
3134                                         break;
3135                                 }
3136                                 at->qid = altq->qid;
3137                                 if (is_ipv4)
3138                                         at->af = AF_INET;
3139                                 else
3140                                         at->af = AF_LINK;
3141                                 at->hdr = ip;
3142                                 break;
3143                         }
3144
3145                         case O_LOG:
3146                                 if (V_fw_verbose)
3147                                         ipfw_log(f, hlen, args, m,
3148                                             oif, offset, tablearg, ip);
3149                                 match = 1;
3150                                 break;
3151
3152                         case O_PROB:
3153                                 match = (random()<((ipfw_insn_u32 *)cmd)->d[0]);
3154                                 break;
3155
3156 #if 0
3157                         case O_VERREVPATH:
3158                                 /* Outgoing packets automatically pass/match */
3159                                 match = ((oif != NULL) ||
3160                                     (m->m_pkthdr.rcvif == NULL) ||
3161                                     (
3162 #ifdef INET6
3163                                     is_ipv6 ?
3164                                         verify_path6(&(args->f_id.src_ip6),
3165                                             m->m_pkthdr.rcvif) :
3166 #endif
3167                                     verify_path(src_ip, m->m_pkthdr.rcvif,
3168                                         args->f_id.fib)));
3169                                 break;
3170
3171                         case O_VERSRCREACH:
3172                                 /* Outgoing packets automatically pass/match */
3173                                 match = (hlen > 0 && ((oif != NULL) ||
3174 #ifdef INET6
3175                                     is_ipv6 ?
3176                                         verify_path6(&(args->f_id.src_ip6),
3177                                             NULL) :
3178 #endif
3179                                     verify_path(src_ip, NULL, args->f_id.fib)));
3180                                 break;
3181
3182                         case O_ANTISPOOF:
3183                                 /* Outgoing packets automatically pass/match */
3184                                 if (oif == NULL && hlen > 0 &&
3185                                     (  (is_ipv4 && in_localaddr(src_ip))
3186 #ifdef INET6
3187                                     || (is_ipv6 &&
3188                                         in6_localaddr(&(args->f_id.src_ip6)))
3189 #endif
3190                                     ))
3191                                         match =
3192 #ifdef INET6
3193                                             is_ipv6 ? verify_path6(
3194                                                 &(args->f_id.src_ip6),
3195                                                 m->m_pkthdr.rcvif) :
3196 #endif
3197                                             verify_path(src_ip,
3198                                                 m->m_pkthdr.rcvif,
3199                                                 args->f_id.fib);
3200                                 else
3201                                         match = 1;
3202                                 break;
3203 #endif
3204
3205                         case O_IPSEC:
3206 #ifdef IPSEC
3207                                 match = (m_tag_find(m,
3208                                     PACKET_TAG_IPSEC_IN_DONE, NULL) != NULL);
3209 #endif
3210                                 /* otherwise no match */
3211                                 break;
3212
3213 #ifdef INET6
3214                         case O_IP6_SRC:
3215                                 match = is_ipv6 &&
3216                                     IN6_ARE_ADDR_EQUAL(&args->f_id.src_ip6,
3217                                     &((ipfw_insn_ip6 *)cmd)->addr6);
3218                                 break;
3219
3220                         case O_IP6_DST:
3221                                 match = is_ipv6 &&
3222                                 IN6_ARE_ADDR_EQUAL(&args->f_id.dst_ip6,
3223                                     &((ipfw_insn_ip6 *)cmd)->addr6);
3224                                 break;
3225                         case O_IP6_SRC_MASK:
3226                         case O_IP6_DST_MASK:
3227                                 if (is_ipv6) {
3228                                         int i = cmdlen - 1;
3229                                         struct in6_addr p;
3230                                         struct in6_addr *d =
3231                                             &((ipfw_insn_ip6 *)cmd)->addr6;
3232
3233                                         for (; !match && i > 0; d += 2,
3234                                             i -= F_INSN_SIZE(struct in6_addr)
3235                                             * 2) {
3236                                                 p = (cmd->opcode ==
3237                                                     O_IP6_SRC_MASK) ?
3238                                                     args->f_id.src_ip6:
3239                                                     args->f_id.dst_ip6;
3240                                                 APPLY_MASK(&p, &d[1]);
3241                                                 match =
3242                                                     IN6_ARE_ADDR_EQUAL(&d[0],
3243                                                     &p);
3244                                         }
3245                                 }
3246                                 break;
3247
3248                         case O_IP6_SRC_ME:
3249                                 match= is_ipv6 && search_ip6_addr_net(&args->f_id.src_ip6);
3250                                 break;
3251
3252                         case O_IP6_DST_ME:
3253                                 match= is_ipv6 && search_ip6_addr_net(&args->f_id.dst_ip6);
3254                                 break;
3255
3256                         case O_FLOW6ID:
3257                                 match = is_ipv6 &&
3258                                     flow6id_match(args->f_id.flow_id6,
3259                                     (ipfw_insn_u32 *) cmd);
3260                                 break;
3261
3262                         case O_EXT_HDR:
3263                                 match = is_ipv6 &&
3264                                     (ext_hd & ((ipfw_insn *) cmd)->arg1);
3265                                 break;
3266
3267                         case O_IP6:
3268                                 match = is_ipv6;
3269                                 break;
3270 #endif
3271
3272                         case O_IP4:
3273                                 match = is_ipv4;
3274                                 break;
3275
3276 #if 0
3277                         case O_TAG: {
3278                                 uint32_t tag = (cmd->arg1 == IP_FW_TABLEARG) ?
3279                                     tablearg : cmd->arg1;
3280
3281                                 /* Packet is already tagged with this tag? */
3282                                 mtag = m_tag_locate(m, MTAG_IPFW, tag, NULL);
3283
3284                                 /* We have `untag' action when F_NOT flag is
3285                                  * present. And we must remove this mtag from
3286                                  * mbuf and reset `match' to zero (`match' will
3287                                  * be inversed later).
3288                                  * Otherwise we should allocate new mtag and
3289                                  * push it into mbuf.
3290                                  */
3291                                 if (cmd->len & F_NOT) { /* `untag' action */
3292                                         if (mtag != NULL)
3293                                                 m_tag_delete(m, mtag);
3294                                 } else if (mtag == NULL) {
3295                                         if ((mtag = m_tag_alloc(MTAG_IPFW,
3296                                             tag, 0, M_NOWAIT)) != NULL)
3297                                                 m_tag_prepend(m, mtag);
3298                                 }
3299                                 match = (cmd->len & F_NOT) ? 0: 1;
3300                                 break;
3301                         }
3302
3303                         case O_FIB: /* try match the specified fib */
3304                                 if (args->f_id.fib == cmd->arg1)
3305                                         match = 1;
3306                                 break;
3307
3308                         case O_TAGGED: {
3309                                 uint32_t tag = (cmd->arg1 == IP_FW_TABLEARG) ?
3310                                     tablearg : cmd->arg1;
3311
3312                                 if (cmdlen == 1) {
3313                                         match = m_tag_locate(m, MTAG_IPFW,
3314                                             tag, NULL) != NULL;
3315                                         break;
3316                                 }
3317
3318                                 /* we have ranges */
3319                                 for (mtag = m_tag_first(m);
3320                                     mtag != NULL && !match;
3321                                     mtag = m_tag_next(m, mtag)) {
3322                                         uint16_t *p;
3323                                         int i;
3324
3325                                         if (mtag->m_tag_cookie != MTAG_IPFW)
3326                                                 continue;
3327
3328                                         p = ((ipfw_insn_u16 *)cmd)->ports;
3329                                         i = cmdlen - 1;
3330                                         for(; !match && i > 0; i--, p += 2)
3331                                                 match =
3332                                                     mtag->m_tag_id >= p[0] &&
3333                                                     mtag->m_tag_id <= p[1];
3334                                 }
3335                                 break;
3336                         }
3337 #endif
3338                                 
3339                         /*
3340                          * The second set of opcodes represents 'actions',
3341                          * i.e. the terminal part of a rule once the packet
3342                          * matches all previous patterns.
3343                          * Typically there is only one action for each rule,
3344                          * and the opcode is stored at the end of the rule
3345                          * (but there are exceptions -- see below).
3346                          *
3347                          * In general, here we set retval and terminate the
3348                          * outer loop (would be a 'break 3' in some language,
3349                          * but we need to set l=0, done=1)
3350                          *
3351                          * Exceptions:
3352                          * O_COUNT and O_SKIPTO actions:
3353                          *   instead of terminating, we jump to the next rule
3354                          *   (setting l=0), or to the SKIPTO target (by
3355                          *   setting f, cmd and l as needed), respectively.
3356                          *
3357                          * O_TAG, O_LOG and O_ALTQ action parameters:
3358                          *   perform some action and set match = 1;
3359                          *
3360                          * O_LIMIT and O_KEEP_STATE: these opcodes are
3361                          *   not real 'actions', and are stored right
3362                          *   before the 'action' part of the rule.
3363                          *   These opcodes try to install an entry in the
3364                          *   state tables; if successful, we continue with
3365                          *   the next opcode (match=1; break;), otherwise
3366                          *   the packet must be dropped (set retval,
3367                          *   break loops with l=0, done=1)
3368                          *
3369                          * O_PROBE_STATE and O_CHECK_STATE: these opcodes
3370                          *   cause a lookup of the state table, and a jump
3371                          *   to the 'action' part of the parent rule
3372                          *   if an entry is found, or
3373                          *   (CHECK_STATE only) a jump to the next rule if
3374                          *   the entry is not found.
3375                          *   The result of the lookup is cached so that
3376                          *   further instances of these opcodes become NOPs.
3377                          *   The jump to the next rule is done by setting
3378                          *   l=0, cmdlen=0.
3379                          */
3380                         case O_LIMIT:
3381                         case O_KEEP_STATE:
3382                                 if (install_state(f,
3383                                     (ipfw_insn_limit *)cmd, args, tablearg)) {
3384                                         /* error or limit violation */
3385                                         retval = IP_FW_DENY;
3386                                         l = 0;  /* exit inner loop */
3387                                         done = 1; /* exit outer loop */
3388                                 }
3389                                 match = 1;
3390                                 break;
3391
3392                         case O_PROBE_STATE:
3393                         case O_CHECK_STATE:
3394                                 /*
3395                                  * dynamic rules are checked at the first
3396                                  * keep-state or check-state occurrence,
3397                                  * with the result being stored in dyn_dir.
3398                                  * The compiler introduces a PROBE_STATE
3399                                  * instruction for us when we have a
3400                                  * KEEP_STATE (because PROBE_STATE needs
3401                                  * to be run first).
3402                                  */
3403                                 if (dyn_dir == MATCH_UNKNOWN &&
3404                                     (q = lookup_dyn_rule(&args->f_id,
3405                                      &dyn_dir, proto == IPPROTO_TCP ?
3406                                         TCP(ulp) : NULL))
3407                                         != NULL) {
3408                                         /*
3409                                          * Found dynamic entry, update stats
3410                                          * and jump to the 'action' part of
3411                                          * the parent rule by setting
3412                                          * f, cmd, l and clearing cmdlen.
3413                                          */
3414                                         q->pcnt++;
3415                                         q->bcnt += pktlen;
3416                                         f = q->rule;
3417                                         cmd = ACTION_PTR(f);
3418                                         l = f->cmd_len - f->act_ofs;
3419                                         IPFW_DYN_UNLOCK();
3420                                         cmdlen = 0;
3421                                         match = 1;
3422                                         break;
3423                                 }
3424                                 /*
3425                                  * Dynamic entry not found. If CHECK_STATE,
3426                                  * skip to next rule, if PROBE_STATE just
3427                                  * ignore and continue with next opcode.
3428                                  */
3429                                 if (cmd->opcode == O_CHECK_STATE)
3430                                         l = 0; /* exit inner loop */
3431                                 match = 1;
3432                                 break;
3433
3434                         case O_ACCEPT:
3435                                 retval = 0;     /* accept */
3436                                 l = 0;          /* exit inner loop */
3437                                 done = 1;       /* exit outer loop */
3438                                 break;
3439
3440                         case O_PIPE:
3441                         case O_QUEUE:
3442                                 args->rule = f; /* report matching rule */
3443                                 args->rule_id = f->id;
3444                                 args->chain_id = chain->id;
3445                                 if (cmd->arg1 == IP_FW_TABLEARG)
3446                                         args->cookie = tablearg;
3447                                 else
3448                                         args->cookie = cmd->arg1;
3449                                 retval = IP_FW_DUMMYNET;
3450                                 l = 0;          /* exit inner loop */
3451                                 done = 1;       /* exit outer loop */
3452                                 break;
3453
3454 #if 0
3455                         case O_DIVERT:
3456                         case O_TEE:
3457                                 if (args->eh) /* not on layer 2 */
3458                                         break;
3459                                 /* otherwise this is terminal */
3460                                 l = 0;          /* exit inner loop */
3461                                 done = 1;       /* exit outer loop */
3462                                 mtag = m_tag_get(PACKET_TAG_DIVERT,
3463                                         sizeof(struct divert_tag),
3464                                         M_NOWAIT);
3465                                 if (mtag == NULL) {
3466                                     retval = IP_FW_DENY;
3467                                 } else {
3468                                     struct divert_tag *dt;
3469                                     dt = (struct divert_tag *)(mtag+1);
3470                                     dt->cookie = f->rulenum;
3471                                     if (cmd->arg1 == IP_FW_TABLEARG)
3472                                         dt->info = tablearg;
3473                                     else
3474                                         dt->info = cmd->arg1;
3475                                     m_tag_prepend(m, mtag);
3476                                     retval = (cmd->opcode == O_DIVERT) ?
3477                                         IP_FW_DIVERT : IP_FW_TEE;
3478                                 }
3479                                 break;
3480 #endif
3481
3482                         case O_COUNT:
3483                         case O_SKIPTO:
3484                                 f->pcnt++;      /* update stats */
3485                                 f->bcnt += pktlen;
3486                                 f->timestamp = time_uptime;
3487                                 if (cmd->opcode == O_COUNT) {
3488                                         l = 0;  /* exit inner loop */
3489                                         break;
3490                                 }
3491                                 /* handle skipto */
3492                                 if (cmd->arg1 == IP_FW_TABLEARG) {
3493                                         f = lookup_next_rule(f, tablearg);
3494                                 } else {
3495                                         if (f->next_rule == NULL)
3496                                                 lookup_next_rule(f, 0);
3497                                         f = f->next_rule;
3498                                 }
3499                                 /*
3500                                  * Skip disabled rules, and
3501                                  * re-enter the inner loop
3502                                  * with the correct f, l and cmd.
3503                                  * Also clear cmdlen and skip_or
3504                                  */
3505                                 while (f && (V_set_disable & (1 << f->set)))
3506                                         f = f->next;
3507                                 if (f) { /* found a valid rule */
3508                                         l = f->cmd_len;
3509                                         cmd = f->cmd;
3510                                 } else {
3511                                         l = 0;  /* exit inner loop */
3512                                 }
3513                                 match = 1;
3514                                 cmdlen = 0;
3515                                 skip_or = 0;
3516                                 break;
3517
3518                         case O_REJECT:
3519                                 /*
3520                                  * Drop the packet and send a reject notice
3521                                  * if the packet is not ICMP (or is an ICMP
3522                                  * query), and it is not multicast/broadcast.
3523                                  */
3524                                 if (hlen > 0 && is_ipv4 && offset == 0 &&
3525                                     (proto != IPPROTO_ICMP ||
3526                                      is_icmp_query(ICMP(ulp))) &&
3527                                     !(m->m_flags & (M_BCAST|M_MCAST)) &&
3528                                     !IN_MULTICAST(ntohl(dst_ip.s_addr))) {
3529                                         send_reject(args, cmd->arg1, ip_len, ip);
3530                                         m = args->m;
3531                                 }
3532                                 /* FALLTHROUGH */
3533 #ifdef INET6
3534                         case O_UNREACH6:
3535                                 if (hlen > 0 && is_ipv6 &&
3536                                     ((offset & IP6F_OFF_MASK) == 0) &&
3537                                     (proto != IPPROTO_ICMPV6 ||
3538                                      (is_icmp6_query(args->f_id.flags) == 1)) &&
3539                                     !(m->m_flags & (M_BCAST|M_MCAST)) &&
3540                                     !IN6_IS_ADDR_MULTICAST(&args->f_id.dst_ip6)) {
3541                                         send_reject6(
3542                                             args, cmd->arg1, hlen,
3543                                             (struct ip6_hdr *)ip);
3544                                         m = args->m;
3545                                 }
3546                                 /* FALLTHROUGH */
3547 #endif
3548                         case O_DENY:
3549                                 retval = IP_FW_DENY;
3550                                 l = 0;          /* exit inner loop */
3551                                 done = 1;       /* exit outer loop */
3552                                 break;
3553
3554                         case O_FORWARD_IP:
3555                                 if (args->eh)   /* not valid on layer2 pkts */
3556                                         break;
3557                                 if (!q || dyn_dir == MATCH_FORWARD) {
3558                                     struct sockaddr_in *sa;
3559                                     sa = &(((ipfw_insn_sa *)cmd)->sa);
3560                                     if (sa->sin_addr.s_addr == INADDR_ANY) {
3561                                         bcopy(sa, &args->hopstore,
3562                                                 sizeof(*sa));
3563                                         args->hopstore.sin_addr.s_addr =
3564                                                 htonl(tablearg);
3565                                         args->next_hop = &args->hopstore;
3566                                     } else {
3567                                         args->next_hop = sa;
3568                                     }
3569                                 }
3570                                 retval = IP_FW_PASS;
3571                                 l = 0;          /* exit inner loop */
3572                                 done = 1;       /* exit outer loop */
3573                                 break;
3574
3575                         case O_NETGRAPH:
3576                         case O_NGTEE:
3577                                 args->rule = f; /* report matching rule */
3578                                 args->rule_id = f->id;
3579                                 args->chain_id = chain->id;
3580                                 if (cmd->arg1 == IP_FW_TABLEARG)
3581                                         args->cookie = tablearg;
3582                                 else
3583                                         args->cookie = cmd->arg1;
3584                                 retval = (cmd->opcode == O_NETGRAPH) ?
3585                                     IP_FW_NETGRAPH : IP_FW_NGTEE;
3586                                 l = 0;          /* exit inner loop */
3587                                 done = 1;       /* exit outer loop */
3588                                 break;
3589
3590 #if 0
3591                         case O_SETFIB:
3592                                 f->pcnt++;      /* update stats */
3593                                 f->bcnt += pktlen;
3594                                 f->timestamp = time_uptime;
3595                                 M_SETFIB(m, cmd->arg1);
3596                                 args->f_id.fib = cmd->arg1;
3597                                 l = 0;          /* exit inner loop */
3598                                 break;
3599
3600                         case O_NAT:
3601                                 if (!IPFW_NAT_LOADED) {
3602                                     retval = IP_FW_DENY;
3603                                 } else {
3604                                     struct cfg_nat *t;
3605                                     int nat_id;
3606
3607                                     args->rule = f; /* Report matching rule. */
3608                                     args->rule_id = f->id;
3609                                     args->chain_id = chain->id;
3610                                     t = ((ipfw_insn_nat *)cmd)->nat;
3611                                     if (t == NULL) {
3612                                         nat_id = (cmd->arg1 == IP_FW_TABLEARG) ?
3613                                                 tablearg : cmd->arg1;
3614                                         LOOKUP_NAT(V_layer3_chain, nat_id, t);
3615                                         if (t == NULL) {
3616                                             retval = IP_FW_DENY;
3617                                             l = 0;      /* exit inner loop */
3618                                             done = 1;   /* exit outer loop */
3619                                             break;
3620                                         }
3621                                         if (cmd->arg1 != IP_FW_TABLEARG)
3622                                             ((ipfw_insn_nat *)cmd)->nat = t;
3623                                     }
3624                                     retval = ipfw_nat_ptr(args, t, m);
3625                                 }
3626                                 l = 0;          /* exit inner loop */
3627                                 done = 1;       /* exit outer loop */
3628                                 break;
3629
3630                         case O_REASS: {
3631                                 int ip_off;
3632
3633                                 f->pcnt++;
3634                                 f->bcnt += pktlen;
3635                                 l = 0;  /* in any case exit inner loop */
3636
3637                                 ip_off = (args->eh != NULL) ?
3638                                 ntohs(ip->ip_off) : ip->ip_off;
3639                                 /* if not fragmented, go to next rule */
3640                                 if ((ip_off & (IP_MF | IP_OFFMASK)) == 0)
3641                                     break;
3642                                 /*
3643                                  * ip_reass() expects len & off in host
3644                                  * byte order: fix them in case we come
3645                                  * from layer2.
3646                                  */
3647                                 if (args->eh != NULL) {
3648                                     ip->ip_len = ntohs(ip->ip_len);
3649                                     ip->ip_off = ntohs(ip->ip_off);
3650                                 }
3651
3652                                 args->m = m = ip_reass(m);
3653
3654                                 /*
3655                                  * IP header checksum fixup after
3656                                  * reassembly and leave header
3657                                  * in network byte order.
3658                                 */
3659                                 if (m == NULL) { /* fragment got swallowed */
3660                                     retval = IP_FW_DENY;
3661                                 } else { /* good, packet complete */
3662                                     int hlen;
3663
3664                                     ip = mtod(m, struct ip *);
3665                                     hlen = ip->ip_hl << 2;
3666                                     /* revert len & off for layer2 pkts */
3667                                     if (args->eh != NULL)
3668                                     ip->ip_len = htons(ip->ip_len);
3669                                     ip->ip_sum = 0;
3670                                     if (hlen == sizeof(struct ip))
3671                                     ip->ip_sum = in_cksum_hdr(ip);
3672                                     else
3673                                     ip->ip_sum = in_cksum(m, hlen);
3674                                     retval = IP_FW_REASS;
3675                                     args->rule = f;
3676                                     args->rule_id = f->id;
3677                                     args->chain_id = chain->id;
3678                                 }
3679                                 done = 1;       /* exit outer loop */
3680                                 break;
3681                         }
3682 #endif
3683
3684                         default:
3685                                 break; // XXX we disabled some
3686                                 panic("-- unknown opcode %d\n", cmd->opcode);
3687                         } /* end of switch() on opcodes */
3688                         /*
3689                          * if we get here with l=0, then match is irrelevant.
3690                          */
3691
3692                         if (cmd->len & F_NOT)
3693                                 match = !match;
3694
3695                         if (match) {
3696                                 if (cmd->len & F_OR)
3697                                         skip_or = 1;
3698                         } else {
3699                                 if (!(cmd->len & F_OR)) /* not an OR block, */
3700                                         break;          /* try next rule    */
3701                         }
3702
3703                 }       /* end of inner loop, scan opcodes */
3704
3705                 if (done)
3706                         break;
3707
3708 /* next_rule:;*/                /* try next rule                */
3709
3710         }               /* end of outer for, scan rules */
3711
3712         if (done) {
3713                 /* Update statistics */
3714                 f->pcnt++;
3715                 f->bcnt += pktlen;
3716                 f->timestamp = time_uptime;
3717         } else {
3718                 retval = IP_FW_DENY;
3719                 printf("ipfw: ouch!, skip past end of rules, denying packet\n");
3720         }
3721         IPFW_RUNLOCK(chain);
3722         return (retval);
3723
3724 pullup_failed:
3725         if (V_fw_verbose)
3726                 printf("ipfw: pullup failed\n");
3727         return (IP_FW_DENY);
3728 }
3729
3730 /*
3731  * When a rule is added/deleted, clear the next_rule pointers in all rules.
3732  * These will be reconstructed on the fly as packets are matched.
3733  */
3734 static void
3735 flush_rule_ptrs(struct ip_fw_chain *chain)
3736 {
3737         struct ip_fw *rule;
3738
3739         IPFW_WLOCK_ASSERT(chain);
3740
3741         chain->id++;
3742
3743         for (rule = chain->rules; rule; rule = rule->next)
3744                 rule->next_rule = NULL;
3745 }
3746
3747 /*
3748  * Add a new rule to the list. Copy the rule into a malloc'ed area, then
3749  * possibly create a rule number and add the rule to the list.
3750  * Update the rule_number in the input struct so the caller knows it as well.
3751  */
3752 static int
3753 add_rule(struct ip_fw_chain *chain, struct ip_fw *input_rule)
3754 {
3755         struct ip_fw *rule, *f, *prev;
3756         int l = RULESIZE(input_rule);
3757
3758         if (chain->rules == NULL && input_rule->rulenum != IPFW_DEFAULT_RULE)
3759                 return (EINVAL);
3760
3761         rule = malloc(l, M_IPFW, M_NOWAIT | M_ZERO);
3762         if (rule == NULL)
3763                 return (ENOSPC);
3764
3765         bcopy(input_rule, rule, l);
3766
3767         rule->next = NULL;
3768         rule->next_rule = NULL;
3769
3770         rule->pcnt = 0;
3771         rule->bcnt = 0;
3772         rule->timestamp = 0;
3773
3774         IPFW_WLOCK(chain);
3775
3776         if (chain->rules == NULL) {     /* default rule */
3777                 chain->rules = rule;
3778                 rule->id = ++chain->id;
3779                 goto done;
3780         }
3781
3782         /*
3783          * If rulenum is 0, find highest numbered rule before the
3784          * default rule, and add autoinc_step
3785          */
3786         if (V_autoinc_step < 1)
3787                 V_autoinc_step = 1;
3788         else if (V_autoinc_step > 1000)
3789                 V_autoinc_step = 1000;
3790         if (rule->rulenum == 0) {
3791                 /*
3792                  * locate the highest numbered rule before default
3793                  */
3794                 for (f = chain->rules; f; f = f->next) {
3795                         if (f->rulenum == IPFW_DEFAULT_RULE)
3796                                 break;
3797                         rule->rulenum = f->rulenum;
3798                 }
3799                 if (rule->rulenum < IPFW_DEFAULT_RULE - V_autoinc_step)
3800                         rule->rulenum += V_autoinc_step;
3801                 input_rule->rulenum = rule->rulenum;
3802         }
3803
3804         /*
3805          * Now insert the new rule in the right place in the sorted list.
3806          */
3807         for (prev = NULL, f = chain->rules; f; prev = f, f = f->next) {
3808                 if (f->rulenum > rule->rulenum) { /* found the location */
3809                         if (prev) {
3810                                 rule->next = f;
3811                                 prev->next = rule;
3812                         } else { /* head insert */
3813                                 rule->next = chain->rules;
3814                                 chain->rules = rule;
3815                         }
3816                         break;
3817                 }
3818         }
3819         flush_rule_ptrs(chain);
3820         /* chain->id incremented inside flush_rule_ptrs() */
3821         rule->id = chain->id;
3822 done:
3823         V_static_count++;
3824         V_static_len += l;
3825         IPFW_WUNLOCK(chain);
3826         DEB(printf("ipfw: installed rule %d, static count now %d\n",
3827                 rule->rulenum, V_static_count);)
3828         return (0);
3829 }
3830
3831 /**
3832  * Remove a static rule (including derived * dynamic rules)
3833  * and place it on the ``reap list'' for later reclamation.
3834  * The caller is in charge of clearing rule pointers to avoid
3835  * dangling pointers.
3836  * @return a pointer to the next entry.
3837  * Arguments are not checked, so they better be correct.
3838  */
3839 static struct ip_fw *
3840 remove_rule(struct ip_fw_chain *chain, struct ip_fw *rule,
3841     struct ip_fw *prev)
3842 {
3843         struct ip_fw *n;
3844         int l = RULESIZE(rule);
3845
3846         IPFW_WLOCK_ASSERT(chain);
3847
3848         n = rule->next;
3849         IPFW_DYN_LOCK();
3850         remove_dyn_rule(rule, NULL /* force removal */);
3851         IPFW_DYN_UNLOCK();
3852         if (prev == NULL)
3853                 chain->rules = n;
3854         else
3855                 prev->next = n;
3856         V_static_count--;
3857         V_static_len -= l;
3858
3859         rule->next = chain->reap;
3860         chain->reap = rule;
3861
3862         return n;
3863 }
3864
3865 /*
3866  * Hook for cleaning up dummynet when an ipfw rule is deleted.
3867  * Set/cleared when dummynet module is loaded/unloaded.
3868  */
3869 void    (*ip_dn_ruledel_ptr)(void *) = NULL;
3870
3871 /**
3872  * Reclaim storage associated with a list of rules.  This is
3873  * typically the list created using remove_rule.
3874  * A NULL pointer on input is handled correctly.
3875  */
3876 static void
3877 reap_rules(struct ip_fw *head)
3878 {
3879         struct ip_fw *rule;
3880
3881         while ((rule = head) != NULL) {
3882                 head = head->next;
3883                 if (ip_dn_ruledel_ptr)
3884                         ip_dn_ruledel_ptr(rule);
3885                 free(rule, M_IPFW);
3886         }
3887 }
3888
3889 /*
3890  * Remove all rules from a chain (except rules in set RESVD_SET
3891  * unless kill_default = 1).  The caller is responsible for
3892  * reclaiming storage for the rules left in chain->reap.
3893  */
3894 static void
3895 free_chain(struct ip_fw_chain *chain, int kill_default)
3896 {
3897         struct ip_fw *prev, *rule;
3898
3899         IPFW_WLOCK_ASSERT(chain);
3900
3901         flush_rule_ptrs(chain); /* more efficient to do outside the loop */
3902         for (prev = NULL, rule = chain->rules; rule ; )
3903                 if (kill_default || rule->set != RESVD_SET)
3904                         rule = remove_rule(chain, rule, prev);
3905                 else {
3906                         prev = rule;
3907                         rule = rule->next;
3908                 }
3909 }
3910
3911 /**
3912  * Remove all rules with given number, and also do set manipulation.
3913  * Assumes chain != NULL && *chain != NULL.
3914  *
3915  * The argument is an u_int32_t. The low 16 bit are the rule or set number,
3916  * the next 8 bits are the new set, the top 8 bits are the command:
3917  *
3918  *      0       delete rules with given number
3919  *      1       delete rules with given set number
3920  *      2       move rules with given number to new set
3921  *      3       move rules with given set number to new set
3922  *      4       swap sets with given numbers
3923  *      5       delete rules with given number and with given set number
3924  */
3925 static int
3926 del_entry(struct ip_fw_chain *chain, u_int32_t arg)
3927 {
3928         struct ip_fw *prev = NULL, *rule;
3929         u_int16_t rulenum;      /* rule or old_set */
3930         u_int8_t cmd, new_set;
3931
3932         rulenum = arg & 0xffff;
3933         cmd = (arg >> 24) & 0xff;
3934         new_set = (arg >> 16) & 0xff;
3935
3936         if (cmd > 5 || new_set > RESVD_SET)
3937                 return EINVAL;
3938         if (cmd == 0 || cmd == 2 || cmd == 5) {
3939                 if (rulenum >= IPFW_DEFAULT_RULE)
3940                         return EINVAL;
3941         } else {
3942                 if (rulenum > RESVD_SET)        /* old_set */
3943                         return EINVAL;
3944         }
3945
3946         IPFW_WLOCK(chain);
3947         rule = chain->rules;    /* common starting point */
3948         chain->reap = NULL;     /* prepare for deletions */
3949         switch (cmd) {
3950         case 0: /* delete rules with given number */
3951                 /*
3952                  * locate first rule to delete
3953                  */
3954                 for (; rule->rulenum < rulenum; prev = rule, rule = rule->next)
3955                         ;
3956                 if (rule->rulenum != rulenum) {
3957                         IPFW_WUNLOCK(chain);
3958                         return EINVAL;
3959                 }
3960
3961                 /*
3962                  * flush pointers outside the loop, then delete all matching
3963                  * rules. prev remains the same throughout the cycle.
3964                  */
3965                 flush_rule_ptrs(chain);
3966                 while (rule->rulenum == rulenum)
3967                         rule = remove_rule(chain, rule, prev);
3968                 break;
3969
3970         case 1: /* delete all rules with given set number */
3971                 flush_rule_ptrs(chain);
3972                 while (rule->rulenum < IPFW_DEFAULT_RULE) {
3973                         if (rule->set == rulenum)
3974                                 rule = remove_rule(chain, rule, prev);
3975                         else {
3976                                 prev = rule;
3977                                 rule = rule->next;
3978                         }
3979                 }
3980                 break;
3981
3982         case 2: /* move rules with given number to new set */
3983                 for (; rule->rulenum < IPFW_DEFAULT_RULE; rule = rule->next)
3984                         if (rule->rulenum == rulenum)
3985                                 rule->set = new_set;
3986                 break;
3987
3988         case 3: /* move rules with given set number to new set */
3989                 for (; rule->rulenum < IPFW_DEFAULT_RULE; rule = rule->next)
3990                         if (rule->set == rulenum)
3991                                 rule->set = new_set;
3992                 break;
3993
3994         case 4: /* swap two sets */
3995                 for (; rule->rulenum < IPFW_DEFAULT_RULE; rule = rule->next)
3996                         if (rule->set == rulenum)
3997                                 rule->set = new_set;
3998                         else if (rule->set == new_set)
3999                                 rule->set = rulenum;
4000                 break;
4001
4002         case 5: /* delete rules with given number and with given set number.
4003                  * rulenum - given rule number;
4004                  * new_set - given set number.
4005                  */
4006                 for (; rule->rulenum < rulenum; prev = rule, rule = rule->next)
4007                         ;
4008                 if (rule->rulenum != rulenum) {
4009                         IPFW_WUNLOCK(chain);
4010                         return (EINVAL);
4011                 }
4012                 flush_rule_ptrs(chain);
4013                 while (rule->rulenum == rulenum) {
4014                         if (rule->set == new_set)
4015                                 rule = remove_rule(chain, rule, prev);
4016                         else {
4017                                 prev = rule;
4018                                 rule = rule->next;
4019                         }
4020                 }
4021         }
4022         /*
4023          * Look for rules to reclaim.  We grab the list before
4024          * releasing the lock then reclaim them w/o the lock to
4025          * avoid a LOR with dummynet.
4026          */
4027         rule = chain->reap;
4028         chain->reap = NULL;
4029         IPFW_WUNLOCK(chain);
4030         if (rule)
4031                 reap_rules(rule);
4032         return 0;
4033 }
4034
4035 /*
4036  * Clear counters for a specific rule.
4037  * The enclosing "table" is assumed locked.
4038  */
4039 static void
4040 clear_counters(struct ip_fw *rule, int log_only)
4041 {
4042         ipfw_insn_log *l = (ipfw_insn_log *)ACTION_PTR(rule);
4043
4044         if (log_only == 0) {
4045                 rule->bcnt = rule->pcnt = 0;
4046                 rule->timestamp = 0;
4047         }
4048         if (l->o.opcode == O_LOG)
4049                 l->log_left = l->max_log;
4050 }
4051
4052 /**
4053  * Reset some or all counters on firewall rules.
4054  * The argument `arg' is an u_int32_t. The low 16 bit are the rule number,
4055  * the next 8 bits are the set number, the top 8 bits are the command:
4056  *      0       work with rules from all set's;
4057  *      1       work with rules only from specified set.
4058  * Specified rule number is zero if we want to clear all entries.
4059  * log_only is 1 if we only want to reset logs, zero otherwise.
4060  */
4061 static int
4062 zero_entry(struct ip_fw_chain *chain, u_int32_t arg, int log_only)
4063 {
4064         struct ip_fw *rule;
4065         char *msg;
4066
4067         uint16_t rulenum = arg & 0xffff;
4068         uint8_t set = (arg >> 16) & 0xff;
4069         uint8_t cmd = (arg >> 24) & 0xff;
4070
4071         if (cmd > 1)
4072                 return (EINVAL);
4073         if (cmd == 1 && set > RESVD_SET)
4074                 return (EINVAL);
4075
4076         IPFW_WLOCK(chain);
4077         if (rulenum == 0) {
4078                 V_norule_counter = 0;
4079                 for (rule = chain->rules; rule; rule = rule->next) {
4080                         /* Skip rules from another set. */
4081                         if (cmd == 1 && rule->set != set)
4082                                 continue;
4083                         clear_counters(rule, log_only);
4084                 }
4085                 msg = log_only ? "All logging counts reset" :
4086                     "Accounting cleared";
4087         } else {
4088                 int cleared = 0;
4089                 /*
4090                  * We can have multiple rules with the same number, so we
4091                  * need to clear them all.
4092                  */
4093                 for (rule = chain->rules; rule; rule = rule->next)
4094                         if (rule->rulenum == rulenum) {
4095                                 while (rule && rule->rulenum == rulenum) {
4096                                         if (cmd == 0 || rule->set == set)
4097                                                 clear_counters(rule, log_only);
4098                                         rule = rule->next;
4099                                 }
4100                                 cleared = 1;
4101                                 break;
4102                         }
4103                 if (!cleared) { /* we did not find any matching rules */
4104                         IPFW_WUNLOCK(chain);
4105                         return (EINVAL);
4106                 }
4107                 msg = log_only ? "logging count reset" : "cleared";
4108         }
4109         IPFW_WUNLOCK(chain);
4110
4111         if (V_fw_verbose) {
4112 #define lev LOG_SECURITY | LOG_NOTICE
4113
4114                 if (rulenum)
4115                         log(lev, "ipfw: Entry %d %s.\n", rulenum, msg);
4116                 else
4117                         log(lev, "ipfw: %s.\n", msg);
4118         }
4119         return (0);
4120 }
4121
4122 /*
4123  * Check validity of the structure before insert.
4124  * Fortunately rules are simple, so this mostly need to check rule sizes.
4125  */
4126 static int
4127 check_ipfw_struct(struct ip_fw *rule, int size)
4128 {
4129         int l, cmdlen = 0;
4130         int have_action=0;
4131         ipfw_insn *cmd;
4132
4133         if (size < sizeof(*rule)) {
4134                 printf("ipfw: rule too short\n");
4135                 return (EINVAL);
4136         }
4137         /* first, check for valid size */
4138         l = RULESIZE(rule);
4139         if (l != size) {
4140                 printf("ipfw: size mismatch (have %d want %d)\n", size, l);
4141                 return (EINVAL);
4142         }
4143         if (rule->act_ofs >= rule->cmd_len) {
4144                 printf("ipfw: bogus action offset (%u > %u)\n",
4145                     rule->act_ofs, rule->cmd_len - 1);
4146                 return (EINVAL);
4147         }
4148         /*
4149          * Now go for the individual checks. Very simple ones, basically only
4150          * instruction sizes.
4151          */
4152         for (l = rule->cmd_len, cmd = rule->cmd ;
4153                         l > 0 ; l -= cmdlen, cmd += cmdlen) {
4154                 cmdlen = F_LEN(cmd);
4155                 if (cmdlen > l) {
4156                         printf("ipfw: opcode %d size truncated\n",
4157                             cmd->opcode);
4158                         return EINVAL;
4159                 }
4160                 DEB(printf("ipfw: opcode %d\n", cmd->opcode);)
4161                 switch (cmd->opcode) {
4162                 case O_PROBE_STATE:
4163                 case O_KEEP_STATE:
4164                 case O_PROTO:
4165                 case O_IP_SRC_ME:
4166                 case O_IP_DST_ME:
4167                 case O_LAYER2:
4168                 case O_IN:
4169                 case O_FRAG:
4170                 case O_DIVERTED:
4171                 case O_IPOPT:
4172                 case O_IPTOS:
4173                 case O_IPPRECEDENCE:
4174                 case O_IPVER:
4175                 case O_TCPWIN:
4176                 case O_TCPFLAGS:
4177                 case O_TCPOPTS:
4178                 case O_ESTAB:
4179                 case O_VERREVPATH:
4180                 case O_VERSRCREACH:
4181                 case O_ANTISPOOF:
4182                 case O_IPSEC:
4183 #ifdef INET6
4184                 case O_IP6_SRC_ME:
4185                 case O_IP6_DST_ME:
4186                 case O_EXT_HDR:
4187                 case O_IP6:
4188 #endif
4189                 case O_IP4:
4190                 case O_TAG:
4191                         if (cmdlen != F_INSN_SIZE(ipfw_insn))
4192                                 goto bad_size;
4193                         break;
4194
4195                 case O_FIB:
4196                         if (cmdlen != F_INSN_SIZE(ipfw_insn))
4197                                 goto bad_size;
4198                         if (cmd->arg1 >= rt_numfibs) {
4199                                 printf("ipfw: invalid fib number %d\n",
4200                                         cmd->arg1);
4201                                 return EINVAL;
4202                         }
4203                         break;
4204
4205                 case O_SETFIB:
4206                         if (cmdlen != F_INSN_SIZE(ipfw_insn))
4207                                 goto bad_size;
4208                         if (cmd->arg1 >= rt_numfibs) {
4209                                 printf("ipfw: invalid fib number %d\n",
4210                                         cmd->arg1);
4211                                 return EINVAL;
4212                         }
4213                         goto check_action;
4214
4215                 case O_UID:
4216                 case O_GID:
4217                 case O_JAIL:
4218                 case O_IP_SRC:
4219                 case O_IP_DST:
4220                 case O_TCPSEQ:
4221                 case O_TCPACK:
4222                 case O_PROB:
4223                 case O_ICMPTYPE:
4224                         if (cmdlen != F_INSN_SIZE(ipfw_insn_u32))
4225                                 goto bad_size;
4226                         break;
4227
4228                 case O_LIMIT:
4229                         if (cmdlen != F_INSN_SIZE(ipfw_insn_limit))
4230                                 goto bad_size;
4231                         break;
4232
4233                 case O_LOG:
4234                         if (cmdlen != F_INSN_SIZE(ipfw_insn_log))
4235                                 goto bad_size;
4236
4237                         ((ipfw_insn_log *)cmd)->log_left =
4238                             ((ipfw_insn_log *)cmd)->max_log;
4239
4240                         break;
4241
4242                 case O_IP_SRC_MASK:
4243                 case O_IP_DST_MASK:
4244                         /* only odd command lengths */
4245                         if ( !(cmdlen & 1) || cmdlen > 31)
4246                                 goto bad_size;
4247                         break;
4248
4249                 case O_IP_SRC_SET:
4250                 case O_IP_DST_SET:
4251                         if (cmd->arg1 == 0 || cmd->arg1 > 256) {
4252                                 printf("ipfw: invalid set size %d\n",
4253                                         cmd->arg1);
4254                                 return EINVAL;
4255                         }
4256                         if (cmdlen != F_INSN_SIZE(ipfw_insn_u32) +
4257                             (cmd->arg1+31)/32 )
4258                                 goto bad_size;
4259                         break;
4260
4261                 case O_IP_SRC_LOOKUP:
4262                 case O_IP_DST_LOOKUP:
4263                         if (cmd->arg1 >= IPFW_TABLES_MAX) {
4264                                 printf("ipfw: invalid table number %d\n",
4265                                     cmd->arg1);
4266                                 return (EINVAL);
4267                         }
4268                         if (cmdlen != F_INSN_SIZE(ipfw_insn) &&
4269                             cmdlen != F_INSN_SIZE(ipfw_insn_u32))
4270                                 goto bad_size;
4271                         break;
4272
4273                 case O_MACADDR2:
4274                         if (cmdlen != F_INSN_SIZE(ipfw_insn_mac))
4275                                 goto bad_size;
4276                         break;
4277
4278                 case O_NOP:
4279                 case O_IPID:
4280                 case O_IPTTL:
4281                 case O_IPLEN:
4282                 case O_TCPDATALEN:
4283                 case O_TAGGED:
4284                         if (cmdlen < 1 || cmdlen > 31)
4285                                 goto bad_size;
4286                         break;
4287
4288                 case O_MAC_TYPE:
4289                 case O_IP_SRCPORT:
4290                 case O_IP_DSTPORT: /* XXX artificial limit, 30 port pairs */
4291                         if (cmdlen < 2 || cmdlen > 31)
4292                                 goto bad_size;
4293                         break;
4294
4295                 case O_RECV:
4296                 case O_XMIT:
4297                 case O_VIA:
4298                         if (cmdlen != F_INSN_SIZE(ipfw_insn_if))
4299                                 goto bad_size;
4300                         break;
4301
4302                 case O_ALTQ:
4303                         if (cmdlen != F_INSN_SIZE(ipfw_insn_altq))
4304                                 goto bad_size;
4305                         break;
4306
4307                 case O_PIPE:
4308                 case O_QUEUE:
4309                         if (cmdlen != F_INSN_SIZE(ipfw_insn))
4310                                 goto bad_size;
4311                         goto check_action;
4312
4313                 case O_FORWARD_IP:
4314 #ifdef  IPFIREWALL_FORWARD
4315                         if (cmdlen != F_INSN_SIZE(ipfw_insn_sa))
4316                                 goto bad_size;
4317                         goto check_action;
4318 #else
4319                         return EINVAL;
4320 #endif
4321
4322                 case O_DIVERT:
4323                 case O_TEE:
4324                         if (ip_divert_ptr == NULL)
4325                                 return EINVAL;
4326                         else
4327                                 goto check_size;
4328                 case O_NETGRAPH:
4329                 case O_NGTEE:
4330                         if (!NG_IPFW_LOADED)
4331                                 return EINVAL;
4332                         else
4333                                 goto check_size;
4334                 case O_NAT:
4335                         if (!IPFW_NAT_LOADED)
4336                                 return EINVAL;
4337                         if (cmdlen != F_INSN_SIZE(ipfw_insn_nat))
4338                                 goto bad_size;          
4339                         goto check_action;
4340                 case O_FORWARD_MAC: /* XXX not implemented yet */
4341                 case O_CHECK_STATE:
4342                 case O_COUNT:
4343                 case O_ACCEPT:
4344                 case O_DENY:
4345                 case O_REJECT:
4346 #ifdef INET6
4347                 case O_UNREACH6:
4348 #endif
4349                 case O_SKIPTO:
4350                 case O_REASS:
4351 check_size:
4352                         if (cmdlen != F_INSN_SIZE(ipfw_insn))
4353                                 goto bad_size;
4354 check_action:
4355                         if (have_action) {
4356                                 printf("ipfw: opcode %d, multiple actions"
4357                                         " not allowed\n",
4358                                         cmd->opcode);
4359                                 return EINVAL;
4360                         }
4361                         have_action = 1;
4362                         if (l != cmdlen) {
4363                                 printf("ipfw: opcode %d, action must be"
4364                                         " last opcode\n",
4365                                         cmd->opcode);
4366                                 return EINVAL;
4367                         }
4368                         break;
4369 #ifdef INET6
4370                 case O_IP6_SRC:
4371                 case O_IP6_DST:
4372                         if (cmdlen != F_INSN_SIZE(struct in6_addr) +
4373                             F_INSN_SIZE(ipfw_insn))
4374                                 goto bad_size;
4375                         break;
4376
4377                 case O_FLOW6ID:
4378                         if (cmdlen != F_INSN_SIZE(ipfw_insn_u32) +
4379                             ((ipfw_insn_u32 *)cmd)->o.arg1)
4380                                 goto bad_size;
4381                         break;
4382
4383                 case O_IP6_SRC_MASK:
4384                 case O_IP6_DST_MASK:
4385                         if ( !(cmdlen & 1) || cmdlen > 127)
4386                                 goto bad_size;
4387                         break;
4388                 case O_ICMP6TYPE:
4389                         if( cmdlen != F_INSN_SIZE( ipfw_insn_icmp6 ) )
4390                                 goto bad_size;
4391                         break;
4392 #endif
4393
4394                 default:
4395                         switch (cmd->opcode) {
4396 #ifndef INET6
4397                         case O_IP6_SRC_ME:
4398                         case O_IP6_DST_ME:
4399                         case O_EXT_HDR:
4400                         case O_IP6:
4401                         case O_UNREACH6:
4402                         case O_IP6_SRC:
4403                         case O_IP6_DST:
4404                         case O_FLOW6ID:
4405                         case O_IP6_SRC_MASK:
4406                         case O_IP6_DST_MASK:
4407                         case O_ICMP6TYPE:
4408                                 printf("ipfw: no IPv6 support in kernel\n");
4409                                 return EPROTONOSUPPORT;
4410 #endif
4411                         default:
4412                                 printf("ipfw: opcode %d, unknown opcode\n",
4413                                         cmd->opcode);
4414                                 return EINVAL;
4415                         }
4416                 }
4417         }
4418         if (have_action == 0) {
4419                 printf("ipfw: missing action\n");
4420                 return EINVAL;
4421         }
4422         return 0;
4423
4424 bad_size:
4425         printf("ipfw: opcode %d size %d wrong\n",
4426                 cmd->opcode, cmdlen);
4427         return EINVAL;
4428 }
4429
4430 /*
4431  * Copy the static rules to the supplied buffer
4432  * and return the amount of space actually used.
4433  */
4434 static size_t
4435 ipfw_getrules(struct ip_fw_chain *chain, void *buf, size_t space)
4436 {
4437         char *bp = buf;
4438         char *ep = bp + space;
4439         struct ip_fw *rule;
4440         int i;
4441         time_t  boot_seconds;
4442
4443         boot_seconds = boottime.tv_sec;
4444         /* XXX this can take a long time and locking will block packet flow */
4445         IPFW_RLOCK(chain);
4446         for (rule = chain->rules; rule ; rule = rule->next) {
4447                 /*
4448                  * Verify the entry fits in the buffer in case the
4449                  * rules changed between calculating buffer space and
4450                  * now.  This would be better done using a generation
4451                  * number but should suffice for now.
4452                  */
4453                 i = RULESIZE(rule);
4454                 if (bp + i <= ep) {
4455                         bcopy(rule, bp, i);
4456                         /*
4457                          * XXX HACK. Store the disable mask in the "next"
4458                          * pointer in a wild attempt to keep the ABI the same.
4459                          * Why do we do this on EVERY rule?
4460                          */
4461                         bcopy(&V_set_disable,
4462                             &(((struct ip_fw *)bp)->next_rule),
4463                             sizeof(V_set_disable));
4464                         if (((struct ip_fw *)bp)->timestamp)
4465                                 ((struct ip_fw *)bp)->timestamp += boot_seconds;
4466                         bp += i;
4467                 }
4468         }
4469         IPFW_RUNLOCK(chain);
4470         return (bp - (char *)buf);
4471 }
4472
4473 /*
4474  * Copy the dynamic rules to the supplied buffer
4475  * and return the amount of space actually used.
4476  * XXX marta if we allocate X and rules grows
4477  * we check for size limit while copying rules into the buffer
4478  */
4479 static size_t
4480 ipfw_getdynrules(struct ip_fw_chain *chain, void *buf, size_t space)
4481 {
4482         char *bp = buf;
4483         char *ep = bp + space;
4484         int i;
4485         time_t  boot_seconds;
4486
4487         printf("dynrules requested\n");
4488         boot_seconds = boottime.tv_sec;
4489
4490         if (V_ipfw_dyn_v) {
4491                 ipfw_dyn_rule *p, *last = NULL;
4492
4493                 IPFW_DYN_LOCK();
4494                 for (i = 0 ; i < V_curr_dyn_buckets; i++)
4495                         for (p = V_ipfw_dyn_v[i] ; p != NULL; p = p->next) {
4496                                 if (bp + sizeof *p <= ep) {
4497                                         ipfw_dyn_rule *dst =
4498                                                 (ipfw_dyn_rule *)bp;
4499                                         bcopy(p, dst, sizeof *p);
4500                                         bcopy(&(p->rule->rulenum), &(dst->rule),
4501                                             sizeof(p->rule->rulenum));
4502                                         /*
4503                                          * store set number into high word of
4504                                          * dst->rule pointer.
4505                                          */
4506                                         bcopy(&(p->rule->set),
4507                                             (char *)&dst->rule +
4508                                             sizeof(p->rule->rulenum),
4509                                             sizeof(p->rule->set));
4510                                         /*
4511                                          * store a non-null value in "next".
4512                                          * The userland code will interpret a
4513                                          * NULL here as a marker
4514                                          * for the last dynamic rule.
4515                                          */
4516                                         bcopy(&dst, &dst->next, sizeof(dst));
4517                                         last = dst;
4518                                         dst->expire =
4519                                             TIME_LEQ(dst->expire, time_uptime) ?
4520                                                 0 : dst->expire - time_uptime ;
4521                                         bp += sizeof(ipfw_dyn_rule);
4522                                 } else {
4523                                         p = NULL;       /* break the loop */
4524                                         i = V_curr_dyn_buckets;
4525                                 }
4526                         }
4527                 IPFW_DYN_UNLOCK();
4528                 if (last != NULL) /* mark last dynamic rule */
4529                         bzero(&last->next, sizeof(last));
4530         }
4531
4532         return (bp - (char *)buf);
4533 }
4534
4535
4536 /**
4537  * {set|get}sockopt parser.
4538  */
4539 static int
4540 ipfw_ctl(struct sockopt *sopt)
4541 {
4542 #define RULE_MAXSIZE    (256*sizeof(u_int32_t))
4543         int error;
4544         size_t size;
4545         struct ip_fw *buf, *rule;
4546         u_int32_t rulenum[2];
4547
4548         error = priv_check(sopt->sopt_td, PRIV_NETINET_IPFW);
4549         if (error)
4550                 return (error);
4551
4552         /*
4553          * Disallow modifications in really-really secure mode, but still allow
4554          * the logging counters to be reset.
4555          */
4556         if (sopt->sopt_name == IP_FW_ADD ||
4557             (sopt->sopt_dir == SOPT_SET && sopt->sopt_name != IP_FW_RESETLOG)) {
4558                 error = securelevel_ge(sopt->sopt_td->td_ucred, 3);
4559                 if (error)
4560                         return (error);
4561         }
4562
4563         error = 0;
4564
4565         switch (sopt->sopt_name) {
4566         case IP_FW_GET:
4567                 /*
4568                  * pass up a copy of the current static rules.
4569                  * The last static rule has number IPFW_DEFAULT_RULE.
4570                  *
4571                  * Note that the calculated size is used to bound the
4572                  * amount of data returned to the user.  The rule set may
4573                  * change between calculating the size and returning the
4574                  * data in which case we'll just return what fits.
4575                  */
4576                 size = V_static_len;    /* size of static rules */
4577
4578                 /*
4579                  * XXX todo: if the user passes a short length just to know
4580                  * how much room is needed, do not bother filling up the
4581                  * buffer, just jump to the sooptcopyout.
4582                  */
4583                 buf = malloc(size, M_TEMP, M_WAITOK);
4584                 error = sooptcopyout(sopt, buf,
4585                                 ipfw_getrules(&V_layer3_chain, buf, size));
4586                 free(buf, M_TEMP);
4587                 break;
4588
4589         case IP_FW_DYN_GET:
4590                 /*
4591                  * pass up a copy of the current dynamic rules.
4592                  * The last dynamic rule has NULL in the "next" field.
4593                  */
4594                 /* if (!V_ipfw_dyn_v) XXX check for empty set ? */
4595                 size = (V_dyn_count * sizeof(ipfw_dyn_rule)); /* size of dyn. rules */
4596
4597                 buf = malloc(size, M_TEMP, M_WAITOK);
4598                 error = sooptcopyout(sopt, buf,
4599                                 ipfw_getdynrules(&V_layer3_chain, buf, size));
4600                 free(buf, M_TEMP);
4601                 break;
4602
4603         case IP_FW_FLUSH:
4604                 /*
4605                  * Normally we cannot release the lock on each iteration.
4606                  * We could do it here only because we start from the head all
4607                  * the times so there is no risk of missing some entries.
4608                  * On the other hand, the risk is that we end up with
4609                  * a very inconsistent ruleset, so better keep the lock
4610                  * around the whole cycle.
4611                  *
4612                  * XXX this code can be improved by resetting the head of
4613                  * the list to point to the default rule, and then freeing
4614                  * the old list without the need for a lock.
4615                  */
4616
4617                 IPFW_WLOCK(&V_layer3_chain);
4618                 V_layer3_chain.reap = NULL;
4619                 free_chain(&V_layer3_chain, 0 /* keep default rule */);
4620                 rule = V_layer3_chain.reap;
4621                 V_layer3_chain.reap = NULL;
4622                 IPFW_WUNLOCK(&V_layer3_chain);
4623                 if (rule != NULL)
4624                         reap_rules(rule);
4625                 break;
4626
4627         case IP_FW_ADD:
4628                 rule = malloc(RULE_MAXSIZE, M_TEMP, M_WAITOK);
4629                 error = sooptcopyin(sopt, rule, RULE_MAXSIZE,
4630                         sizeof(struct ip_fw) );
4631                 if (error == 0)
4632                         error = check_ipfw_struct(rule, sopt->sopt_valsize);
4633                 if (error == 0) {
4634                         error = add_rule(&V_layer3_chain, rule);
4635                         size = RULESIZE(rule);
4636                         if (!error && sopt->sopt_dir == SOPT_GET)
4637                                 error = sooptcopyout(sopt, rule, size);
4638                 }
4639                 free(rule, M_TEMP);
4640                 break;
4641
4642         case IP_FW_DEL:
4643                 /*
4644                  * IP_FW_DEL is used for deleting single rules or sets,
4645                  * and (ab)used to atomically manipulate sets. Argument size
4646                  * is used to distinguish between the two:
4647                  *    sizeof(u_int32_t)
4648                  *      delete single rule or set of rules,
4649                  *      or reassign rules (or sets) to a different set.
4650                  *    2*sizeof(u_int32_t)
4651                  *      atomic disable/enable sets.
4652                  *      first u_int32_t contains sets to be disabled,
4653                  *      second u_int32_t contains sets to be enabled.
4654                  */
4655                 error = sooptcopyin(sopt, rulenum,
4656                         2*sizeof(u_int32_t), sizeof(u_int32_t));
4657                 if (error)
4658                         break;
4659                 size = sopt->sopt_valsize;
4660                 if (size == sizeof(u_int32_t))  /* delete or reassign */
4661                         error = del_entry(&V_layer3_chain, rulenum[0]);
4662                 else if (size == 2*sizeof(u_int32_t)) /* set enable/disable */
4663                         V_set_disable =
4664                             (V_set_disable | rulenum[0]) & ~rulenum[1] &
4665                             ~(1<<RESVD_SET); /* set RESVD_SET always enabled */
4666                 else
4667                         error = EINVAL;
4668                 break;
4669
4670         case IP_FW_ZERO:
4671         case IP_FW_RESETLOG: /* argument is an u_int_32, the rule number */
4672                 rulenum[0] = 0;
4673                 if (sopt->sopt_val != 0) {
4674                     error = sooptcopyin(sopt, rulenum,
4675                             sizeof(u_int32_t), sizeof(u_int32_t));
4676                     if (error)
4677                         break;
4678                 }
4679                 error = zero_entry(&V_layer3_chain, rulenum[0],
4680                         sopt->sopt_name == IP_FW_RESETLOG);
4681                 break;
4682
4683         case IP_FW_TABLE_ADD:
4684                 {
4685                         ipfw_table_entry ent;
4686
4687                         error = sooptcopyin(sopt, &ent,
4688                             sizeof(ent), sizeof(ent));
4689                         if (error)
4690                                 break;
4691                         error = add_table_entry(&V_layer3_chain, ent.tbl,
4692                             ent.addr, ent.masklen, ent.value);
4693                 }
4694                 break;
4695
4696         case IP_FW_TABLE_DEL:
4697                 {
4698                         ipfw_table_entry ent;
4699
4700                         error = sooptcopyin(sopt, &ent,
4701                             sizeof(ent), sizeof(ent));
4702                         if (error)
4703                                 break;
4704                         error = del_table_entry(&V_layer3_chain, ent.tbl,
4705                             ent.addr, ent.masklen);
4706                 }
4707                 break;
4708
4709         case IP_FW_TABLE_FLUSH:
4710                 {
4711                         u_int16_t tbl;
4712
4713                         error = sooptcopyin(sopt, &tbl,
4714                             sizeof(tbl), sizeof(tbl));
4715                         if (error)
4716                                 break;
4717                         IPFW_WLOCK(&V_layer3_chain);
4718                         error = flush_table(&V_layer3_chain, tbl);
4719                         IPFW_WUNLOCK(&V_layer3_chain);
4720                 }
4721                 break;
4722
4723         case IP_FW_TABLE_GETSIZE:
4724                 {
4725                         u_int32_t tbl, cnt;
4726
4727                         if ((error = sooptcopyin(sopt, &tbl, sizeof(tbl),
4728                             sizeof(tbl))))
4729                                 break;
4730                         IPFW_RLOCK(&V_layer3_chain);
4731                         error = count_table(&V_layer3_chain, tbl, &cnt);
4732                         IPFW_RUNLOCK(&V_layer3_chain);
4733                         if (error)
4734                                 break;
4735                         error = sooptcopyout(sopt, &cnt, sizeof(cnt));
4736                 }
4737                 break;
4738
4739         case IP_FW_TABLE_LIST:
4740                 {
4741                         ipfw_table *tbl;
4742
4743                         if (sopt->sopt_valsize < sizeof(*tbl)) {
4744                                 error = EINVAL;
4745                                 break;
4746                         }
4747                         size = sopt->sopt_valsize;
4748                         tbl = malloc(size, M_TEMP, M_WAITOK);
4749                         error = sooptcopyin(sopt, tbl, size, sizeof(*tbl));
4750                         if (error) {
4751                                 free(tbl, M_TEMP);
4752                                 break;
4753                         }
4754                         tbl->size = (size - sizeof(*tbl)) /
4755                             sizeof(ipfw_table_entry);
4756                         IPFW_RLOCK(&V_layer3_chain);
4757                         error = dump_table(&V_layer3_chain, tbl);
4758                         IPFW_RUNLOCK(&V_layer3_chain);
4759                         if (error) {
4760                                 free(tbl, M_TEMP);
4761                                 break;
4762                         }
4763                         error = sooptcopyout(sopt, tbl, size);
4764                         free(tbl, M_TEMP);
4765                 }
4766                 break;
4767
4768         case IP_FW_NAT_CFG:
4769                 if (IPFW_NAT_LOADED)
4770                         error = ipfw_nat_cfg_ptr(sopt);
4771                 else {
4772                         printf("IP_FW_NAT_CFG: %s\n",
4773                                 "ipfw_nat not present, please load it");
4774                         error = EINVAL;
4775                 }
4776                 break;
4777
4778         case IP_FW_NAT_DEL:
4779                 if (IPFW_NAT_LOADED)
4780                         error = ipfw_nat_del_ptr(sopt);
4781                 else {
4782                         printf("IP_FW_NAT_DEL: %s\n",
4783                                 "ipfw_nat not present, please load it");
4784                         error = EINVAL;
4785                 }
4786                 break;
4787
4788         case IP_FW_NAT_GET_CONFIG:
4789                 if (IPFW_NAT_LOADED)
4790                         error = ipfw_nat_get_cfg_ptr(sopt);
4791                 else {
4792                         printf("IP_FW_NAT_GET_CFG: %s\n",
4793                                 "ipfw_nat not present, please load it");
4794                         error = EINVAL;
4795                 }
4796                 break;
4797
4798         case IP_FW_NAT_GET_LOG:
4799                 if (IPFW_NAT_LOADED)
4800                         error = ipfw_nat_get_log_ptr(sopt);
4801                 else {
4802                         printf("IP_FW_NAT_GET_LOG: %s\n",
4803                                 "ipfw_nat not present, please load it");
4804                         error = EINVAL;
4805                 }
4806                 break;
4807
4808         default:
4809                 printf("ipfw: ipfw_ctl invalid option %d\n", sopt->sopt_name);
4810                 error = EINVAL;
4811         }
4812
4813         return (error);
4814 #undef RULE_MAXSIZE
4815 }
4816
4817 /**
4818  * dummynet needs a reference to the default rule, because rules can be
4819  * deleted while packets hold a reference to them. When this happens,
4820  * dummynet changes the reference to the default rule (it could well be a
4821  * NULL pointer, but this way we do not need to check for the special
4822  * case, plus here he have info on the default behaviour).
4823  */
4824 struct ip_fw *ip_fw_default_rule;
4825
4826 /*
4827  * This procedure is only used to handle keepalives. It is invoked
4828  * every dyn_keepalive_period
4829  */
4830 static void
4831 ipfw_tick(void * vnetx)
4832 {
4833         struct mbuf *m0, *m, *mnext, **mtailp;
4834 #ifdef INET6
4835         struct mbuf *m6, **m6_tailp;
4836 #endif
4837         int i;
4838         ipfw_dyn_rule *q;
4839 #ifdef VIMAGE
4840         struct vnet *vp = vnetx;
4841 #endif
4842
4843         CURVNET_SET(vp);
4844         if (V_dyn_keepalive == 0 || V_ipfw_dyn_v == NULL || V_dyn_count == 0)
4845                 goto done;
4846
4847         /*
4848          * We make a chain of packets to go out here -- not deferring
4849          * until after we drop the IPFW dynamic rule lock would result
4850          * in a lock order reversal with the normal packet input -> ipfw
4851          * call stack.
4852          */
4853         m0 = NULL;
4854         mtailp = &m0;
4855 #ifdef INET6
4856         m6 = NULL;
4857         m6_tailp = &m6;
4858 #endif
4859         IPFW_DYN_LOCK();
4860         for (i = 0 ; i < V_curr_dyn_buckets ; i++) {
4861                 for (q = V_ipfw_dyn_v[i] ; q ; q = q->next ) {
4862                         if (q->dyn_type == O_LIMIT_PARENT)
4863                                 continue;
4864                         if (q->id.proto != IPPROTO_TCP)
4865                                 continue;
4866                         if ( (q->state & BOTH_SYN) != BOTH_SYN)
4867                                 continue;
4868                         if (TIME_LEQ( time_uptime+V_dyn_keepalive_interval,
4869                             q->expire))
4870                                 continue;       /* too early */
4871                         if (TIME_LEQ(q->expire, time_uptime))
4872                                 continue;       /* too late, rule expired */
4873
4874                         m = send_pkt(NULL, &(q->id), q->ack_rev - 1,
4875                                 q->ack_fwd, TH_SYN);
4876                         mnext = send_pkt(NULL, &(q->id), q->ack_fwd - 1,
4877                                 q->ack_rev, 0);
4878
4879                         switch (q->id.addr_type) {
4880                         case 4:
4881                                 if (m != NULL) {
4882                                         *mtailp = m;
4883                                         mtailp = &(*mtailp)->m_nextpkt;
4884                                 }
4885                                 if (mnext != NULL) {
4886                                         *mtailp = mnext;
4887                                         mtailp = &(*mtailp)->m_nextpkt;
4888                                 }
4889                                 break;
4890 #ifdef INET6
4891                         case 6:
4892                                 if (m != NULL) {
4893                                         *m6_tailp = m;
4894                                         m6_tailp = &(*m6_tailp)->m_nextpkt;
4895                                 }
4896                                 if (mnext != NULL) {
4897                                         *m6_tailp = mnext;
4898                                         m6_tailp = &(*m6_tailp)->m_nextpkt;
4899                                 }
4900                                 break;
4901 #endif
4902                         }
4903
4904                         m = mnext = NULL;
4905                 }
4906         }
4907         IPFW_DYN_UNLOCK();
4908         for (m = mnext = m0; m != NULL; m = mnext) {
4909                 mnext = m->m_nextpkt;
4910                 m->m_nextpkt = NULL;
4911                 ip_output(m, NULL, NULL, 0, NULL, NULL);
4912         }
4913 #ifdef INET6
4914         for (m = mnext = m6; m != NULL; m = mnext) {
4915                 mnext = m->m_nextpkt;
4916                 m->m_nextpkt = NULL;
4917                 ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL);
4918         }
4919 #endif
4920 done:
4921         callout_reset(&V_ipfw_timeout, V_dyn_keepalive_period*hz,
4922                 ipfw_tick, NULL);
4923         CURVNET_RESTORE();
4924 }
4925
4926 static int vnet_ipfw_init(const void *);
4927
4928 int
4929 ipfw_init(void)
4930 {
4931         int error = 0;
4932
4933         ipfw_dyn_rule_zone = uma_zcreate("IPFW dynamic rule",
4934             sizeof(ipfw_dyn_rule), NULL, NULL, NULL, NULL,
4935             UMA_ALIGN_PTR, 0);
4936
4937         IPFW_DYN_LOCK_INIT();
4938         error = vnet_ipfw_init(NULL);
4939         if (error) {
4940                 IPFW_DYN_LOCK_DESTROY();
4941                 IPFW_LOCK_DESTROY(&V_layer3_chain);
4942                 uma_zdestroy(ipfw_dyn_rule_zone);
4943                 return (error);
4944         }
4945
4946         /*
4947          * Only print out this stuff the first time around,
4948          * when called from the sysinit code.
4949          */
4950         printf("ipfw2 "
4951 #ifdef INET6
4952                 "(+ipv6) "
4953 #endif
4954                 "initialized, divert %s, nat %s, "
4955                 "rule-based forwarding "
4956 #ifdef IPFIREWALL_FORWARD
4957                 "enabled, "
4958 #else
4959                 "disabled, "
4960 #endif
4961                 "default to %s, logging ",
4962 #ifdef IPDIVERT
4963                 "enabled",
4964 #else
4965                 "loadable",
4966 #endif
4967 #ifdef IPFIREWALL_NAT
4968                 "enabled",
4969 #else
4970                 "loadable",
4971 #endif
4972                 default_to_accept ? "accept" : "deny");
4973
4974         /*
4975          * Note: V_xxx variables can be accessed here but the vnet specific
4976          * initializer may not have been called yet for the VIMAGE case.
4977          * Tuneables will have been processed. We will print out values for
4978          * the default vnet.
4979          * XXX This should all be rationalized AFTER 8.0
4980          */
4981         if (V_fw_verbose == 0)
4982                 printf("disabled\n");
4983         else if (V_verbose_limit == 0)
4984                 printf("unlimited\n");
4985         else
4986                 printf("limited to %d packets/entry by default\n",
4987                     V_verbose_limit);
4988
4989         return (error);
4990 }
4991
4992 void
4993 ipfw_destroy(void)
4994 {
4995         struct ip_fw *reap;
4996
4997         ip_fw_chk_ptr = NULL;
4998         ip_fw_ctl_ptr = NULL;
4999         callout_drain(&ipfw_timeout);
5000         IPFW_WLOCK(&V_layer3_chain);
5001         flush_tables(&V_layer3_chain);
5002         V_layer3_chain.reap = NULL;