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