1 /* 2 * Copyright (c) 2014 - 2018 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Bill Yuan <bycn82@dragonflybsd.org> 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 3. Neither the name of The DragonFly Project nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific, prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 #include "opt_ipfw.h" 36 #include "opt_inet.h" 37 #ifndef INET 38 #error IPFIREWALL3 requires INET. 39 #endif /* INET */ 40 41 #include <sys/param.h> 42 #include <sys/kernel.h> 43 #include <sys/malloc.h> 44 #include <sys/mbuf.h> 45 #include <sys/socketvar.h> 46 #include <sys/sysctl.h> 47 #include <sys/systimer.h> 48 #include <sys/thread2.h> 49 #include <sys/in_cksum.h> 50 #include <sys/systm.h> 51 #include <sys/proc.h> 52 #include <sys/socket.h> 53 #include <sys/syslog.h> 54 #include <sys/ucred.h> 55 #include <sys/lock.h> 56 #include <sys/mplock2.h> 57 #include <sys/tree.h> 58 59 #include <net/if.h> 60 #include <net/ethernet.h> 61 #include <net/netmsg2.h> 62 #include <net/netisr2.h> 63 #include <net/route.h> 64 65 #include <netinet/ip.h> 66 #include <netinet/in.h> 67 #include <netinet/in_systm.h> 68 #include <netinet/in_var.h> 69 #include <netinet/in_pcb.h> 70 #include <netinet/ip_var.h> 71 #include <netinet/ip_icmp.h> 72 #include <netinet/tcp.h> 73 #include <netinet/tcp_timer.h> 74 #include <netinet/tcp_var.h> 75 #include <netinet/tcpip.h> 76 #include <netinet/udp.h> 77 #include <netinet/udp_var.h> 78 #include <netinet/ip_divert.h> 79 #include <netinet/if_ether.h> 80 81 #include <net/ipfw3/ip_fw.h> 82 #include <net/ipfw3_basic/ip_fw3_table.h> 83 #include <net/ipfw3_basic/ip_fw3_sync.h> 84 #include <net/ipfw3_basic/ip_fw3_basic.h> 85 #include <net/ipfw3_basic/ip_fw3_state.h> 86 87 extern struct ipfw3_context *fw3_ctx[MAXCPU]; 88 extern struct ipfw3_sync_context fw3_sync_ctx; 89 extern struct ipfw3_state_context *fw3_state_ctx[MAXCPU]; 90 extern ip_fw_ctl_t *ipfw_ctl_basic_ptr; 91 92 extern int sysctl_var_fw3_verbose; 93 94 extern int sysctl_var_state_max_tcp_in; 95 extern int sysctl_var_state_max_udp_in; 96 extern int sysctl_var_state_max_icmp_in; 97 98 extern int sysctl_var_state_max_tcp_out; 99 extern int sysctl_var_state_max_udp_out; 100 extern int sysctl_var_state_max_icmp_out; 101 102 extern int sysctl_var_icmp_timeout; 103 extern int sysctl_var_tcp_timeout; 104 extern int sysctl_var_udp_timeout; 105 106 static struct ip_fw * 107 lookup_next_rule(struct ip_fw *me) 108 { 109 struct ip_fw *rule = NULL; 110 ipfw_insn *cmd; 111 112 /* look for action, in case it is a skipto */ 113 cmd = ACTION_PTR(me); 114 if ((int)cmd->module == MODULE_BASIC_ID && 115 (int)cmd->opcode == O_BASIC_SKIPTO) { 116 for (rule = me->next; rule; rule = rule->next) { 117 if (rule->rulenum >= cmd->arg1) 118 break; 119 } 120 } 121 if (rule == NULL) /* failure or not a skipto */ 122 rule = me->next; 123 124 me->next_rule = rule; 125 return rule; 126 } 127 128 129 static int 130 iface_match(struct ifnet *ifp, ipfw_insn_if *cmd) 131 { 132 if (ifp == NULL) /* no iface with this packet, match fails */ 133 return 0; 134 135 /* Check by name or by IP address */ 136 if (cmd->name[0] != '\0') { /* match by name */ 137 /* Check name */ 138 if (cmd->p.glob) { 139 if (kfnmatch(cmd->name, ifp->if_xname, 0) == 0) 140 return(1); 141 } else { 142 if (strncmp(ifp->if_xname, cmd->name, IFNAMSIZ) == 0) 143 return(1); 144 } 145 } else { 146 struct ifaddr_container *ifac; 147 148 TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) { 149 struct ifaddr *ia = ifac->ifa; 150 151 if (ia->ifa_addr == NULL) 152 continue; 153 if (ia->ifa_addr->sa_family != AF_INET) 154 continue; 155 if (cmd->p.ip.s_addr == 156 ((struct sockaddr_in *) 157 (ia->ifa_addr))->sin_addr.s_addr) 158 return(1); /* match */ 159 160 } 161 } 162 return 0; /* no match, fail ... */ 163 } 164 165 /* implimentation of the checker functions */ 166 void 167 check_count(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args, 168 struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len) 169 { 170 (*f)->pcnt++; 171 (*f)->bcnt += ip_len; 172 (*f)->timestamp = time_second; 173 *cmd_ctl = IP_FW_CTL_NEXT; 174 } 175 176 void 177 check_skipto(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args, 178 struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len) 179 { 180 (*f)->pcnt++; 181 (*f)->bcnt += ip_len; 182 (*f)->timestamp = time_second; 183 if ((*f)->next_rule == NULL) 184 lookup_next_rule(*f); 185 *f = (*f)->next_rule; 186 *cmd_ctl = IP_FW_CTL_AGAIN; 187 } 188 189 void 190 check_forward(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args, 191 struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len) 192 { 193 struct sockaddr_in *sin, *sa; 194 struct m_tag *mtag; 195 196 if ((*args)->eh) { /* not valid on layer2 pkts */ 197 *cmd_ctl=IP_FW_CTL_NEXT; 198 return; 199 } 200 201 (*f)->pcnt++; 202 (*f)->bcnt += ip_len; 203 (*f)->timestamp = time_second; 204 if ((*f)->next_rule == NULL) 205 lookup_next_rule(*f); 206 207 mtag = m_tag_get(PACKET_TAG_IPFORWARD, 208 sizeof(*sin), M_INTWAIT | M_NULLOK); 209 if (mtag == NULL) { 210 *cmd_val = IP_FW_DENY; 211 *cmd_ctl = IP_FW_CTL_DONE; 212 return; 213 } 214 sin = m_tag_data(mtag); 215 sa = &((ipfw_insn_sa *)cmd)->sa; 216 /* arg3: count of the dest, arg1: type of fwd */ 217 int i = 0; 218 if(cmd->arg3 > 1) { 219 if (cmd->arg1 == 0) { /* type: random */ 220 i = krandom() % cmd->arg3; 221 } else if (cmd->arg1 == 1) { /* type: round-robin */ 222 i = cmd->arg2++ % cmd->arg3; 223 } else if (cmd->arg1 == 2) { /* type: sticky */ 224 struct ip *ip = mtod((*args)->m, struct ip *); 225 i = ip->ip_src.s_addr & (cmd->arg3 - 1); 226 } 227 sa += i; 228 } 229 *sin = *sa; /* apply the destination */ 230 m_tag_prepend((*args)->m, mtag); 231 (*args)->m->m_pkthdr.fw_flags |= IPFORWARD_MBUF_TAGGED; 232 (*args)->m->m_pkthdr.fw_flags &= ~BRIDGE_MBUF_TAGGED; 233 *cmd_ctl = IP_FW_CTL_DONE; 234 *cmd_val = IP_FW_PASS; 235 } 236 237 void 238 check_in(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args, 239 struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len) 240 { 241 *cmd_ctl = IP_FW_CTL_NO; 242 *cmd_val = ((*args)->oif == NULL); 243 } 244 245 void 246 check_out(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args, 247 struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len) 248 { 249 *cmd_ctl = IP_FW_CTL_NO; 250 *cmd_val = ((*args)->oif != NULL); 251 } 252 253 void 254 check_via(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args, 255 struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len) 256 { 257 *cmd_ctl = IP_FW_CTL_NO; 258 *cmd_val = iface_match((*args)->oif ? 259 (*args)->oif : (*args)->m->m_pkthdr.rcvif, 260 (ipfw_insn_if *)cmd); 261 } 262 263 void 264 check_proto(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args, 265 struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len) 266 { 267 *cmd_ctl = IP_FW_CTL_NO; 268 *cmd_val = ((*args)->f_id.proto == cmd->arg1); 269 } 270 271 void 272 check_prob(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args, 273 struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len) 274 { 275 *cmd_ctl = IP_FW_CTL_NO; 276 *cmd_val = (krandom() % 100) < cmd->arg1; 277 } 278 279 void 280 check_from(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args, 281 struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len) 282 { 283 u_int hlen = 0; 284 struct mbuf *m = (*args)->m; 285 struct ip *ip = mtod(m, struct ip *); 286 struct in_addr src_ip = ip->ip_src; 287 288 if ((*args)->eh == NULL || 289 (m->m_pkthdr.len >= sizeof(struct ip) && 290 ntohs((*args)->eh->ether_type) == ETHERTYPE_IP)) { 291 hlen = ip->ip_hl << 2; 292 } 293 *cmd_val = (hlen > 0 && 294 ((ipfw_insn_ip *)cmd)->addr.s_addr == src_ip.s_addr); 295 *cmd_ctl = IP_FW_CTL_NO; 296 } 297 298 void 299 check_from_lookup(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args, 300 struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len) 301 { 302 struct ipfw3_context *ctx = fw3_ctx[mycpuid]; 303 struct ipfw3_table_context *table_ctx; 304 struct radix_node_head *rnh; 305 struct sockaddr_in sa; 306 307 struct mbuf *m = (*args)->m; 308 struct ip *ip = mtod(m, struct ip *); 309 struct in_addr src_ip = ip->ip_src; 310 311 *cmd_val = IP_FW_NOT_MATCH; 312 313 table_ctx = ctx->table_ctx; 314 table_ctx += cmd->arg1; 315 316 if (table_ctx->type != 0) { 317 rnh = table_ctx->node; 318 sa.sin_len = 8; 319 sa.sin_addr.s_addr = src_ip.s_addr; 320 if(rnh->rnh_lookup((char *)&sa, NULL, rnh) != NULL) 321 *cmd_val = IP_FW_MATCH; 322 } 323 *cmd_ctl = IP_FW_CTL_NO; 324 } 325 326 void 327 check_from_me(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args, 328 struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len) 329 { 330 u_int hlen = 0; 331 struct mbuf *m = (*args)->m; 332 struct ip *ip = mtod(m, struct ip *); 333 struct in_addr src_ip = ip->ip_src; 334 335 if ((*args)->eh == NULL || 336 (m->m_pkthdr.len >= sizeof(struct ip) && 337 ntohs((*args)->eh->ether_type) == ETHERTYPE_IP)) { 338 hlen = ip->ip_hl << 2; 339 } 340 *cmd_ctl = IP_FW_CTL_NO; 341 if (hlen > 0) { 342 struct ifnet *tif; 343 tif = INADDR_TO_IFP(&src_ip); 344 *cmd_val = (tif != NULL); 345 } else { 346 *cmd_val = IP_FW_NOT_MATCH; 347 } 348 } 349 350 void 351 check_from_mask(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args, 352 struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len) 353 { 354 u_int hlen = 0; 355 struct mbuf *m = (*args)->m; 356 struct ip *ip = mtod(m, struct ip *); 357 struct in_addr src_ip = ip->ip_src; 358 359 if ((*args)->eh == NULL || 360 (m->m_pkthdr.len >= sizeof(struct ip) && 361 ntohs((*args)->eh->ether_type) == ETHERTYPE_IP)) { 362 hlen = ip->ip_hl << 2; 363 } 364 365 *cmd_ctl = IP_FW_CTL_NO; 366 *cmd_val = (hlen > 0 && 367 ((ipfw_insn_ip *)cmd)->addr.s_addr == 368 (src_ip.s_addr & 369 ((ipfw_insn_ip *)cmd)->mask.s_addr)); 370 } 371 372 void 373 check_to(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args, 374 struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len) 375 { 376 u_int hlen = 0; 377 struct mbuf *m = (*args)->m; 378 struct ip *ip = mtod(m, struct ip *); 379 struct in_addr dst_ip = ip->ip_dst; 380 381 if ((*args)->eh == NULL || 382 (m->m_pkthdr.len >= sizeof(struct ip) && 383 ntohs((*args)->eh->ether_type) == ETHERTYPE_IP)) { 384 hlen = ip->ip_hl << 2; 385 } 386 *cmd_val = (hlen > 0 && 387 ((ipfw_insn_ip *)cmd)->addr.s_addr == dst_ip.s_addr); 388 *cmd_ctl = IP_FW_CTL_NO; 389 } 390 391 void 392 check_to_lookup(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args, 393 struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len) 394 { 395 struct ipfw3_context *ctx = fw3_ctx[mycpuid]; 396 struct ipfw3_table_context *table_ctx; 397 struct radix_node_head *rnh; 398 struct sockaddr_in sa; 399 400 struct mbuf *m = (*args)->m; 401 struct ip *ip = mtod(m, struct ip *); 402 struct in_addr dst_ip = ip->ip_dst; 403 404 *cmd_val = IP_FW_NOT_MATCH; 405 406 table_ctx = ctx->table_ctx; 407 table_ctx += cmd->arg1; 408 409 if (table_ctx->type != 0) { 410 rnh = table_ctx->node; 411 sa.sin_len = 8; 412 sa.sin_addr.s_addr = dst_ip.s_addr; 413 if(rnh->rnh_lookup((char *)&sa, NULL, rnh) != NULL) 414 *cmd_val = IP_FW_MATCH; 415 } 416 *cmd_ctl = IP_FW_CTL_NO; 417 } 418 419 void 420 check_to_me(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args, 421 struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len) 422 { 423 u_int hlen = 0; 424 struct mbuf *m = (*args)->m; 425 struct ip *ip = mtod(m, struct ip *); 426 struct in_addr dst_ip = ip->ip_dst; 427 428 if ((*args)->eh == NULL || 429 (m->m_pkthdr.len >= sizeof(struct ip) && 430 ntohs((*args)->eh->ether_type) == ETHERTYPE_IP)) { 431 hlen = ip->ip_hl << 2; 432 } 433 *cmd_ctl = IP_FW_CTL_NO; 434 if (hlen > 0) { 435 struct ifnet *tif; 436 tif = INADDR_TO_IFP(&dst_ip); 437 *cmd_val = (tif != NULL); 438 } else { 439 *cmd_val = IP_FW_NOT_MATCH; 440 } 441 } 442 443 void 444 check_to_mask(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args, 445 struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len) 446 { 447 u_int hlen = 0; 448 struct mbuf *m = (*args)->m; 449 struct ip *ip = mtod(m, struct ip *); 450 struct in_addr dst_ip = ip->ip_dst; 451 452 if ((*args)->eh == NULL || 453 (m->m_pkthdr.len >= sizeof(struct ip) && 454 ntohs((*args)->eh->ether_type) == ETHERTYPE_IP)) { 455 hlen = ip->ip_hl << 2; 456 } 457 458 *cmd_ctl = IP_FW_CTL_NO; 459 *cmd_val = (hlen > 0 && 460 ((ipfw_insn_ip *)cmd)->addr.s_addr == 461 (dst_ip.s_addr & 462 ((ipfw_insn_ip *)cmd)->mask.s_addr)); 463 } 464 465 void 466 check_tag(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args, 467 struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len) 468 { 469 struct m_tag *mtag = m_tag_locate((*args)->m, 470 MTAG_IPFW, cmd->arg1, NULL); 471 if (mtag == NULL) { 472 mtag = m_tag_alloc(MTAG_IPFW,cmd->arg1, 0, M_NOWAIT); 473 if (mtag != NULL) 474 m_tag_prepend((*args)->m, mtag); 475 476 } 477 (*f)->pcnt++; 478 (*f)->bcnt += ip_len; 479 (*f)->timestamp = time_second; 480 *cmd_ctl = IP_FW_CTL_NEXT; 481 } 482 483 void 484 check_untag(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args, 485 struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len) 486 { 487 struct m_tag *mtag = m_tag_locate((*args)->m, 488 MTAG_IPFW, cmd->arg1, NULL); 489 if (mtag != NULL) 490 m_tag_delete((*args)->m, mtag); 491 492 (*f)->pcnt++; 493 (*f)->bcnt += ip_len; 494 (*f)->timestamp = time_second; 495 *cmd_ctl = IP_FW_CTL_NEXT; 496 } 497 498 void 499 check_tagged(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args, 500 struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len) 501 { 502 *cmd_ctl = IP_FW_CTL_NO; 503 if (m_tag_locate( (*args)->m, MTAG_IPFW,cmd->arg1, NULL) != NULL ) 504 *cmd_val = IP_FW_MATCH; 505 else 506 *cmd_val = IP_FW_NOT_MATCH; 507 } 508 509 void 510 check_src_port(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args, 511 struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len) 512 { 513 *cmd_ctl = IP_FW_CTL_NO; 514 if ((*args)->f_id.src_port == cmd->arg1) 515 *cmd_val = IP_FW_MATCH; 516 else 517 *cmd_val = IP_FW_NOT_MATCH; 518 } 519 520 void 521 check_dst_port(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args, 522 struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len) 523 { 524 *cmd_ctl = IP_FW_CTL_NO; 525 if ((*args)->f_id.dst_port == cmd->arg1) 526 *cmd_val = IP_FW_MATCH; 527 else 528 *cmd_val = IP_FW_NOT_MATCH; 529 } 530 531 void 532 check_src_n_port(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args, 533 struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len) 534 { 535 struct in_addr src_ip; 536 u_int hlen = 0; 537 struct mbuf *m = (*args)->m; 538 struct ip *ip = mtod(m, struct ip *); 539 src_ip = ip->ip_src; 540 if ((*args)->eh == NULL || 541 (m->m_pkthdr.len >= sizeof(struct ip) && 542 ntohs((*args)->eh->ether_type) == ETHERTYPE_IP)) { 543 hlen = ip->ip_hl << 2; 544 } 545 *cmd_val = (hlen > 0 && ((ipfw_insn_ip *)cmd)->addr.s_addr == src_ip.s_addr); 546 *cmd_ctl = IP_FW_CTL_NO; 547 if (*cmd_val && (*args)->f_id.src_port == cmd->arg1) 548 *cmd_val = IP_FW_MATCH; 549 else 550 *cmd_val = IP_FW_NOT_MATCH; 551 } 552 553 void 554 check_dst_n_port(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args, 555 struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len) 556 { 557 struct in_addr dst_ip; 558 u_int hlen = 0; 559 struct mbuf *m = (*args)->m; 560 struct ip *ip = mtod(m, struct ip *); 561 dst_ip = ip->ip_dst; 562 if ((*args)->eh == NULL || 563 (m->m_pkthdr.len >= sizeof(struct ip) && 564 ntohs((*args)->eh->ether_type) == ETHERTYPE_IP)) { 565 hlen = ip->ip_hl << 2; 566 } 567 *cmd_val = (hlen > 0 && ((ipfw_insn_ip *)cmd)->addr.s_addr == dst_ip.s_addr); 568 *cmd_ctl = IP_FW_CTL_NO; 569 if (*cmd_val && (*args)->f_id.dst_port == cmd->arg1) 570 *cmd_val = IP_FW_MATCH; 571 else 572 *cmd_val = IP_FW_NOT_MATCH; 573 } 574 575 int 576 ip_fw3_basic_init(void) 577 { 578 ip_fw3_register_module(MODULE_BASIC_ID, MODULE_BASIC_NAME); 579 ip_fw3_register_filter_funcs(MODULE_BASIC_ID, O_BASIC_COUNT, 580 (filter_func)check_count); 581 ip_fw3_register_filter_funcs(MODULE_BASIC_ID, O_BASIC_SKIPTO, 582 (filter_func)check_skipto); 583 ip_fw3_register_filter_funcs(MODULE_BASIC_ID, O_BASIC_FORWARD, 584 (filter_func)check_forward); 585 ip_fw3_register_filter_funcs(MODULE_BASIC_ID, O_BASIC_KEEP_STATE, 586 (filter_func)check_keep_state); 587 ip_fw3_register_filter_funcs(MODULE_BASIC_ID, O_BASIC_CHECK_STATE, 588 (filter_func)check_check_state); 589 590 ip_fw3_register_filter_funcs(MODULE_BASIC_ID, 591 O_BASIC_IN, (filter_func)check_in); 592 ip_fw3_register_filter_funcs(MODULE_BASIC_ID, 593 O_BASIC_OUT, (filter_func)check_out); 594 ip_fw3_register_filter_funcs(MODULE_BASIC_ID, 595 O_BASIC_VIA, (filter_func)check_via); 596 ip_fw3_register_filter_funcs(MODULE_BASIC_ID, 597 O_BASIC_XMIT, (filter_func)check_via); 598 ip_fw3_register_filter_funcs(MODULE_BASIC_ID, 599 O_BASIC_RECV, (filter_func)check_via); 600 601 ip_fw3_register_filter_funcs(MODULE_BASIC_ID, 602 O_BASIC_PROTO, (filter_func)check_proto); 603 ip_fw3_register_filter_funcs(MODULE_BASIC_ID, 604 O_BASIC_PROB, (filter_func)check_prob); 605 ip_fw3_register_filter_funcs(MODULE_BASIC_ID, 606 O_BASIC_IP_SRC, (filter_func)check_from); 607 ip_fw3_register_filter_funcs(MODULE_BASIC_ID, 608 O_BASIC_IP_SRC_LOOKUP, (filter_func)check_from_lookup); 609 ip_fw3_register_filter_funcs(MODULE_BASIC_ID, 610 O_BASIC_IP_SRC_ME, (filter_func)check_from_me); 611 ip_fw3_register_filter_funcs(MODULE_BASIC_ID, 612 O_BASIC_IP_SRC_MASK, (filter_func)check_from_mask); 613 ip_fw3_register_filter_funcs(MODULE_BASIC_ID, 614 O_BASIC_IP_DST, (filter_func)check_to); 615 ip_fw3_register_filter_funcs(MODULE_BASIC_ID, 616 O_BASIC_IP_DST_LOOKUP, (filter_func)check_to_lookup); 617 ip_fw3_register_filter_funcs(MODULE_BASIC_ID, 618 O_BASIC_IP_DST_ME, (filter_func)check_to_me); 619 ip_fw3_register_filter_funcs(MODULE_BASIC_ID, 620 O_BASIC_IP_DST_MASK, (filter_func)check_to_mask); 621 ip_fw3_register_filter_funcs(MODULE_BASIC_ID, 622 O_BASIC_TAG, (filter_func)check_tag); 623 ip_fw3_register_filter_funcs(MODULE_BASIC_ID, 624 O_BASIC_UNTAG, (filter_func)check_untag); 625 ip_fw3_register_filter_funcs(MODULE_BASIC_ID, 626 O_BASIC_TAGGED, (filter_func)check_tagged); 627 ip_fw3_register_filter_funcs(MODULE_BASIC_ID, 628 O_BASIC_IP_SRCPORT, (filter_func)check_src_port); 629 ip_fw3_register_filter_funcs(MODULE_BASIC_ID, 630 O_BASIC_IP_DSTPORT, (filter_func)check_dst_port); 631 ip_fw3_register_filter_funcs(MODULE_BASIC_ID, 632 O_BASIC_IP_SRC_N_PORT, (filter_func)check_src_n_port); 633 ip_fw3_register_filter_funcs(MODULE_BASIC_ID, 634 O_BASIC_IP_DST_N_PORT, (filter_func)check_dst_n_port); 635 636 return 0; 637 } 638 639 int 640 ip_fw3_basic_fini(void) 641 { 642 return ip_fw3_unregister_module(MODULE_BASIC_ID); 643 } 644 645 static int 646 ipfw3_basic_modevent(module_t mod, int type, void *data) 647 { 648 int err; 649 switch (type) { 650 case MOD_LOAD: 651 err = ip_fw3_basic_init(); 652 break; 653 case MOD_UNLOAD: 654 err = ip_fw3_basic_fini(); 655 break; 656 default: 657 err = 1; 658 } 659 ip_fw3_state_modevent(type); 660 return err; 661 } 662 663 static moduledata_t ipfw3_basic_mod = { 664 "ipfw3_basic", 665 ipfw3_basic_modevent, 666 NULL 667 }; 668 DECLARE_MODULE(ipfw3_basic, ipfw3_basic_mod, SI_SUB_PROTO_END, SI_ORDER_ANY); 669 MODULE_DEPEND(ipfw3_basic, ipfw3, 1, 1, 1); 670 MODULE_VERSION(ipfw3_basic, 1); 671