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