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