1 /* 2 * Copyright (c) 1993 Daniel Boulet 3 * Copyright (c) 1994 Ugen J.S.Antsilevich 4 * Copyright (c) 2002 Luigi Rizzo, Universita` di Pisa 5 * Copyright (c) 2015 - 2018 The DragonFly Project. All rights reserved. 6 * 7 * This code is derived from software contributed to The DragonFly Project 8 * by Bill Yuan <bycn82@dragonflybsd.org> 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 3. Neither the name of The DragonFly Project nor the names of its 21 * contributors may be used to endorse or promote products derived 22 * from this software without specific, prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 27 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 28 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 29 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 32 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 33 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 34 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 */ 38 39 #ifndef _IP_FW3_H_ 40 #define _IP_FW3_H_ 41 42 /* 43 * _IPFW2_H is from ipfw/ip_fw2.h, both cannot be included past this 44 * point but we need both the IPFW2_LOADED and IPFW3_LOADED macros 45 */ 46 #ifndef _IPFW2_H 47 48 49 #include <net/bpf.h> 50 51 52 #define NEED1(msg) {if (ac < 1) errx(EX_USAGE, msg);} 53 #define NEED2(msg) {if (ac < 2) errx(EX_USAGE, msg);} 54 #define NEED(c, n, msg) {if (c < n) errx(EX_USAGE, msg);} 55 56 #define NEXT_ARG ac--; if(ac > 0){av++;} 57 #define NEXT_ARG1 (*ac)--; if(*ac > 0){(*av)++;} 58 #define SWAP_ARG \ 59 do { \ 60 if (ac > 2 && isdigit(*(av[1]))) { \ 61 char *p = av[1]; \ 62 av[1] = av[2]; \ 63 av[2] = p; \ 64 } \ 65 } while (0) 66 67 #define IPFW_RULE_SIZE_MAX 255 /* unit: uint32_t */ 68 69 /* 70 * type of the keyword, it indecates the position of the keyword in the rule 71 * BEFORE ACTION FROM TO FILTER OTHER 72 */ 73 #define NONE 0 74 #define BEFORE 1 75 #define ACTION 2 76 #define PROTO 3 77 #define FROM 4 78 #define TO 5 79 #define FILTER 6 80 #define AFTER 7 81 82 #define NOT_IN_USE 0 83 #define IN_USE 1 84 85 #define SIZE_OF_IPFWINSN 8 86 #define LEN_OF_IPFWINSN 2 87 #define IPFW_DEFAULT_RULE 65535 88 #define IPFW_DEFAULT_SET 0 89 #define IPFW_ALL_SETS 0 90 91 /* 92 * Template for instructions. 93 * 94 * ipfw_insn is used for all instructions which require no operands, 95 * a single 16-bit value (arg1), or a couple of 8-bit values. 96 * 97 * For other instructions which require different/larger arguments 98 * we have derived structures, ipfw_insn_*. 99 * 100 * The size of the instruction (in 32-bit words) is in the low 101 * 6 bits of "len". The 2 remaining bits are used to implement 102 * NOT and OR on individual instructions. Given a type, you can 103 * compute the length to be put in "len" using F_INSN_SIZE(t) 104 * 105 * F_NOT negates the match result of the instruction. 106 * 107 * F_OR is used to build or blocks. By default, instructions 108 * are evaluated as part of a logical AND. An "or" block 109 * { X or Y or Z } contains F_OR set in all but the last 110 * instruction of the block. A match will cause the code 111 * to skip past the last instruction of the block. 112 * 113 * NOTA BENE: in a couple of places we assume that 114 * sizeof(ipfw_insn) == sizeof(uint32_t) 115 * this needs to be fixed. 116 * 117 */ 118 119 #define F_NOT 0x80 120 #define F_OR 0x40 121 #define F_LEN_MASK 0x3f 122 #define F_LEN(cmd) ((cmd)->len & F_LEN_MASK) 123 124 typedef struct _ipfw_insn { /* template for instructions */ 125 uint8_t opcode; 126 uint8_t len; /* numer of 32-byte words */ 127 uint16_t arg1; 128 129 uint8_t module; 130 uint8_t arg3; 131 uint16_t arg2; 132 } ipfw_insn; 133 134 #define ACTION_PTR(rule) \ 135 (ipfw_insn *)((uint32_t *)((rule)->cmd) + ((rule)->act_ofs)) 136 137 /* 138 * The F_INSN_SIZE(type) computes the size, in 4-byte words, of 139 * a given type. 140 */ 141 #define F_INSN_SIZE(t) ((sizeof (t))/sizeof(uint32_t)) 142 143 #define MTAG_IPFW 1148380143 /* IPFW-tagged cookie */ 144 145 /* 146 * This is used to store an array of 16-bit entries (ports etc.) 147 */ 148 typedef struct _ipfw_insn_u16 { 149 ipfw_insn o; 150 uint16_t ports[2]; /* there may be more */ 151 } ipfw_insn_u16; 152 153 /* 154 * This is used to store an array of 32-bit entries 155 * (uid, single IPv4 addresses etc.) 156 */ 157 typedef struct _ipfw_insn_u32 { 158 ipfw_insn o; 159 uint32_t d[1]; /* one or more */ 160 } ipfw_insn_u32; 161 162 /* 163 * This is used to store IP addr-mask pairs. 164 */ 165 typedef struct _ipfw_insn_ip { 166 ipfw_insn o; 167 struct in_addr addr; 168 struct in_addr mask; 169 } ipfw_insn_ip; 170 171 /* 172 * This is used to forward to a given address (ip) 173 */ 174 typedef struct _ipfw_insn_sa { 175 ipfw_insn o; 176 struct sockaddr_in sa; 177 } ipfw_insn_sa; 178 179 /* 180 * This is used for MAC addr-mask pairs. 181 */ 182 typedef struct _ipfw_insn_mac { 183 ipfw_insn o; 184 u_char addr[12]; /* dst[6] + src[6] */ 185 u_char mask[12]; /* dst[6] + src[6] */ 186 } ipfw_insn_mac; 187 188 /* 189 * This is used for interface match rules (recv xx, xmit xx) 190 */ 191 typedef struct _ipfw_insn_if { 192 ipfw_insn o; 193 union { 194 struct in_addr ip; 195 int glob; 196 } p; 197 char name[IFNAMSIZ]; 198 } ipfw_insn_if; 199 200 /* 201 * This is used for pipe and queue actions, which need to store 202 * a single pointer (which can have different size on different 203 * architectures. 204 */ 205 typedef struct _ipfw_insn_pipe { 206 ipfw_insn o; 207 void *pipe_ptr; 208 } ipfw_insn_pipe; 209 210 /* 211 * This is used for limit rules. 212 */ 213 typedef struct _ipfw_insn_limit { 214 ipfw_insn o; 215 uint8_t _pad; 216 uint8_t limit_mask; /* combination of DYN_* below */ 217 #define DYN_SRC_ADDR 0x1 218 #define DYN_SRC_PORT 0x2 219 #define DYN_DST_ADDR 0x4 220 #define DYN_DST_PORT 0x8 221 222 uint16_t conn_limit; 223 } ipfw_insn_limit; 224 225 /* 226 * This is used for bpf filtering. 227 */ 228 typedef struct _ipfw_insn_bpf { 229 ipfw_insn o; 230 char bf_str[128]; 231 u_int bf_len; 232 struct bpf_insn bf_insn[1]; 233 } ipfw_insn_bpf; 234 235 /* 236 * Here we have the structure representing an ipfw rule. 237 * 238 * It starts with a general area (with link fields and counters) 239 * followed by an array of one or more instructions, which the code 240 * accesses as an array of 32-bit values. 241 * 242 * Given a rule pointer r: 243 * 244 * r->cmd is the start of the first instruction. 245 * ACTION_PTR(r) is the start of the first action (things to do 246 * once a rule matched). 247 * 248 * When assembling instruction, remember the following: 249 * 250 * + if a rule has a "keep-state" (or "limit") option, then the 251 * first instruction (at r->cmd) MUST BE an O_PROBE_STATE 252 * + if a rule has a "log" option, then the first action 253 * (at ACTION_PTR(r)) MUST be O_LOG 254 * 255 * NOTE: we use a simple linked list of rules because we never need 256 * to delete a rule without scanning the list. We do not use 257 * queue(3) macros for portability and readability. 258 */ 259 260 struct ip_fw { 261 struct ip_fw *next; /* linked list of rules */ 262 struct ip_fw *next_rule; /* ptr to next [skipto] rule */ 263 uint16_t act_ofs; /* offset of action in 32-bit units */ 264 uint16_t cmd_len; /* # of 32-bit words in cmd */ 265 uint16_t rulenum; /* rule number */ 266 uint8_t set; /* rule set (0..31) */ 267 uint8_t flags; /* IPFW_USR_F_ */ 268 269 /* These fields are present in all rules. */ 270 uint64_t pcnt; /* Packet counter */ 271 uint64_t bcnt; /* Byte counter */ 272 uint32_t timestamp; /* tv_sec of last match */ 273 274 struct ip_fw *sibling; /* pointer to the rule in next CPU */ 275 276 ipfw_insn cmd[1]; /* storage for commands */ 277 }; 278 #define LEN_FW3 sizeof(struct ip_fw) 279 280 #define IPFW_RULE_F_INVALID 0x1 281 #define IPFW_RULE_F_STATE 0x2 282 283 #define RULESIZE(rule) (sizeof(struct ip_fw) + (rule)->cmd_len * 4 - SIZE_OF_IPFWINSN) 284 285 /* 286 * This structure is used as a flow mask and a flow id for various 287 * parts of the code. 288 */ 289 struct ipfw_flow_id { 290 uint32_t dst_ip; 291 uint32_t src_ip; 292 uint16_t dst_port; 293 uint16_t src_port; 294 uint8_t proto; 295 uint8_t flags; /* protocol-specific flags */ 296 }; 297 298 299 /* ip_fw3_chk/ip_fw_chk_ptr return values */ 300 #define IP_FW_PASS 0 301 #define IP_FW_DENY 1 302 #define IP_FW_DIVERT 2 303 #define IP_FW_TEE 3 304 #define IP_FW_DUMMYNET 4 305 #define IP_FW_NAT 5 306 #define IP_FW_ROUTE 6 307 308 /* ip_fw3_chk controller values */ 309 #define IP_FW_CTL_NO 0 310 #define IP_FW_CTL_DONE 1 311 #define IP_FW_CTL_AGAIN 2 312 #define IP_FW_CTL_NEXT 3 313 #define IP_FW_CTL_NAT 4 314 #define IP_FW_CTL_LOOP 5 315 #define IP_FW_CTL_CHK_STATE 6 316 317 #define IP_FW_NOT_MATCH 0 318 #define IP_FW_MATCH 1 319 320 /* 321 * arguments for calling ip_fw3_chk() and dummynet_io(). We put them 322 * all into a structure because this way it is easier and more 323 * efficient to pass variables around and extend the interface. 324 */ 325 struct ip_fw_args { 326 struct mbuf *m; /* the mbuf chain */ 327 struct ifnet *oif; /* output interface */ 328 struct ip_fw *rule; /* matching rule */ 329 struct ether_header *eh; /* for bridged packets */ 330 331 struct ipfw_flow_id f_id; /* grabbed from IP header */ 332 333 /* 334 * Depend on the return value of ip_fw3_chk/ip_fw_chk_ptr 335 * 'cookie' field may save following information: 336 * 337 * IP_FW_DUMMYNET 338 * The pipe or queue number 339 */ 340 uint32_t cookie; 341 }; 342 343 struct ipfw_ioc_rule { 344 uint16_t act_ofs; /* offset of action in 32-bit units */ 345 uint16_t cmd_len; /* # of 32-bit words in cmd */ 346 uint16_t rulenum; /* rule number */ 347 uint8_t set; /* rule set (0..31) */ 348 uint8_t insert; /* insert or append */ 349 350 /* Rule set information */ 351 uint32_t sets; /* disabled rule sets */ 352 353 /* Statistics */ 354 uint64_t pcnt; /* Packet counter */ 355 uint64_t bcnt; /* Byte counter */ 356 uint32_t timestamp; /* tv_sec of last match */ 357 358 ipfw_insn cmd[1]; /* storage for commands */ 359 }; 360 361 #define IOC_RULESIZE(rule) \ 362 (sizeof(struct ipfw_ioc_rule) + (rule)->cmd_len * 4 - SIZE_OF_IPFWINSN) 363 364 365 /* IP_FW_X header/opcodes */ 366 typedef struct _ip_fw_x_header { 367 uint16_t opcode; /* Operation opcode */ 368 uint16_t _pad; /* Opcode version */ 369 } ip_fw_x_header; 370 371 /* IP_FW3 opcodes */ 372 #define IP_FW_ADD 50 /* add a firewall rule to chain */ 373 #define IP_FW_DEL 51 /* delete a firewall rule from chain */ 374 #define IP_FW_FLUSH 52 /* flush firewall rule chain */ 375 #define IP_FW_ZERO 53 /* clear single/all firewall counter(s) */ 376 #define IP_FW_GET 54 /* get entire firewall rule chain */ 377 #define IP_FW_RESETLOG 55 /* reset logging counters */ 378 379 #define IP_FW_STATE_ADD 56 /* add one state */ 380 #define IP_FW_STATE_DEL 57 /* delete states of one rulenum */ 381 #define IP_FW_STATE_FLUSH 58 /* flush all states */ 382 #define IP_FW_STATE_GET 59 /* get all states */ 383 384 #define IP_DUMMYNET_CONFIGURE 60 /* add/configure a dummynet pipe */ 385 #define IP_DUMMYNET_DEL 61 /* delete a dummynet pipe from chain */ 386 #define IP_DUMMYNET_FLUSH 62 /* flush dummynet */ 387 #define IP_DUMMYNET_GET 64 /* get entire dummynet pipes */ 388 389 #define IP_FW_MODULE 67 /* get modules names */ 390 391 #define IP_FW_NAT_ADD 68 /* add/config a nat rule */ 392 #define IP_FW_NAT_DEL 69 /* delete a nat rule */ 393 #define IP_FW_NAT_FLUSH 70 /* get configuration of a nat rule */ 394 #define IP_FW_NAT_GET 71 /* get config of a nat rule */ 395 #define IP_FW_NAT_GET_RECORD 72 /* get nat record of a nat rule */ 396 397 #define IP_FW_TABLE_CREATE 73 /* table_create */ 398 #define IP_FW_TABLE_DELETE 74 /* table_delete */ 399 #define IP_FW_TABLE_APPEND 75 /* table_append */ 400 #define IP_FW_TABLE_REMOVE 76 /* table_remove */ 401 #define IP_FW_TABLE_LIST 77 /* table_list */ 402 #define IP_FW_TABLE_FLUSH 78 /* table_flush */ 403 #define IP_FW_TABLE_SHOW 79 /* table_show */ 404 #define IP_FW_TABLE_TEST 80 /* table_test */ 405 #define IP_FW_TABLE_RENAME 81 /* rename a table */ 406 407 /* opcodes for ipfw3sync */ 408 #define IP_FW_SYNC_SHOW_CONF 82 /* show sync config */ 409 #define IP_FW_SYNC_SHOW_STATUS 83 /* show edge & centre running status */ 410 411 #define IP_FW_SYNC_EDGE_CONF 84 /* config sync edge */ 412 #define IP_FW_SYNC_EDGE_START 85 /* start the edge */ 413 #define IP_FW_SYNC_EDGE_STOP 86 /* stop the edge */ 414 #define IP_FW_SYNC_EDGE_TEST 87 /* test sync edge */ 415 #define IP_FW_SYNC_EDGE_CLEAR 88 /* stop and clear the edge */ 416 417 #define IP_FW_SYNC_CENTRE_CONF 89 /* config sync centre */ 418 #define IP_FW_SYNC_CENTRE_START 90 /* start the centre */ 419 #define IP_FW_SYNC_CENTRE_STOP 91 /* stop the centre */ 420 #define IP_FW_SYNC_CENTRE_TEST 92 /* test sync centre */ 421 #define IP_FW_SYNC_CENTRE_CLEAR 93 /* stop and clear the centre */ 422 423 #define IP_FW_SET_GET 95 /* get the set config */ 424 #define IP_FW_SET_MOVE_RULE 96 /* move a rule to set */ 425 #define IP_FW_SET_MOVE_SET 97 /* move all rules from set a to b */ 426 #define IP_FW_SET_SWAP 98 /* swap 2 sets */ 427 #define IP_FW_SET_TOGGLE 99 /* enable/disable a set */ 428 #define IP_FW_SET_FLUSH 100 /* flush the rule of the set */ 429 430 #endif /* _IPFW2_H */ 431 #ifdef _KERNEL 432 433 #include <net/netisr2.h> 434 435 int ip_fw3_sockopt(struct sockopt *); 436 437 extern int ip_fw3_loaded; 438 439 #define IPFW3_LOADED (ip_fw3_loaded) 440 441 #ifdef IPFIREWALL3_DEBUG 442 #define IPFW3_DEBUG1(str) \ 443 do { \ 444 kprintf(str); \ 445 } while (0) 446 #define IPFW3_DEBUG(fmt, ...) \ 447 do { \ 448 kprintf(fmt, __VA_ARGS__); \ 449 } while (0) 450 #else 451 #define IPFW3_DEBUG1(str) ((void)0) 452 #define IPFW3_DEBUG(fmt, ...) ((void)0) 453 #endif 454 455 typedef int ip_fw_ctl_t(struct sockopt *); 456 typedef int ip_fw_chk_t(struct ip_fw_args *); 457 typedef struct mbuf *ip_fw_dn_io_t(struct mbuf *, int, int, struct ip_fw_args *); 458 typedef void *ip_fw_log_t(struct mbuf *m, struct ether_header *eh, uint16_t id); 459 460 #ifndef _IPFW2_H 461 462 int ip_fw_sockopt(struct sockopt *); 463 464 struct sockopt; 465 struct dn_flow_set; 466 467 468 extern ip_fw_chk_t *ip_fw_chk_ptr; 469 extern ip_fw_ctl_t *ip_fw_ctl_x_ptr; 470 extern ip_fw_dn_io_t *ip_fw_dn_io_ptr; 471 472 473 #define IPFW_TABLES_MAX 32 474 #define IPFW_USR_F_NORULE 0x01 475 #define IPFW_CFGCPUID 0 476 #define IPFW_CFGPORT netisr_cpuport(IPFW_CFGCPUID) 477 #define IPFW_ASSERT_CFGPORT(msgport) \ 478 KASSERT((msgport) == IPFW_CFGPORT, ("not IPFW CFGPORT")) 479 480 481 /* root of place holding all information, per-cpu */ 482 struct ipfw3_context { 483 struct ip_fw *rules; /* rules*/ 484 struct ip_fw *default_rule; /* default rule*/ 485 struct ipfw3_state_context *state_ctx; 486 struct ipfw3_table_context *table_ctx; 487 488 /* each bit represents a disabled set, 0 is the default set */ 489 uint32_t sets; 490 }; 491 #define LEN_FW3_CTX sizeof(struct ipfw3_context) 492 493 struct ipfw3_module{ 494 int type; 495 int id; 496 char name[20]; 497 }; 498 499 500 /* 501 * Definitions for IP option names. 502 */ 503 #define IP_FW_IPOPT_LSRR 0x01 504 #define IP_FW_IPOPT_SSRR 0x02 505 #define IP_FW_IPOPT_RR 0x04 506 #define IP_FW_IPOPT_TS 0x08 507 508 /* 509 * Definitions for TCP option names. 510 */ 511 #define IP_FW_TCPOPT_MSS 0x01 512 #define IP_FW_TCPOPT_WINDOW 0x02 513 #define IP_FW_TCPOPT_SACK 0x04 514 #define IP_FW_TCPOPT_TS 0x08 515 #define IP_FW_TCPOPT_CC 0x10 516 517 #define ICMP_REJECT_RST 0x100 /* fake ICMP code (send a TCP RST) */ 518 519 #define MATCH_REVERSE 0 520 #define MATCH_FORWARD 1 521 #define MATCH_NONE 2 522 #define MATCH_UNKNOWN 3 523 524 #define L3HDR(T, ip) ((T *)((uint32_t *)(ip) + (ip)->ip_hl)) 525 526 527 typedef void (*filter_func)(int *cmd_ctl,int *cmd_val,struct ip_fw_args **args, 528 struct ip_fw **f,ipfw_insn *cmd, uint16_t ip_len); 529 530 void check_accept(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args, 531 struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len); 532 void check_deny(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 void ip_fw3_register_module(int module_id,char *module_name); 536 int ip_fw3_unregister_module(int module_id); 537 void ip_fw3_register_filter_funcs(int module, int opcode, filter_func func); 538 void ip_fw3_unregister_filter_funcs(int module,filter_func func); 539 540 void init_module(void); 541 int ip_fw3_free_rule(struct ip_fw *rule); 542 int ip_fw3_chk(struct ip_fw_args *args); 543 struct mbuf *ip_fw3_dummynet_io(struct mbuf *m, int pipe_nr, int dir, struct ip_fw_args *fwa); 544 void add_rule_dispatch(netmsg_t nmsg); 545 void ip_fw3_add_rule(struct ipfw_ioc_rule *ioc_rule); 546 struct ip_fw *ip_fw3_delete_rule(struct ipfw3_context *ctx, 547 struct ip_fw *prev, struct ip_fw *rule); 548 void flush_rule_dispatch(netmsg_t nmsg); 549 void ip_fw3_ctl_flush_rule(int); 550 void delete_rule_dispatch(netmsg_t nmsg); 551 int ip_fw3_ctl_delete_rule(struct sockopt *sopt); 552 void ip_fw3_clear_counters(struct ip_fw *rule); 553 void ip_fw3_zero_entry_dispatch(netmsg_t nmsg); 554 int ip_fw3_ctl_zero_entry(int rulenum, int log_only); 555 int ip_fw3_ctl_add_rule(struct sockopt *sopt); 556 int ip_fw3_ctl_get_modules(struct sockopt *sopt); 557 int ip_fw3_ctl_get_rules(struct sockopt *sopt); 558 int ip_fw3_ctl_x(struct sockopt *sopt); 559 int ip_fw3_ctl(struct sockopt *sopt); 560 int ip_fw3_ctl_sockopt(struct sockopt *sopt); 561 int ip_fw3_check_in(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir); 562 int ip_fw3_check_out(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir); 563 void ip_fw3_hook(void); 564 void ip_fw3_dehook(void); 565 void ip_fw3_sysctl_enable_dispatch(netmsg_t nmsg); 566 void ctx_init_dispatch(netmsg_t nmsg); 567 void init_dispatch(netmsg_t nmsg); 568 int ip_fw3_init(void); 569 void fini_dispatch(netmsg_t nmsg); 570 int ip_fw3_fini(void); 571 572 #endif /* _KERNEL */ 573 #endif /* _IPFW2_H */ 574 #endif /* _IP_FW3_H_ */ 575