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