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