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 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 #ifdef _KERNEL 43 #include <net/bpf.h> 44 #include <net/netisr2.h> 45 46 int ip_fw3_sockopt(struct sockopt *); 47 extern int ip_fw3_loaded; 48 49 #else 50 #include <pcap/bpf.h> 51 #define PCAP_DONT_INCLUDE_PCAP_BPF_H 52 #endif 53 54 #define IPFW3_LOADED (ip_fw3_loaded) 55 56 /* 57 * _IPFW2_H is from ipfw/ip_fw2.h, both cannot be included past this 58 * point but we need both the IPFW2_LOADED and IPFW3_LOADED macros 59 */ 60 #ifndef _IPFW2_H 61 #define _IPFW2_H 62 63 #define RESERVED_SIZE 12 64 #define SIZE_OF_IPFWINSN 8 65 #define LEN_OF_IPFWINSN 2 66 #define IPFW_DEFAULT_RULE 65535 /* rulenum for the default rule */ 67 #define IPFW_DEFAULT_SET 31 /* set number for the default rule */ 68 69 /* 70 * Template for instructions. 71 * 72 * ipfw_insn is used for all instructions which require no operands, 73 * a single 16-bit value (arg1), or a couple of 8-bit values. 74 * 75 * For other instructions which require different/larger arguments 76 * we have derived structures, ipfw_insn_*. 77 * 78 * The size of the instruction (in 32-bit words) is in the low 79 * 6 bits of "len". The 2 remaining bits are used to implement 80 * NOT and OR on individual instructions. Given a type, you can 81 * compute the length to be put in "len" using F_INSN_SIZE(t) 82 * 83 * F_NOT negates the match result of the instruction. 84 * 85 * F_OR is used to build or blocks. By default, instructions 86 * are evaluated as part of a logical AND. An "or" block 87 * { X or Y or Z } contains F_OR set in all but the last 88 * instruction of the block. A match will cause the code 89 * to skip past the last instruction of the block. 90 * 91 * NOTA BENE: in a couple of places we assume that 92 * sizeof(ipfw_insn) == sizeof(uint32_t) 93 * this needs to be fixed. 94 * 95 */ 96 97 #define F_NOT 0x80 98 #define F_OR 0x40 99 #define F_LEN_MASK 0x3f 100 #define F_LEN(cmd) ((cmd)->len & F_LEN_MASK) 101 102 typedef struct _ipfw_insn { /* template for instructions */ 103 uint8_t opcode; 104 uint8_t len; /* numer of 32-byte words */ 105 uint16_t arg1; 106 107 uint8_t module; 108 uint8_t arg3; 109 uint16_t arg2; 110 } ipfw_insn; 111 112 /* 113 * The F_INSN_SIZE(type) computes the size, in 4-byte words, of 114 * a given type. 115 */ 116 #define F_INSN_SIZE(t) ((sizeof (t))/sizeof(uint32_t)) 117 118 #define MTAG_IPFW 1148380143 /* IPFW-tagged cookie */ 119 120 /* 121 * This is used to store an array of 16-bit entries (ports etc.) 122 */ 123 typedef struct _ipfw_insn_u16 { 124 ipfw_insn o; 125 uint16_t ports[2]; /* there may be more */ 126 } ipfw_insn_u16; 127 128 /* 129 * This is used to store an array of 32-bit entries 130 * (uid, single IPv4 addresses etc.) 131 */ 132 typedef struct _ipfw_insn_u32 { 133 ipfw_insn o; 134 uint32_t d[1]; /* one or more */ 135 } ipfw_insn_u32; 136 137 /* 138 * This is used to store IP addr-mask pairs. 139 */ 140 typedef struct _ipfw_insn_ip { 141 ipfw_insn o; 142 struct in_addr addr; 143 struct in_addr mask; 144 } ipfw_insn_ip; 145 146 /* 147 * This is used to forward to a given address (ip) 148 */ 149 typedef struct _ipfw_insn_sa { 150 ipfw_insn o; 151 struct sockaddr_in sa; 152 } ipfw_insn_sa; 153 154 /* 155 * This is used for MAC addr-mask pairs. 156 */ 157 typedef struct _ipfw_insn_mac { 158 ipfw_insn o; 159 u_char addr[12]; /* dst[6] + src[6] */ 160 u_char mask[12]; /* dst[6] + src[6] */ 161 } ipfw_insn_mac; 162 163 /* 164 * This is used for interface match rules (recv xx, xmit xx) 165 */ 166 typedef struct _ipfw_insn_if { 167 ipfw_insn o; 168 union { 169 struct in_addr ip; 170 int glob; 171 } p; 172 char name[IFNAMSIZ]; 173 } ipfw_insn_if; 174 175 /* 176 * This is used for pipe and queue actions, which need to store 177 * a single pointer (which can have different size on different 178 * architectures. 179 */ 180 typedef struct _ipfw_insn_pipe { 181 ipfw_insn o; 182 void *pipe_ptr; 183 } ipfw_insn_pipe; 184 185 /* 186 * This is used for limit rules. 187 */ 188 typedef struct _ipfw_insn_limit { 189 ipfw_insn o; 190 uint8_t _pad; 191 uint8_t limit_mask; /* combination of DYN_* below */ 192 #define DYN_SRC_ADDR 0x1 193 #define DYN_SRC_PORT 0x2 194 #define DYN_DST_ADDR 0x4 195 #define DYN_DST_PORT 0x8 196 197 uint16_t conn_limit; 198 } ipfw_insn_limit; 199 200 /* 201 * This is used for bpf filtering. 202 */ 203 typedef struct _ipfw_insn_bpf { 204 ipfw_insn o; 205 char bf_str[128]; 206 u_int bf_len; 207 struct bpf_insn bf_insn[1]; 208 } ipfw_insn_bpf; 209 210 /* 211 * Here we have the structure representing an ipfw rule. 212 * 213 * It starts with a general area (with link fields and counters) 214 * followed by an array of one or more instructions, which the code 215 * accesses as an array of 32-bit values. 216 * 217 * Given a rule pointer r: 218 * 219 * r->cmd is the start of the first instruction. 220 * ACTION_PTR(r) is the start of the first action (things to do 221 * once a rule matched). 222 * 223 * When assembling instruction, remember the following: 224 * 225 * + if a rule has a "keep-state" (or "limit") option, then the 226 * first instruction (at r->cmd) MUST BE an O_PROBE_STATE 227 * + if a rule has a "log" option, then the first action 228 * (at ACTION_PTR(r)) MUST be O_LOG 229 * 230 * NOTE: we use a simple linked list of rules because we never need 231 * to delete a rule without scanning the list. We do not use 232 * queue(3) macros for portability and readability. 233 */ 234 235 struct ip_fw { 236 struct ip_fw *next; /* linked list of rules */ 237 struct ip_fw *next_rule; /* ptr to next [skipto] rule */ 238 uint16_t act_ofs; /* offset of action in 32-bit units */ 239 uint16_t cmd_len; /* # of 32-bit words in cmd */ 240 uint16_t rulenum; /* rule number */ 241 uint8_t set; /* rule set (0..31) */ 242 uint8_t flags; /* IPFW_USR_F_ */ 243 244 /* These fields are present in all rules. */ 245 uint64_t pcnt; /* Packet counter */ 246 uint64_t bcnt; /* Byte counter */ 247 uint32_t timestamp; /* tv_sec of last match */ 248 249 struct ip_fw *sibling; /* pointer to the rule in next CPU */ 250 251 ipfw_insn cmd[1]; /* storage for commands */ 252 }; 253 254 255 #define IPFW_RULE_F_INVALID 0x1 256 #define IPFW_RULE_F_STATE 0x2 257 258 #define RULESIZE(rule) (sizeof(struct ip_fw) + (rule)->cmd_len * 4 - SIZE_OF_IPFWINSN) 259 260 /* 261 * This structure is used as a flow mask and a flow id for various 262 * parts of the code. 263 */ 264 struct ipfw_flow_id { 265 uint32_t dst_ip; 266 uint32_t src_ip; 267 uint16_t dst_port; 268 uint16_t src_port; 269 uint8_t proto; 270 uint8_t flags; /* protocol-specific flags */ 271 }; 272 273 struct ip_fw_state { 274 struct ip_fw_state *next; 275 struct ipfw_flow_id flow_id; 276 struct ip_fw *stub; 277 278 uint64_t pcnt; /* packet match counter */ 279 uint64_t bcnt; /* byte match counter */ 280 281 uint16_t lifetime; 282 uint32_t timestamp; 283 uint32_t expiry; 284 }; 285 286 287 /* ipfw_chk/ip_fw_chk_ptr return values */ 288 #define IP_FW_PASS 0 289 #define IP_FW_DENY 1 290 #define IP_FW_DIVERT 2 291 #define IP_FW_TEE 3 292 #define IP_FW_DUMMYNET 4 293 #define IP_FW_NAT 5 294 #define IP_FW_ROUTE 6 295 296 /* ipfw_chk controller values */ 297 #define IP_FW_CTL_NO 0 298 #define IP_FW_CTL_DONE 1 299 #define IP_FW_CTL_AGAIN 2 300 #define IP_FW_CTL_NEXT 3 301 #define IP_FW_CTL_NAT 4 302 #define IP_FW_CTL_LOOP 5 303 #define IP_FW_CTL_CHK_STATE 6 304 305 #define IP_FW_NOT_MATCH 0 306 #define IP_FW_MATCH 1 307 308 /* 309 * arguments for calling ipfw_chk() and dummynet_io(). We put them 310 * all into a structure because this way it is easier and more 311 * efficient to pass variables around and extend the interface. 312 */ 313 struct ip_fw_args { 314 struct mbuf *m; /* the mbuf chain */ 315 struct ifnet *oif; /* output interface */ 316 struct ip_fw *rule; /* matching rule */ 317 struct ether_header *eh; /* for bridged packets */ 318 319 struct ipfw_flow_id f_id; /* grabbed from IP header */ 320 321 /* 322 * Depend on the return value of ipfw_chk/ip_fw_chk_ptr 323 * 'cookie' field may save following information: 324 * 325 * IP_FW_TEE or IP_FW_DIVERT 326 * The divert port number 327 * 328 * IP_FW_DUMMYNET 329 * The pipe or queue number 330 */ 331 uint32_t cookie; 332 }; 333 334 #ifdef _KERNEL 335 /* 336 * Function definitions. 337 */ 338 int ip_fw_sockopt(struct sockopt *); 339 int ipfw_ctl_x(struct sockopt *sopt); 340 341 /* Firewall hooks */ 342 struct sockopt; 343 struct dn_flow_set; 344 345 typedef int ip_fw_chk_t(struct ip_fw_args *); 346 typedef int ip_fw_ctl_t(struct sockopt *); 347 typedef struct mbuf 348 *ip_fw_dn_io_t(struct mbuf *, int, int, struct ip_fw_args *); 349 350 351 extern ip_fw_chk_t *ip_fw_chk_ptr; 352 extern ip_fw_ctl_t *ip_fw_ctl_x_ptr; 353 extern ip_fw_dn_io_t *ip_fw_dn_io_ptr; 354 355 extern int fw3_one_pass; 356 extern int fw3_enable; 357 358 359 #define IPFW_CFGCPUID 0 360 #define IPFW_CFGPORT netisr_cpuport(IPFW_CFGCPUID) 361 #define IPFW_ASSERT_CFGPORT(msgport) \ 362 KASSERT((msgport) == IPFW_CFGPORT, ("not IPFW CFGPORT")) 363 364 #define IPFW_TABLES_MAX 32 365 366 /* root of place holding all information, per-cpu */ 367 struct ipfw_context { 368 struct ip_fw *ipfw_rule_chain; /* list of rules*/ 369 struct ip_fw *ipfw_default_rule; /* default rule */ 370 struct ipfw_state_context *state_ctx; 371 struct ipfw_table_context *table_ctx; 372 uint16_t state_hash_size; 373 uint32_t ipfw_set_disable; 374 }; 375 376 /* place to hold the states */ 377 struct ipfw_state_context { 378 struct ip_fw_state *state; 379 struct ip_fw_state *last; 380 int count; 381 }; 382 383 384 typedef void (*filter_func)(int *cmd_ctl,int *cmd_val,struct ip_fw_args **args, 385 struct ip_fw **f,ipfw_insn *cmd,uint16_t ip_len); 386 void register_ipfw_filter_funcs(int module,int opcode,filter_func func); 387 void unregister_ipfw_filter_funcs(int module,filter_func func); 388 void register_ipfw_module(int module_id,char *module_name); 389 int unregister_ipfw_module(int module_id); 390 391 #endif 392 393 #define ACTION_PTR(rule) \ 394 (ipfw_insn *)((uint32_t *)((rule)->cmd) + ((rule)->act_ofs)) 395 396 397 398 struct ipfw_ioc_rule { 399 uint16_t act_ofs; /* offset of action in 32-bit units */ 400 uint16_t cmd_len; /* # of 32-bit words in cmd */ 401 uint16_t rulenum; /* rule number */ 402 uint8_t set; /* rule set (0..31) */ 403 uint8_t usr_flags; /* IPFW_USR_F_ */ 404 405 /* Rule set information */ 406 uint32_t set_disable; /* disabled rule sets */ 407 uint32_t static_count; /* # of static rules */ 408 uint32_t static_len; /* total length of static rules */ 409 410 /* Statistics */ 411 uint64_t pcnt; /* Packet counter */ 412 uint64_t bcnt; /* Byte counter */ 413 uint32_t timestamp; /* tv_sec of last match */ 414 415 uint8_t reserved[RESERVED_SIZE]; 416 417 ipfw_insn cmd[1]; /* storage for commands */ 418 }; 419 420 #define IPFW_USR_F_NORULE 0x01 421 422 #define IPFW_RULE_SIZE_MAX 255 /* unit: uint32_t */ 423 424 #define IOC_RULESIZE(rule) \ 425 (sizeof(struct ipfw_ioc_rule) + (rule)->cmd_len * 4 - SIZE_OF_IPFWINSN) 426 427 struct ipfw_ioc_flowid { 428 uint16_t type; /* ETHERTYPE_ */ 429 uint16_t pad; 430 union { 431 struct { 432 uint32_t dst_ip; 433 uint32_t src_ip; 434 uint16_t dst_port; 435 uint16_t src_port; 436 uint8_t proto; 437 } ip; 438 uint8_t pad[64]; 439 } u; 440 }; 441 442 struct ipfw_ioc_state { 443 uint64_t pcnt; /* packet match counter */ 444 uint64_t bcnt; /* byte match counter */ 445 uint16_t lifetime; 446 uint32_t timestamp; /* alive time */ 447 uint32_t expiry; /* expire time */ 448 449 uint16_t rulenum; 450 uint16_t cpuid; 451 struct ipfw_flow_id flow_id; /* proto +src/dst ip/port */ 452 uint8_t reserved[16]; 453 }; 454 455 /* 456 * Definitions for IP option names. 457 */ 458 #define IP_FW_IPOPT_LSRR 0x01 459 #define IP_FW_IPOPT_SSRR 0x02 460 #define IP_FW_IPOPT_RR 0x04 461 #define IP_FW_IPOPT_TS 0x08 462 463 /* 464 * Definitions for TCP option names. 465 */ 466 #define IP_FW_TCPOPT_MSS 0x01 467 #define IP_FW_TCPOPT_WINDOW 0x02 468 #define IP_FW_TCPOPT_SACK 0x04 469 #define IP_FW_TCPOPT_TS 0x08 470 #define IP_FW_TCPOPT_CC 0x10 471 472 #define ICMP_REJECT_RST 0x100 /* fake ICMP code (send a TCP RST) */ 473 474 struct ipfw_module{ 475 int type; 476 int id; 477 char name[20]; 478 }; 479 480 /* 481 * type of the keyword, it indecates the position of the keyword in the rule 482 * BEFORE ACTION FROM TO FILTER OTHER 483 */ 484 #define NONE 0 485 #define BEFORE 1 486 #define ACTION 2 487 #define PROTO 3 488 #define FROM 4 489 #define TO 5 490 #define FILTER 6 491 #define AFTER 7 492 493 #define NOT_IN_USE 0 494 #define IN_USE 1 495 496 497 #define NEED1(msg) {if (ac < 1) errx(EX_USAGE, msg);} 498 #define NEED2(msg) {if (ac < 2) errx(EX_USAGE, msg);} 499 #define NEED(c, n, msg) {if (c < n) errx(EX_USAGE, msg);} 500 501 #define NEXT_ARG ac--; if(ac > 0){av++;} 502 #define NEXT_ARG1 (*ac)--; if(*ac > 0){(*av)++;} 503 504 #define MATCH_REVERSE 0 505 #define MATCH_FORWARD 1 506 #define MATCH_NONE 2 507 #define MATCH_UNKNOWN 3 508 509 #define BOTH_SYN (TH_SYN | (TH_SYN << 8)) 510 #define BOTH_FIN (TH_FIN | (TH_FIN << 8)) 511 512 #define TIME_LEQ(a, b) ((int)((a) - (b)) <= 0) 513 #define L3HDR(T, ip) ((T *)((uint32_t *)(ip) + (ip)->ip_hl)) 514 515 /* IP_FW_X header/opcodes */ 516 typedef struct _ip_fw_x_header { 517 uint16_t opcode; /* Operation opcode */ 518 uint16_t _pad; /* Opcode version */ 519 } ip_fw_x_header; 520 521 typedef void ipfw_basic_delete_state_t(struct ip_fw *); 522 typedef void ipfw_basic_append_state_t(struct ipfw_ioc_state *); 523 typedef void ipfw_sync_send_state_t(struct ip_fw_state *, int cpu, int hash); 524 525 /* IP_FW3 opcodes */ 526 527 #define IP_FW_ADD 50 /* add a firewall rule to chain */ 528 #define IP_FW_DEL 51 /* delete a firewall rule from chain */ 529 #define IP_FW_FLUSH 52 /* flush firewall rule chain */ 530 #define IP_FW_ZERO 53 /* clear single/all firewall counter(s) */ 531 #define IP_FW_GET 54 /* get entire firewall rule chain */ 532 #define IP_FW_RESETLOG 55 /* reset logging counters */ 533 534 #define IP_DUMMYNET_CONFIGURE 60 /* add/configure a dummynet pipe */ 535 #define IP_DUMMYNET_DEL 61 /* delete a dummynet pipe from chain */ 536 #define IP_DUMMYNET_FLUSH 62 /* flush dummynet */ 537 #define IP_DUMMYNET_GET 64 /* get entire dummynet pipes */ 538 539 #define IP_FW_MODULE 67 /* get modules names */ 540 541 #define IP_FW_NAT_ADD 68 /* add/config a nat rule */ 542 #define IP_FW_NAT_DEL 69 /* delete a nat rule */ 543 #define IP_FW_NAT_FLUSH 70 /* get configuration of a nat rule */ 544 #define IP_FW_NAT_GET 71 /* get config of a nat rule */ 545 #define IP_FW_NAT_GET_RECORD 72 /* get nat record of a nat rule */ 546 547 #define IP_FW_STATE_ADD 56 /* add one state */ 548 #define IP_FW_STATE_DEL 57 /* delete states of one rulenum */ 549 #define IP_FW_STATE_FLUSH 58 /* flush all states */ 550 551 #define IP_FW_TABLE_CREATE 73 /* table_create */ 552 #define IP_FW_TABLE_DELETE 74 /* table_delete */ 553 #define IP_FW_TABLE_APPEND 75 /* table_append */ 554 #define IP_FW_TABLE_REMOVE 76 /* table_remove */ 555 #define IP_FW_TABLE_LIST 77 /* table_list */ 556 #define IP_FW_TABLE_FLUSH 78 /* table_flush */ 557 #define IP_FW_TABLE_SHOW 79 /* table_show */ 558 #define IP_FW_TABLE_TEST 80 /* table_test */ 559 #define IP_FW_TABLE_RENAME 81 /* rename a table */ 560 561 /* opcodes for ipfw3sync */ 562 #define IP_FW_SYNC_SHOW_CONF 82 /* show sync config */ 563 #define IP_FW_SYNC_SHOW_STATUS 83 /* show edge & centre running status */ 564 565 #define IP_FW_SYNC_EDGE_CONF 84 /* config sync edge */ 566 #define IP_FW_SYNC_EDGE_START 85 /* start the edge */ 567 #define IP_FW_SYNC_EDGE_STOP 86 /* stop the edge */ 568 #define IP_FW_SYNC_EDGE_TEST 87 /* test sync edge */ 569 #define IP_FW_SYNC_EDGE_CLEAR 88 /* stop and clear the edge */ 570 571 #define IP_FW_SYNC_CENTRE_CONF 89 /* config sync centre */ 572 #define IP_FW_SYNC_CENTRE_START 90 /* start the centre */ 573 #define IP_FW_SYNC_CENTRE_STOP 91 /* stop the centre */ 574 #define IP_FW_SYNC_CENTRE_TEST 92 /* test sync centre */ 575 #define IP_FW_SYNC_CENTRE_CLEAR 93 /* stop and clear the centre */ 576 #endif 577 578 #endif /* _IP_FW3_H_ */ 579