ip_fw.h revision 215179
1139823Simp/*- 2193516Sluigi * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa 33969Sjkh * 498943Sluigi * Redistribution and use in source and binary forms, with or without 598943Sluigi * modification, are permitted provided that the following conditions 698943Sluigi * are met: 798943Sluigi * 1. Redistributions of source code must retain the above copyright 898943Sluigi * notice, this list of conditions and the following disclaimer. 998943Sluigi * 2. Redistributions in binary form must reproduce the above copyright 1098943Sluigi * notice, this list of conditions and the following disclaimer in the 1198943Sluigi * documentation and/or other materials provided with the distribution. 123969Sjkh * 1398943Sluigi * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1498943Sluigi * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1598943Sluigi * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1698943Sluigi * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1798943Sluigi * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1898943Sluigi * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 1998943Sluigi * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2098943Sluigi * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2198943Sluigi * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2298943Sluigi * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2398943Sluigi * SUCH DAMAGE. 243969Sjkh * 2550477Speter * $FreeBSD: head/sys/netinet/ip_fw.h 215179 2010-11-12 13:05:17Z luigi $ 263969Sjkh */ 273969Sjkh 2898943Sluigi#ifndef _IPFW2_H 2998943Sluigi#define _IPFW2_H 30133920Sandre 313969Sjkh/* 32183012Srik * The default rule number. By the design of ip_fw, the default rule 33183012Srik * is the last one, so its number can also serve as the highest number 34183012Srik * allowed for a rule. The ip_fw code relies on both meanings of this 35183012Srik * constant. 36182818Srik */ 37182818Srik#define IPFW_DEFAULT_RULE 65535 38182818Srik 39182818Srik/* 40183240Srik * The number of ipfw tables. The maximum allowed table number is the 41183240Srik * (IPFW_TABLES_MAX - 1). 42183240Srik */ 43183240Srik#define IPFW_TABLES_MAX 128 44183240Srik 45183240Srik/* 46193516Sluigi * Most commands (queue, pipe, tag, untag, limit...) can have a 16-bit 47193516Sluigi * argument between 1 and 65534. The value 0 is unused, the value 48193516Sluigi * 65535 (IP_FW_TABLEARG) is used to represent 'tablearg', i.e. the 49193516Sluigi * can be 1..65534, or 65535 to indicate the use of a 'tablearg' 50193516Sluigi * result of the most recent table() lookup. 51193516Sluigi * Note that 16bit is only a historical limit, resulting from 52193516Sluigi * the use of a 16-bit fields for that value. In reality, we can have 53193516Sluigi * 2^32 pipes, queues, tag values and so on, and use 0 as a tablearg. 54193516Sluigi */ 55193516Sluigi#define IPFW_ARG_MIN 1 56193516Sluigi#define IPFW_ARG_MAX 65534 57193516Sluigi#define IP_FW_TABLEARG 65535 /* XXX should use 0 */ 58193516Sluigi 59193516Sluigi/* 6098943Sluigi * The kernel representation of ipfw rules is made of a list of 6198943Sluigi * 'instructions' (for all practical purposes equivalent to BPF 6298943Sluigi * instructions), which specify which fields of the packet 63115793Sticso * (or its metadata) should be analysed. 6426359Sjulian * 6598943Sluigi * Each instruction is stored in a structure which begins with 6698943Sluigi * "ipfw_insn", and can contain extra fields depending on the 6798943Sluigi * instruction type (listed below). 68115793Sticso * Note that the code is written so that individual instructions 69115793Sticso * have a size which is a multiple of 32 bits. This means that, if 70115793Sticso * such structures contain pointers or other 64-bit entities, 71115793Sticso * (there is just one instance now) they may end up unaligned on 72115793Sticso * 64-bit architectures, so the must be handled with care. 7398943Sluigi * 7498943Sluigi * "enum ipfw_opcodes" are the opcodes supported. We can have up 75133600Scsjp * to 256 different opcodes. When adding new opcodes, they should 76133600Scsjp * be appended to the end of the opcode list before O_LAST_OPCODE, 77133600Scsjp * this will prevent the ABI from being broken, otherwise users 78133600Scsjp * will have to recompile ipfw(8) when they update the kernel. 7926359Sjulian */ 8026359Sjulian 8198943Sluigienum ipfw_opcodes { /* arguments (4 byte each) */ 8298943Sluigi O_NOP, 8398943Sluigi 8498943Sluigi O_IP_SRC, /* u32 = IP */ 8598943Sluigi O_IP_SRC_MASK, /* ip = IP/mask */ 8698943Sluigi O_IP_SRC_ME, /* none */ 8798943Sluigi O_IP_SRC_SET, /* u32=base, arg1=len, bitmap */ 8898943Sluigi 8998943Sluigi O_IP_DST, /* u32 = IP */ 9098943Sluigi O_IP_DST_MASK, /* ip = IP/mask */ 9198943Sluigi O_IP_DST_ME, /* none */ 9298943Sluigi O_IP_DST_SET, /* u32=base, arg1=len, bitmap */ 9398943Sluigi 9498943Sluigi O_IP_SRCPORT, /* (n)port list:mask 4 byte ea */ 9598943Sluigi O_IP_DSTPORT, /* (n)port list:mask 4 byte ea */ 9698943Sluigi O_PROTO, /* arg1=protocol */ 9798943Sluigi 9898943Sluigi O_MACADDR2, /* 2 mac addr:mask */ 9998943Sluigi O_MAC_TYPE, /* same as srcport */ 10098943Sluigi 10198943Sluigi O_LAYER2, /* none */ 10298943Sluigi O_IN, /* none */ 10398943Sluigi O_FRAG, /* none */ 10498943Sluigi 10598943Sluigi O_RECV, /* none */ 10698943Sluigi O_XMIT, /* none */ 10798943Sluigi O_VIA, /* none */ 10898943Sluigi 10998943Sluigi O_IPOPT, /* arg1 = 2*u8 bitmap */ 11098943Sluigi O_IPLEN, /* arg1 = len */ 11198943Sluigi O_IPID, /* arg1 = id */ 11298943Sluigi 11398943Sluigi O_IPTOS, /* arg1 = id */ 11499475Sluigi O_IPPRECEDENCE, /* arg1 = precedence << 5 */ 11598943Sluigi O_IPTTL, /* arg1 = TTL */ 11698943Sluigi 11798943Sluigi O_IPVER, /* arg1 = version */ 11898943Sluigi O_UID, /* u32 = id */ 11998943Sluigi O_GID, /* u32 = id */ 12098943Sluigi O_ESTAB, /* none (tcp established) */ 12198943Sluigi O_TCPFLAGS, /* arg1 = 2*u8 bitmap */ 12298943Sluigi O_TCPWIN, /* arg1 = desired win */ 12398943Sluigi O_TCPSEQ, /* u32 = desired seq. */ 12498943Sluigi O_TCPACK, /* u32 = desired seq. */ 12598943Sluigi O_ICMPTYPE, /* u32 = icmp bitmap */ 12698943Sluigi O_TCPOPTS, /* arg1 = 2*u8 bitmap */ 12798943Sluigi 128112250Scjc O_VERREVPATH, /* none */ 129128575Sandre O_VERSRCREACH, /* none */ 130112250Scjc 13198943Sluigi O_PROBE_STATE, /* none */ 13298943Sluigi O_KEEP_STATE, /* none */ 13398943Sluigi O_LIMIT, /* ipfw_insn_limit */ 13498943Sluigi O_LIMIT_PARENT, /* dyn_type, not an opcode. */ 135117240Sluigi 13698943Sluigi /* 137117240Sluigi * These are really 'actions'. 13898943Sluigi */ 13998943Sluigi 14098943Sluigi O_LOG, /* ipfw_insn_log */ 14198943Sluigi O_PROB, /* u32 = match probability */ 14298943Sluigi 14398943Sluigi O_CHECK_STATE, /* none */ 14498943Sluigi O_ACCEPT, /* none */ 14598943Sluigi O_DENY, /* none */ 14698943Sluigi O_REJECT, /* arg1=icmp arg (same as deny) */ 14798943Sluigi O_COUNT, /* none */ 14898943Sluigi O_SKIPTO, /* arg1=next rule number */ 14998943Sluigi O_PIPE, /* arg1=pipe number */ 15098943Sluigi O_QUEUE, /* arg1=queue number */ 15198943Sluigi O_DIVERT, /* arg1=port number */ 15298943Sluigi O_TEE, /* arg1=port number */ 15398943Sluigi O_FORWARD_IP, /* fwd sockaddr */ 15498943Sluigi O_FORWARD_MAC, /* fwd mac */ 155165648Spiso O_NAT, /* nope */ 156190633Spiso O_REASS, /* none */ 157190633Spiso 158117240Sluigi /* 159117240Sluigi * More opcodes. 160117240Sluigi */ 161117240Sluigi O_IPSEC, /* has ipsec history */ 162130281Sru O_IP_SRC_LOOKUP, /* arg1=table number, u32=value */ 163130281Sru O_IP_DST_LOOKUP, /* arg1=table number, u32=value */ 164133849Sobrien O_ANTISPOOF, /* none */ 165133600Scsjp O_JAIL, /* u32 = id */ 166136071Sgreen O_ALTQ, /* u32 = altq classif. qid */ 167136073Sgreen O_DIVERTED, /* arg1=bitmap (1:loop, 2:out) */ 168136075Sgreen O_TCPDATALEN, /* arg1 = tcp data len */ 169145246Sbrooks O_IP6_SRC, /* address without mask */ 170145246Sbrooks O_IP6_SRC_ME, /* my addresses */ 171145246Sbrooks O_IP6_SRC_MASK, /* address with the mask */ 172145246Sbrooks O_IP6_DST, 173145246Sbrooks O_IP6_DST_ME, 174145246Sbrooks O_IP6_DST_MASK, 175145246Sbrooks O_FLOW6ID, /* for flow id tag in the ipv6 pkt */ 176145246Sbrooks O_ICMP6TYPE, /* icmp6 packet type filtering */ 177145246Sbrooks O_EXT_HDR, /* filtering for ipv6 extension header */ 178145246Sbrooks O_IP6, 179117240Sluigi 180141351Sglebius /* 181141351Sglebius * actions for ng_ipfw 182141351Sglebius */ 183141351Sglebius O_NETGRAPH, /* send to ng_ipfw */ 184141351Sglebius O_NGTEE, /* copy to ng_ipfw */ 185141351Sglebius 186146894Smlaier O_IP4, 187146894Smlaier 188149020Sbz O_UNREACH6, /* arg1=icmpv6 code arg (deny) */ 189149020Sbz 190158879Soleg O_TAG, /* arg1=tag number */ 191158879Soleg O_TAGGED, /* arg1=tag number */ 192158879Soleg 193178888Sjulian O_SETFIB, /* arg1=FIB number */ 194178888Sjulian O_FIB, /* arg1=FIB desired fib number */ 195215179Sluigi 196215179Sluigi O_SOCKARG, /* socket argument */ 197178888Sjulian 19898943Sluigi O_LAST_OPCODE /* not an opcode! */ 19926359Sjulian}; 20026359Sjulian 201215179Sluigi 20226359Sjulian/* 203145246Sbrooks * The extension header are filtered only for presence using a bit 204145246Sbrooks * vector with a flag for each header. 205145246Sbrooks */ 206145246Sbrooks#define EXT_FRAGMENT 0x1 207145246Sbrooks#define EXT_HOPOPTS 0x2 208145246Sbrooks#define EXT_ROUTING 0x4 209145246Sbrooks#define EXT_AH 0x8 210145246Sbrooks#define EXT_ESP 0x10 211149020Sbz#define EXT_DSTOPTS 0x20 212169245Sbz#define EXT_RTHDR0 0x40 213169245Sbz#define EXT_RTHDR2 0x80 214145246Sbrooks 215145246Sbrooks/* 21698943Sluigi * Template for instructions. 2173969Sjkh * 21898943Sluigi * ipfw_insn is used for all instructions which require no operands, 21998943Sluigi * a single 16-bit value (arg1), or a couple of 8-bit values. 22098943Sluigi * 22198943Sluigi * For other instructions which require different/larger arguments 22298943Sluigi * we have derived structures, ipfw_insn_*. 22398943Sluigi * 22498943Sluigi * The size of the instruction (in 32-bit words) is in the low 22598943Sluigi * 6 bits of "len". The 2 remaining bits are used to implement 22698943Sluigi * NOT and OR on individual instructions. Given a type, you can 22798943Sluigi * compute the length to be put in "len" using F_INSN_SIZE(t) 22898943Sluigi * 22998943Sluigi * F_NOT negates the match result of the instruction. 23098943Sluigi * 23198943Sluigi * F_OR is used to build or blocks. By default, instructions 23298943Sluigi * are evaluated as part of a logical AND. An "or" block 23398943Sluigi * { X or Y or Z } contains F_OR set in all but the last 23498943Sluigi * instruction of the block. A match will cause the code 23598943Sluigi * to skip past the last instruction of the block. 23698943Sluigi * 23798943Sluigi * NOTA BENE: in a couple of places we assume that 23898943Sluigi * sizeof(ipfw_insn) == sizeof(u_int32_t) 23998943Sluigi * this needs to be fixed. 24098943Sluigi * 2413969Sjkh */ 24298943Sluigitypedef struct _ipfw_insn { /* template for instructions */ 243200020Sluigi u_int8_t opcode; 244183744Srwatson u_int8_t len; /* number of 32-bit words */ 24598943Sluigi#define F_NOT 0x80 24698943Sluigi#define F_OR 0x40 24798943Sluigi#define F_LEN_MASK 0x3f 24898943Sluigi#define F_LEN(cmd) ((cmd)->len & F_LEN_MASK) 2493969Sjkh 25098943Sluigi u_int16_t arg1; 25198943Sluigi} ipfw_insn; 25298943Sluigi 25396245Sluigi/* 25498943Sluigi * The F_INSN_SIZE(type) computes the size, in 4-byte words, of 25598943Sluigi * a given type. 25696245Sluigi */ 25798943Sluigi#define F_INSN_SIZE(t) ((sizeof (t))/sizeof(u_int32_t)) 25896245Sluigi 25998943Sluigi/* 26098943Sluigi * This is used to store an array of 16-bit entries (ports etc.) 26198943Sluigi */ 26298943Sluigitypedef struct _ipfw_insn_u16 { 26398943Sluigi ipfw_insn o; 26498943Sluigi u_int16_t ports[2]; /* there may be more */ 26598943Sluigi} ipfw_insn_u16; 26696245Sluigi 26798943Sluigi/* 26898943Sluigi * This is used to store an array of 32-bit entries 26998943Sluigi * (uid, single IPv4 addresses etc.) 27098943Sluigi */ 27198943Sluigitypedef struct _ipfw_insn_u32 { 27298943Sluigi ipfw_insn o; 27398943Sluigi u_int32_t d[1]; /* one or more */ 27498943Sluigi} ipfw_insn_u32; 27584058Sluigi 27698943Sluigi/* 27798943Sluigi * This is used to store IP addr-mask pairs. 27898943Sluigi */ 27998943Sluigitypedef struct _ipfw_insn_ip { 28098943Sluigi ipfw_insn o; 28198943Sluigi struct in_addr addr; 28298943Sluigi struct in_addr mask; 28398943Sluigi} ipfw_insn_ip; 2843969Sjkh 28598943Sluigi/* 286117240Sluigi * This is used to forward to a given address (ip). 28798943Sluigi */ 28898943Sluigitypedef struct _ipfw_insn_sa { 28998943Sluigi ipfw_insn o; 29098943Sluigi struct sockaddr_in sa; 29198943Sluigi} ipfw_insn_sa; 29285665Sjoe 29398943Sluigi/* 29498943Sluigi * This is used for MAC addr-mask pairs. 29598943Sluigi */ 29698943Sluigitypedef struct _ipfw_insn_mac { 29798943Sluigi ipfw_insn o; 29898943Sluigi u_char addr[12]; /* dst[6] + src[6] */ 29998943Sluigi u_char mask[12]; /* dst[6] + src[6] */ 30098943Sluigi} ipfw_insn_mac; 30185665Sjoe 30298943Sluigi/* 303117240Sluigi * This is used for interface match rules (recv xx, xmit xx). 30498943Sluigi */ 30598943Sluigitypedef struct _ipfw_insn_if { 30698943Sluigi ipfw_insn o; 30798943Sluigi union { 30898943Sluigi struct in_addr ip; 309121816Sbrooks int glob; 31098943Sluigi } p; 31198943Sluigi char name[IFNAMSIZ]; 31298943Sluigi} ipfw_insn_if; 31398943Sluigi 31498943Sluigi/* 315136071Sgreen * This is used for storing an altq queue id number. 316136071Sgreen */ 317136071Sgreentypedef struct _ipfw_insn_altq { 318136071Sgreen ipfw_insn o; 319136071Sgreen u_int32_t qid; 320136071Sgreen} ipfw_insn_altq; 321136071Sgreen 322136071Sgreen/* 32398943Sluigi * This is used for limit rules. 32498943Sluigi */ 32598943Sluigitypedef struct _ipfw_insn_limit { 32698943Sluigi ipfw_insn o; 32798943Sluigi u_int8_t _pad; 32898943Sluigi u_int8_t limit_mask; /* combination of DYN_* below */ 32984058Sluigi#define DYN_SRC_ADDR 0x1 33084058Sluigi#define DYN_SRC_PORT 0x2 33184058Sluigi#define DYN_DST_ADDR 0x4 33284058Sluigi#define DYN_DST_PORT 0x8 33385665Sjoe 33498943Sluigi u_int16_t conn_limit; 33598943Sluigi} ipfw_insn_limit; 33649630Sluigi 33798943Sluigi/* 338117240Sluigi * This is used for log instructions. 33998943Sluigi */ 34098943Sluigitypedef struct _ipfw_insn_log { 34198943Sluigi ipfw_insn o; 34298943Sluigi u_int32_t max_log; /* how many do we log -- 0 = all */ 34398943Sluigi u_int32_t log_left; /* how many left to log */ 34498943Sluigi} ipfw_insn_log; 34526359Sjulian 346175659Srwatson/* 347175659Srwatson * Data structures required by both ipfw(8) and ipfw(4) but not part of the 348178673Srwatson * management API are protected by IPFW_INTERNAL. 349175659Srwatson */ 350175659Srwatson#ifdef IPFW_INTERNAL 351165648Spiso/* Server pool support (LSNAT). */ 352165648Spisostruct cfg_spool { 353165648Spiso LIST_ENTRY(cfg_spool) _next; /* chain of spool instances */ 354165648Spiso struct in_addr addr; 355165648Spiso u_short port; 356165648Spiso}; 357175659Srwatson#endif 358165648Spiso 359165648Spiso/* Redirect modes id. */ 360165648Spiso#define REDIR_ADDR 0x01 361165648Spiso#define REDIR_PORT 0x02 362165648Spiso#define REDIR_PROTO 0x04 363165648Spiso 364175659Srwatson#ifdef IPFW_INTERNAL 365165648Spiso/* Nat redirect configuration. */ 366165648Spisostruct cfg_redir { 367165648Spiso LIST_ENTRY(cfg_redir) _next; /* chain of redir instances */ 368165648Spiso u_int16_t mode; /* type of redirect mode */ 369165648Spiso struct in_addr laddr; /* local ip address */ 370165648Spiso struct in_addr paddr; /* public ip address */ 371165648Spiso struct in_addr raddr; /* remote ip address */ 372165648Spiso u_short lport; /* local port */ 373165648Spiso u_short pport; /* public port */ 374165648Spiso u_short rport; /* remote port */ 375165648Spiso u_short pport_cnt; /* number of public ports */ 376165648Spiso u_short rport_cnt; /* number of remote ports */ 377165648Spiso int proto; /* protocol: tcp/udp */ 378165648Spiso struct alias_link **alink; 379165648Spiso /* num of entry in spool chain */ 380165648Spiso u_int16_t spool_cnt; 381165648Spiso /* chain of spool instances */ 382165648Spiso LIST_HEAD(spool_chain, cfg_spool) spool_chain; 383165648Spiso}; 384175659Srwatson#endif 385165648Spiso 386165648Spiso#define NAT_BUF_LEN 1024 387175659Srwatson 388175659Srwatson#ifdef IPFW_INTERNAL 389165648Spiso/* Nat configuration data struct. */ 390165648Spisostruct cfg_nat { 391165648Spiso /* chain of nat instances */ 392165648Spiso LIST_ENTRY(cfg_nat) _next; 393165648Spiso int id; /* nat id */ 394165648Spiso struct in_addr ip; /* nat ip address */ 395165648Spiso char if_name[IF_NAMESIZE]; /* interface name */ 396165648Spiso int mode; /* aliasing mode */ 397165648Spiso struct libalias *lib; /* libalias instance */ 398165648Spiso /* number of entry in spool chain */ 399165648Spiso int redir_cnt; 400165648Spiso /* chain of redir instances */ 401165648Spiso LIST_HEAD(redir_chain, cfg_redir) redir_chain; 402165648Spiso}; 403175659Srwatson#endif 404165648Spiso 405165648Spiso#define SOF_NAT sizeof(struct cfg_nat) 406165648Spiso#define SOF_REDIR sizeof(struct cfg_redir) 407165648Spiso#define SOF_SPOOL sizeof(struct cfg_spool) 408165648Spiso 409165648Spiso/* Nat command. */ 410165648Spisotypedef struct _ipfw_insn_nat { 411165648Spiso ipfw_insn o; 412165648Spiso struct cfg_nat *nat; 413165648Spiso} ipfw_insn_nat; 414165648Spiso 415145246Sbrooks/* Apply ipv6 mask on ipv6 addr */ 416145246Sbrooks#define APPLY_MASK(addr,mask) \ 417145246Sbrooks (addr)->__u6_addr.__u6_addr32[0] &= (mask)->__u6_addr.__u6_addr32[0]; \ 418145246Sbrooks (addr)->__u6_addr.__u6_addr32[1] &= (mask)->__u6_addr.__u6_addr32[1]; \ 419145246Sbrooks (addr)->__u6_addr.__u6_addr32[2] &= (mask)->__u6_addr.__u6_addr32[2]; \ 420145246Sbrooks (addr)->__u6_addr.__u6_addr32[3] &= (mask)->__u6_addr.__u6_addr32[3]; 421145246Sbrooks 422145246Sbrooks/* Structure for ipv6 */ 423145246Sbrookstypedef struct _ipfw_insn_ip6 { 424145246Sbrooks ipfw_insn o; 425145246Sbrooks struct in6_addr addr6; 426145246Sbrooks struct in6_addr mask6; 427145246Sbrooks} ipfw_insn_ip6; 428145246Sbrooks 429145246Sbrooks/* Used to support icmp6 types */ 430145246Sbrookstypedef struct _ipfw_insn_icmp6 { 431145246Sbrooks ipfw_insn o; 432145246Sbrooks uint32_t d[7]; /* XXX This number si related to the netinet/icmp6.h 433145246Sbrooks * define ICMP6_MAXTYPE 434145246Sbrooks * as follows: n = ICMP6_MAXTYPE/32 + 1 435145246Sbrooks * Actually is 203 436145246Sbrooks */ 437145246Sbrooks} ipfw_insn_icmp6; 438145246Sbrooks 43985689Sjoe/* 44098943Sluigi * Here we have the structure representing an ipfw rule. 44183725Sluigi * 44298943Sluigi * It starts with a general area (with link fields and counters) 44398943Sluigi * followed by an array of one or more instructions, which the code 44498943Sluigi * accesses as an array of 32-bit values. 44583725Sluigi * 44698943Sluigi * Given a rule pointer r: 44798943Sluigi * 44898943Sluigi * r->cmd is the start of the first instruction. 44998943Sluigi * ACTION_PTR(r) is the start of the first action (things to do 45098943Sluigi * once a rule matched). 45198943Sluigi * 45298943Sluigi * When assembling instruction, remember the following: 45398943Sluigi * 45498943Sluigi * + if a rule has a "keep-state" (or "limit") option, then the 45598943Sluigi * first instruction (at r->cmd) MUST BE an O_PROBE_STATE 45698943Sluigi * + if a rule has a "log" option, then the first action 45798943Sluigi * (at ACTION_PTR(r)) MUST be O_LOG 458136071Sgreen * + if a rule has an "altq" option, it comes after "log" 459158879Soleg * + if a rule has an O_TAG option, it comes after "log" and "altq" 46098943Sluigi * 46198943Sluigi * NOTE: we use a simple linked list of rules because we never need 46298943Sluigi * to delete a rule without scanning the list. We do not use 46398943Sluigi * queue(3) macros for portability and readability. 46483725Sluigi */ 46583725Sluigi 46698943Sluigistruct ip_fw { 467200855Sluigi struct ip_fw *x_next; /* linked list of rules */ 468101628Sluigi struct ip_fw *next_rule; /* ptr to next [skipto] rule */ 469117240Sluigi /* 'next_rule' is used to pass up 'set_disable' status */ 470117240Sluigi 471193859Soleg uint16_t act_ofs; /* offset of action in 32-bit units */ 472193859Soleg uint16_t cmd_len; /* # of 32-bit words in cmd */ 473193859Soleg uint16_t rulenum; /* rule number */ 474193859Soleg uint8_t set; /* rule set (0..31) */ 475117654Sluigi#define RESVD_SET 31 /* set for default and persistent rules */ 476193859Soleg uint8_t _pad; /* padding */ 477193859Soleg uint32_t id; /* rule id */ 47898943Sluigi 47998943Sluigi /* These fields are present in all rules. */ 480193859Soleg uint64_t pcnt; /* Packet counter */ 481193859Soleg uint64_t bcnt; /* Byte counter */ 482193859Soleg uint32_t timestamp; /* tv_sec of last match */ 48398943Sluigi 48498943Sluigi ipfw_insn cmd[1]; /* storage for commands */ 48598943Sluigi}; 48698943Sluigi 48798943Sluigi#define ACTION_PTR(rule) \ 48898943Sluigi (ipfw_insn *)( (u_int32_t *)((rule)->cmd) + ((rule)->act_ofs) ) 48998943Sluigi 49098943Sluigi#define RULESIZE(rule) (sizeof(struct ip_fw) + \ 49198943Sluigi ((struct ip_fw *)(rule))->cmd_len * 4 - 4) 49298943Sluigi 493205173Sluigi#if 1 // should be moved to in.h 4944277Sjkh/* 49598943Sluigi * This structure is used as a flow mask and a flow id for various 49698943Sluigi * parts of the code. 497205173Sluigi * addr_type is used in userland and kernel to mark the address type. 498205173Sluigi * fib is used in the kernel to record the fib in use. 499205173Sluigi * _flags is used in the kernel to store tcp flags for dynamic rules. 50057113Sluigi */ 50157113Sluigistruct ipfw_flow_id { 502204591Sluigi uint32_t dst_ip; 503204591Sluigi uint32_t src_ip; 504204591Sluigi uint16_t dst_port; 505204591Sluigi uint16_t src_port; 506205173Sluigi uint8_t fib; 507205173Sluigi uint8_t proto; 508205173Sluigi uint8_t _flags; /* protocol-specific flags */ 509205173Sluigi uint8_t addr_type; /* 4=ip4, 6=ip6, 1=ether ? */ 510204591Sluigi struct in6_addr dst_ip6; 511145246Sbrooks struct in6_addr src_ip6; 512204591Sluigi uint32_t flow_id6; 513205173Sluigi uint32_t extra; /* queue/pipe or frag_id */ 51485665Sjoe}; 515204591Sluigi#endif 51657113Sluigi 517145246Sbrooks#define IS_IP6_FLOW_ID(id) ((id)->addr_type == 6) 518145246Sbrooks 51957113Sluigi/* 520117240Sluigi * Dynamic ipfw rule. 52157113Sluigi */ 52298943Sluigitypedef struct _ipfw_dyn_rule ipfw_dyn_rule; 52398943Sluigi 52498943Sluigistruct _ipfw_dyn_rule { 52598943Sluigi ipfw_dyn_rule *next; /* linked list of rules. */ 52698943Sluigi struct ip_fw *rule; /* pointer to rule */ 527117240Sluigi /* 'rule' is used to pass up the rule number (from the parent) */ 528117240Sluigi 52998943Sluigi ipfw_dyn_rule *parent; /* pointer to parent rule */ 53098943Sluigi u_int64_t pcnt; /* packet match counter */ 53198943Sluigi u_int64_t bcnt; /* byte match counter */ 532115793Sticso struct ipfw_flow_id id; /* (masked) flow id */ 533115793Sticso u_int32_t expire; /* expire time */ 53498943Sluigi u_int32_t bucket; /* which bucket in hash table */ 53585665Sjoe u_int32_t state; /* state of this rule (typically a 53685665Sjoe * combination of TCP flags) 53785665Sjoe */ 538100004Sluigi u_int32_t ack_fwd; /* most recent ACKs in forward */ 539100004Sluigi u_int32_t ack_rev; /* and reverse directions (used */ 540100004Sluigi /* to generate keepalives) */ 54198943Sluigi u_int16_t dyn_type; /* rule type */ 54298943Sluigi u_int16_t count; /* refcount */ 54385665Sjoe}; 54457113Sluigi 54557113Sluigi/* 54611119Sugen * Definitions for IP option names. 54711119Sugen */ 54885665Sjoe#define IP_FW_IPOPT_LSRR 0x01 54985665Sjoe#define IP_FW_IPOPT_SSRR 0x02 55085665Sjoe#define IP_FW_IPOPT_RR 0x04 55185665Sjoe#define IP_FW_IPOPT_TS 0x08 55211119Sugen 55311119Sugen/* 55461420Sdan * Definitions for TCP option names. 55561420Sdan */ 55685665Sjoe#define IP_FW_TCPOPT_MSS 0x01 55785665Sjoe#define IP_FW_TCPOPT_WINDOW 0x02 55885665Sjoe#define IP_FW_TCPOPT_SACK 0x04 55985665Sjoe#define IP_FW_TCPOPT_TS 0x08 56085665Sjoe#define IP_FW_TCPOPT_CC 0x10 56161420Sdan 56298943Sluigi#define ICMP_REJECT_RST 0x100 /* fake ICMP code (send a TCP RST) */ 563149020Sbz#define ICMP6_UNREACH_RST 0x100 /* fake ICMPv6 code (send a TCP RST) */ 56498943Sluigi 56561420Sdan/* 566130281Sru * These are used for lookup tables. 567130281Sru */ 568130281Srutypedef struct _ipfw_table_entry { 569130281Sru in_addr_t addr; /* network address */ 570130281Sru u_int32_t value; /* value */ 571130281Sru u_int16_t tbl; /* table number */ 572130281Sru u_int8_t masklen; /* mask length */ 573130281Sru} ipfw_table_entry; 574130281Sru 575130281Srutypedef struct _ipfw_table { 576130281Sru u_int32_t size; /* size of entries in bytes */ 577130281Sru u_int32_t cnt; /* # of entries */ 578130281Sru u_int16_t tbl; /* table number */ 579130281Sru ipfw_table_entry ent[0]; /* entries */ 580130281Sru} ipfw_table; 581130281Sru 58298943Sluigi#endif /* _IPFW2_H */ 583