]> git.saurik.com Git - apple/xnu.git/blob - bsd/netinet/ip_fw2.c
xnu-4570.1.46.tar.gz
[apple/xnu.git] / bsd / netinet / ip_fw2.c
1 /*
2 * Copyright (c) 2004-2016 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29 /*
30 * Copyright (c) 2002 Luigi Rizzo, Universita` di Pisa
31 *
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
34 * are met:
35 * 1. Redistributions of source code must retain the above copyright
36 * notice, this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright
38 * notice, this list of conditions and the following disclaimer in the
39 * documentation and/or other materials provided with the distribution.
40 *
41 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * $FreeBSD: src/sys/netinet/ip_fw2.c,v 1.6.2.18 2003/10/17 11:01:03 scottl Exp $
54 */
55
56 #define DEB(x)
57 #define DDB(x) x
58
59 /*
60 * Implement IP packet firewall (new version)
61 */
62
63 #ifndef INET
64 #error IPFIREWALL requires INET.
65 #endif /* INET */
66
67 #if IPFW2
68
69 #include <sys/param.h>
70 #include <sys/systm.h>
71 #include <sys/malloc.h>
72 #include <sys/mbuf.h>
73 #include <sys/mcache.h>
74 #include <sys/kernel.h>
75 #include <sys/proc.h>
76 #include <sys/socket.h>
77 #include <sys/socketvar.h>
78 #include <sys/sysctl.h>
79 #include <sys/syslog.h>
80 #include <sys/ucred.h>
81 #include <sys/kern_event.h>
82 #include <sys/kauth.h>
83
84 #include <net/if.h>
85 #include <net/net_kev.h>
86 #include <net/route.h>
87 #include <netinet/in.h>
88 #include <netinet/in_systm.h>
89 #include <netinet/in_var.h>
90 #include <netinet/in_pcb.h>
91 #include <netinet/ip.h>
92 #include <netinet/ip_var.h>
93 #include <netinet/ip_icmp.h>
94 #include <netinet/ip_fw.h>
95 #include <netinet/ip_divert.h>
96
97 #if DUMMYNET
98 #include <netinet/ip_dummynet.h>
99 #endif /* DUMMYNET */
100
101 #include <netinet/tcp.h>
102 #include <netinet/tcp_timer.h>
103 #include <netinet/tcp_var.h>
104 #include <netinet/tcpip.h>
105 #include <netinet/udp.h>
106 #include <netinet/udp_var.h>
107
108 #ifdef IPSEC
109 #include <netinet6/ipsec.h>
110 #endif
111
112 #include <netinet/if_ether.h> /* XXX for ETHERTYPE_IP */
113
114 #include "ip_fw2_compat.h"
115
116 #include <sys/kern_event.h>
117 #include <stdarg.h>
118
119 /*
120 #include <machine/in_cksum.h>
121 */ /* XXX for in_cksum */
122
123 /*
124 * XXX This one should go in sys/mbuf.h. It is used to avoid that
125 * a firewall-generated packet loops forever through the firewall.
126 */
127 #ifndef M_SKIP_FIREWALL
128 #define M_SKIP_FIREWALL 0x4000
129 #endif
130
131 /*
132 * set_disable contains one bit per set value (0..31).
133 * If the bit is set, all rules with the corresponding set
134 * are disabled. Set RESVD_SET(31) is reserved for the default rule
135 * and rules that are not deleted by the flush command,
136 * and CANNOT be disabled.
137 * Rules in set RESVD_SET can only be deleted explicitly.
138 */
139 static u_int32_t set_disable;
140
141 int fw_verbose;
142 static int verbose_limit;
143 extern int fw_bypass;
144
145 #define IPFW_RULE_INACTIVE 1
146
147 /*
148 * list of rules for layer 3
149 */
150 static struct ip_fw *layer3_chain;
151
152 MALLOC_DEFINE(M_IPFW, "IpFw/IpAcct", "IpFw/IpAcct chain's");
153
154 static int fw_debug = 0;
155 static int autoinc_step = 100; /* bounded to 1..1000 in add_rule() */
156
157 static void ipfw_kev_post_msg(u_int32_t );
158
159 static int Get32static_len(void);
160 static int Get64static_len(void);
161
162 #ifdef SYSCTL_NODE
163
164 static int ipfw_sysctl SYSCTL_HANDLER_ARGS;
165
166 SYSCTL_NODE(_net_inet_ip, OID_AUTO, fw, CTLFLAG_RW|CTLFLAG_LOCKED, 0, "Firewall");
167 SYSCTL_PROC(_net_inet_ip_fw, OID_AUTO, enable,
168 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
169 &fw_enable, 0, ipfw_sysctl, "I", "Enable ipfw");
170 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, autoinc_step, CTLFLAG_RW | CTLFLAG_LOCKED,
171 &autoinc_step, 0, "Rule number autincrement step");
172 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, one_pass,
173 CTLFLAG_RW | CTLFLAG_LOCKED,
174 &fw_one_pass, 0,
175 "Only do a single pass through ipfw when using dummynet(4)");
176 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, debug,
177 CTLFLAG_RW | CTLFLAG_LOCKED,
178 &fw_debug, 0, "Enable printing of debug ip_fw statements");
179 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, verbose,
180 CTLFLAG_RW | CTLFLAG_LOCKED,
181 &fw_verbose, 0, "Log matches to ipfw rules");
182 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, verbose_limit, CTLFLAG_RW | CTLFLAG_LOCKED,
183 &verbose_limit, 0, "Set upper limit of matches of ipfw rules logged");
184
185 /*
186 * IP FW Stealth Logging:
187 */
188 typedef enum ipfw_stealth_stats_type {
189 IPFW_STEALTH_STATS_UDP,
190 IPFW_STEALTH_STATS_TCP,
191 IPFW_STEALTH_STATS_UDPv6,
192 IPFW_STEALTH_STATS_TCPv6,
193 IPFW_STEALTH_STATS_MAX,
194 } ipfw_stealth_stats_type_t;
195
196 #define IPFW_STEALTH_TIMEOUT_SEC 30
197
198 #define DYN_KEEPALIVE_LEEWAY 15
199
200 // Piggybagging Stealth stats with ipfw_tick().
201 #define IPFW_STEALTH_TIMEOUT_FREQUENCY (30 / dyn_keepalive_period)
202
203 static const char* ipfw_stealth_stats_str [IPFW_STEALTH_STATS_MAX] = {
204 "UDP", "TCP", "UDP v6", "TCP v6",
205 };
206
207 static uint32_t ipfw_stealth_stats_needs_flush = FALSE;
208 static uint32_t ipfw_stealth_stats[IPFW_STEALTH_STATS_MAX];
209
210 static void ipfw_stealth_flush_stats(void);
211 void ipfw_stealth_stats_incr_udp(void);
212 void ipfw_stealth_stats_incr_tcp(void);
213 void ipfw_stealth_stats_incr_udpv6(void);
214 void ipfw_stealth_stats_incr_tcpv6(void);
215
216 /*
217 * Description of dynamic rules.
218 *
219 * Dynamic rules are stored in lists accessed through a hash table
220 * (ipfw_dyn_v) whose size is curr_dyn_buckets. This value can
221 * be modified through the sysctl variable dyn_buckets which is
222 * updated when the table becomes empty.
223 *
224 * XXX currently there is only one list, ipfw_dyn.
225 *
226 * When a packet is received, its address fields are first masked
227 * with the mask defined for the rule, then hashed, then matched
228 * against the entries in the corresponding list.
229 * Dynamic rules can be used for different purposes:
230 * + stateful rules;
231 * + enforcing limits on the number of sessions;
232 * + in-kernel NAT (not implemented yet)
233 *
234 * The lifetime of dynamic rules is regulated by dyn_*_lifetime,
235 * measured in seconds and depending on the flags.
236 *
237 * The total number of dynamic rules is stored in dyn_count.
238 * The max number of dynamic rules is dyn_max. When we reach
239 * the maximum number of rules we do not create anymore. This is
240 * done to avoid consuming too much memory, but also too much
241 * time when searching on each packet (ideally, we should try instead
242 * to put a limit on the length of the list on each bucket...).
243 *
244 * Each dynamic rule holds a pointer to the parent ipfw rule so
245 * we know what action to perform. Dynamic rules are removed when
246 * the parent rule is deleted. XXX we should make them survive.
247 *
248 * There are some limitations with dynamic rules -- we do not
249 * obey the 'randomized match', and we do not do multiple
250 * passes through the firewall. XXX check the latter!!!
251 */
252 static ipfw_dyn_rule **ipfw_dyn_v = NULL;
253 static u_int32_t dyn_buckets = 256; /* must be power of 2 */
254 static u_int32_t curr_dyn_buckets = 256; /* must be power of 2 */
255
256 /*
257 * Timeouts for various events in handing dynamic rules.
258 */
259 static u_int32_t dyn_ack_lifetime = 300;
260 static u_int32_t dyn_syn_lifetime = 20;
261 static u_int32_t dyn_fin_lifetime = 1;
262 static u_int32_t dyn_rst_lifetime = 1;
263 static u_int32_t dyn_udp_lifetime = 10;
264 static u_int32_t dyn_short_lifetime = 5;
265
266 /*
267 * Keepalives are sent if dyn_keepalive is set. They are sent every
268 * dyn_keepalive_period seconds, in the last dyn_keepalive_interval
269 * seconds of lifetime of a rule.
270 * dyn_rst_lifetime and dyn_fin_lifetime should be strictly lower
271 * than dyn_keepalive_period.
272 */
273
274 static u_int32_t dyn_keepalive_interval = 25;
275 static u_int32_t dyn_keepalive_period = 5;
276 static u_int32_t dyn_keepalive = 1; /* do send keepalives */
277
278 static u_int32_t static_count; /* # of static rules */
279 static u_int32_t static_len; /* size in bytes of static rules */
280 static u_int32_t static_len_32; /* size in bytes of static rules for 32 bit client */
281 static u_int32_t static_len_64; /* size in bytes of static rules for 64 bit client */
282 static u_int32_t dyn_count; /* # of dynamic rules */
283 static u_int32_t dyn_max = 4096; /* max # of dynamic rules */
284
285 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_buckets, CTLFLAG_RW | CTLFLAG_LOCKED,
286 &dyn_buckets, 0, "Number of dyn. buckets");
287 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, curr_dyn_buckets, CTLFLAG_RD | CTLFLAG_LOCKED,
288 &curr_dyn_buckets, 0, "Current Number of dyn. buckets");
289 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_count, CTLFLAG_RD | CTLFLAG_LOCKED,
290 &dyn_count, 0, "Number of dyn. rules");
291 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_max, CTLFLAG_RW | CTLFLAG_LOCKED,
292 &dyn_max, 0, "Max number of dyn. rules");
293 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, static_count, CTLFLAG_RD | CTLFLAG_LOCKED,
294 &static_count, 0, "Number of static rules");
295 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_ack_lifetime, CTLFLAG_RW | CTLFLAG_LOCKED,
296 &dyn_ack_lifetime, 0, "Lifetime of dyn. rules for acks");
297 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_syn_lifetime, CTLFLAG_RW | CTLFLAG_LOCKED,
298 &dyn_syn_lifetime, 0, "Lifetime of dyn. rules for syn");
299 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_fin_lifetime, CTLFLAG_RW | CTLFLAG_LOCKED,
300 &dyn_fin_lifetime, 0, "Lifetime of dyn. rules for fin");
301 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_rst_lifetime, CTLFLAG_RW | CTLFLAG_LOCKED,
302 &dyn_rst_lifetime, 0, "Lifetime of dyn. rules for rst");
303 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_udp_lifetime, CTLFLAG_RW | CTLFLAG_LOCKED,
304 &dyn_udp_lifetime, 0, "Lifetime of dyn. rules for UDP");
305 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_short_lifetime, CTLFLAG_RW | CTLFLAG_LOCKED,
306 &dyn_short_lifetime, 0, "Lifetime of dyn. rules for other situations");
307 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_keepalive, CTLFLAG_RW | CTLFLAG_LOCKED,
308 &dyn_keepalive, 0, "Enable keepalives for dyn. rules");
309
310
311 static int
312 ipfw_sysctl SYSCTL_HANDLER_ARGS
313 {
314 #pragma unused(arg1, arg2)
315 int error;
316
317 error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req);
318 if (error || !req->newptr)
319 return (error);
320
321 ipfw_kev_post_msg(KEV_IPFW_ENABLE);
322
323 return error;
324 }
325
326 #endif /* SYSCTL_NODE */
327
328
329 static ip_fw_chk_t ipfw_chk;
330
331 /* firewall lock */
332 lck_grp_t *ipfw_mutex_grp;
333 lck_grp_attr_t *ipfw_mutex_grp_attr;
334 lck_attr_t *ipfw_mutex_attr;
335 decl_lck_mtx_data(,ipfw_mutex_data);
336 lck_mtx_t *ipfw_mutex = &ipfw_mutex_data;
337
338 extern void ipfwsyslog( int level, const char *format,...);
339
340 #define ipfwstring "ipfw:"
341 static size_t ipfwstringlen;
342
343 #define dolog( a ) { \
344 if ( fw_verbose == 2 ) /* Apple logging, log to ipfw.log */ \
345 ipfwsyslog a ; \
346 else log a ; \
347 }
348
349 #define RULESIZE64(rule) (sizeof(struct ip_fw_64) + \
350 ((struct ip_fw *)(rule))->cmd_len * 4 - 4)
351
352 #define RULESIZE32(rule) (sizeof(struct ip_fw_32) + \
353 ((struct ip_fw *)(rule))->cmd_len * 4 - 4)
354
355 void ipfwsyslog( int level, const char *format,...)
356 {
357 #define msgsize 100
358
359 struct kev_msg ev_msg;
360 va_list ap;
361 char msgBuf[msgsize];
362 char *dptr = msgBuf;
363 unsigned char pri;
364 int loglen;
365
366 bzero(msgBuf, msgsize);
367 bzero(&ev_msg, sizeof(struct kev_msg));
368 va_start( ap, format );
369 loglen = vsnprintf(msgBuf, msgsize, format, ap);
370 va_end( ap );
371
372 ev_msg.vendor_code = KEV_VENDOR_APPLE;
373 ev_msg.kev_class = KEV_NETWORK_CLASS;
374 ev_msg.kev_subclass = KEV_LOG_SUBCLASS;
375 ev_msg.event_code = IPFWLOGEVENT;
376
377 /* get rid of the trailing \n */
378 if (loglen < msgsize)
379 dptr[loglen-1] = 0;
380 else
381 dptr[msgsize-1] = 0;
382
383 pri = LOG_PRI(level);
384
385 /* remove "ipfw:" prefix if logging to ipfw log */
386 if ( !(strncmp( ipfwstring, msgBuf, ipfwstringlen))){
387 dptr = msgBuf+ipfwstringlen;
388 }
389
390 ev_msg.dv[0].data_ptr = &pri;
391 ev_msg.dv[0].data_length = 1;
392 ev_msg.dv[1].data_ptr = dptr;
393 ev_msg.dv[1].data_length = 100; /* bug in kern_post_msg, it can't handle size > 256-msghdr */
394 ev_msg.dv[2].data_length = 0;
395
396 kev_post_msg(&ev_msg);
397 }
398
399 static inline void ipfw_stealth_stats_incr(uint32_t type)
400 {
401 if (type >= IPFW_STEALTH_STATS_MAX)
402 return;
403
404 ipfw_stealth_stats[type]++;
405
406 if (!ipfw_stealth_stats_needs_flush) {
407 ipfw_stealth_stats_needs_flush = TRUE;
408 }
409 }
410
411 void ipfw_stealth_stats_incr_udp(void)
412 {
413 ipfw_stealth_stats_incr(IPFW_STEALTH_STATS_UDP);
414 }
415
416 void ipfw_stealth_stats_incr_tcp(void)
417 {
418 ipfw_stealth_stats_incr(IPFW_STEALTH_STATS_TCP);
419 }
420
421 void ipfw_stealth_stats_incr_udpv6(void)
422 {
423 ipfw_stealth_stats_incr(IPFW_STEALTH_STATS_UDPv6);
424 }
425
426 void ipfw_stealth_stats_incr_tcpv6(void)
427 {
428 ipfw_stealth_stats_incr(IPFW_STEALTH_STATS_TCPv6);
429 }
430
431 static void ipfw_stealth_flush_stats(void)
432 {
433 int i;
434
435 for (i = 0; i < IPFW_STEALTH_STATS_MAX; i++) {
436 if (ipfw_stealth_stats[i]) {
437 ipfwsyslog (LOG_INFO, "Stealth Mode connection attempt to %s %d times",
438 ipfw_stealth_stats_str[i], ipfw_stealth_stats[i]);
439 ipfw_stealth_stats[i] = 0;
440 }
441 }
442 ipfw_stealth_stats_needs_flush = FALSE;
443 }
444
445 /*
446 * This macro maps an ip pointer into a layer3 header pointer of type T
447 */
448 #define L3HDR(T, ip) ((T *)((u_int32_t *)(ip) + (ip)->ip_hl))
449
450 static __inline int
451 icmptype_match(struct ip *ip, ipfw_insn_u32 *cmd)
452 {
453 int type = L3HDR(struct icmp,ip)->icmp_type;
454
455 return (type <= ICMP_MAXTYPE && (cmd->d[0] & (1<<type)) );
456 }
457
458 #define TT ( (1 << ICMP_ECHO) | (1 << ICMP_ROUTERSOLICIT) | \
459 (1 << ICMP_TSTAMP) | (1 << ICMP_IREQ) | (1 << ICMP_MASKREQ) )
460
461 static int
462 is_icmp_query(struct ip *ip)
463 {
464 int type = L3HDR(struct icmp, ip)->icmp_type;
465 return (type <= ICMP_MAXTYPE && (TT & (1<<type)) );
466 }
467 #undef TT
468
469 static int
470 Get32static_len(void)
471 {
472 int diff;
473 int len = static_len_32;
474 struct ip_fw *rule;
475 char *useraction;
476
477 for (rule = layer3_chain; rule ; rule = rule->next) {
478 if (rule->reserved_1 == IPFW_RULE_INACTIVE) {
479 continue;
480 }
481 if ( rule->act_ofs ){
482 useraction = (char*)ACTION_PTR( rule );
483 if ( ((ipfw_insn*)useraction)->opcode == O_QUEUE || ((ipfw_insn*)useraction)->opcode == O_PIPE){
484 diff = sizeof(ipfw_insn_pipe) - sizeof(ipfw_insn_pipe_32);
485 if (diff)
486 len -= diff;
487 }
488 }
489 }
490 return len;
491 }
492
493 static int
494 Get64static_len(void)
495 {
496 int diff;
497 int len = static_len_64;
498 struct ip_fw *rule;
499 char *useraction;
500
501 for (rule = layer3_chain; rule ; rule = rule->next) {
502 if (rule->reserved_1 == IPFW_RULE_INACTIVE) {
503 continue;
504 }
505 if ( rule->act_ofs ){
506 useraction = (char *)ACTION_PTR( rule );
507 if ( ((ipfw_insn*)useraction)->opcode == O_QUEUE || ((ipfw_insn*)useraction)->opcode == O_PIPE){
508 diff = sizeof(ipfw_insn_pipe_64) - sizeof(ipfw_insn_pipe);
509 if (diff)
510 len += diff;
511 }
512 }
513 }
514 return len;
515 }
516
517 static void
518 copyto32fw_insn( struct ip_fw_32 *fw32 , struct ip_fw *user_ip_fw, int cmdsize)
519 {
520 char *end;
521 char *fw32action;
522 char *useraction;
523 int justcmdsize;
524 int diff=0;
525 int actioncopysize;
526
527 end = ((char*)user_ip_fw->cmd) + cmdsize;
528 useraction = (char*)ACTION_PTR( user_ip_fw );
529 fw32action = (char*)fw32->cmd + (user_ip_fw->act_ofs * sizeof(uint32_t));
530 if ( ( justcmdsize = ( fw32action - (char*)fw32->cmd)))
531 bcopy( user_ip_fw->cmd, fw32->cmd, justcmdsize);
532 while ( useraction < end ){
533 if ( ((ipfw_insn*)useraction)->opcode == O_QUEUE || ((ipfw_insn*)useraction)->opcode == O_PIPE){
534 actioncopysize = sizeof(ipfw_insn_pipe_32);
535 ((ipfw_insn*)fw32action)->opcode = ((ipfw_insn*)useraction)->opcode;
536 ((ipfw_insn*)fw32action)->arg1 = ((ipfw_insn*)useraction)->arg1;
537 ((ipfw_insn*)fw32action)->len = F_INSN_SIZE(ipfw_insn_pipe_32);
538 diff = ((ipfw_insn*)useraction)->len - ((ipfw_insn*)fw32action)->len;
539 if ( diff ){
540 fw32->cmd_len -= diff;
541 }
542 } else{
543 actioncopysize = (F_LEN((ipfw_insn*)useraction) ? (F_LEN((ipfw_insn*)useraction)) : 1 ) * sizeof(uint32_t);
544 bcopy( useraction, fw32action, actioncopysize );
545 }
546 useraction += (F_LEN((ipfw_insn*)useraction) ? (F_LEN((ipfw_insn*)useraction)) : 1 ) * sizeof(uint32_t);
547 fw32action += actioncopysize;
548 }
549 }
550
551 static void
552 copyto64fw_insn( struct ip_fw_64 *fw64 , struct ip_fw *user_ip_fw, int cmdsize)
553 {
554 char *end;
555 char *fw64action;
556 char *useraction;
557 int justcmdsize;
558 int diff;
559 int actioncopysize;
560
561 end = ((char *)user_ip_fw->cmd) + cmdsize;
562 useraction = (char*)ACTION_PTR( user_ip_fw );
563 if ( (justcmdsize = (useraction - (char*)user_ip_fw->cmd)))
564 bcopy( user_ip_fw->cmd, fw64->cmd, justcmdsize);
565 fw64action = (char*)fw64->cmd + justcmdsize;
566 while ( useraction < end ){
567 if ( ((ipfw_insn*)user_ip_fw)->opcode == O_QUEUE || ((ipfw_insn*)user_ip_fw)->opcode == O_PIPE){
568 actioncopysize = sizeof(ipfw_insn_pipe_64);
569 ((ipfw_insn*)fw64action)->opcode = ((ipfw_insn*)useraction)->opcode;
570 ((ipfw_insn*)fw64action)->arg1 = ((ipfw_insn*)useraction)->arg1;
571 ((ipfw_insn*)fw64action)->len = F_INSN_SIZE(ipfw_insn_pipe_64);
572 diff = ((ipfw_insn*)fw64action)->len - ((ipfw_insn*)useraction)->len;
573 if (diff)
574 fw64->cmd_len += diff;
575
576 } else{
577 actioncopysize = (F_LEN((ipfw_insn*)useraction) ? (F_LEN((ipfw_insn*)useraction)) : 1 ) * sizeof(uint32_t);
578 bcopy( useraction, fw64action, actioncopysize );
579 }
580 useraction += (F_LEN((ipfw_insn*)useraction) ? (F_LEN((ipfw_insn*)useraction)) : 1 ) * sizeof(uint32_t);
581 fw64action += actioncopysize;
582 }
583 }
584
585 static void
586 copyto32fw( struct ip_fw *user_ip_fw, struct ip_fw_32 *fw32 , __unused size_t copysize)
587 {
588 size_t rulesize, cmdsize;
589
590 fw32->version = user_ip_fw->version;
591 fw32->context = CAST_DOWN_EXPLICIT( user32_addr_t, user_ip_fw->context);
592 fw32->next = CAST_DOWN_EXPLICIT(user32_addr_t, user_ip_fw->next);
593 fw32->next_rule = CAST_DOWN_EXPLICIT(user32_addr_t, user_ip_fw->next_rule);
594 fw32->act_ofs = user_ip_fw->act_ofs;
595 fw32->cmd_len = user_ip_fw->cmd_len;
596 fw32->rulenum = user_ip_fw->rulenum;
597 fw32->set = user_ip_fw->set;
598 fw32->set_masks[0] = user_ip_fw->set_masks[0];
599 fw32->set_masks[1] = user_ip_fw->set_masks[1];
600 fw32->pcnt = user_ip_fw->pcnt;
601 fw32->bcnt = user_ip_fw->bcnt;
602 fw32->timestamp = user_ip_fw->timestamp;
603 fw32->reserved_1 = user_ip_fw->reserved_1;
604 fw32->reserved_2 = user_ip_fw->reserved_2;
605 rulesize = sizeof(struct ip_fw_32) + (user_ip_fw->cmd_len * sizeof(ipfw_insn) - 4);
606 cmdsize = user_ip_fw->cmd_len * sizeof(u_int32_t);
607 copyto32fw_insn( fw32, user_ip_fw, cmdsize );
608 }
609
610 static void
611 copyto64fw( struct ip_fw *user_ip_fw, struct ip_fw_64 *fw64, size_t copysize)
612 {
613 size_t rulesize, cmdsize;
614
615 fw64->version = user_ip_fw->version;
616 fw64->context = CAST_DOWN_EXPLICIT(__uint64_t, user_ip_fw->context);
617 fw64->next = CAST_DOWN_EXPLICIT(user64_addr_t, user_ip_fw->next);
618 fw64->next_rule = CAST_DOWN_EXPLICIT(user64_addr_t, user_ip_fw->next_rule);
619 fw64->act_ofs = user_ip_fw->act_ofs;
620 fw64->cmd_len = user_ip_fw->cmd_len;
621 fw64->rulenum = user_ip_fw->rulenum;
622 fw64->set = user_ip_fw->set;
623 fw64->set_masks[0] = user_ip_fw->set_masks[0];
624 fw64->set_masks[1] = user_ip_fw->set_masks[1];
625 fw64->pcnt = user_ip_fw->pcnt;
626 fw64->bcnt = user_ip_fw->bcnt;
627 fw64->timestamp = user_ip_fw->timestamp;
628 fw64->reserved_1 = user_ip_fw->reserved_1;
629 fw64->reserved_2 = user_ip_fw->reserved_2;
630 rulesize = sizeof(struct ip_fw_64) + (user_ip_fw->cmd_len * sizeof(ipfw_insn) - 4);
631 if (rulesize > copysize)
632 cmdsize = copysize - sizeof(struct ip_fw_64) + 4;
633 else
634 cmdsize = user_ip_fw->cmd_len * sizeof(u_int32_t);
635 copyto64fw_insn( fw64, user_ip_fw, cmdsize);
636 }
637
638 static int
639 copyfrom32fw_insn( struct ip_fw_32 *fw32 , struct ip_fw *user_ip_fw, int cmdsize)
640 {
641 char *end;
642 char *fw32action;
643 char *useraction;
644 int justcmdsize;
645 int diff;
646 int actioncopysize;
647
648 end = ((char*)fw32->cmd) + cmdsize;
649 fw32action = (char*)ACTION_PTR( fw32 );
650 if ((justcmdsize = (fw32action - (char*)fw32->cmd)))
651 bcopy( fw32->cmd, user_ip_fw->cmd, justcmdsize);
652 useraction = (char*)user_ip_fw->cmd + justcmdsize;
653 while ( fw32action < end ){
654 if ( ((ipfw_insn*)fw32action)->opcode == O_QUEUE || ((ipfw_insn*)fw32action)->opcode == O_PIPE){
655 actioncopysize = sizeof(ipfw_insn_pipe);
656 ((ipfw_insn*)useraction)->opcode = ((ipfw_insn*)fw32action)->opcode;
657 ((ipfw_insn*)useraction)->arg1 = ((ipfw_insn*)fw32action)->arg1;
658 ((ipfw_insn*)useraction)->len = F_INSN_SIZE(ipfw_insn_pipe);
659 diff = ((ipfw_insn*)useraction)->len - ((ipfw_insn*)fw32action)->len;
660 if (diff){
661 /* readjust the cmd_len */
662 user_ip_fw->cmd_len += diff;
663 }
664 } else{
665 actioncopysize = (F_LEN((ipfw_insn*)fw32action) ? (F_LEN((ipfw_insn*)fw32action)) : 1 ) * sizeof(uint32_t);
666 bcopy( fw32action, useraction, actioncopysize );
667 }
668 fw32action += (F_LEN((ipfw_insn*)fw32action) ? (F_LEN((ipfw_insn*)fw32action)) : 1 ) * sizeof(uint32_t);
669 useraction += actioncopysize;
670 }
671
672 return( useraction - (char*)user_ip_fw->cmd );
673 }
674
675 static int
676 copyfrom64fw_insn( struct ip_fw_64 *fw64 , struct ip_fw *user_ip_fw, int cmdsize)
677 {
678 char *end;
679 char *fw64action;
680 char *useraction;
681 int justcmdsize;
682 int diff;
683 int actioncopysize;
684
685 end = ((char *)fw64->cmd) + cmdsize ;
686 fw64action = (char*)ACTION_PTR( fw64 );
687 if ( (justcmdsize = (fw64action - (char*)fw64->cmd)))
688 bcopy( fw64->cmd, user_ip_fw->cmd, justcmdsize);
689 useraction = (char*)user_ip_fw->cmd + justcmdsize;
690 while ( fw64action < end ){
691 if ( ((ipfw_insn*)fw64action)->opcode == O_QUEUE || ((ipfw_insn*)fw64action)->opcode == O_PIPE){
692 actioncopysize = sizeof(ipfw_insn_pipe);
693 ((ipfw_insn*)useraction)->opcode = ((ipfw_insn*)fw64action)->opcode;
694 ((ipfw_insn*)useraction)->arg1 = ((ipfw_insn*)fw64action)->arg1;
695 ((ipfw_insn*)useraction)->len = F_INSN_SIZE(ipfw_insn_pipe);
696 diff = ((ipfw_insn*)fw64action)->len - ((ipfw_insn*)useraction)->len;
697 if (diff) {
698 /* readjust the cmd_len */
699 user_ip_fw->cmd_len -= diff;
700 }
701 } else{
702 actioncopysize = (F_LEN((ipfw_insn*)fw64action) ? (F_LEN((ipfw_insn*)fw64action)) : 1 ) * sizeof(uint32_t);
703 bcopy( fw64action, useraction, actioncopysize );
704 }
705 fw64action += (F_LEN((ipfw_insn*)fw64action) ? (F_LEN((ipfw_insn*)fw64action)) : 1 ) * sizeof(uint32_t);
706 useraction += actioncopysize;
707 }
708 return( useraction - (char*)user_ip_fw->cmd );
709 }
710
711 static size_t
712 copyfrom32fw( struct ip_fw_32 *fw32, struct ip_fw *user_ip_fw, size_t copysize)
713 {
714 size_t rulesize, cmdsize;
715
716 user_ip_fw->version = fw32->version;
717 user_ip_fw->context = CAST_DOWN(void *, fw32->context);
718 user_ip_fw->next = CAST_DOWN(struct ip_fw*, fw32->next);
719 user_ip_fw->next_rule = CAST_DOWN_EXPLICIT(struct ip_fw*, fw32->next_rule);
720 user_ip_fw->act_ofs = fw32->act_ofs;
721 user_ip_fw->cmd_len = fw32->cmd_len;
722 user_ip_fw->rulenum = fw32->rulenum;
723 user_ip_fw->set = fw32->set;
724 user_ip_fw->set_masks[0] = fw32->set_masks[0];
725 user_ip_fw->set_masks[1] = fw32->set_masks[1];
726 user_ip_fw->pcnt = fw32->pcnt;
727 user_ip_fw->bcnt = fw32->bcnt;
728 user_ip_fw->timestamp = fw32->timestamp;
729 user_ip_fw->reserved_1 = fw32->reserved_1;
730 user_ip_fw->reserved_2 = fw32->reserved_2;
731 rulesize = sizeof(struct ip_fw_32) + (fw32->cmd_len * sizeof(ipfw_insn) - 4);
732 if ( rulesize > copysize )
733 cmdsize = copysize - sizeof(struct ip_fw_32)-4;
734 else
735 cmdsize = fw32->cmd_len * sizeof(ipfw_insn);
736 cmdsize = copyfrom32fw_insn( fw32, user_ip_fw, cmdsize);
737 return( sizeof(struct ip_fw) + cmdsize - 4);
738 }
739
740 static size_t
741 copyfrom64fw( struct ip_fw_64 *fw64, struct ip_fw *user_ip_fw, size_t copysize)
742 {
743 size_t rulesize, cmdsize;
744
745 user_ip_fw->version = fw64->version;
746 user_ip_fw->context = CAST_DOWN_EXPLICIT( void *, fw64->context);
747 user_ip_fw->next = CAST_DOWN_EXPLICIT(struct ip_fw*, fw64->next);
748 user_ip_fw->next_rule = CAST_DOWN_EXPLICIT(struct ip_fw*, fw64->next_rule);
749 user_ip_fw->act_ofs = fw64->act_ofs;
750 user_ip_fw->cmd_len = fw64->cmd_len;
751 user_ip_fw->rulenum = fw64->rulenum;
752 user_ip_fw->set = fw64->set;
753 user_ip_fw->set_masks[0] = fw64->set_masks[0];
754 user_ip_fw->set_masks[1] = fw64->set_masks[1];
755 user_ip_fw->pcnt = fw64->pcnt;
756 user_ip_fw->bcnt = fw64->bcnt;
757 user_ip_fw->timestamp = fw64->timestamp;
758 user_ip_fw->reserved_1 = fw64->reserved_1;
759 user_ip_fw->reserved_2 = fw64->reserved_2;
760 //bcopy( fw64->cmd, user_ip_fw->cmd, fw64->cmd_len * sizeof(ipfw_insn));
761 rulesize = sizeof(struct ip_fw_64) + (fw64->cmd_len * sizeof(ipfw_insn) - 4);
762 if ( rulesize > copysize )
763 cmdsize = copysize - sizeof(struct ip_fw_64)-4;
764 else
765 cmdsize = fw64->cmd_len * sizeof(ipfw_insn);
766 cmdsize = copyfrom64fw_insn( fw64, user_ip_fw, cmdsize);
767 return( sizeof(struct ip_fw) + cmdsize - 4);
768 }
769
770 void
771 externalize_flow_id(struct ipfw_flow_id *dst, struct ip_flow_id *src);
772 void
773 externalize_flow_id(struct ipfw_flow_id *dst, struct ip_flow_id *src)
774 {
775 dst->dst_ip = src->dst_ip;
776 dst->src_ip = src->src_ip;
777 dst->dst_port = src->dst_port;
778 dst->src_port = src->src_port;
779 dst->proto = src->proto;
780 dst->flags = src->flags;
781 }
782
783 static
784 void cp_dyn_to_comp_32( struct ipfw_dyn_rule_compat_32 *dyn_rule_vers1, int *len)
785 {
786 struct ipfw_dyn_rule_compat_32 *dyn_last=NULL;
787 ipfw_dyn_rule *p;
788 int i;
789
790 if (ipfw_dyn_v) {
791 for (i = 0; i < curr_dyn_buckets; i++) {
792 for ( p = ipfw_dyn_v[i] ; p != NULL ; p = p->next) {
793 dyn_rule_vers1->chain = (user32_addr_t)(p->rule->rulenum);
794 externalize_flow_id(&dyn_rule_vers1->id, &p->id);
795 externalize_flow_id(&dyn_rule_vers1->mask, &p->id);
796 dyn_rule_vers1->type = p->dyn_type;
797 dyn_rule_vers1->expire = p->expire;
798 dyn_rule_vers1->pcnt = p->pcnt;
799 dyn_rule_vers1->bcnt = p->bcnt;
800 dyn_rule_vers1->bucket = p->bucket;
801 dyn_rule_vers1->state = p->state;
802
803 dyn_rule_vers1->next = CAST_DOWN_EXPLICIT( user32_addr_t, p->next);
804 dyn_last = dyn_rule_vers1;
805
806 *len += sizeof(*dyn_rule_vers1);
807 dyn_rule_vers1++;
808 }
809 }
810
811 if (dyn_last != NULL) {
812 dyn_last->next = ((user32_addr_t)0);
813 }
814 }
815 }
816
817
818 static
819 void cp_dyn_to_comp_64( struct ipfw_dyn_rule_compat_64 *dyn_rule_vers1, int *len)
820 {
821 struct ipfw_dyn_rule_compat_64 *dyn_last=NULL;
822 ipfw_dyn_rule *p;
823 int i;
824
825 if (ipfw_dyn_v) {
826 for (i = 0; i < curr_dyn_buckets; i++) {
827 for ( p = ipfw_dyn_v[i] ; p != NULL ; p = p->next) {
828 dyn_rule_vers1->chain = (user64_addr_t) p->rule->rulenum;
829 externalize_flow_id(&dyn_rule_vers1->id, &p->id);
830 externalize_flow_id(&dyn_rule_vers1->mask, &p->id);
831 dyn_rule_vers1->type = p->dyn_type;
832 dyn_rule_vers1->expire = p->expire;
833 dyn_rule_vers1->pcnt = p->pcnt;
834 dyn_rule_vers1->bcnt = p->bcnt;
835 dyn_rule_vers1->bucket = p->bucket;
836 dyn_rule_vers1->state = p->state;
837
838 dyn_rule_vers1->next = CAST_DOWN(user64_addr_t, p->next);
839 dyn_last = dyn_rule_vers1;
840
841 *len += sizeof(*dyn_rule_vers1);
842 dyn_rule_vers1++;
843 }
844 }
845
846 if (dyn_last != NULL) {
847 dyn_last->next = CAST_DOWN(user64_addr_t, NULL);
848 }
849 }
850 }
851
852 static int
853 sooptcopyin_fw( struct sockopt *sopt, struct ip_fw *user_ip_fw, size_t *size )
854 {
855 size_t valsize, copyinsize = 0;
856 int error = 0;
857
858 valsize = sopt->sopt_valsize;
859 if ( size )
860 copyinsize = *size;
861 if (proc_is64bit(sopt->sopt_p)) {
862 struct ip_fw_64 *fw64=NULL;
863
864 if ( valsize < sizeof(struct ip_fw_64) ) {
865 return(EINVAL);
866 }
867 if ( !copyinsize )
868 copyinsize = sizeof(struct ip_fw_64);
869 if ( valsize > copyinsize )
870 sopt->sopt_valsize = valsize = copyinsize;
871
872 if ( sopt->sopt_p != 0) {
873 fw64 = _MALLOC(copyinsize, M_TEMP, M_WAITOK);
874 if ( fw64 == NULL )
875 return(ENOBUFS);
876 if ((error = copyin(sopt->sopt_val, fw64, valsize)) != 0){
877 _FREE(fw64, M_TEMP);
878 return error;
879 }
880 }
881 else {
882 bcopy(CAST_DOWN(caddr_t, sopt->sopt_val), fw64, valsize);
883 }
884 valsize = copyfrom64fw( fw64, user_ip_fw, valsize );
885 _FREE( fw64, M_TEMP);
886 }else {
887 struct ip_fw_32 *fw32=NULL;
888
889 if ( valsize < sizeof(struct ip_fw_32) ) {
890 return(EINVAL);
891 }
892 if ( !copyinsize)
893 copyinsize = sizeof(struct ip_fw_32);
894 if ( valsize > copyinsize)
895 sopt->sopt_valsize = valsize = copyinsize;
896
897 if ( sopt->sopt_p != 0) {
898 fw32 = _MALLOC(copyinsize, M_TEMP, M_WAITOK);
899 if ( fw32 == NULL )
900 return(ENOBUFS);
901 if ( (error = copyin(sopt->sopt_val, fw32, valsize)) != 0){
902 _FREE( fw32, M_TEMP);
903 return( error );
904 }
905 }
906 else {
907 bcopy(CAST_DOWN(caddr_t, sopt->sopt_val), fw32, valsize);
908 }
909 valsize = copyfrom32fw( fw32, user_ip_fw, valsize);
910 _FREE( fw32, M_TEMP);
911 }
912 if ( size )
913 *size = valsize;
914 return error;
915 }
916
917 /*
918 * The following checks use two arrays of 8 or 16 bits to store the
919 * bits that we want set or clear, respectively. They are in the
920 * low and high half of cmd->arg1 or cmd->d[0].
921 *
922 * We scan options and store the bits we find set. We succeed if
923 *
924 * (want_set & ~bits) == 0 && (want_clear & ~bits) == want_clear
925 *
926 * The code is sometimes optimized not to store additional variables.
927 */
928
929 static int
930 flags_match(ipfw_insn *cmd, u_int8_t bits)
931 {
932 u_char want_clear;
933 bits = ~bits;
934
935 if ( ((cmd->arg1 & 0xff) & bits) != 0)
936 return 0; /* some bits we want set were clear */
937 want_clear = (cmd->arg1 >> 8) & 0xff;
938 if ( (want_clear & bits) != want_clear)
939 return 0; /* some bits we want clear were set */
940 return 1;
941 }
942
943 static int
944 ipopts_match(struct ip *ip, ipfw_insn *cmd)
945 {
946 int optlen, bits = 0;
947 u_char *cp = (u_char *)(ip + 1);
948 int x = (ip->ip_hl << 2) - sizeof (struct ip);
949
950 for (; x > 0; x -= optlen, cp += optlen) {
951 int opt = cp[IPOPT_OPTVAL];
952
953 if (opt == IPOPT_EOL)
954 break;
955 if (opt == IPOPT_NOP)
956 optlen = 1;
957 else {
958 optlen = cp[IPOPT_OLEN];
959 if (optlen <= 0 || optlen > x)
960 return 0; /* invalid or truncated */
961 }
962 switch (opt) {
963
964 default:
965 break;
966
967 case IPOPT_LSRR:
968 bits |= IP_FW_IPOPT_LSRR;
969 break;
970
971 case IPOPT_SSRR:
972 bits |= IP_FW_IPOPT_SSRR;
973 break;
974
975 case IPOPT_RR:
976 bits |= IP_FW_IPOPT_RR;
977 break;
978
979 case IPOPT_TS:
980 bits |= IP_FW_IPOPT_TS;
981 break;
982 }
983 }
984 return (flags_match(cmd, bits));
985 }
986
987 static int
988 tcpopts_match(struct ip *ip, ipfw_insn *cmd)
989 {
990 int optlen, bits = 0;
991 struct tcphdr *tcp = L3HDR(struct tcphdr,ip);
992 u_char *cp = (u_char *)(tcp + 1);
993 int x = (tcp->th_off << 2) - sizeof(struct tcphdr);
994
995 for (; x > 0; x -= optlen, cp += optlen) {
996 int opt = cp[0];
997 if (opt == TCPOPT_EOL)
998 break;
999 if (opt == TCPOPT_NOP)
1000 optlen = 1;
1001 else {
1002 optlen = cp[1];
1003 if (optlen <= 0)
1004 break;
1005 }
1006
1007 switch (opt) {
1008
1009 default:
1010 break;
1011
1012 case TCPOPT_MAXSEG:
1013 bits |= IP_FW_TCPOPT_MSS;
1014 break;
1015
1016 case TCPOPT_WINDOW:
1017 bits |= IP_FW_TCPOPT_WINDOW;
1018 break;
1019
1020 case TCPOPT_SACK_PERMITTED:
1021 case TCPOPT_SACK:
1022 bits |= IP_FW_TCPOPT_SACK;
1023 break;
1024
1025 case TCPOPT_TIMESTAMP:
1026 bits |= IP_FW_TCPOPT_TS;
1027 break;
1028
1029 case TCPOPT_CC:
1030 case TCPOPT_CCNEW:
1031 case TCPOPT_CCECHO:
1032 bits |= IP_FW_TCPOPT_CC;
1033 break;
1034 }
1035 }
1036 return (flags_match(cmd, bits));
1037 }
1038
1039 static int
1040 iface_match(struct ifnet *ifp, ipfw_insn_if *cmd)
1041 {
1042 if (ifp == NULL) /* no iface with this packet, match fails */
1043 return 0;
1044 /* Check by name or by IP address */
1045 if (cmd->name[0] != '\0') { /* match by name */
1046 /* Check unit number (-1 is wildcard) */
1047 if (cmd->p.unit != -1 && cmd->p.unit != ifp->if_unit)
1048 return(0);
1049 /* Check name */
1050 if (!strncmp(ifp->if_name, cmd->name, IFNAMSIZ))
1051 return(1);
1052 } else {
1053 struct ifaddr *ia;
1054
1055 ifnet_lock_shared(ifp);
1056 TAILQ_FOREACH(ia, &ifp->if_addrhead, ifa_link) {
1057 IFA_LOCK(ia);
1058 if (ia->ifa_addr->sa_family != AF_INET) {
1059 IFA_UNLOCK(ia);
1060 continue;
1061 }
1062 if (cmd->p.ip.s_addr == ((struct sockaddr_in *)
1063 (ia->ifa_addr))->sin_addr.s_addr) {
1064 IFA_UNLOCK(ia);
1065 ifnet_lock_done(ifp);
1066 return(1); /* match */
1067 }
1068 IFA_UNLOCK(ia);
1069 }
1070 ifnet_lock_done(ifp);
1071 }
1072 return(0); /* no match, fail ... */
1073 }
1074
1075 /*
1076 * The 'verrevpath' option checks that the interface that an IP packet
1077 * arrives on is the same interface that traffic destined for the
1078 * packet's source address would be routed out of. This is a measure
1079 * to block forged packets. This is also commonly known as "anti-spoofing"
1080 * or Unicast Reverse Path Forwarding (Unicast RFP) in Cisco-ese. The
1081 * name of the knob is purposely reminisent of the Cisco IOS command,
1082 *
1083 * ip verify unicast reverse-path
1084 *
1085 * which implements the same functionality. But note that syntax is
1086 * misleading. The check may be performed on all IP packets whether unicast,
1087 * multicast, or broadcast.
1088 */
1089 static int
1090 verify_rev_path(struct in_addr src, struct ifnet *ifp)
1091 {
1092 static struct route ro;
1093 struct sockaddr_in *dst;
1094
1095 bzero(&ro, sizeof (ro));
1096 dst = (struct sockaddr_in *)&(ro.ro_dst);
1097
1098 /* Check if we've cached the route from the previous call. */
1099 if (src.s_addr != dst->sin_addr.s_addr) {
1100 dst->sin_family = AF_INET;
1101 dst->sin_len = sizeof(*dst);
1102 dst->sin_addr = src;
1103
1104 rtalloc_ign(&ro, RTF_CLONING|RTF_PRCLONING, false);
1105 }
1106 if (ro.ro_rt != NULL) {
1107 RT_LOCK_SPIN(ro.ro_rt);
1108 } else {
1109 ROUTE_RELEASE(&ro);
1110 return 0; /* No route */
1111 }
1112 if ((ifp == NULL) ||
1113 (ro.ro_rt->rt_ifp->if_index != ifp->if_index)) {
1114 RT_UNLOCK(ro.ro_rt);
1115 ROUTE_RELEASE(&ro);
1116 return 0;
1117 }
1118 RT_UNLOCK(ro.ro_rt);
1119 ROUTE_RELEASE(&ro);
1120 return 1;
1121 }
1122
1123
1124 static u_int64_t norule_counter; /* counter for ipfw_log(NULL...) */
1125
1126 #define SNPARGS(buf, len) buf + len, sizeof(buf) > len ? sizeof(buf) - len : 0
1127 #define SNP(buf) buf, sizeof(buf)
1128
1129 /*
1130 * We enter here when we have a rule with O_LOG.
1131 * XXX this function alone takes about 2Kbytes of code!
1132 */
1133 static void
1134 ipfw_log(struct ip_fw *f, u_int hlen, struct ether_header *eh,
1135 struct mbuf *m, struct ifnet *oif)
1136 {
1137 const char *action;
1138 int limit_reached = 0;
1139 char ipv4str[MAX_IPv4_STR_LEN];
1140 char action2[40], proto[48], fragment[28];
1141
1142 fragment[0] = '\0';
1143 proto[0] = '\0';
1144
1145 if (f == NULL) { /* bogus pkt */
1146 if (verbose_limit != 0 && norule_counter >= verbose_limit)
1147 return;
1148 norule_counter++;
1149 if (norule_counter == verbose_limit)
1150 limit_reached = verbose_limit;
1151 action = "Refuse";
1152 } else { /* O_LOG is the first action, find the real one */
1153 ipfw_insn *cmd = ACTION_PTR(f);
1154 ipfw_insn_log *l = (ipfw_insn_log *)cmd;
1155
1156 if (l->max_log != 0 && l->log_left == 0)
1157 return;
1158 l->log_left--;
1159 if (l->log_left == 0)
1160 limit_reached = l->max_log;
1161 cmd += F_LEN(cmd); /* point to first action */
1162 if (cmd->opcode == O_PROB)
1163 cmd += F_LEN(cmd);
1164
1165 action = action2;
1166 switch (cmd->opcode) {
1167 case O_DENY:
1168 action = "Deny";
1169 break;
1170
1171 case O_REJECT:
1172 if (cmd->arg1==ICMP_REJECT_RST)
1173 action = "Reset";
1174 else if (cmd->arg1==ICMP_UNREACH_HOST)
1175 action = "Reject";
1176 else
1177 snprintf(SNPARGS(action2, 0), "Unreach %d",
1178 cmd->arg1);
1179 break;
1180
1181 case O_ACCEPT:
1182 action = "Accept";
1183 break;
1184 case O_COUNT:
1185 action = "Count";
1186 break;
1187 case O_DIVERT:
1188 snprintf(SNPARGS(action2, 0), "Divert %d",
1189 cmd->arg1);
1190 break;
1191 case O_TEE:
1192 snprintf(SNPARGS(action2, 0), "Tee %d",
1193 cmd->arg1);
1194 break;
1195 case O_SKIPTO:
1196 snprintf(SNPARGS(action2, 0), "SkipTo %d",
1197 cmd->arg1);
1198 break;
1199 case O_PIPE:
1200 snprintf(SNPARGS(action2, 0), "Pipe %d",
1201 cmd->arg1);
1202 break;
1203 case O_QUEUE:
1204 snprintf(SNPARGS(action2, 0), "Queue %d",
1205 cmd->arg1);
1206 break;
1207 case O_FORWARD_IP: {
1208 ipfw_insn_sa *sa = (ipfw_insn_sa *)cmd;
1209 int len;
1210
1211 if (f->reserved_1 == IPFW_RULE_INACTIVE) {
1212 break;
1213 }
1214 len = snprintf(SNPARGS(action2, 0), "Forward to %s",
1215 inet_ntop(AF_INET, &sa->sa.sin_addr, ipv4str, sizeof(ipv4str)));
1216 if (sa->sa.sin_port)
1217 snprintf(SNPARGS(action2, len), ":%d",
1218 sa->sa.sin_port);
1219 }
1220 break;
1221 default:
1222 action = "UNKNOWN";
1223 break;
1224 }
1225 }
1226
1227 if (hlen == 0) { /* non-ip */
1228 snprintf(SNPARGS(proto, 0), "MAC");
1229 } else {
1230 struct ip *ip = mtod(m, struct ip *);
1231 /* these three are all aliases to the same thing */
1232 struct icmp *const icmp = L3HDR(struct icmp, ip);
1233 struct tcphdr *const tcp = (struct tcphdr *)icmp;
1234 struct udphdr *const udp = (struct udphdr *)icmp;
1235
1236 int ip_off, offset, ip_len;
1237
1238 int len;
1239
1240 if (eh != NULL) { /* layer 2 packets are as on the wire */
1241 ip_off = ntohs(ip->ip_off);
1242 ip_len = ntohs(ip->ip_len);
1243 } else {
1244 ip_off = ip->ip_off;
1245 ip_len = ip->ip_len;
1246 }
1247 offset = ip_off & IP_OFFMASK;
1248 switch (ip->ip_p) {
1249 case IPPROTO_TCP:
1250 len = snprintf(SNPARGS(proto, 0), "TCP %s",
1251 inet_ntop(AF_INET, &ip->ip_src, ipv4str, sizeof(ipv4str)));
1252 if (offset == 0)
1253 snprintf(SNPARGS(proto, len), ":%d %s:%d",
1254 ntohs(tcp->th_sport),
1255 inet_ntop(AF_INET, &ip->ip_dst, ipv4str, sizeof(ipv4str)),
1256 ntohs(tcp->th_dport));
1257 else
1258 snprintf(SNPARGS(proto, len), " %s",
1259 inet_ntop(AF_INET, &ip->ip_dst, ipv4str, sizeof(ipv4str)));
1260 break;
1261
1262 case IPPROTO_UDP:
1263 len = snprintf(SNPARGS(proto, 0), "UDP %s",
1264 inet_ntop(AF_INET, &ip->ip_src, ipv4str, sizeof(ipv4str)));
1265 if (offset == 0)
1266 snprintf(SNPARGS(proto, len), ":%d %s:%d",
1267 ntohs(udp->uh_sport),
1268 inet_ntop(AF_INET, &ip->ip_dst, ipv4str, sizeof(ipv4str)),
1269 ntohs(udp->uh_dport));
1270 else
1271 snprintf(SNPARGS(proto, len), " %s",
1272 inet_ntop(AF_INET, &ip->ip_dst, ipv4str, sizeof(ipv4str)));
1273 break;
1274
1275 case IPPROTO_ICMP:
1276 if (offset == 0)
1277 len = snprintf(SNPARGS(proto, 0),
1278 "ICMP:%u.%u ",
1279 icmp->icmp_type, icmp->icmp_code);
1280 else
1281 len = snprintf(SNPARGS(proto, 0), "ICMP ");
1282 len += snprintf(SNPARGS(proto, len), "%s",
1283 inet_ntop(AF_INET, &ip->ip_src, ipv4str, sizeof(ipv4str)));
1284 snprintf(SNPARGS(proto, len), " %s",
1285 inet_ntop(AF_INET, &ip->ip_dst, ipv4str, sizeof(ipv4str)));
1286 break;
1287
1288 default:
1289 len = snprintf(SNPARGS(proto, 0), "P:%d %s", ip->ip_p,
1290 inet_ntop(AF_INET, &ip->ip_src, ipv4str, sizeof(ipv4str)));
1291 snprintf(SNPARGS(proto, len), " %s",
1292 inet_ntop(AF_INET, &ip->ip_dst, ipv4str, sizeof(ipv4str)));
1293 break;
1294 }
1295
1296 if (ip_off & (IP_MF | IP_OFFMASK))
1297 snprintf(SNPARGS(fragment, 0), " (frag %d:%d@%d%s)",
1298 ntohs(ip->ip_id), ip_len - (ip->ip_hl << 2),
1299 offset << 3,
1300 (ip_off & IP_MF) ? "+" : "");
1301 }
1302 if (oif || m->m_pkthdr.rcvif)
1303 {
1304 dolog((LOG_AUTHPRIV | LOG_INFO,
1305 "ipfw: %d %s %s %s via %s%d%s\n",
1306 f ? f->rulenum : -1,
1307 action, proto, oif ? "out" : "in",
1308 oif ? oif->if_name : m->m_pkthdr.rcvif->if_name,
1309 oif ? oif->if_unit : m->m_pkthdr.rcvif->if_unit,
1310 fragment));
1311 }
1312 else{
1313 dolog((LOG_AUTHPRIV | LOG_INFO,
1314 "ipfw: %d %s %s [no if info]%s\n",
1315 f ? f->rulenum : -1,
1316 action, proto, fragment));
1317 }
1318 if (limit_reached){
1319 dolog((LOG_AUTHPRIV | LOG_NOTICE,
1320 "ipfw: limit %d reached on entry %d\n",
1321 limit_reached, f ? f->rulenum : -1));
1322 }
1323 }
1324
1325 /*
1326 * IMPORTANT: the hash function for dynamic rules must be commutative
1327 * in source and destination (ip,port), because rules are bidirectional
1328 * and we want to find both in the same bucket.
1329 */
1330 static __inline int
1331 hash_packet(struct ip_flow_id *id)
1332 {
1333 u_int32_t i;
1334
1335 i = (id->dst_ip) ^ (id->src_ip) ^ (id->dst_port) ^ (id->src_port);
1336 i &= (curr_dyn_buckets - 1);
1337 return i;
1338 }
1339
1340 /**
1341 * unlink a dynamic rule from a chain. prev is a pointer to
1342 * the previous one, q is a pointer to the rule to delete,
1343 * head is a pointer to the head of the queue.
1344 * Modifies q and potentially also head.
1345 */
1346 #define UNLINK_DYN_RULE(prev, head, q) { \
1347 ipfw_dyn_rule *old_q = q; \
1348 \
1349 /* remove a refcount to the parent */ \
1350 if (q->dyn_type == O_LIMIT) \
1351 q->parent->count--; \
1352 DEB(printf("ipfw: unlink entry 0x%08x %d -> 0x%08x %d, %d left\n",\
1353 (q->id.src_ip), (q->id.src_port), \
1354 (q->id.dst_ip), (q->id.dst_port), dyn_count-1 ); ) \
1355 if (prev != NULL) \
1356 prev->next = q = q->next; \
1357 else \
1358 head = q = q->next; \
1359 dyn_count--; \
1360 _FREE(old_q, M_IPFW); }
1361
1362 #define TIME_LEQ(a,b) ((int)((a)-(b)) <= 0)
1363
1364 /**
1365 * Remove dynamic rules pointing to "rule", or all of them if rule == NULL.
1366 *
1367 * If keep_me == NULL, rules are deleted even if not expired,
1368 * otherwise only expired rules are removed.
1369 *
1370 * The value of the second parameter is also used to point to identify
1371 * a rule we absolutely do not want to remove (e.g. because we are
1372 * holding a reference to it -- this is the case with O_LIMIT_PARENT
1373 * rules). The pointer is only used for comparison, so any non-null
1374 * value will do.
1375 */
1376 static void
1377 remove_dyn_rule(struct ip_fw *rule, ipfw_dyn_rule *keep_me)
1378 {
1379 static u_int32_t last_remove = 0;
1380
1381 #define FORCE (keep_me == NULL)
1382
1383 ipfw_dyn_rule *prev, *q;
1384 int i, pass = 0, max_pass = 0;
1385 struct timeval timenow;
1386
1387 getmicrotime(&timenow);
1388
1389 if (ipfw_dyn_v == NULL || dyn_count == 0)
1390 return;
1391 /* do not expire more than once per second, it is useless */
1392 if (!FORCE && last_remove == timenow.tv_sec)
1393 return;
1394 last_remove = timenow.tv_sec;
1395
1396 /*
1397 * because O_LIMIT refer to parent rules, during the first pass only
1398 * remove child and mark any pending LIMIT_PARENT, and remove
1399 * them in a second pass.
1400 */
1401 next_pass:
1402 for (i = 0 ; i < curr_dyn_buckets ; i++) {
1403 for (prev=NULL, q = ipfw_dyn_v[i] ; q ; ) {
1404 /*
1405 * Logic can become complex here, so we split tests.
1406 */
1407 if (q == keep_me)
1408 goto next;
1409 if (rule != NULL && rule != q->rule)
1410 goto next; /* not the one we are looking for */
1411 if (q->dyn_type == O_LIMIT_PARENT) {
1412 /*
1413 * handle parent in the second pass,
1414 * record we need one.
1415 */
1416 max_pass = 1;
1417 if (pass == 0)
1418 goto next;
1419 if (FORCE && q->count != 0 ) {
1420 /* XXX should not happen! */
1421 printf("ipfw: OUCH! cannot remove rule,"
1422 " count %d\n", q->count);
1423 }
1424 } else {
1425 if (!FORCE &&
1426 !TIME_LEQ( q->expire, timenow.tv_sec ))
1427 goto next;
1428 }
1429 if (q->dyn_type != O_LIMIT_PARENT || !q->count) {
1430 UNLINK_DYN_RULE(prev, ipfw_dyn_v[i], q);
1431 continue;
1432 }
1433 next:
1434 prev=q;
1435 q=q->next;
1436 }
1437 }
1438 if (pass++ < max_pass)
1439 goto next_pass;
1440 }
1441
1442
1443 /**
1444 * lookup a dynamic rule.
1445 */
1446 static ipfw_dyn_rule *
1447 lookup_dyn_rule(struct ip_flow_id *pkt, int *match_direction,
1448 struct tcphdr *tcp)
1449 {
1450 /*
1451 * stateful ipfw extensions.
1452 * Lookup into dynamic session queue
1453 */
1454 #define MATCH_REVERSE 0
1455 #define MATCH_FORWARD 1
1456 #define MATCH_NONE 2
1457 #define MATCH_UNKNOWN 3
1458 #define BOTH_SYN (TH_SYN | (TH_SYN << 8))
1459 #define BOTH_FIN (TH_FIN | (TH_FIN << 8))
1460
1461 int i, dir = MATCH_NONE;
1462 ipfw_dyn_rule *prev, *q=NULL;
1463 struct timeval timenow;
1464
1465 getmicrotime(&timenow);
1466
1467 if (ipfw_dyn_v == NULL)
1468 goto done; /* not found */
1469 i = hash_packet( pkt );
1470 for (prev=NULL, q = ipfw_dyn_v[i] ; q != NULL ; ) {
1471 if (q->dyn_type == O_LIMIT_PARENT && q->count)
1472 goto next;
1473 if (TIME_LEQ( q->expire, timenow.tv_sec)) { /* expire entry */
1474 int dounlink = 1;
1475
1476 /* check if entry is TCP */
1477 if ( q->id.proto == IPPROTO_TCP )
1478 {
1479 /* do not delete an established TCP connection which hasn't been closed by both sides */
1480 if ( (q->state & (BOTH_SYN | BOTH_FIN)) != (BOTH_SYN | BOTH_FIN) )
1481 dounlink = 0;
1482 }
1483 if ( dounlink ){
1484 UNLINK_DYN_RULE(prev, ipfw_dyn_v[i], q);
1485 continue;
1486 }
1487 }
1488 if (pkt->proto == q->id.proto &&
1489 q->dyn_type != O_LIMIT_PARENT) {
1490 if (pkt->src_ip == q->id.src_ip &&
1491 pkt->dst_ip == q->id.dst_ip &&
1492 pkt->src_port == q->id.src_port &&
1493 pkt->dst_port == q->id.dst_port ) {
1494 dir = MATCH_FORWARD;
1495 break;
1496 }
1497 if (pkt->src_ip == q->id.dst_ip &&
1498 pkt->dst_ip == q->id.src_ip &&
1499 pkt->src_port == q->id.dst_port &&
1500 pkt->dst_port == q->id.src_port ) {
1501 dir = MATCH_REVERSE;
1502 break;
1503 }
1504 }
1505 next:
1506 prev = q;
1507 q = q->next;
1508 }
1509 if (q == NULL)
1510 goto done; /* q = NULL, not found */
1511
1512 if ( prev != NULL) { /* found and not in front */
1513 prev->next = q->next;
1514 q->next = ipfw_dyn_v[i];
1515 ipfw_dyn_v[i] = q;
1516 }
1517 if (pkt->proto == IPPROTO_TCP) { /* update state according to flags */
1518 u_char flags = pkt->flags & (TH_FIN|TH_SYN|TH_RST);
1519
1520 q->state |= (dir == MATCH_FORWARD ) ? flags : (flags << 8);
1521 switch (q->state) {
1522 case TH_SYN: /* opening */
1523 q->expire = timenow.tv_sec + dyn_syn_lifetime;
1524 break;
1525
1526 case BOTH_SYN: /* move to established */
1527 case BOTH_SYN | TH_FIN : /* one side tries to close */
1528 case BOTH_SYN | (TH_FIN << 8) :
1529 if (tcp) {
1530 #define _SEQ_GE(a,b) ((int)(a) - (int)(b) >= 0)
1531 u_int32_t ack = ntohl(tcp->th_ack);
1532 if (dir == MATCH_FORWARD) {
1533 if (q->ack_fwd == 0 || _SEQ_GE(ack, q->ack_fwd))
1534 q->ack_fwd = ack;
1535 else { /* ignore out-of-sequence */
1536 break;
1537 }
1538 } else {
1539 if (q->ack_rev == 0 || _SEQ_GE(ack, q->ack_rev))
1540 q->ack_rev = ack;
1541 else { /* ignore out-of-sequence */
1542 break;
1543 }
1544 }
1545 }
1546 q->expire = timenow.tv_sec + dyn_ack_lifetime;
1547 break;
1548
1549 case BOTH_SYN | BOTH_FIN: /* both sides closed */
1550 if (dyn_fin_lifetime >= dyn_keepalive_period)
1551 dyn_fin_lifetime = dyn_keepalive_period - 1;
1552 q->expire = timenow.tv_sec + dyn_fin_lifetime;
1553 break;
1554
1555 default:
1556 #if 0
1557 /*
1558 * reset or some invalid combination, but can also
1559 * occur if we use keep-state the wrong way.
1560 */
1561 if ( (q->state & ((TH_RST << 8)|TH_RST)) == 0)
1562 printf("invalid state: 0x%x\n", q->state);
1563 #endif
1564 if (dyn_rst_lifetime >= dyn_keepalive_period)
1565 dyn_rst_lifetime = dyn_keepalive_period - 1;
1566 q->expire = timenow.tv_sec + dyn_rst_lifetime;
1567 break;
1568 }
1569 } else if (pkt->proto == IPPROTO_UDP) {
1570 q->expire = timenow.tv_sec + dyn_udp_lifetime;
1571 } else {
1572 /* other protocols */
1573 q->expire = timenow.tv_sec + dyn_short_lifetime;
1574 }
1575 done:
1576 if (match_direction)
1577 *match_direction = dir;
1578 return q;
1579 }
1580
1581 static void
1582 realloc_dynamic_table(void)
1583 {
1584 /*
1585 * Try reallocation, make sure we have a power of 2 and do
1586 * not allow more than 64k entries. In case of overflow,
1587 * default to 1024.
1588 */
1589
1590 if (dyn_buckets > 65536)
1591 dyn_buckets = 1024;
1592 if ((dyn_buckets & (dyn_buckets-1)) != 0) { /* not a power of 2 */
1593 dyn_buckets = curr_dyn_buckets; /* reset */
1594 return;
1595 }
1596 curr_dyn_buckets = dyn_buckets;
1597 if (ipfw_dyn_v != NULL)
1598 _FREE(ipfw_dyn_v, M_IPFW);
1599 for (;;) {
1600 ipfw_dyn_v = _MALLOC(curr_dyn_buckets * sizeof(ipfw_dyn_rule *),
1601 M_IPFW, M_NOWAIT | M_ZERO);
1602 if (ipfw_dyn_v != NULL || curr_dyn_buckets <= 2)
1603 break;
1604 curr_dyn_buckets /= 2;
1605 }
1606 }
1607
1608 /**
1609 * Install state of type 'type' for a dynamic session.
1610 * The hash table contains two type of rules:
1611 * - regular rules (O_KEEP_STATE)
1612 * - rules for sessions with limited number of sess per user
1613 * (O_LIMIT). When they are created, the parent is
1614 * increased by 1, and decreased on delete. In this case,
1615 * the third parameter is the parent rule and not the chain.
1616 * - "parent" rules for the above (O_LIMIT_PARENT).
1617 */
1618 static ipfw_dyn_rule *
1619 add_dyn_rule(struct ip_flow_id *id, u_int8_t dyn_type, struct ip_fw *rule)
1620 {
1621 ipfw_dyn_rule *r;
1622 int i;
1623 struct timeval timenow;
1624
1625 getmicrotime(&timenow);
1626
1627 if (ipfw_dyn_v == NULL ||
1628 (dyn_count == 0 && dyn_buckets != curr_dyn_buckets)) {
1629 realloc_dynamic_table();
1630 if (ipfw_dyn_v == NULL)
1631 return NULL; /* failed ! */
1632 }
1633 i = hash_packet(id);
1634
1635 r = _MALLOC(sizeof *r, M_IPFW, M_NOWAIT | M_ZERO);
1636 if (r == NULL) {
1637 #if IPFW_DEBUG
1638 printf ("ipfw: sorry cannot allocate state\n");
1639 #endif
1640 return NULL;
1641 }
1642
1643 /* increase refcount on parent, and set pointer */
1644 if (dyn_type == O_LIMIT) {
1645 ipfw_dyn_rule *parent = (ipfw_dyn_rule *)rule;
1646 if ( parent->dyn_type != O_LIMIT_PARENT)
1647 panic("invalid parent");
1648 parent->count++;
1649 r->parent = parent;
1650 rule = parent->rule;
1651 }
1652
1653 r->id = *id;
1654 r->expire = timenow.tv_sec + dyn_syn_lifetime;
1655 r->rule = rule;
1656 r->dyn_type = dyn_type;
1657 r->pcnt = r->bcnt = 0;
1658 r->count = 0;
1659
1660 r->bucket = i;
1661 r->next = ipfw_dyn_v[i];
1662 ipfw_dyn_v[i] = r;
1663 dyn_count++;
1664 DEB(printf("ipfw: add dyn entry ty %d 0x%08x %d -> 0x%08x %d, total %d\n",
1665 dyn_type,
1666 (r->id.src_ip), (r->id.src_port),
1667 (r->id.dst_ip), (r->id.dst_port),
1668 dyn_count ); )
1669 return r;
1670 }
1671
1672 /**
1673 * lookup dynamic parent rule using pkt and rule as search keys.
1674 * If the lookup fails, then install one.
1675 */
1676 static ipfw_dyn_rule *
1677 lookup_dyn_parent(struct ip_flow_id *pkt, struct ip_fw *rule)
1678 {
1679 ipfw_dyn_rule *q;
1680 int i;
1681 struct timeval timenow;
1682
1683 getmicrotime(&timenow);
1684
1685 if (ipfw_dyn_v) {
1686 i = hash_packet( pkt );
1687 for (q = ipfw_dyn_v[i] ; q != NULL ; q=q->next)
1688 if (q->dyn_type == O_LIMIT_PARENT &&
1689 rule== q->rule &&
1690 pkt->proto == q->id.proto &&
1691 pkt->src_ip == q->id.src_ip &&
1692 pkt->dst_ip == q->id.dst_ip &&
1693 pkt->src_port == q->id.src_port &&
1694 pkt->dst_port == q->id.dst_port) {
1695 q->expire = timenow.tv_sec + dyn_short_lifetime;
1696 DEB(printf("ipfw: lookup_dyn_parent found "
1697 "0x%llx\n", (uint64_t)VM_KERNEL_ADDRPERM(q));)
1698 return q;
1699 }
1700 }
1701 return add_dyn_rule(pkt, O_LIMIT_PARENT, rule);
1702 }
1703
1704 /**
1705 * Install dynamic state for rule type cmd->o.opcode
1706 *
1707 * Returns 1 (failure) if state is not installed because of errors or because
1708 * session limitations are enforced.
1709 */
1710 static int
1711 install_state(struct ip_fw *rule, ipfw_insn_limit *cmd,
1712 struct ip_fw_args *args)
1713 {
1714 static int last_log;
1715 struct timeval timenow;
1716
1717 ipfw_dyn_rule *q;
1718 getmicrotime(&timenow);
1719
1720 DEB(printf("ipfw: install state type %d 0x%08x %u -> 0x%08x %u\n",
1721 cmd->o.opcode,
1722 (args->fwa_id.src_ip), (args->fwa_id.src_port),
1723 (args->fwa_id.dst_ip), (args->fwa_id.dst_port) );)
1724
1725 q = lookup_dyn_rule(&args->fwa_id, NULL, NULL);
1726
1727 if (q != NULL) { /* should never occur */
1728 if (last_log != timenow.tv_sec) {
1729 last_log = timenow.tv_sec;
1730 printf("ipfw: install_state: entry already present, done\n");
1731 }
1732 return 0;
1733 }
1734
1735 if (dyn_count >= dyn_max)
1736 /*
1737 * Run out of slots, try to remove any expired rule.
1738 */
1739 remove_dyn_rule(NULL, (ipfw_dyn_rule *)1);
1740
1741 if (dyn_count >= dyn_max) {
1742 if (last_log != timenow.tv_sec) {
1743 last_log = timenow.tv_sec;
1744 printf("ipfw: install_state: Too many dynamic rules\n");
1745 }
1746 return 1; /* cannot install, notify caller */
1747 }
1748
1749 switch (cmd->o.opcode) {
1750 case O_KEEP_STATE: /* bidir rule */
1751 add_dyn_rule(&args->fwa_id, O_KEEP_STATE, rule);
1752 break;
1753
1754 case O_LIMIT: /* limit number of sessions */
1755 {
1756 u_int16_t limit_mask = cmd->limit_mask;
1757 struct ip_flow_id id;
1758 ipfw_dyn_rule *parent;
1759
1760 DEB(printf("ipfw: installing dyn-limit rule %d\n",
1761 cmd->conn_limit);)
1762
1763 id.dst_ip = id.src_ip = 0;
1764 id.dst_port = id.src_port = 0;
1765 id.proto = args->fwa_id.proto;
1766
1767 if (limit_mask & DYN_SRC_ADDR)
1768 id.src_ip = args->fwa_id.src_ip;
1769 if (limit_mask & DYN_DST_ADDR)
1770 id.dst_ip = args->fwa_id.dst_ip;
1771 if (limit_mask & DYN_SRC_PORT)
1772 id.src_port = args->fwa_id.src_port;
1773 if (limit_mask & DYN_DST_PORT)
1774 id.dst_port = args->fwa_id.dst_port;
1775 parent = lookup_dyn_parent(&id, rule);
1776 if (parent == NULL) {
1777 printf("ipfw: add parent failed\n");
1778 return 1;
1779 }
1780 if (parent->count >= cmd->conn_limit) {
1781 /*
1782 * See if we can remove some expired rule.
1783 */
1784 remove_dyn_rule(rule, parent);
1785 if (parent->count >= cmd->conn_limit) {
1786 if (fw_verbose && last_log != timenow.tv_sec) {
1787 last_log = timenow.tv_sec;
1788 dolog((LOG_AUTHPRIV | LOG_DEBUG,
1789 "drop session, too many entries\n"));
1790 }
1791 return 1;
1792 }
1793 }
1794 add_dyn_rule(&args->fwa_id, O_LIMIT, (struct ip_fw *)parent);
1795 }
1796 break;
1797 default:
1798 printf("ipfw: unknown dynamic rule type %u\n", cmd->o.opcode);
1799 return 1;
1800 }
1801 lookup_dyn_rule(&args->fwa_id, NULL, NULL); /* XXX just set lifetime */
1802 return 0;
1803 }
1804
1805 /*
1806 * Generate a TCP packet, containing either a RST or a keepalive.
1807 * When flags & TH_RST, we are sending a RST packet, because of a
1808 * "reset" action matched the packet.
1809 * Otherwise we are sending a keepalive, and flags & TH_
1810 */
1811 static struct mbuf *
1812 send_pkt(struct ip_flow_id *id, u_int32_t seq, u_int32_t ack, int flags)
1813 {
1814 struct mbuf *m;
1815 struct ip *ip;
1816 struct tcphdr *tcp;
1817
1818 MGETHDR(m, M_DONTWAIT, MT_HEADER); /* MAC-OK */
1819 if (m == 0)
1820 return NULL;
1821 m->m_pkthdr.rcvif = (struct ifnet *)0;
1822 m->m_pkthdr.len = m->m_len = sizeof(struct ip) + sizeof(struct tcphdr);
1823 m->m_data += max_linkhdr;
1824
1825 ip = mtod(m, struct ip *);
1826 bzero(ip, m->m_len);
1827 tcp = (struct tcphdr *)(ip + 1); /* no IP options */
1828 ip->ip_p = IPPROTO_TCP;
1829 tcp->th_off = 5;
1830 /*
1831 * Assume we are sending a RST (or a keepalive in the reverse
1832 * direction), swap src and destination addresses and ports.
1833 */
1834 ip->ip_src.s_addr = htonl(id->dst_ip);
1835 ip->ip_dst.s_addr = htonl(id->src_ip);
1836 tcp->th_sport = htons(id->dst_port);
1837 tcp->th_dport = htons(id->src_port);
1838 if (flags & TH_RST) { /* we are sending a RST */
1839 if (flags & TH_ACK) {
1840 tcp->th_seq = htonl(ack);
1841 tcp->th_ack = htonl(0);
1842 tcp->th_flags = TH_RST;
1843 } else {
1844 if (flags & TH_SYN)
1845 seq++;
1846 tcp->th_seq = htonl(0);
1847 tcp->th_ack = htonl(seq);
1848 tcp->th_flags = TH_RST | TH_ACK;
1849 }
1850 } else {
1851 /*
1852 * We are sending a keepalive. flags & TH_SYN determines
1853 * the direction, forward if set, reverse if clear.
1854 * NOTE: seq and ack are always assumed to be correct
1855 * as set by the caller. This may be confusing...
1856 */
1857 if (flags & TH_SYN) {
1858 /*
1859 * we have to rewrite the correct addresses!
1860 */
1861 ip->ip_dst.s_addr = htonl(id->dst_ip);
1862 ip->ip_src.s_addr = htonl(id->src_ip);
1863 tcp->th_dport = htons(id->dst_port);
1864 tcp->th_sport = htons(id->src_port);
1865 }
1866 tcp->th_seq = htonl(seq);
1867 tcp->th_ack = htonl(ack);
1868 tcp->th_flags = TH_ACK;
1869 }
1870 /*
1871 * set ip_len to the payload size so we can compute
1872 * the tcp checksum on the pseudoheader
1873 * XXX check this, could save a couple of words ?
1874 */
1875 ip->ip_len = htons(sizeof(struct tcphdr));
1876 tcp->th_sum = in_cksum(m, m->m_pkthdr.len);
1877 /*
1878 * now fill fields left out earlier
1879 */
1880 ip->ip_ttl = ip_defttl;
1881 ip->ip_len = m->m_pkthdr.len;
1882 m->m_flags |= M_SKIP_FIREWALL;
1883
1884 return m;
1885 }
1886
1887 /*
1888 * sends a reject message, consuming the mbuf passed as an argument.
1889 */
1890 static void
1891 send_reject(struct ip_fw_args *args, int code, int offset, __unused int ip_len)
1892 {
1893
1894 if (code != ICMP_REJECT_RST) { /* Send an ICMP unreach */
1895 /* We need the IP header in host order for icmp_error(). */
1896 if (args->fwa_eh != NULL) {
1897 struct ip *ip = mtod(args->fwa_m, struct ip *);
1898 ip->ip_len = ntohs(ip->ip_len);
1899 ip->ip_off = ntohs(ip->ip_off);
1900 }
1901 args->fwa_m->m_flags |= M_SKIP_FIREWALL;
1902 icmp_error(args->fwa_m, ICMP_UNREACH, code, 0L, 0);
1903 } else if (offset == 0 && args->fwa_id.proto == IPPROTO_TCP) {
1904 struct tcphdr *const tcp =
1905 L3HDR(struct tcphdr, mtod(args->fwa_m, struct ip *));
1906 if ( (tcp->th_flags & TH_RST) == 0) {
1907 struct mbuf *m;
1908
1909 m = send_pkt(&(args->fwa_id), ntohl(tcp->th_seq),
1910 ntohl(tcp->th_ack),
1911 tcp->th_flags | TH_RST);
1912 if (m != NULL) {
1913 struct route sro; /* fake route */
1914
1915 bzero (&sro, sizeof (sro));
1916 ip_output(m, NULL, &sro, 0, NULL, NULL);
1917 ROUTE_RELEASE(&sro);
1918 }
1919 }
1920 m_freem(args->fwa_m);
1921 } else
1922 m_freem(args->fwa_m);
1923 args->fwa_m = NULL;
1924 }
1925
1926 /**
1927 *
1928 * Given an ip_fw *, lookup_next_rule will return a pointer
1929 * to the next rule, which can be either the jump
1930 * target (for skipto instructions) or the next one in the list (in
1931 * all other cases including a missing jump target).
1932 * The result is also written in the "next_rule" field of the rule.
1933 * Backward jumps are not allowed, so start looking from the next
1934 * rule...
1935 *
1936 * This never returns NULL -- in case we do not have an exact match,
1937 * the next rule is returned. When the ruleset is changed,
1938 * pointers are flushed so we are always correct.
1939 */
1940
1941 static struct ip_fw *
1942 lookup_next_rule(struct ip_fw *me)
1943 {
1944 struct ip_fw *rule = NULL;
1945 ipfw_insn *cmd;
1946
1947 /* look for action, in case it is a skipto */
1948 cmd = ACTION_PTR(me);
1949 if (cmd->opcode == O_LOG)
1950 cmd += F_LEN(cmd);
1951 if ( cmd->opcode == O_SKIPTO )
1952 for (rule = me->next; rule ; rule = rule->next)
1953 if (rule->rulenum >= cmd->arg1)
1954 break;
1955 if (rule == NULL) /* failure or not a skipto */
1956 rule = me->next;
1957 me->next_rule = rule;
1958 return rule;
1959 }
1960
1961 /*
1962 * The main check routine for the firewall.
1963 *
1964 * All arguments are in args so we can modify them and return them
1965 * back to the caller.
1966 *
1967 * Parameters:
1968 *
1969 * args->fwa_m (in/out) The packet; we set to NULL when/if we nuke it.
1970 * Starts with the IP header.
1971 * args->fwa_eh (in) Mac header if present, or NULL for layer3 packet.
1972 * args->fwa_oif Outgoing interface, or NULL if packet is incoming.
1973 * The incoming interface is in the mbuf. (in)
1974 * args->fwa_divert_rule (in/out)
1975 * Skip up to the first rule past this rule number;
1976 * upon return, non-zero port number for divert or tee.
1977 *
1978 * args->fwa_ipfw_rule Pointer to the last matching rule (in/out)
1979 * args->fwa_next_hop Socket we are forwarding to (out).
1980 * args->fwa_id Addresses grabbed from the packet (out)
1981 *
1982 * Return value:
1983 *
1984 * IP_FW_PORT_DENY_FLAG the packet must be dropped.
1985 * 0 The packet is to be accepted and routed normally OR
1986 * the packet was denied/rejected and has been dropped;
1987 * in the latter case, *m is equal to NULL upon return.
1988 * port Divert the packet to port, with these caveats:
1989 *
1990 * - If IP_FW_PORT_TEE_FLAG is set, tee the packet instead
1991 * of diverting it (ie, 'ipfw tee').
1992 *
1993 * - If IP_FW_PORT_DYNT_FLAG is set, interpret the lower
1994 * 16 bits as a dummynet pipe number instead of diverting
1995 */
1996
1997 static int
1998 ipfw_chk(struct ip_fw_args *args)
1999 {
2000 /*
2001 * Local variables hold state during the processing of a packet.
2002 *
2003 * IMPORTANT NOTE: to speed up the processing of rules, there
2004 * are some assumption on the values of the variables, which
2005 * are documented here. Should you change them, please check
2006 * the implementation of the various instructions to make sure
2007 * that they still work.
2008 *
2009 * args->fwa_eh The MAC header. It is non-null for a layer2
2010 * packet, it is NULL for a layer-3 packet.
2011 *
2012 * m | args->fwa_m Pointer to the mbuf, as received from the caller.
2013 * It may change if ipfw_chk() does an m_pullup, or if it
2014 * consumes the packet because it calls send_reject().
2015 * XXX This has to change, so that ipfw_chk() never modifies
2016 * or consumes the buffer.
2017 * ip is simply an alias of the value of m, and it is kept
2018 * in sync with it (the packet is supposed to start with
2019 * the ip header).
2020 */
2021 struct mbuf *m = args->fwa_m;
2022 struct ip *ip = mtod(m, struct ip *);
2023
2024 /*
2025 * oif | args->fwa_oif If NULL, ipfw_chk has been called on the
2026 * inbound path (ether_input, bdg_forward, ip_input).
2027 * If non-NULL, ipfw_chk has been called on the outbound path
2028 * (ether_output, ip_output).
2029 */
2030 struct ifnet *oif = args->fwa_oif;
2031
2032 struct ip_fw *f = NULL; /* matching rule */
2033 int retval = 0;
2034
2035 /*
2036 * hlen The length of the IPv4 header.
2037 * hlen >0 means we have an IPv4 packet.
2038 */
2039 u_int hlen = 0; /* hlen >0 means we have an IP pkt */
2040
2041 /*
2042 * offset The offset of a fragment. offset != 0 means that
2043 * we have a fragment at this offset of an IPv4 packet.
2044 * offset == 0 means that (if this is an IPv4 packet)
2045 * this is the first or only fragment.
2046 */
2047 u_short offset = 0;
2048
2049 /*
2050 * Local copies of addresses. They are only valid if we have
2051 * an IP packet.
2052 *
2053 * proto The protocol. Set to 0 for non-ip packets,
2054 * or to the protocol read from the packet otherwise.
2055 * proto != 0 means that we have an IPv4 packet.
2056 *
2057 * src_port, dst_port port numbers, in HOST format. Only
2058 * valid for TCP and UDP packets.
2059 *
2060 * src_ip, dst_ip ip addresses, in NETWORK format.
2061 * Only valid for IPv4 packets.
2062 */
2063 u_int8_t proto;
2064 u_int16_t src_port = 0, dst_port = 0; /* NOTE: host format */
2065 struct in_addr src_ip = { 0 } , dst_ip = { 0 }; /* NOTE: network format */
2066 u_int16_t ip_len=0;
2067 int pktlen;
2068 int dyn_dir = MATCH_UNKNOWN;
2069 ipfw_dyn_rule *q = NULL;
2070 struct timeval timenow;
2071
2072 if (m->m_flags & M_SKIP_FIREWALL || fw_bypass) {
2073 return 0; /* accept */
2074 }
2075
2076 /*
2077 * Clear packet chain if we find one here.
2078 */
2079
2080 if (m->m_nextpkt != NULL) {
2081 m_freem_list(m->m_nextpkt);
2082 m->m_nextpkt = NULL;
2083 }
2084
2085 lck_mtx_lock(ipfw_mutex);
2086
2087 getmicrotime(&timenow);
2088 /*
2089 * dyn_dir = MATCH_UNKNOWN when rules unchecked,
2090 * MATCH_NONE when checked and not matched (q = NULL),
2091 * MATCH_FORWARD or MATCH_REVERSE otherwise (q != NULL)
2092 */
2093
2094 pktlen = m->m_pkthdr.len;
2095 if (args->fwa_eh == NULL || /* layer 3 packet */
2096 ( m->m_pkthdr.len >= sizeof(struct ip) &&
2097 ntohs(args->fwa_eh->ether_type) == ETHERTYPE_IP))
2098 hlen = ip->ip_hl << 2;
2099
2100 /*
2101 * Collect parameters into local variables for faster matching.
2102 */
2103 if (hlen == 0) { /* do not grab addresses for non-ip pkts */
2104 proto = args->fwa_id.proto = 0; /* mark f_id invalid */
2105 goto after_ip_checks;
2106 }
2107
2108 proto = args->fwa_id.proto = ip->ip_p;
2109 src_ip = ip->ip_src;
2110 dst_ip = ip->ip_dst;
2111 if (args->fwa_eh != NULL) { /* layer 2 packets are as on the wire */
2112 offset = ntohs(ip->ip_off) & IP_OFFMASK;
2113 ip_len = ntohs(ip->ip_len);
2114 } else {
2115 offset = ip->ip_off & IP_OFFMASK;
2116 ip_len = ip->ip_len;
2117 }
2118 pktlen = ip_len < pktlen ? ip_len : pktlen;
2119
2120 #define PULLUP_TO(len) \
2121 do { \
2122 if ((m)->m_len < (len)) { \
2123 args->fwa_m = m = m_pullup(m, (len)); \
2124 if (m == 0) \
2125 goto pullup_failed; \
2126 ip = mtod(m, struct ip *); \
2127 } \
2128 } while (0)
2129
2130 if (offset == 0) {
2131 switch (proto) {
2132 case IPPROTO_TCP:
2133 {
2134 struct tcphdr *tcp;
2135
2136 PULLUP_TO(hlen + sizeof(struct tcphdr));
2137 tcp = L3HDR(struct tcphdr, ip);
2138 dst_port = tcp->th_dport;
2139 src_port = tcp->th_sport;
2140 args->fwa_id.flags = tcp->th_flags;
2141 }
2142 break;
2143
2144 case IPPROTO_UDP:
2145 {
2146 struct udphdr *udp;
2147
2148 PULLUP_TO(hlen + sizeof(struct udphdr));
2149 udp = L3HDR(struct udphdr, ip);
2150 dst_port = udp->uh_dport;
2151 src_port = udp->uh_sport;
2152 }
2153 break;
2154
2155 case IPPROTO_ICMP:
2156 PULLUP_TO(hlen + 4); /* type, code and checksum. */
2157 args->fwa_id.flags = L3HDR(struct icmp, ip)->icmp_type;
2158 break;
2159
2160 default:
2161 break;
2162 }
2163 #undef PULLUP_TO
2164 }
2165
2166 args->fwa_id.src_ip = ntohl(src_ip.s_addr);
2167 args->fwa_id.dst_ip = ntohl(dst_ip.s_addr);
2168 args->fwa_id.src_port = src_port = ntohs(src_port);
2169 args->fwa_id.dst_port = dst_port = ntohs(dst_port);
2170
2171 after_ip_checks:
2172 if (args->fwa_ipfw_rule) {
2173 /*
2174 * Packet has already been tagged. Look for the next rule
2175 * to restart processing.
2176 *
2177 * If fw_one_pass != 0 then just accept it.
2178 * XXX should not happen here, but optimized out in
2179 * the caller.
2180 */
2181 if (fw_one_pass) {
2182 lck_mtx_unlock(ipfw_mutex);
2183 return 0;
2184 }
2185
2186 f = args->fwa_ipfw_rule->next_rule;
2187 if (f == NULL)
2188 f = lookup_next_rule(args->fwa_ipfw_rule);
2189 } else {
2190 /*
2191 * Find the starting rule. It can be either the first
2192 * one, or the one after divert_rule if asked so.
2193 */
2194 int skipto = args->fwa_divert_rule;
2195
2196 f = layer3_chain;
2197 if (args->fwa_eh == NULL && skipto != 0) {
2198 if (skipto >= IPFW_DEFAULT_RULE) {
2199 lck_mtx_unlock(ipfw_mutex);
2200 return(IP_FW_PORT_DENY_FLAG); /* invalid */
2201 }
2202 while (f && f->rulenum <= skipto)
2203 f = f->next;
2204 if (f == NULL) { /* drop packet */
2205 lck_mtx_unlock(ipfw_mutex);
2206 return(IP_FW_PORT_DENY_FLAG);
2207 }
2208 }
2209 }
2210 args->fwa_divert_rule = 0; /* reset to avoid confusion later */
2211
2212 /*
2213 * Now scan the rules, and parse microinstructions for each rule.
2214 */
2215 for (; f; f = f->next) {
2216 int l, cmdlen;
2217 ipfw_insn *cmd;
2218 int skip_or; /* skip rest of OR block */
2219
2220 again:
2221 if (f->reserved_1 == IPFW_RULE_INACTIVE) {
2222 continue;
2223 }
2224
2225 if (set_disable & (1 << f->set) )
2226 continue;
2227
2228 skip_or = 0;
2229 for (l = f->cmd_len, cmd = f->cmd ; l > 0 ;
2230 l -= cmdlen, cmd += cmdlen) {
2231 int match;
2232
2233 /*
2234 * check_body is a jump target used when we find a
2235 * CHECK_STATE, and need to jump to the body of
2236 * the target rule.
2237 */
2238
2239 check_body:
2240 cmdlen = F_LEN(cmd);
2241 /*
2242 * An OR block (insn_1 || .. || insn_n) has the
2243 * F_OR bit set in all but the last instruction.
2244 * The first match will set "skip_or", and cause
2245 * the following instructions to be skipped until
2246 * past the one with the F_OR bit clear.
2247 */
2248 if (skip_or) { /* skip this instruction */
2249 if ((cmd->len & F_OR) == 0)
2250 skip_or = 0; /* next one is good */
2251 continue;
2252 }
2253 match = 0; /* set to 1 if we succeed */
2254
2255 switch (cmd->opcode) {
2256 /*
2257 * The first set of opcodes compares the packet's
2258 * fields with some pattern, setting 'match' if a
2259 * match is found. At the end of the loop there is
2260 * logic to deal with F_NOT and F_OR flags associated
2261 * with the opcode.
2262 */
2263 case O_NOP:
2264 match = 1;
2265 break;
2266
2267 case O_FORWARD_MAC:
2268 printf("ipfw: opcode %d unimplemented\n",
2269 cmd->opcode);
2270 break;
2271
2272 #ifndef __APPLE__
2273 case O_GID:
2274 #endif
2275 case O_UID:
2276 /*
2277 * We only check offset == 0 && proto != 0,
2278 * as this ensures that we have an IPv4
2279 * packet with the ports info.
2280 */
2281 if (offset!=0)
2282 break;
2283
2284 {
2285 struct inpcbinfo *pi;
2286 int wildcard;
2287 struct inpcb *pcb;
2288
2289 if (proto == IPPROTO_TCP) {
2290 wildcard = 0;
2291 pi = &tcbinfo;
2292 } else if (proto == IPPROTO_UDP) {
2293 wildcard = 1;
2294 pi = &udbinfo;
2295 } else
2296 break;
2297
2298 pcb = (oif) ?
2299 in_pcblookup_hash(pi,
2300 dst_ip, htons(dst_port),
2301 src_ip, htons(src_port),
2302 wildcard, oif) :
2303 in_pcblookup_hash(pi,
2304 src_ip, htons(src_port),
2305 dst_ip, htons(dst_port),
2306 wildcard, NULL);
2307
2308 if (pcb == NULL || pcb->inp_socket == NULL)
2309 break;
2310 #if __FreeBSD_version < 500034
2311 #define socheckuid(a,b) (kauth_cred_getuid((a)->so_cred) != (b))
2312 #endif
2313 if (cmd->opcode == O_UID) {
2314 match =
2315 #ifdef __APPLE__
2316 (kauth_cred_getuid(pcb->inp_socket->so_cred) == (uid_t)((ipfw_insn_u32 *)cmd)->d[0]);
2317 #else
2318 !socheckuid(pcb->inp_socket,
2319 (uid_t)((ipfw_insn_u32 *)cmd)->d[0]);
2320 #endif
2321 }
2322 #ifndef __APPLE__
2323 else {
2324 match = 0;
2325 kauth_cred_ismember_gid(pcb->inp_socket->so_cred,
2326 (gid_t)((ipfw_insn_u32 *)cmd)->d[0], &match);
2327 }
2328 #endif
2329 /* release reference on pcb */
2330 in_pcb_checkstate(pcb, WNT_RELEASE, 0);
2331 }
2332
2333 break;
2334
2335 case O_RECV:
2336 match = iface_match(m->m_pkthdr.rcvif,
2337 (ipfw_insn_if *)cmd);
2338 break;
2339
2340 case O_XMIT:
2341 match = iface_match(oif, (ipfw_insn_if *)cmd);
2342 break;
2343
2344 case O_VIA:
2345 match = iface_match(oif ? oif :
2346 m->m_pkthdr.rcvif, (ipfw_insn_if *)cmd);
2347 break;
2348
2349 case O_MACADDR2:
2350 if (args->fwa_eh != NULL) { /* have MAC header */
2351 u_int32_t *want = (u_int32_t *)
2352 ((ipfw_insn_mac *)cmd)->addr;
2353 u_int32_t *mask = (u_int32_t *)
2354 ((ipfw_insn_mac *)cmd)->mask;
2355 u_int32_t *hdr = (u_int32_t *)args->fwa_eh;
2356
2357 match =
2358 ( want[0] == (hdr[0] & mask[0]) &&
2359 want[1] == (hdr[1] & mask[1]) &&
2360 want[2] == (hdr[2] & mask[2]) );
2361 }
2362 break;
2363
2364 case O_MAC_TYPE:
2365 if (args->fwa_eh != NULL) {
2366 u_int16_t t =
2367 ntohs(args->fwa_eh->ether_type);
2368 u_int16_t *p =
2369 ((ipfw_insn_u16 *)cmd)->ports;
2370 int i;
2371
2372 for (i = cmdlen - 1; !match && i>0;
2373 i--, p += 2)
2374 match = (t>=p[0] && t<=p[1]);
2375 }
2376 break;
2377
2378 case O_FRAG:
2379 match = (hlen > 0 && offset != 0);
2380 break;
2381
2382 case O_IN: /* "out" is "not in" */
2383 match = (oif == NULL);
2384 break;
2385
2386 case O_LAYER2:
2387 match = (args->fwa_eh != NULL);
2388 break;
2389
2390 case O_PROTO:
2391 /*
2392 * We do not allow an arg of 0 so the
2393 * check of "proto" only suffices.
2394 */
2395 match = (proto == cmd->arg1);
2396 break;
2397
2398 case O_IP_SRC:
2399 match = (hlen > 0 &&
2400 ((ipfw_insn_ip *)cmd)->addr.s_addr ==
2401 src_ip.s_addr);
2402 break;
2403
2404 case O_IP_SRC_MASK:
2405 case O_IP_DST_MASK:
2406 if (hlen > 0) {
2407 uint32_t a =
2408 (cmd->opcode == O_IP_DST_MASK) ?
2409 dst_ip.s_addr : src_ip.s_addr;
2410 uint32_t *p = ((ipfw_insn_u32 *)cmd)->d;
2411 int i = cmdlen-1;
2412
2413 for (; !match && i>0; i-= 2, p+= 2)
2414 match = (p[0] == (a & p[1]));
2415 }
2416 break;
2417
2418 case O_IP_SRC_ME:
2419 if (hlen > 0) {
2420 struct ifnet *tif;
2421
2422 INADDR_TO_IFP(src_ip, tif);
2423 match = (tif != NULL);
2424 }
2425 break;
2426
2427 case O_IP_DST_SET:
2428 case O_IP_SRC_SET:
2429 if (hlen > 0) {
2430 u_int32_t *d = (u_int32_t *)(cmd+1);
2431 u_int32_t addr =
2432 cmd->opcode == O_IP_DST_SET ?
2433 args->fwa_id.dst_ip :
2434 args->fwa_id.src_ip;
2435
2436 if (addr < d[0])
2437 break;
2438 addr -= d[0]; /* subtract base */
2439 match = (addr < cmd->arg1) &&
2440 ( d[ 1 + (addr>>5)] &
2441 (1<<(addr & 0x1f)) );
2442 }
2443 break;
2444
2445 case O_IP_DST:
2446 match = (hlen > 0 &&
2447 ((ipfw_insn_ip *)cmd)->addr.s_addr ==
2448 dst_ip.s_addr);
2449 break;
2450
2451 case O_IP_DST_ME:
2452 if (hlen > 0) {
2453 struct ifnet *tif;
2454
2455 INADDR_TO_IFP(dst_ip, tif);
2456 match = (tif != NULL);
2457 }
2458 break;
2459
2460 case O_IP_SRCPORT:
2461 case O_IP_DSTPORT:
2462 /*
2463 * offset == 0 && proto != 0 is enough
2464 * to guarantee that we have an IPv4
2465 * packet with port info.
2466 */
2467 if ((proto==IPPROTO_UDP || proto==IPPROTO_TCP)
2468 && offset == 0) {
2469 u_int16_t x =
2470 (cmd->opcode == O_IP_SRCPORT) ?
2471 src_port : dst_port ;
2472 u_int16_t *p =
2473 ((ipfw_insn_u16 *)cmd)->ports;
2474 int i;
2475
2476 for (i = cmdlen - 1; !match && i>0;
2477 i--, p += 2)
2478 match = (x>=p[0] && x<=p[1]);
2479 }
2480 break;
2481
2482 case O_ICMPTYPE:
2483 match = (offset == 0 && proto==IPPROTO_ICMP &&
2484 icmptype_match(ip, (ipfw_insn_u32 *)cmd) );
2485 break;
2486
2487 case O_IPOPT:
2488 match = (hlen > 0 && ipopts_match(ip, cmd) );
2489 break;
2490
2491 case O_IPVER:
2492 match = (hlen > 0 && cmd->arg1 == ip->ip_v);
2493 break;
2494
2495 case O_IPID:
2496 case O_IPLEN:
2497 case O_IPTTL:
2498 if (hlen > 0) { /* only for IP packets */
2499 uint16_t x;
2500 uint16_t *p;
2501 int i;
2502
2503 if (cmd->opcode == O_IPLEN)
2504 x = ip_len;
2505 else if (cmd->opcode == O_IPTTL)
2506 x = ip->ip_ttl;
2507 else /* must be IPID */
2508 x = ntohs(ip->ip_id);
2509 if (cmdlen == 1) {
2510 match = (cmd->arg1 == x);
2511 break;
2512 }
2513 /* otherwise we have ranges */
2514 p = ((ipfw_insn_u16 *)cmd)->ports;
2515 i = cmdlen - 1;
2516 for (; !match && i>0; i--, p += 2)
2517 match = (x >= p[0] && x <= p[1]);
2518 }
2519 break;
2520
2521 case O_IPPRECEDENCE:
2522 match = (hlen > 0 &&
2523 (cmd->arg1 == (ip->ip_tos & 0xe0)) );
2524 break;
2525
2526 case O_IPTOS:
2527 match = (hlen > 0 &&
2528 flags_match(cmd, ip->ip_tos));
2529 break;
2530
2531 case O_TCPFLAGS:
2532 match = (proto == IPPROTO_TCP && offset == 0 &&
2533 flags_match(cmd,
2534 L3HDR(struct tcphdr,ip)->th_flags));
2535 break;
2536
2537 case O_TCPOPTS:
2538 match = (proto == IPPROTO_TCP && offset == 0 &&
2539 tcpopts_match(ip, cmd));
2540 break;
2541
2542 case O_TCPSEQ:
2543 match = (proto == IPPROTO_TCP && offset == 0 &&
2544 ((ipfw_insn_u32 *)cmd)->d[0] ==
2545 L3HDR(struct tcphdr,ip)->th_seq);
2546 break;
2547
2548 case O_TCPACK:
2549 match = (proto == IPPROTO_TCP && offset == 0 &&
2550 ((ipfw_insn_u32 *)cmd)->d[0] ==
2551 L3HDR(struct tcphdr,ip)->th_ack);
2552 break;
2553
2554 case O_TCPWIN:
2555 match = (proto == IPPROTO_TCP && offset == 0 &&
2556 cmd->arg1 ==
2557 L3HDR(struct tcphdr,ip)->th_win);
2558 break;
2559
2560 case O_ESTAB:
2561 /* reject packets which have SYN only */
2562 /* XXX should i also check for TH_ACK ? */
2563 match = (proto == IPPROTO_TCP && offset == 0 &&
2564 (L3HDR(struct tcphdr,ip)->th_flags &
2565 (TH_RST | TH_ACK | TH_SYN)) != TH_SYN);
2566 break;
2567
2568 case O_LOG:
2569 if (fw_verbose)
2570 ipfw_log(f, hlen, args->fwa_eh, m, oif);
2571 match = 1;
2572 break;
2573
2574 case O_PROB:
2575 match = (random()<((ipfw_insn_u32 *)cmd)->d[0]);
2576 break;
2577
2578 case O_VERREVPATH:
2579 /* Outgoing packets automatically pass/match */
2580 match = ((oif != NULL) ||
2581 (m->m_pkthdr.rcvif == NULL) ||
2582 verify_rev_path(src_ip, m->m_pkthdr.rcvif));
2583 break;
2584
2585 case O_IPSEC:
2586 #ifdef FAST_IPSEC
2587 match = (m_tag_find(m,
2588 PACKET_TAG_IPSEC_IN_DONE, NULL) != NULL);
2589 #endif
2590 #ifdef IPSEC
2591 match = (ipsec_gethist(m, NULL) != NULL);
2592 #endif
2593 /* otherwise no match */
2594 break;
2595
2596 /*
2597 * The second set of opcodes represents 'actions',
2598 * i.e. the terminal part of a rule once the packet
2599 * matches all previous patterns.
2600 * Typically there is only one action for each rule,
2601 * and the opcode is stored at the end of the rule
2602 * (but there are exceptions -- see below).
2603 *
2604 * In general, here we set retval and terminate the
2605 * outer loop (would be a 'break 3' in some language,
2606 * but we need to do a 'goto done').
2607 *
2608 * Exceptions:
2609 * O_COUNT and O_SKIPTO actions:
2610 * instead of terminating, we jump to the next rule
2611 * ('goto next_rule', equivalent to a 'break 2'),
2612 * or to the SKIPTO target ('goto again' after
2613 * having set f, cmd and l), respectively.
2614 *
2615 * O_LIMIT and O_KEEP_STATE: these opcodes are
2616 * not real 'actions', and are stored right
2617 * before the 'action' part of the rule.
2618 * These opcodes try to install an entry in the
2619 * state tables; if successful, we continue with
2620 * the next opcode (match=1; break;), otherwise
2621 * the packet * must be dropped
2622 * ('goto done' after setting retval);
2623 *
2624 * O_PROBE_STATE and O_CHECK_STATE: these opcodes
2625 * cause a lookup of the state table, and a jump
2626 * to the 'action' part of the parent rule
2627 * ('goto check_body') if an entry is found, or
2628 * (CHECK_STATE only) a jump to the next rule if
2629 * the entry is not found ('goto next_rule').
2630 * The result of the lookup is cached to make
2631 * further instances of these opcodes are
2632 * effectively NOPs.
2633 */
2634 case O_LIMIT:
2635 case O_KEEP_STATE:
2636 if (install_state(f,
2637 (ipfw_insn_limit *)cmd, args)) {
2638 retval = IP_FW_PORT_DENY_FLAG;
2639 goto done; /* error/limit violation */
2640 }
2641 match = 1;
2642 break;
2643
2644 case O_PROBE_STATE:
2645 case O_CHECK_STATE:
2646 /*
2647 * dynamic rules are checked at the first
2648 * keep-state or check-state occurrence,
2649 * with the result being stored in dyn_dir.
2650 * The compiler introduces a PROBE_STATE
2651 * instruction for us when we have a
2652 * KEEP_STATE (because PROBE_STATE needs
2653 * to be run first).
2654 */
2655 if (dyn_dir == MATCH_UNKNOWN &&
2656 (q = lookup_dyn_rule(&args->fwa_id,
2657 &dyn_dir, proto == IPPROTO_TCP ?
2658 L3HDR(struct tcphdr, ip) : NULL))
2659 != NULL) {
2660 /*
2661 * Found dynamic entry, update stats
2662 * and jump to the 'action' part of
2663 * the parent rule.
2664 */
2665 q->pcnt++;
2666 q->bcnt += pktlen;
2667 f = q->rule;
2668 cmd = ACTION_PTR(f);
2669 l = f->cmd_len - f->act_ofs;
2670 goto check_body;
2671 }
2672 /*
2673 * Dynamic entry not found. If CHECK_STATE,
2674 * skip to next rule, if PROBE_STATE just
2675 * ignore and continue with next opcode.
2676 */
2677 if (cmd->opcode == O_CHECK_STATE)
2678 goto next_rule;
2679 match = 1;
2680 break;
2681
2682 case O_ACCEPT:
2683 retval = 0; /* accept */
2684 goto done;
2685
2686 case O_PIPE:
2687 case O_QUEUE:
2688 args->fwa_ipfw_rule = f; /* report matching rule */
2689 retval = cmd->arg1 | IP_FW_PORT_DYNT_FLAG;
2690 goto done;
2691
2692 case O_DIVERT:
2693 case O_TEE:
2694 if (args->fwa_eh) /* not on layer 2 */
2695 break;
2696 args->fwa_divert_rule = f->rulenum;
2697 retval = (cmd->opcode == O_DIVERT) ?
2698 cmd->arg1 :
2699 cmd->arg1 | IP_FW_PORT_TEE_FLAG;
2700 goto done;
2701
2702 case O_COUNT:
2703 case O_SKIPTO:
2704 f->pcnt++; /* update stats */
2705 f->bcnt += pktlen;
2706 f->timestamp = timenow.tv_sec;
2707 if (cmd->opcode == O_COUNT)
2708 goto next_rule;
2709 /* handle skipto */
2710 if (f->next_rule == NULL)
2711 lookup_next_rule(f);
2712 f = f->next_rule;
2713 goto again;
2714
2715 case O_REJECT:
2716 /*
2717 * Drop the packet and send a reject notice
2718 * if the packet is not ICMP (or is an ICMP
2719 * query), and it is not multicast/broadcast.
2720 */
2721 if (hlen > 0 && offset == 0 &&
2722 (proto != IPPROTO_ICMP ||
2723 is_icmp_query(ip)) &&
2724 !(m->m_flags & (M_BCAST|M_MCAST)) &&
2725 !IN_MULTICAST(dst_ip.s_addr)) {
2726 send_reject(args, cmd->arg1,
2727 offset,ip_len);
2728 m = args->fwa_m;
2729 }
2730 /* FALLTHROUGH */
2731 case O_DENY:
2732 retval = IP_FW_PORT_DENY_FLAG;
2733 goto done;
2734
2735 case O_FORWARD_IP:
2736 if (args->fwa_eh) /* not valid on layer2 pkts */
2737 break;
2738 if (!q || dyn_dir == MATCH_FORWARD)
2739 args->fwa_next_hop =
2740 &((ipfw_insn_sa *)cmd)->sa;
2741 retval = 0;
2742 goto done;
2743
2744 default:
2745 panic("-- unknown opcode %d\n", cmd->opcode);
2746 } /* end of switch() on opcodes */
2747
2748 if (cmd->len & F_NOT)
2749 match = !match;
2750
2751 if (match) {
2752 if (cmd->len & F_OR)
2753 skip_or = 1;
2754 } else {
2755 if (!(cmd->len & F_OR)) /* not an OR block, */
2756 break; /* try next rule */
2757 }
2758
2759 } /* end of inner for, scan opcodes */
2760
2761 next_rule:; /* try next rule */
2762
2763 } /* end of outer for, scan rules */
2764 printf("ipfw: ouch!, skip past end of rules, denying packet\n");
2765 lck_mtx_unlock(ipfw_mutex);
2766 return(IP_FW_PORT_DENY_FLAG);
2767
2768 done:
2769 /* Update statistics */
2770 f->pcnt++;
2771 f->bcnt += pktlen;
2772 f->timestamp = timenow.tv_sec;
2773 lck_mtx_unlock(ipfw_mutex);
2774 return retval;
2775
2776 pullup_failed:
2777 if (fw_verbose)
2778 printf("ipfw: pullup failed\n");
2779 lck_mtx_unlock(ipfw_mutex);
2780 return(IP_FW_PORT_DENY_FLAG);
2781 }
2782
2783 /*
2784 * When a rule is added/deleted, clear the next_rule pointers in all rules.
2785 * These will be reconstructed on the fly as packets are matched.
2786 * Must be called at splimp().
2787 */
2788 static void
2789 flush_rule_ptrs(void)
2790 {
2791 struct ip_fw *rule;
2792
2793 for (rule = layer3_chain; rule; rule = rule->next)
2794 rule->next_rule = NULL;
2795 }
2796
2797 /*
2798 * When pipes/queues are deleted, clear the "pipe_ptr" pointer to a given
2799 * pipe/queue, or to all of them (match == NULL).
2800 * Must be called at splimp().
2801 */
2802 void
2803 flush_pipe_ptrs(struct dn_flow_set *match)
2804 {
2805 struct ip_fw *rule;
2806
2807 for (rule = layer3_chain; rule; rule = rule->next) {
2808 ipfw_insn_pipe *cmd = (ipfw_insn_pipe *)ACTION_PTR(rule);
2809
2810 if (cmd->o.opcode != O_PIPE && cmd->o.opcode != O_QUEUE)
2811 continue;
2812 /*
2813 * XXX Use bcmp/bzero to handle pipe_ptr to overcome
2814 * possible alignment problems on 64-bit architectures.
2815 * This code is seldom used so we do not worry too
2816 * much about efficiency.
2817 */
2818 if (match == NULL ||
2819 !bcmp(&cmd->pipe_ptr, &match, sizeof(match)) )
2820 bzero(&cmd->pipe_ptr, sizeof(cmd->pipe_ptr));
2821 }
2822 }
2823
2824 /*
2825 * Add a new rule to the list. Copy the rule into a malloc'ed area, then
2826 * possibly create a rule number and add the rule to the list.
2827 * Update the rule_number in the input struct so the caller knows it as well.
2828 */
2829 static int
2830 add_rule(struct ip_fw **head, struct ip_fw *input_rule)
2831 {
2832 struct ip_fw *rule, *f, *prev;
2833 int l = RULESIZE(input_rule);
2834
2835 if (*head == NULL && input_rule->rulenum != IPFW_DEFAULT_RULE)
2836 return (EINVAL);
2837
2838 rule = _MALLOC(l, M_IPFW, M_WAIT | M_ZERO);
2839 if (rule == NULL) {
2840 printf("ipfw2: add_rule MALLOC failed\n");
2841 return (ENOSPC);
2842 }
2843
2844 bcopy(input_rule, rule, l);
2845
2846 rule->next = NULL;
2847 rule->next_rule = NULL;
2848
2849 rule->pcnt = 0;
2850 rule->bcnt = 0;
2851 rule->timestamp = 0;
2852
2853 if (*head == NULL) { /* default rule */
2854 *head = rule;
2855 goto done;
2856 }
2857
2858 /*
2859 * If rulenum is 0, find highest numbered rule before the
2860 * default rule, and add autoinc_step
2861 */
2862 if (autoinc_step < 1)
2863 autoinc_step = 1;
2864 else if (autoinc_step > 1000)
2865 autoinc_step = 1000;
2866 if (rule->rulenum == 0) {
2867 /*
2868 * locate the highest numbered rule before default
2869 */
2870 for (f = *head; f; f = f->next) {
2871 if (f->rulenum == IPFW_DEFAULT_RULE)
2872 break;
2873 rule->rulenum = f->rulenum;
2874 }
2875 if (rule->rulenum < IPFW_DEFAULT_RULE - autoinc_step)
2876 rule->rulenum += autoinc_step;
2877 input_rule->rulenum = rule->rulenum;
2878 }
2879
2880 /*
2881 * Now insert the new rule in the right place in the sorted list.
2882 */
2883 for (prev = NULL, f = *head; f; prev = f, f = f->next) {
2884 if (f->rulenum > rule->rulenum) { /* found the location */
2885 if (prev) {
2886 rule->next = f;
2887 prev->next = rule;
2888 } else { /* head insert */
2889 rule->next = *head;
2890 *head = rule;
2891 }
2892 break;
2893 }
2894 }
2895 flush_rule_ptrs();
2896 done:
2897 static_count++;
2898 static_len += l;
2899 static_len_32 += RULESIZE32(input_rule);
2900 static_len_64 += RULESIZE64(input_rule);
2901 DEB(printf("ipfw: installed rule %d, static count now %d\n",
2902 rule->rulenum, static_count);)
2903 return (0);
2904 }
2905
2906 /**
2907 * Free storage associated with a static rule (including derived
2908 * dynamic rules).
2909 * The caller is in charge of clearing rule pointers to avoid
2910 * dangling pointers.
2911 * @return a pointer to the next entry.
2912 * Arguments are not checked, so they better be correct.
2913 * Must be called at splimp().
2914 */
2915 static struct ip_fw *
2916 delete_rule(struct ip_fw **head, struct ip_fw *prev, struct ip_fw *rule)
2917 {
2918 struct ip_fw *n;
2919 int l = RULESIZE(rule);
2920
2921 n = rule->next;
2922 remove_dyn_rule(rule, NULL /* force removal */);
2923 if (prev == NULL)
2924 *head = n;
2925 else
2926 prev->next = n;
2927 static_count--;
2928 static_len -= l;
2929 static_len_32 -= RULESIZE32(rule);
2930 static_len_64 -= RULESIZE64(rule);
2931
2932 #if DUMMYNET
2933 if (DUMMYNET_LOADED)
2934 dn_ipfw_rule_delete(rule);
2935 #endif /* DUMMYNET */
2936 _FREE(rule, M_IPFW);
2937 return n;
2938 }
2939
2940 #if DEBUG_INACTIVE_RULES
2941 static void
2942 print_chain(struct ip_fw **chain)
2943 {
2944 struct ip_fw *rule = *chain;
2945
2946 for (; rule; rule = rule->next) {
2947 ipfw_insn *cmd = ACTION_PTR(rule);
2948
2949 printf("ipfw: rule->rulenum = %d\n", rule->rulenum);
2950
2951 if (rule->reserved_1 == IPFW_RULE_INACTIVE) {
2952 printf("ipfw: rule->reserved = IPFW_RULE_INACTIVE\n");
2953 }
2954
2955 switch (cmd->opcode) {
2956 case O_DENY:
2957 printf("ipfw: ACTION: Deny\n");
2958 break;
2959
2960 case O_REJECT:
2961 if (cmd->arg1==ICMP_REJECT_RST)
2962 printf("ipfw: ACTION: Reset\n");
2963 else if (cmd->arg1==ICMP_UNREACH_HOST)
2964 printf("ipfw: ACTION: Reject\n");
2965 break;
2966
2967 case O_ACCEPT:
2968 printf("ipfw: ACTION: Accept\n");
2969 break;
2970 case O_COUNT:
2971 printf("ipfw: ACTION: Count\n");
2972 break;
2973 case O_DIVERT:
2974 printf("ipfw: ACTION: Divert\n");
2975 break;
2976 case O_TEE:
2977 printf("ipfw: ACTION: Tee\n");
2978 break;
2979 case O_SKIPTO:
2980 printf("ipfw: ACTION: SkipTo\n");
2981 break;
2982 case O_PIPE:
2983 printf("ipfw: ACTION: Pipe\n");
2984 break;
2985 case O_QUEUE:
2986 printf("ipfw: ACTION: Queue\n");
2987 break;
2988 case O_FORWARD_IP:
2989 printf("ipfw: ACTION: Forward\n");
2990 break;
2991 default:
2992 printf("ipfw: invalid action! %d\n", cmd->opcode);
2993 }
2994 }
2995 }
2996 #endif /* DEBUG_INACTIVE_RULES */
2997
2998 static void
2999 flush_inactive(void *param)
3000 {
3001 struct ip_fw *inactive_rule = (struct ip_fw *)param;
3002 struct ip_fw *rule, *prev;
3003
3004 lck_mtx_lock(ipfw_mutex);
3005
3006 for (rule = layer3_chain, prev = NULL; rule; ) {
3007 if (rule == inactive_rule && rule->reserved_1 == IPFW_RULE_INACTIVE) {
3008 struct ip_fw *n = rule;
3009
3010 if (prev == NULL) {
3011 layer3_chain = rule->next;
3012 }
3013 else {
3014 prev->next = rule->next;
3015 }
3016 rule = rule->next;
3017 _FREE(n, M_IPFW);
3018 }
3019 else {
3020 prev = rule;
3021 rule = rule->next;
3022 }
3023 }
3024
3025 #if DEBUG_INACTIVE_RULES
3026 print_chain(&layer3_chain);
3027 #endif
3028 lck_mtx_unlock(ipfw_mutex);
3029 }
3030
3031 static void
3032 mark_inactive(struct ip_fw **prev, struct ip_fw **rule)
3033 {
3034 int l = RULESIZE(*rule);
3035
3036 if ((*rule)->reserved_1 != IPFW_RULE_INACTIVE) {
3037 (*rule)->reserved_1 = IPFW_RULE_INACTIVE;
3038 static_count--;
3039 static_len -= l;
3040 static_len_32 -= RULESIZE32(*rule);
3041 static_len_64 -= RULESIZE64(*rule);
3042
3043 timeout(flush_inactive, *rule, 30*hz); /* 30 sec. */
3044 }
3045
3046 *prev = *rule;
3047 *rule = (*rule)->next;
3048 }
3049
3050 /*
3051 * Deletes all rules from a chain (except rules in set RESVD_SET
3052 * unless kill_default = 1).
3053 * Must be called at splimp().
3054 */
3055 static void
3056 free_chain(struct ip_fw **chain, int kill_default)
3057 {
3058 struct ip_fw *prev, *rule;
3059
3060 flush_rule_ptrs(); /* more efficient to do outside the loop */
3061 for (prev = NULL, rule = *chain; rule ; )
3062 if (kill_default || rule->set != RESVD_SET) {
3063 ipfw_insn *cmd = ACTION_PTR(rule);
3064
3065 /* skip over forwarding rules so struct isn't
3066 * deleted while pointer is still in use elsewhere
3067 */
3068 if (cmd->opcode == O_FORWARD_IP) {
3069 mark_inactive(&prev, &rule);
3070 }
3071 else {
3072 rule = delete_rule(chain, prev, rule);
3073 }
3074 }
3075 else {
3076 prev = rule;
3077 rule = rule->next;
3078 }
3079 }
3080
3081 /**
3082 * Remove all rules with given number, and also do set manipulation.
3083 * Assumes chain != NULL && *chain != NULL.
3084 *
3085 * The argument is an u_int32_t. The low 16 bit are the rule or set number,
3086 * the next 8 bits are the new set, the top 8 bits are the command:
3087 *
3088 * 0 delete rules with given number
3089 * 1 delete rules with given set number
3090 * 2 move rules with given number to new set
3091 * 3 move rules with given set number to new set
3092 * 4 swap sets with given numbers
3093 */
3094 static int
3095 del_entry(struct ip_fw **chain, u_int32_t arg)
3096 {
3097 struct ip_fw *prev = NULL, *rule = *chain;
3098 u_int16_t rulenum; /* rule or old_set */
3099 u_int8_t cmd, new_set;
3100
3101 rulenum = arg & 0xffff;
3102 cmd = (arg >> 24) & 0xff;
3103 new_set = (arg >> 16) & 0xff;
3104
3105 if (cmd > 4)
3106 return EINVAL;
3107 if (new_set > RESVD_SET)
3108 return EINVAL;
3109 if (cmd == 0 || cmd == 2) {
3110 if (rulenum >= IPFW_DEFAULT_RULE)
3111 return EINVAL;
3112 } else {
3113 if (rulenum > RESVD_SET) /* old_set */
3114 return EINVAL;
3115 }
3116
3117 switch (cmd) {
3118 case 0: /* delete rules with given number */
3119 /*
3120 * locate first rule to delete
3121 */
3122 for (; rule->rulenum < rulenum; prev = rule, rule = rule->next)
3123 ;
3124 if (rule->rulenum != rulenum)
3125 return EINVAL;
3126
3127 /*
3128 * flush pointers outside the loop, then delete all matching
3129 * rules. prev remains the same throughout the cycle.
3130 */
3131 flush_rule_ptrs();
3132 while (rule->rulenum == rulenum) {
3133 ipfw_insn *insn = ACTION_PTR(rule);
3134
3135 /* keep forwarding rules around so struct isn't
3136 * deleted while pointer is still in use elsewhere
3137 */
3138 if (insn->opcode == O_FORWARD_IP) {
3139 mark_inactive(&prev, &rule);
3140 }
3141 else {
3142 rule = delete_rule(chain, prev, rule);
3143 }
3144 }
3145 break;
3146
3147 case 1: /* delete all rules with given set number */
3148 flush_rule_ptrs();
3149 while (rule->rulenum < IPFW_DEFAULT_RULE) {
3150 if (rule->set == rulenum) {
3151 ipfw_insn *insn = ACTION_PTR(rule);
3152
3153 /* keep forwarding rules around so struct isn't
3154 * deleted while pointer is still in use elsewhere
3155 */
3156 if (insn->opcode == O_FORWARD_IP) {
3157 mark_inactive(&prev, &rule);
3158 }
3159 else {
3160 rule = delete_rule(chain, prev, rule);
3161 }
3162 }
3163 else {
3164 prev = rule;
3165 rule = rule->next;
3166 }
3167 }
3168 break;
3169
3170 case 2: /* move rules with given number to new set */
3171 for (; rule->rulenum < IPFW_DEFAULT_RULE; rule = rule->next)
3172 if (rule->rulenum == rulenum)
3173 rule->set = new_set;
3174 break;
3175
3176 case 3: /* move rules with given set number to new set */
3177 for (; rule->rulenum < IPFW_DEFAULT_RULE; rule = rule->next)
3178 if (rule->set == rulenum)
3179 rule->set = new_set;
3180 break;
3181
3182 case 4: /* swap two sets */
3183 for (; rule->rulenum < IPFW_DEFAULT_RULE; rule = rule->next)
3184 if (rule->set == rulenum)
3185 rule->set = new_set;
3186 else if (rule->set == new_set)
3187 rule->set = rulenum;
3188 break;
3189 }
3190 return 0;
3191 }
3192
3193 /*
3194 * Clear counters for a specific rule.
3195 */
3196 static void
3197 clear_counters(struct ip_fw *rule, int log_only)
3198 {
3199 ipfw_insn_log *l = (ipfw_insn_log *)ACTION_PTR(rule);
3200
3201 if (log_only == 0) {
3202 rule->bcnt = rule->pcnt = 0;
3203 rule->timestamp = 0;
3204 }
3205 if (l->o.opcode == O_LOG)
3206 l->log_left = l->max_log;
3207 }
3208
3209 /**
3210 * Reset some or all counters on firewall rules.
3211 * @arg frwl is null to clear all entries, or contains a specific
3212 * rule number.
3213 * @arg log_only is 1 if we only want to reset logs, zero otherwise.
3214 */
3215 static int
3216 zero_entry(int rulenum, int log_only)
3217 {
3218 struct ip_fw *rule;
3219 const char *msg;
3220
3221 if (rulenum == 0) {
3222 norule_counter = 0;
3223 for (rule = layer3_chain; rule; rule = rule->next)
3224 clear_counters(rule, log_only);
3225 msg = log_only ? "ipfw: All logging counts reset.\n" :
3226 "ipfw: Accounting cleared.\n";
3227 } else {
3228 int cleared = 0;
3229 /*
3230 * We can have multiple rules with the same number, so we
3231 * need to clear them all.
3232 */
3233 for (rule = layer3_chain; rule; rule = rule->next)
3234 if (rule->rulenum == rulenum) {
3235 while (rule && rule->rulenum == rulenum) {
3236 clear_counters(rule, log_only);
3237 rule = rule->next;
3238 }
3239 cleared = 1;
3240 break;
3241 }
3242 if (!cleared) /* we did not find any matching rules */
3243 return (EINVAL);
3244 msg = log_only ? "ipfw: Entry %d logging count reset.\n" :
3245 "ipfw: Entry %d cleared.\n";
3246 }
3247 if (fw_verbose)
3248 {
3249 dolog((LOG_AUTHPRIV | LOG_NOTICE, msg, rulenum));
3250 }
3251 return (0);
3252 }
3253
3254 /*
3255 * Check validity of the structure before insert.
3256 * Fortunately rules are simple, so this mostly need to check rule sizes.
3257 */
3258 static int
3259 check_ipfw_struct(struct ip_fw *rule, int size)
3260 {
3261 int l, cmdlen = 0;
3262 int have_action=0;
3263 ipfw_insn *cmd;
3264
3265 if (size < sizeof(*rule)) {
3266 printf("ipfw: rule too short\n");
3267 return (EINVAL);
3268 }
3269 /* first, check for valid size */
3270 l = RULESIZE(rule);
3271 if (l != size) {
3272 printf("ipfw: size mismatch (have %d want %d)\n", size, l);
3273 return (EINVAL);
3274 }
3275 /*
3276 * Now go for the individual checks. Very simple ones, basically only
3277 * instruction sizes.
3278 */
3279 for (l = rule->cmd_len, cmd = rule->cmd ;
3280 l > 0 ; l -= cmdlen, cmd += cmdlen) {
3281 cmdlen = F_LEN(cmd);
3282 if (cmdlen > l) {
3283 printf("ipfw: opcode %d size truncated\n",
3284 cmd->opcode);
3285 return EINVAL;
3286 }
3287 DEB(printf("ipfw: opcode %d\n", cmd->opcode);)
3288 switch (cmd->opcode) {
3289 case O_PROBE_STATE:
3290 case O_KEEP_STATE:
3291 case O_PROTO:
3292 case O_IP_SRC_ME:
3293 case O_IP_DST_ME:
3294 case O_LAYER2:
3295 case O_IN:
3296 case O_FRAG:
3297 case O_IPOPT:
3298 case O_IPTOS:
3299 case O_IPPRECEDENCE:
3300 case O_IPVER:
3301 case O_TCPWIN:
3302 case O_TCPFLAGS:
3303 case O_TCPOPTS:
3304 case O_ESTAB:
3305 case O_VERREVPATH:
3306 case O_IPSEC:
3307 if (cmdlen != F_INSN_SIZE(ipfw_insn))
3308 goto bad_size;
3309 break;
3310 case O_UID:
3311 #ifndef __APPLE__
3312 case O_GID:
3313 #endif /* __APPLE__ */
3314 case O_IP_SRC:
3315 case O_IP_DST:
3316 case O_TCPSEQ:
3317 case O_TCPACK:
3318 case O_PROB:
3319 case O_ICMPTYPE:
3320 if (cmdlen != F_INSN_SIZE(ipfw_insn_u32))
3321 goto bad_size;
3322 break;
3323
3324 case O_LIMIT:
3325 if (cmdlen != F_INSN_SIZE(ipfw_insn_limit))
3326 goto bad_size;
3327 break;
3328
3329 case O_LOG:
3330 if (cmdlen != F_INSN_SIZE(ipfw_insn_log))
3331 goto bad_size;
3332
3333 /* enforce logging limit */
3334 if (fw_verbose &&
3335 ((ipfw_insn_log *)cmd)->max_log == 0 && verbose_limit != 0) {
3336 ((ipfw_insn_log *)cmd)->max_log = verbose_limit;
3337 }
3338
3339 ((ipfw_insn_log *)cmd)->log_left =
3340 ((ipfw_insn_log *)cmd)->max_log;
3341
3342 break;
3343
3344 case O_IP_SRC_MASK:
3345 case O_IP_DST_MASK:
3346 /* only odd command lengths */
3347 if ( !(cmdlen & 1) || cmdlen > 31)
3348 goto bad_size;
3349 break;
3350
3351 case O_IP_SRC_SET:
3352 case O_IP_DST_SET:
3353 if (cmd->arg1 == 0 || cmd->arg1 > 256) {
3354 printf("ipfw: invalid set size %d\n",
3355 cmd->arg1);
3356 return EINVAL;
3357 }
3358 if (cmdlen != F_INSN_SIZE(ipfw_insn_u32) +
3359 (cmd->arg1+31)/32 )
3360 goto bad_size;
3361 break;
3362
3363 case O_MACADDR2:
3364 if (cmdlen != F_INSN_SIZE(ipfw_insn_mac))
3365 goto bad_size;
3366 break;
3367
3368 case O_NOP:
3369 case O_IPID:
3370 case O_IPTTL:
3371 case O_IPLEN:
3372 if (cmdlen < 1 || cmdlen > 31)
3373 goto bad_size;
3374 break;
3375
3376 case O_MAC_TYPE:
3377 case O_IP_SRCPORT:
3378 case O_IP_DSTPORT: /* XXX artificial limit, 30 port pairs */
3379 if (cmdlen < 2 || cmdlen > 31)
3380 goto bad_size;
3381 break;
3382
3383 case O_RECV:
3384 case O_XMIT:
3385 case O_VIA:
3386 if (cmdlen != F_INSN_SIZE(ipfw_insn_if))
3387 goto bad_size;
3388 break;
3389
3390 case O_PIPE:
3391 case O_QUEUE:
3392 if (cmdlen != F_INSN_SIZE(ipfw_insn_pipe))
3393 goto bad_size;
3394 goto check_action;
3395
3396 case O_FORWARD_IP:
3397 if (cmdlen != F_INSN_SIZE(ipfw_insn_sa))
3398 goto bad_size;
3399 goto check_action;
3400
3401 case O_FORWARD_MAC: /* XXX not implemented yet */
3402 case O_CHECK_STATE:
3403 case O_COUNT:
3404 case O_ACCEPT:
3405 case O_DENY:
3406 case O_REJECT:
3407 case O_SKIPTO:
3408 case O_DIVERT:
3409 case O_TEE:
3410 if (cmdlen != F_INSN_SIZE(ipfw_insn))
3411 goto bad_size;
3412 check_action:
3413 if (have_action) {
3414 printf("ipfw: opcode %d, multiple actions"
3415 " not allowed\n",
3416 cmd->opcode);
3417 return EINVAL;
3418 }
3419 have_action = 1;
3420 if (l != cmdlen) {
3421 printf("ipfw: opcode %d, action must be"
3422 " last opcode\n",
3423 cmd->opcode);
3424 return EINVAL;
3425 }
3426 break;
3427 default:
3428 printf("ipfw: opcode %d, unknown opcode\n",
3429 cmd->opcode);
3430 return EINVAL;
3431 }
3432 }
3433 if (have_action == 0) {
3434 printf("ipfw: missing action\n");
3435 return EINVAL;
3436 }
3437 return 0;
3438
3439 bad_size:
3440 printf("ipfw: opcode %d size %d wrong\n",
3441 cmd->opcode, cmdlen);
3442 return EINVAL;
3443 }
3444
3445
3446 static void
3447 ipfw_kev_post_msg(u_int32_t event_code)
3448 {
3449 struct kev_msg ev_msg;
3450
3451 bzero(&ev_msg, sizeof(struct kev_msg));
3452
3453 ev_msg.vendor_code = KEV_VENDOR_APPLE;
3454 ev_msg.kev_class = KEV_FIREWALL_CLASS;
3455 ev_msg.kev_subclass = KEV_IPFW_SUBCLASS;
3456 ev_msg.event_code = event_code;
3457
3458 kev_post_msg(&ev_msg);
3459
3460 }
3461
3462 /**
3463 * {set|get}sockopt parser.
3464 */
3465 static int
3466 ipfw_ctl(struct sockopt *sopt)
3467 {
3468 #define RULE_MAXSIZE (256*sizeof(u_int32_t))
3469 u_int32_t api_version;
3470 int command;
3471 int error;
3472 size_t size;
3473 size_t rulesize = RULE_MAXSIZE;
3474 struct ip_fw *bp , *buf, *rule;
3475 int is64user = 0;
3476
3477 /* copy of orig sopt to send to ipfw_get_command_and_version() */
3478 struct sockopt tmp_sopt = *sopt;
3479 struct timeval timenow;
3480
3481 getmicrotime(&timenow);
3482
3483 /*
3484 * Disallow modifications in really-really secure mode, but still allow
3485 * the logging counters to be reset.
3486 */
3487 if (sopt->sopt_name == IP_FW_ADD ||
3488 (sopt->sopt_dir == SOPT_SET && sopt->sopt_name != IP_FW_RESETLOG)) {
3489 #if __FreeBSD_version >= 500034
3490 error = securelevel_ge(sopt->sopt_td->td_ucred, 3);
3491 if (error)
3492 return (error);
3493 #else /* FreeBSD 4.x */
3494 if (securelevel >= 3)
3495 return (EPERM);
3496 #endif
3497 }
3498
3499 /* first get the command and version, then do conversion as necessary */
3500 error = ipfw_get_command_and_version(&tmp_sopt, &command, &api_version);
3501 if (error) {
3502 /* error getting the version */
3503 return error;
3504 }
3505
3506 if (proc_is64bit(sopt->sopt_p))
3507 is64user = 1;
3508
3509 switch (command) {
3510 case IP_FW_GET:
3511 {
3512 size_t dynrulesize;
3513 /*
3514 * pass up a copy of the current rules. Static rules
3515 * come first (the last of which has number IPFW_DEFAULT_RULE),
3516 * followed by a possibly empty list of dynamic rule.
3517 * The last dynamic rule has NULL in the "next" field.
3518 */
3519 lck_mtx_lock(ipfw_mutex);
3520
3521 if (is64user){
3522 size = Get64static_len();
3523 dynrulesize = sizeof(ipfw_dyn_rule_64);
3524 if (ipfw_dyn_v)
3525 size += (dyn_count * dynrulesize);
3526 }else {
3527 size = Get32static_len();
3528 dynrulesize = sizeof(ipfw_dyn_rule_32);
3529 if (ipfw_dyn_v)
3530 size += (dyn_count * dynrulesize);
3531 }
3532
3533 /*
3534 * XXX todo: if the user passes a short length just to know
3535 * how much room is needed, do not bother filling up the
3536 * buffer, just jump to the sooptcopyout.
3537 */
3538 buf = _MALLOC(size, M_TEMP, M_WAITOK | M_ZERO);
3539 if (buf == 0) {
3540 lck_mtx_unlock(ipfw_mutex);
3541 error = ENOBUFS;
3542 break;
3543 }
3544
3545 bp = buf;
3546 for (rule = layer3_chain; rule ; rule = rule->next) {
3547
3548 if (rule->reserved_1 == IPFW_RULE_INACTIVE) {
3549 continue;
3550 }
3551
3552 if (is64user){
3553 int rulesize_64;
3554
3555 copyto64fw( rule, (struct ip_fw_64 *)bp, size);
3556 bcopy(&set_disable, &(( (struct ip_fw_64*)bp)->next_rule), sizeof(set_disable));
3557 /* do not use macro RULESIZE64 since we want RULESIZE for ip_fw_64 */
3558 rulesize_64 = sizeof(struct ip_fw_64) + ((struct ip_fw_64 *)(bp))->cmd_len * 4 - 4;
3559 bp = (struct ip_fw *)((char *)bp + rulesize_64);
3560 }else{
3561 int rulesize_32;
3562
3563 copyto32fw( rule, (struct ip_fw_32*)bp, size);
3564 bcopy(&set_disable, &(( (struct ip_fw_32*)bp)->next_rule), sizeof(set_disable));
3565 /* do not use macro RULESIZE32 since we want RULESIZE for ip_fw_32 */
3566 rulesize_32 = sizeof(struct ip_fw_32) + ((struct ip_fw_32 *)(bp))->cmd_len * 4 - 4;
3567 bp = (struct ip_fw *)((char *)bp + rulesize_32);
3568 }
3569 }
3570 if (ipfw_dyn_v) {
3571 int i;
3572 ipfw_dyn_rule *p;
3573 char *dst, *last = NULL;
3574
3575 dst = (char *)bp;
3576 for (i = 0 ; i < curr_dyn_buckets ; i++ )
3577 for ( p = ipfw_dyn_v[i] ; p != NULL ;
3578 p = p->next, dst += dynrulesize ) {
3579 if ( is64user ){
3580 ipfw_dyn_rule_64 *ipfw_dyn_dst;
3581
3582 ipfw_dyn_dst = (ipfw_dyn_rule_64 *)dst;
3583 /*
3584 * store a non-null value in "next".
3585 * The userland code will interpret a
3586 * NULL here as a marker
3587 * for the last dynamic rule.
3588 */
3589 ipfw_dyn_dst->next = CAST_DOWN_EXPLICIT(user64_addr_t, dst);
3590 ipfw_dyn_dst->rule = p->rule->rulenum;
3591 ipfw_dyn_dst->parent = CAST_DOWN(user64_addr_t, p->parent);
3592 ipfw_dyn_dst->pcnt = p->pcnt;
3593 ipfw_dyn_dst->bcnt = p->bcnt;
3594 externalize_flow_id(&ipfw_dyn_dst->id, &p->id);
3595 ipfw_dyn_dst->expire =
3596 TIME_LEQ(p->expire, timenow.tv_sec) ?
3597 0 : p->expire - timenow.tv_sec;
3598 ipfw_dyn_dst->bucket = p->bucket;
3599 ipfw_dyn_dst->state = p->state;
3600 ipfw_dyn_dst->ack_fwd = p->ack_fwd;
3601 ipfw_dyn_dst->ack_rev = p->ack_rev;
3602 ipfw_dyn_dst->dyn_type = p->dyn_type;
3603 ipfw_dyn_dst->count = p->count;
3604 last = (char*)ipfw_dyn_dst;
3605 } else {
3606 ipfw_dyn_rule_32 *ipfw_dyn_dst;
3607
3608 ipfw_dyn_dst = (ipfw_dyn_rule_32 *)dst;
3609 /*
3610 * store a non-null value in "next".
3611 * The userland code will interpret a
3612 * NULL here as a marker
3613 * for the last dynamic rule.
3614 */
3615 ipfw_dyn_dst->next = CAST_DOWN_EXPLICIT(user32_addr_t, dst);
3616 ipfw_dyn_dst->rule = p->rule->rulenum;
3617 ipfw_dyn_dst->parent = CAST_DOWN_EXPLICIT(user32_addr_t, p->parent);
3618 ipfw_dyn_dst->pcnt = p->pcnt;
3619 ipfw_dyn_dst->bcnt = p->bcnt;
3620 externalize_flow_id(&ipfw_dyn_dst->id, &p->id);
3621 ipfw_dyn_dst->expire =
3622 TIME_LEQ(p->expire, timenow.tv_sec) ?
3623 0 : p->expire - timenow.tv_sec;
3624 ipfw_dyn_dst->bucket = p->bucket;
3625 ipfw_dyn_dst->state = p->state;
3626 ipfw_dyn_dst->ack_fwd = p->ack_fwd;
3627 ipfw_dyn_dst->ack_rev = p->ack_rev;
3628 ipfw_dyn_dst->dyn_type = p->dyn_type;
3629 ipfw_dyn_dst->count = p->count;
3630 last = (char*)ipfw_dyn_dst;
3631 }
3632 }
3633 /* mark last dynamic rule */
3634 if (last != NULL) {
3635 if (is64user)
3636 ((ipfw_dyn_rule_64 *)last)->next = 0;
3637 else
3638 ((ipfw_dyn_rule_32 *)last)->next = 0;
3639 }
3640 }
3641 lck_mtx_unlock(ipfw_mutex);
3642
3643 /* convert back if necessary and copyout */
3644 if (api_version == IP_FW_VERSION_0) {
3645 int i, len = 0;
3646 struct ip_old_fw *buf2, *rule_vers0;
3647
3648 lck_mtx_lock(ipfw_mutex);
3649 buf2 = _MALLOC(static_count * sizeof(struct ip_old_fw), M_TEMP, M_WAITOK);
3650 if (buf2 == 0) {
3651 lck_mtx_unlock(ipfw_mutex);
3652 error = ENOBUFS;
3653 }
3654
3655 if (!error) {
3656 bp = buf;
3657 rule_vers0 = buf2;
3658
3659 for (i = 0; i < static_count; i++) {
3660 /* static rules have different sizes */
3661 int j = RULESIZE(bp);
3662 ipfw_convert_from_latest(bp, rule_vers0, api_version, is64user);
3663 bp = (struct ip_fw *)((char *)bp + j);
3664 len += sizeof(*rule_vers0);
3665 rule_vers0++;
3666 }
3667 lck_mtx_unlock(ipfw_mutex);
3668 error = sooptcopyout(sopt, buf2, len);
3669 _FREE(buf2, M_TEMP);
3670 }
3671 } else if (api_version == IP_FW_VERSION_1) {
3672 int i, len = 0, buf_size;
3673 struct ip_fw_compat *buf2;
3674 size_t ipfwcompsize;
3675 size_t ipfwdyncompsize;
3676 char *rule_vers1;
3677
3678 lck_mtx_lock(ipfw_mutex);
3679 if ( is64user ){
3680 ipfwcompsize = sizeof(struct ip_fw_compat_64);
3681 ipfwdyncompsize = sizeof(struct ipfw_dyn_rule_compat_64);
3682 } else {
3683 ipfwcompsize = sizeof(struct ip_fw_compat_32);
3684 ipfwdyncompsize = sizeof(struct ipfw_dyn_rule_compat_32);
3685 }
3686
3687 buf_size = static_count * ipfwcompsize +
3688 dyn_count * ipfwdyncompsize;
3689
3690 buf2 = _MALLOC(buf_size, M_TEMP, M_WAITOK);
3691 if (buf2 == 0) {
3692 lck_mtx_unlock(ipfw_mutex);
3693 error = ENOBUFS;
3694 }
3695 if (!error) {
3696 bp = buf;
3697 rule_vers1 = (char*)buf2;
3698
3699 /* first do static rules */
3700 for (i = 0; i < static_count; i++) {
3701 /* static rules have different sizes */
3702 if ( is64user ){
3703 int rulesize_64;
3704 ipfw_convert_from_latest(bp, (void *)rule_vers1, api_version, is64user);
3705 rulesize_64 = sizeof(struct ip_fw_64) + ((struct ip_fw_64 *)(bp))->cmd_len * 4 - 4;
3706 bp = (struct ip_fw *)((char *)bp + rulesize_64);
3707 }else {
3708 int rulesize_32;
3709 ipfw_convert_from_latest(bp, (void *)rule_vers1, api_version, is64user);
3710 rulesize_32 = sizeof(struct ip_fw_32) + ((struct ip_fw_32 *)(bp))->cmd_len * 4 - 4;
3711 bp = (struct ip_fw *)((char *)bp + rulesize_32);
3712 }
3713 len += ipfwcompsize;
3714 rule_vers1 += ipfwcompsize;
3715 }
3716 /* now do dynamic rules */
3717 if ( is64user )
3718 cp_dyn_to_comp_64( (struct ipfw_dyn_rule_compat_64 *)rule_vers1, &len);
3719 else
3720 cp_dyn_to_comp_32( (struct ipfw_dyn_rule_compat_32 *)rule_vers1, &len);
3721
3722 lck_mtx_unlock(ipfw_mutex);
3723 error = sooptcopyout(sopt, buf2, len);
3724 _FREE(buf2, M_TEMP);
3725 }
3726 } else {
3727 error = sooptcopyout(sopt, buf, size);
3728 }
3729
3730 _FREE(buf, M_TEMP);
3731 break;
3732 }
3733
3734 case IP_FW_FLUSH:
3735 /*
3736 * Normally we cannot release the lock on each iteration.
3737 * We could do it here only because we start from the head all
3738 * the times so there is no risk of missing some entries.
3739 * On the other hand, the risk is that we end up with
3740 * a very inconsistent ruleset, so better keep the lock
3741 * around the whole cycle.
3742 *
3743 * XXX this code can be improved by resetting the head of
3744 * the list to point to the default rule, and then freeing
3745 * the old list without the need for a lock.
3746 */
3747
3748 lck_mtx_lock(ipfw_mutex);
3749 free_chain(&layer3_chain, 0 /* keep default rule */);
3750 fw_bypass = 1;
3751 #if DEBUG_INACTIVE_RULES
3752 print_chain(&layer3_chain);
3753 #endif
3754 lck_mtx_unlock(ipfw_mutex);
3755 break;
3756
3757 case IP_FW_ADD:
3758 {
3759 size_t savedsopt_valsize=0;
3760 rule = _MALLOC(RULE_MAXSIZE, M_TEMP, M_WAITOK | M_ZERO);
3761 if (rule == 0) {
3762 error = ENOBUFS;
3763 break;
3764 }
3765
3766 if (api_version != IP_FW_CURRENT_API_VERSION) {
3767 error = ipfw_convert_to_latest(sopt, rule, api_version, is64user);
3768 }
3769 else {
3770 savedsopt_valsize = sopt->sopt_valsize; /* it might get modified in sooptcopyin_fw */
3771 error = sooptcopyin_fw( sopt, rule, &rulesize);
3772
3773 }
3774
3775 if (!error) {
3776 if ((api_version == IP_FW_VERSION_0) || (api_version == IP_FW_VERSION_1)) {
3777 /* the rule has already been checked so just
3778 * adjust sopt_valsize to match what would be expected.
3779 */
3780 sopt->sopt_valsize = RULESIZE(rule);
3781 rulesize = RULESIZE(rule);
3782 }
3783 error = check_ipfw_struct(rule, rulesize);
3784 if (!error) {
3785 lck_mtx_lock(ipfw_mutex);
3786 error = add_rule(&layer3_chain, rule);
3787 if (!error && fw_bypass)
3788 fw_bypass = 0;
3789 lck_mtx_unlock(ipfw_mutex);
3790
3791 size = RULESIZE(rule);
3792 if (!error && sopt->sopt_dir == SOPT_GET) {
3793 /* convert back if necessary and copyout */
3794 if (api_version == IP_FW_VERSION_0) {
3795 struct ip_old_fw rule_vers0;
3796
3797 ipfw_convert_from_latest(rule, &rule_vers0, api_version, is64user);
3798 sopt->sopt_valsize = sizeof(struct ip_old_fw);
3799
3800 error = sooptcopyout(sopt, &rule_vers0, sizeof(struct ip_old_fw));
3801 } else if (api_version == IP_FW_VERSION_1) {
3802 struct ip_fw_compat rule_vers1;
3803 ipfw_convert_from_latest(rule, &rule_vers1, api_version, is64user);
3804 sopt->sopt_valsize = sizeof(struct ip_fw_compat);
3805
3806 error = sooptcopyout(sopt, &rule_vers1, sizeof(struct ip_fw_compat));
3807 } else {
3808 char *userrule;
3809 userrule = _MALLOC(savedsopt_valsize, M_TEMP, M_WAITOK);
3810 if ( userrule == NULL )
3811 userrule = (char*)rule;
3812 if (proc_is64bit(sopt->sopt_p)){
3813 copyto64fw( rule, (struct ip_fw_64*)userrule, savedsopt_valsize);
3814 }
3815 else {
3816 copyto32fw( rule, (struct ip_fw_32*)userrule, savedsopt_valsize);
3817 }
3818 error = sooptcopyout(sopt, userrule, savedsopt_valsize);
3819 if ( userrule )
3820 _FREE(userrule, M_TEMP);
3821 }
3822 }
3823 }
3824 }
3825
3826 _FREE(rule, M_TEMP);
3827 break;
3828 }
3829 case IP_FW_DEL:
3830 {
3831 /*
3832 * IP_FW_DEL is used for deleting single rules or sets,
3833 * and (ab)used to atomically manipulate sets.
3834 * rule->rulenum != 0 indicates single rule delete
3835 * rule->set_masks used to manipulate sets
3836 * rule->set_masks[0] contains info on sets to be
3837 * disabled, swapped, or moved
3838 * rule->set_masks[1] contains sets to be enabled.
3839 */
3840
3841 /* there is only a simple rule passed in
3842 * (no cmds), so use a temp struct to copy
3843 */
3844 struct ip_fw temp_rule;
3845 u_int32_t arg;
3846 u_int8_t cmd;
3847
3848 bzero(&temp_rule, sizeof(struct ip_fw));
3849 if (api_version != IP_FW_CURRENT_API_VERSION) {
3850 error = ipfw_convert_to_latest(sopt, &temp_rule, api_version, is64user);
3851 }
3852 else {
3853 error = sooptcopyin_fw(sopt, &temp_rule, 0 );
3854 }
3855
3856 if (!error) {
3857 /* set_masks is used to distinguish between deleting
3858 * single rules or atomically manipulating sets
3859 */
3860 lck_mtx_lock(ipfw_mutex);
3861
3862 arg = temp_rule.set_masks[0];
3863 cmd = (arg >> 24) & 0xff;
3864
3865 if (temp_rule.rulenum) {
3866 /* single rule */
3867 error = del_entry(&layer3_chain, temp_rule.rulenum);
3868 #if DEBUG_INACTIVE_RULES
3869 print_chain(&layer3_chain);
3870 #endif
3871 }
3872 else if (cmd) {
3873 /* set reassignment - see comment above del_entry() for details */
3874 error = del_entry(&layer3_chain, temp_rule.set_masks[0]);
3875 #if DEBUG_INACTIVE_RULES
3876 print_chain(&layer3_chain);
3877 #endif
3878 }
3879 else if (temp_rule.set_masks[0] != 0 ||
3880 temp_rule.set_masks[1] != 0) {
3881 /* set enable/disable */
3882 set_disable =
3883 (set_disable | temp_rule.set_masks[0]) & ~temp_rule.set_masks[1] &
3884 ~(1<<RESVD_SET); /* set RESVD_SET always enabled */
3885 }
3886
3887 if (!layer3_chain->next)
3888 fw_bypass = 1;
3889 lck_mtx_unlock(ipfw_mutex);
3890 }
3891 break;
3892 }
3893 case IP_FW_ZERO:
3894 case IP_FW_RESETLOG: /* using rule->rulenum */
3895 {
3896 /* there is only a simple rule passed in
3897 * (no cmds), so use a temp struct to copy
3898 */
3899 struct ip_fw temp_rule;
3900
3901 bzero(&temp_rule, sizeof(struct ip_fw));
3902
3903 if (api_version != IP_FW_CURRENT_API_VERSION) {
3904 error = ipfw_convert_to_latest(sopt, &temp_rule, api_version, is64user);
3905 }
3906 else {
3907 if (sopt->sopt_val != 0) {
3908 error = sooptcopyin_fw( sopt, &temp_rule, 0);
3909 }
3910 }
3911
3912 if (!error) {
3913 lck_mtx_lock(ipfw_mutex);
3914 error = zero_entry(temp_rule.rulenum, sopt->sopt_name == IP_FW_RESETLOG);
3915 lck_mtx_unlock(ipfw_mutex);
3916 }
3917 break;
3918 }
3919 default:
3920 printf("ipfw: ipfw_ctl invalid option %d\n", sopt->sopt_name);
3921 error = EINVAL;
3922 }
3923
3924 if (error != EINVAL) {
3925 switch (command) {
3926 case IP_FW_ADD:
3927 case IP_OLD_FW_ADD:
3928 ipfw_kev_post_msg(KEV_IPFW_ADD);
3929 break;
3930 case IP_OLD_FW_DEL:
3931 case IP_FW_DEL:
3932 ipfw_kev_post_msg(KEV_IPFW_DEL);
3933 break;
3934 case IP_FW_FLUSH:
3935 case IP_OLD_FW_FLUSH:
3936 ipfw_kev_post_msg(KEV_IPFW_FLUSH);
3937 break;
3938
3939 default:
3940 break;
3941 }
3942 }
3943
3944 return (error);
3945 }
3946
3947 /**
3948 * dummynet needs a reference to the default rule, because rules can be
3949 * deleted while packets hold a reference to them. When this happens,
3950 * dummynet changes the reference to the default rule (it could well be a
3951 * NULL pointer, but this way we do not need to check for the special
3952 * case, plus here he have info on the default behaviour).
3953 */
3954 struct ip_fw *ip_fw_default_rule;
3955
3956 /*
3957 * This procedure is only used to handle keepalives. It is invoked
3958 * every dyn_keepalive_period
3959 */
3960 static void
3961 ipfw_tick(__unused void * unused)
3962 {
3963 struct mbuf *m0, *m, *mnext, **mtailp;
3964 int i;
3965 ipfw_dyn_rule *q;
3966 struct timeval timenow;
3967 static int stealth_cnt = 0;
3968
3969 if (ipfw_stealth_stats_needs_flush) {
3970 stealth_cnt++;
3971 if (!(stealth_cnt % IPFW_STEALTH_TIMEOUT_FREQUENCY)) {
3972 ipfw_stealth_flush_stats();
3973 }
3974 }
3975
3976 if (dyn_keepalive == 0 || ipfw_dyn_v == NULL || dyn_count == 0)
3977 goto done;
3978
3979 getmicrotime(&timenow);
3980
3981 /*
3982 * We make a chain of packets to go out here -- not deferring
3983 * until after we drop the ipfw lock would result
3984 * in a lock order reversal with the normal packet input -> ipfw
3985 * call stack.
3986 */
3987 m0 = NULL;
3988 mtailp = &m0;
3989
3990 lck_mtx_lock(ipfw_mutex);
3991 for (i = 0 ; i < curr_dyn_buckets ; i++) {
3992 for (q = ipfw_dyn_v[i] ; q ; q = q->next ) {
3993 if (q->dyn_type == O_LIMIT_PARENT)
3994 continue;
3995 if (q->id.proto != IPPROTO_TCP)
3996 continue;
3997 if ( (q->state & BOTH_SYN) != BOTH_SYN)
3998 continue;
3999 if (TIME_LEQ( timenow.tv_sec+dyn_keepalive_interval,
4000 q->expire))
4001 continue; /* too early */
4002 if (TIME_LEQ(q->expire, timenow.tv_sec))
4003 continue; /* too late, rule expired */
4004
4005 *mtailp = send_pkt(&(q->id), q->ack_rev - 1, q->ack_fwd, TH_SYN);
4006 if (*mtailp != NULL)
4007 mtailp = &(*mtailp)->m_nextpkt;
4008
4009 *mtailp = send_pkt(&(q->id), q->ack_fwd - 1, q->ack_rev, 0);
4010 if (*mtailp != NULL)
4011 mtailp = &(*mtailp)->m_nextpkt;
4012 }
4013 }
4014 lck_mtx_unlock(ipfw_mutex);
4015
4016 for (m = mnext = m0; m != NULL; m = mnext) {
4017 struct route sro; /* fake route */
4018
4019 mnext = m->m_nextpkt;
4020 m->m_nextpkt = NULL;
4021 bzero (&sro, sizeof (sro));
4022 ip_output(m, NULL, &sro, 0, NULL, NULL);
4023 ROUTE_RELEASE(&sro);
4024 }
4025 done:
4026 timeout_with_leeway(ipfw_tick, NULL, dyn_keepalive_period*hz,
4027 DYN_KEEPALIVE_LEEWAY*hz);
4028 }
4029
4030 void
4031 ipfw_init(void)
4032 {
4033 struct ip_fw default_rule;
4034
4035 /* setup locks */
4036 ipfw_mutex_grp_attr = lck_grp_attr_alloc_init();
4037 ipfw_mutex_grp = lck_grp_alloc_init("ipfw", ipfw_mutex_grp_attr);
4038 ipfw_mutex_attr = lck_attr_alloc_init();
4039 lck_mtx_init(ipfw_mutex, ipfw_mutex_grp, ipfw_mutex_attr);
4040
4041 layer3_chain = NULL;
4042
4043 bzero(&default_rule, sizeof default_rule);
4044
4045 default_rule.act_ofs = 0;
4046 default_rule.rulenum = IPFW_DEFAULT_RULE;
4047 default_rule.cmd_len = 1;
4048 default_rule.set = RESVD_SET;
4049
4050 default_rule.cmd[0].len = 1;
4051 default_rule.cmd[0].opcode =
4052 #ifdef IPFIREWALL_DEFAULT_TO_ACCEPT
4053 (1) ? O_ACCEPT :
4054 #endif
4055 O_DENY;
4056
4057 if (add_rule(&layer3_chain, &default_rule)) {
4058 printf("ipfw2: add_rule failed adding default rule\n");
4059 printf("ipfw2 failed initialization!!\n");
4060 fw_enable = 0;
4061 }
4062 else {
4063 ip_fw_default_rule = layer3_chain;
4064
4065 #ifdef IPFIREWALL_VERBOSE
4066 fw_verbose = 1;
4067 #endif
4068 #ifdef IPFIREWALL_VERBOSE_LIMIT
4069 verbose_limit = IPFIREWALL_VERBOSE_LIMIT;
4070 #endif
4071 if (fw_verbose) {
4072 if (!verbose_limit)
4073 printf("ipfw2 verbose logging enabled: unlimited logging by default\n");
4074 else
4075 printf("ipfw2 verbose logging enabled: limited to %d packets/entry by default\n",
4076 verbose_limit);
4077 }
4078 }
4079
4080 ip_fw_chk_ptr = ipfw_chk;
4081 ip_fw_ctl_ptr = ipfw_ctl;
4082
4083 ipfwstringlen = strlen( ipfwstring );
4084
4085 timeout(ipfw_tick, NULL, hz);
4086 }
4087
4088 #endif /* IPFW2 */