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$ 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/* 40232865Smelifaro * Default number of ipfw tables. 41183240Srik */ 42233478Smelifaro#define IPFW_TABLES_MAX 65535 43233478Smelifaro#define IPFW_TABLES_DEFAULT 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/* 60223666Sae * Number of entries in the call stack of the call/return commands. 61223666Sae * Call stack currently is an uint16_t array with rule numbers. 62223666Sae */ 63223666Sae#define IPFW_CALLSTACK_SIZE 16 64223666Sae 65232865Smelifaro/* IP_FW3 header/opcodes */ 66232865Smelifarotypedef struct _ip_fw3_opheader { 67232865Smelifaro uint16_t opcode; /* Operation opcode */ 68232865Smelifaro uint16_t reserved[3]; /* Align to 64-bit boundary */ 69232865Smelifaro} ip_fw3_opheader; 70232865Smelifaro 71232865Smelifaro 72232865Smelifaro/* IPFW extented tables support */ 73232865Smelifaro#define IP_FW_TABLE_XADD 86 /* add entry */ 74232865Smelifaro#define IP_FW_TABLE_XDEL 87 /* delete entry */ 75232865Smelifaro#define IP_FW_TABLE_XGETSIZE 88 /* get table size */ 76232865Smelifaro#define IP_FW_TABLE_XLIST 89 /* list table contents */ 77232865Smelifaro 78223666Sae/* 7998943Sluigi * The kernel representation of ipfw rules is made of a list of 8098943Sluigi * 'instructions' (for all practical purposes equivalent to BPF 8198943Sluigi * instructions), which specify which fields of the packet 82115793Sticso * (or its metadata) should be analysed. 8326359Sjulian * 8498943Sluigi * Each instruction is stored in a structure which begins with 8598943Sluigi * "ipfw_insn", and can contain extra fields depending on the 8698943Sluigi * instruction type (listed below). 87115793Sticso * Note that the code is written so that individual instructions 88115793Sticso * have a size which is a multiple of 32 bits. This means that, if 89115793Sticso * such structures contain pointers or other 64-bit entities, 90115793Sticso * (there is just one instance now) they may end up unaligned on 91115793Sticso * 64-bit architectures, so the must be handled with care. 9298943Sluigi * 9398943Sluigi * "enum ipfw_opcodes" are the opcodes supported. We can have up 94133600Scsjp * to 256 different opcodes. When adding new opcodes, they should 95133600Scsjp * be appended to the end of the opcode list before O_LAST_OPCODE, 96133600Scsjp * this will prevent the ABI from being broken, otherwise users 97133600Scsjp * will have to recompile ipfw(8) when they update the kernel. 9826359Sjulian */ 9926359Sjulian 10098943Sluigienum ipfw_opcodes { /* arguments (4 byte each) */ 10198943Sluigi O_NOP, 10298943Sluigi 10398943Sluigi O_IP_SRC, /* u32 = IP */ 10498943Sluigi O_IP_SRC_MASK, /* ip = IP/mask */ 10598943Sluigi O_IP_SRC_ME, /* none */ 10698943Sluigi O_IP_SRC_SET, /* u32=base, arg1=len, bitmap */ 10798943Sluigi 10898943Sluigi O_IP_DST, /* u32 = IP */ 10998943Sluigi O_IP_DST_MASK, /* ip = IP/mask */ 11098943Sluigi O_IP_DST_ME, /* none */ 11198943Sluigi O_IP_DST_SET, /* u32=base, arg1=len, bitmap */ 11298943Sluigi 11398943Sluigi O_IP_SRCPORT, /* (n)port list:mask 4 byte ea */ 11498943Sluigi O_IP_DSTPORT, /* (n)port list:mask 4 byte ea */ 11598943Sluigi O_PROTO, /* arg1=protocol */ 11698943Sluigi 11798943Sluigi O_MACADDR2, /* 2 mac addr:mask */ 11898943Sluigi O_MAC_TYPE, /* same as srcport */ 11998943Sluigi 12098943Sluigi O_LAYER2, /* none */ 12198943Sluigi O_IN, /* none */ 12298943Sluigi O_FRAG, /* none */ 12398943Sluigi 12498943Sluigi O_RECV, /* none */ 12598943Sluigi O_XMIT, /* none */ 12698943Sluigi O_VIA, /* none */ 12798943Sluigi 12898943Sluigi O_IPOPT, /* arg1 = 2*u8 bitmap */ 12998943Sluigi O_IPLEN, /* arg1 = len */ 13098943Sluigi O_IPID, /* arg1 = id */ 13198943Sluigi 13298943Sluigi O_IPTOS, /* arg1 = id */ 13399475Sluigi O_IPPRECEDENCE, /* arg1 = precedence << 5 */ 13498943Sluigi O_IPTTL, /* arg1 = TTL */ 13598943Sluigi 13698943Sluigi O_IPVER, /* arg1 = version */ 13798943Sluigi O_UID, /* u32 = id */ 13898943Sluigi O_GID, /* u32 = id */ 13998943Sluigi O_ESTAB, /* none (tcp established) */ 14098943Sluigi O_TCPFLAGS, /* arg1 = 2*u8 bitmap */ 14198943Sluigi O_TCPWIN, /* arg1 = desired win */ 14298943Sluigi O_TCPSEQ, /* u32 = desired seq. */ 14398943Sluigi O_TCPACK, /* u32 = desired seq. */ 14498943Sluigi O_ICMPTYPE, /* u32 = icmp bitmap */ 14598943Sluigi O_TCPOPTS, /* arg1 = 2*u8 bitmap */ 14698943Sluigi 147112250Scjc O_VERREVPATH, /* none */ 148128575Sandre O_VERSRCREACH, /* none */ 149112250Scjc 15098943Sluigi O_PROBE_STATE, /* none */ 15198943Sluigi O_KEEP_STATE, /* none */ 15298943Sluigi O_LIMIT, /* ipfw_insn_limit */ 15398943Sluigi O_LIMIT_PARENT, /* dyn_type, not an opcode. */ 154117240Sluigi 15598943Sluigi /* 156117240Sluigi * These are really 'actions'. 15798943Sluigi */ 15898943Sluigi 15998943Sluigi O_LOG, /* ipfw_insn_log */ 16098943Sluigi O_PROB, /* u32 = match probability */ 16198943Sluigi 16298943Sluigi O_CHECK_STATE, /* none */ 16398943Sluigi O_ACCEPT, /* none */ 16498943Sluigi O_DENY, /* none */ 16598943Sluigi O_REJECT, /* arg1=icmp arg (same as deny) */ 16698943Sluigi O_COUNT, /* none */ 16798943Sluigi O_SKIPTO, /* arg1=next rule number */ 16898943Sluigi O_PIPE, /* arg1=pipe number */ 16998943Sluigi O_QUEUE, /* arg1=queue number */ 17098943Sluigi O_DIVERT, /* arg1=port number */ 17198943Sluigi O_TEE, /* arg1=port number */ 17298943Sluigi O_FORWARD_IP, /* fwd sockaddr */ 17398943Sluigi O_FORWARD_MAC, /* fwd mac */ 174165648Spiso O_NAT, /* nope */ 175190633Spiso O_REASS, /* none */ 176190633Spiso 177117240Sluigi /* 178117240Sluigi * More opcodes. 179117240Sluigi */ 180117240Sluigi O_IPSEC, /* has ipsec history */ 181130281Sru O_IP_SRC_LOOKUP, /* arg1=table number, u32=value */ 182130281Sru O_IP_DST_LOOKUP, /* arg1=table number, u32=value */ 183133849Sobrien O_ANTISPOOF, /* none */ 184133600Scsjp O_JAIL, /* u32 = id */ 185136071Sgreen O_ALTQ, /* u32 = altq classif. qid */ 186136073Sgreen O_DIVERTED, /* arg1=bitmap (1:loop, 2:out) */ 187136075Sgreen O_TCPDATALEN, /* arg1 = tcp data len */ 188145246Sbrooks O_IP6_SRC, /* address without mask */ 189145246Sbrooks O_IP6_SRC_ME, /* my addresses */ 190145246Sbrooks O_IP6_SRC_MASK, /* address with the mask */ 191145246Sbrooks O_IP6_DST, 192145246Sbrooks O_IP6_DST_ME, 193145246Sbrooks O_IP6_DST_MASK, 194145246Sbrooks O_FLOW6ID, /* for flow id tag in the ipv6 pkt */ 195145246Sbrooks O_ICMP6TYPE, /* icmp6 packet type filtering */ 196145246Sbrooks O_EXT_HDR, /* filtering for ipv6 extension header */ 197145246Sbrooks O_IP6, 198117240Sluigi 199141351Sglebius /* 200141351Sglebius * actions for ng_ipfw 201141351Sglebius */ 202141351Sglebius O_NETGRAPH, /* send to ng_ipfw */ 203141351Sglebius O_NGTEE, /* copy to ng_ipfw */ 204141351Sglebius 205146894Smlaier O_IP4, 206146894Smlaier 207149020Sbz O_UNREACH6, /* arg1=icmpv6 code arg (deny) */ 208149020Sbz 209158879Soleg O_TAG, /* arg1=tag number */ 210158879Soleg O_TAGGED, /* arg1=tag number */ 211158879Soleg 212178888Sjulian O_SETFIB, /* arg1=FIB number */ 213178888Sjulian O_FIB, /* arg1=FIB desired fib number */ 214215179Sluigi 215215179Sluigi O_SOCKARG, /* socket argument */ 216178888Sjulian 217223666Sae O_CALLRETURN, /* arg1=called rule number */ 218223666Sae 219225044Sbz O_FORWARD_IP6, /* fwd sockaddr_in6 */ 220225044Sbz 221248552Smelifaro O_DSCP, /* 2 u32 = DSCP mask */ 222248552Smelifaro O_SETDSCP, /* arg1=DSCP value */ 223248552Smelifaro 22498943Sluigi O_LAST_OPCODE /* not an opcode! */ 22526359Sjulian}; 22626359Sjulian 227215179Sluigi 22826359Sjulian/* 229145246Sbrooks * The extension header are filtered only for presence using a bit 230145246Sbrooks * vector with a flag for each header. 231145246Sbrooks */ 232145246Sbrooks#define EXT_FRAGMENT 0x1 233145246Sbrooks#define EXT_HOPOPTS 0x2 234145246Sbrooks#define EXT_ROUTING 0x4 235145246Sbrooks#define EXT_AH 0x8 236145246Sbrooks#define EXT_ESP 0x10 237149020Sbz#define EXT_DSTOPTS 0x20 238169245Sbz#define EXT_RTHDR0 0x40 239169245Sbz#define EXT_RTHDR2 0x80 240145246Sbrooks 241145246Sbrooks/* 24298943Sluigi * Template for instructions. 2433969Sjkh * 24498943Sluigi * ipfw_insn is used for all instructions which require no operands, 24598943Sluigi * a single 16-bit value (arg1), or a couple of 8-bit values. 24698943Sluigi * 24798943Sluigi * For other instructions which require different/larger arguments 24898943Sluigi * we have derived structures, ipfw_insn_*. 24998943Sluigi * 25098943Sluigi * The size of the instruction (in 32-bit words) is in the low 25198943Sluigi * 6 bits of "len". The 2 remaining bits are used to implement 25298943Sluigi * NOT and OR on individual instructions. Given a type, you can 25398943Sluigi * compute the length to be put in "len" using F_INSN_SIZE(t) 25498943Sluigi * 25598943Sluigi * F_NOT negates the match result of the instruction. 25698943Sluigi * 25798943Sluigi * F_OR is used to build or blocks. By default, instructions 25898943Sluigi * are evaluated as part of a logical AND. An "or" block 25998943Sluigi * { X or Y or Z } contains F_OR set in all but the last 26098943Sluigi * instruction of the block. A match will cause the code 26198943Sluigi * to skip past the last instruction of the block. 26298943Sluigi * 26398943Sluigi * NOTA BENE: in a couple of places we assume that 26498943Sluigi * sizeof(ipfw_insn) == sizeof(u_int32_t) 26598943Sluigi * this needs to be fixed. 26698943Sluigi * 2673969Sjkh */ 26898943Sluigitypedef struct _ipfw_insn { /* template for instructions */ 269200020Sluigi u_int8_t opcode; 270183744Srwatson u_int8_t len; /* number of 32-bit words */ 27198943Sluigi#define F_NOT 0x80 27298943Sluigi#define F_OR 0x40 27398943Sluigi#define F_LEN_MASK 0x3f 27498943Sluigi#define F_LEN(cmd) ((cmd)->len & F_LEN_MASK) 2753969Sjkh 27698943Sluigi u_int16_t arg1; 27798943Sluigi} ipfw_insn; 27898943Sluigi 27996245Sluigi/* 28098943Sluigi * The F_INSN_SIZE(type) computes the size, in 4-byte words, of 28198943Sluigi * a given type. 28296245Sluigi */ 28398943Sluigi#define F_INSN_SIZE(t) ((sizeof (t))/sizeof(u_int32_t)) 28496245Sluigi 28598943Sluigi/* 28698943Sluigi * This is used to store an array of 16-bit entries (ports etc.) 28798943Sluigi */ 28898943Sluigitypedef struct _ipfw_insn_u16 { 28998943Sluigi ipfw_insn o; 29098943Sluigi u_int16_t ports[2]; /* there may be more */ 29198943Sluigi} ipfw_insn_u16; 29296245Sluigi 29398943Sluigi/* 29498943Sluigi * This is used to store an array of 32-bit entries 29598943Sluigi * (uid, single IPv4 addresses etc.) 29698943Sluigi */ 29798943Sluigitypedef struct _ipfw_insn_u32 { 29898943Sluigi ipfw_insn o; 29998943Sluigi u_int32_t d[1]; /* one or more */ 30098943Sluigi} ipfw_insn_u32; 30184058Sluigi 30298943Sluigi/* 30398943Sluigi * This is used to store IP addr-mask pairs. 30498943Sluigi */ 30598943Sluigitypedef struct _ipfw_insn_ip { 30698943Sluigi ipfw_insn o; 30798943Sluigi struct in_addr addr; 30898943Sluigi struct in_addr mask; 30998943Sluigi} ipfw_insn_ip; 3103969Sjkh 31198943Sluigi/* 312117240Sluigi * This is used to forward to a given address (ip). 31398943Sluigi */ 31498943Sluigitypedef struct _ipfw_insn_sa { 31598943Sluigi ipfw_insn o; 31698943Sluigi struct sockaddr_in sa; 31798943Sluigi} ipfw_insn_sa; 31885665Sjoe 31998943Sluigi/* 320225044Sbz * This is used to forward to a given address (ipv6). 321225044Sbz */ 322225044Sbztypedef struct _ipfw_insn_sa6 { 323225044Sbz ipfw_insn o; 324225044Sbz struct sockaddr_in6 sa; 325225044Sbz} ipfw_insn_sa6; 326225044Sbz 327225044Sbz/* 32898943Sluigi * This is used for MAC addr-mask pairs. 32998943Sluigi */ 33098943Sluigitypedef struct _ipfw_insn_mac { 33198943Sluigi ipfw_insn o; 33298943Sluigi u_char addr[12]; /* dst[6] + src[6] */ 33398943Sluigi u_char mask[12]; /* dst[6] + src[6] */ 33498943Sluigi} ipfw_insn_mac; 33585665Sjoe 33698943Sluigi/* 337117240Sluigi * This is used for interface match rules (recv xx, xmit xx). 33898943Sluigi */ 33998943Sluigitypedef struct _ipfw_insn_if { 34098943Sluigi ipfw_insn o; 34198943Sluigi union { 34298943Sluigi struct in_addr ip; 343121816Sbrooks int glob; 34498943Sluigi } p; 34598943Sluigi char name[IFNAMSIZ]; 34698943Sluigi} ipfw_insn_if; 34798943Sluigi 34898943Sluigi/* 349136071Sgreen * This is used for storing an altq queue id number. 350136071Sgreen */ 351136071Sgreentypedef struct _ipfw_insn_altq { 352136071Sgreen ipfw_insn o; 353136071Sgreen u_int32_t qid; 354136071Sgreen} ipfw_insn_altq; 355136071Sgreen 356136071Sgreen/* 35798943Sluigi * This is used for limit rules. 35898943Sluigi */ 35998943Sluigitypedef struct _ipfw_insn_limit { 36098943Sluigi ipfw_insn o; 36198943Sluigi u_int8_t _pad; 36298943Sluigi u_int8_t limit_mask; /* combination of DYN_* below */ 36384058Sluigi#define DYN_SRC_ADDR 0x1 36484058Sluigi#define DYN_SRC_PORT 0x2 36584058Sluigi#define DYN_DST_ADDR 0x4 36684058Sluigi#define DYN_DST_PORT 0x8 36785665Sjoe 36898943Sluigi u_int16_t conn_limit; 36998943Sluigi} ipfw_insn_limit; 37049630Sluigi 37198943Sluigi/* 372117240Sluigi * This is used for log instructions. 37398943Sluigi */ 37498943Sluigitypedef struct _ipfw_insn_log { 37598943Sluigi ipfw_insn o; 37698943Sluigi u_int32_t max_log; /* how many do we log -- 0 = all */ 37798943Sluigi u_int32_t log_left; /* how many left to log */ 37898943Sluigi} ipfw_insn_log; 37926359Sjulian 380175659Srwatson/* 381175659Srwatson * Data structures required by both ipfw(8) and ipfw(4) but not part of the 382178673Srwatson * management API are protected by IPFW_INTERNAL. 383175659Srwatson */ 384175659Srwatson#ifdef IPFW_INTERNAL 385165648Spiso/* Server pool support (LSNAT). */ 386165648Spisostruct cfg_spool { 387165648Spiso LIST_ENTRY(cfg_spool) _next; /* chain of spool instances */ 388165648Spiso struct in_addr addr; 389165648Spiso u_short port; 390165648Spiso}; 391175659Srwatson#endif 392165648Spiso 393165648Spiso/* Redirect modes id. */ 394165648Spiso#define REDIR_ADDR 0x01 395165648Spiso#define REDIR_PORT 0x02 396165648Spiso#define REDIR_PROTO 0x04 397165648Spiso 398175659Srwatson#ifdef IPFW_INTERNAL 399165648Spiso/* Nat redirect configuration. */ 400165648Spisostruct cfg_redir { 401165648Spiso LIST_ENTRY(cfg_redir) _next; /* chain of redir instances */ 402165648Spiso u_int16_t mode; /* type of redirect mode */ 403165648Spiso struct in_addr laddr; /* local ip address */ 404165648Spiso struct in_addr paddr; /* public ip address */ 405165648Spiso struct in_addr raddr; /* remote ip address */ 406165648Spiso u_short lport; /* local port */ 407165648Spiso u_short pport; /* public port */ 408165648Spiso u_short rport; /* remote port */ 409165648Spiso u_short pport_cnt; /* number of public ports */ 410165648Spiso u_short rport_cnt; /* number of remote ports */ 411165648Spiso int proto; /* protocol: tcp/udp */ 412165648Spiso struct alias_link **alink; 413165648Spiso /* num of entry in spool chain */ 414165648Spiso u_int16_t spool_cnt; 415165648Spiso /* chain of spool instances */ 416165648Spiso LIST_HEAD(spool_chain, cfg_spool) spool_chain; 417165648Spiso}; 418175659Srwatson#endif 419165648Spiso 420175659Srwatson#ifdef IPFW_INTERNAL 421165648Spiso/* Nat configuration data struct. */ 422165648Spisostruct cfg_nat { 423165648Spiso /* chain of nat instances */ 424165648Spiso LIST_ENTRY(cfg_nat) _next; 425165648Spiso int id; /* nat id */ 426165648Spiso struct in_addr ip; /* nat ip address */ 427165648Spiso char if_name[IF_NAMESIZE]; /* interface name */ 428165648Spiso int mode; /* aliasing mode */ 429165648Spiso struct libalias *lib; /* libalias instance */ 430165648Spiso /* number of entry in spool chain */ 431165648Spiso int redir_cnt; 432165648Spiso /* chain of redir instances */ 433165648Spiso LIST_HEAD(redir_chain, cfg_redir) redir_chain; 434165648Spiso}; 435175659Srwatson#endif 436165648Spiso 437165648Spiso#define SOF_NAT sizeof(struct cfg_nat) 438165648Spiso#define SOF_REDIR sizeof(struct cfg_redir) 439165648Spiso#define SOF_SPOOL sizeof(struct cfg_spool) 440165648Spiso 441165648Spiso/* Nat command. */ 442165648Spisotypedef struct _ipfw_insn_nat { 443165648Spiso ipfw_insn o; 444165648Spiso struct cfg_nat *nat; 445165648Spiso} ipfw_insn_nat; 446165648Spiso 447145246Sbrooks/* Apply ipv6 mask on ipv6 addr */ 448145246Sbrooks#define APPLY_MASK(addr,mask) \ 449145246Sbrooks (addr)->__u6_addr.__u6_addr32[0] &= (mask)->__u6_addr.__u6_addr32[0]; \ 450145246Sbrooks (addr)->__u6_addr.__u6_addr32[1] &= (mask)->__u6_addr.__u6_addr32[1]; \ 451145246Sbrooks (addr)->__u6_addr.__u6_addr32[2] &= (mask)->__u6_addr.__u6_addr32[2]; \ 452145246Sbrooks (addr)->__u6_addr.__u6_addr32[3] &= (mask)->__u6_addr.__u6_addr32[3]; 453145246Sbrooks 454145246Sbrooks/* Structure for ipv6 */ 455145246Sbrookstypedef struct _ipfw_insn_ip6 { 456145246Sbrooks ipfw_insn o; 457145246Sbrooks struct in6_addr addr6; 458145246Sbrooks struct in6_addr mask6; 459145246Sbrooks} ipfw_insn_ip6; 460145246Sbrooks 461145246Sbrooks/* Used to support icmp6 types */ 462145246Sbrookstypedef struct _ipfw_insn_icmp6 { 463145246Sbrooks ipfw_insn o; 464145246Sbrooks uint32_t d[7]; /* XXX This number si related to the netinet/icmp6.h 465145246Sbrooks * define ICMP6_MAXTYPE 466145246Sbrooks * as follows: n = ICMP6_MAXTYPE/32 + 1 467145246Sbrooks * Actually is 203 468145246Sbrooks */ 469145246Sbrooks} ipfw_insn_icmp6; 470145246Sbrooks 47185689Sjoe/* 47298943Sluigi * Here we have the structure representing an ipfw rule. 47383725Sluigi * 47498943Sluigi * It starts with a general area (with link fields and counters) 47598943Sluigi * followed by an array of one or more instructions, which the code 47698943Sluigi * accesses as an array of 32-bit values. 47783725Sluigi * 47898943Sluigi * Given a rule pointer r: 47998943Sluigi * 48098943Sluigi * r->cmd is the start of the first instruction. 48198943Sluigi * ACTION_PTR(r) is the start of the first action (things to do 48298943Sluigi * once a rule matched). 48398943Sluigi * 48498943Sluigi * When assembling instruction, remember the following: 48598943Sluigi * 48698943Sluigi * + if a rule has a "keep-state" (or "limit") option, then the 48798943Sluigi * first instruction (at r->cmd) MUST BE an O_PROBE_STATE 48898943Sluigi * + if a rule has a "log" option, then the first action 48998943Sluigi * (at ACTION_PTR(r)) MUST be O_LOG 490136071Sgreen * + if a rule has an "altq" option, it comes after "log" 491158879Soleg * + if a rule has an O_TAG option, it comes after "log" and "altq" 49298943Sluigi * 49398943Sluigi * NOTE: we use a simple linked list of rules because we never need 49498943Sluigi * to delete a rule without scanning the list. We do not use 49598943Sluigi * queue(3) macros for portability and readability. 49683725Sluigi */ 49783725Sluigi 49898943Sluigistruct ip_fw { 499200855Sluigi struct ip_fw *x_next; /* linked list of rules */ 500101628Sluigi struct ip_fw *next_rule; /* ptr to next [skipto] rule */ 501117240Sluigi /* 'next_rule' is used to pass up 'set_disable' status */ 502117240Sluigi 503193859Soleg uint16_t act_ofs; /* offset of action in 32-bit units */ 504193859Soleg uint16_t cmd_len; /* # of 32-bit words in cmd */ 505193859Soleg uint16_t rulenum; /* rule number */ 506193859Soleg uint8_t set; /* rule set (0..31) */ 507117654Sluigi#define RESVD_SET 31 /* set for default and persistent rules */ 508193859Soleg uint8_t _pad; /* padding */ 509193859Soleg uint32_t id; /* rule id */ 51098943Sluigi 51198943Sluigi /* These fields are present in all rules. */ 512193859Soleg uint64_t pcnt; /* Packet counter */ 513193859Soleg uint64_t bcnt; /* Byte counter */ 514193859Soleg uint32_t timestamp; /* tv_sec of last match */ 51598943Sluigi 51698943Sluigi ipfw_insn cmd[1]; /* storage for commands */ 51798943Sluigi}; 51898943Sluigi 51998943Sluigi#define ACTION_PTR(rule) \ 52098943Sluigi (ipfw_insn *)( (u_int32_t *)((rule)->cmd) + ((rule)->act_ofs) ) 52198943Sluigi 52298943Sluigi#define RULESIZE(rule) (sizeof(struct ip_fw) + \ 52398943Sluigi ((struct ip_fw *)(rule))->cmd_len * 4 - 4) 52498943Sluigi 525205173Sluigi#if 1 // should be moved to in.h 5264277Sjkh/* 52798943Sluigi * This structure is used as a flow mask and a flow id for various 52898943Sluigi * parts of the code. 529205173Sluigi * addr_type is used in userland and kernel to mark the address type. 530205173Sluigi * fib is used in the kernel to record the fib in use. 531205173Sluigi * _flags is used in the kernel to store tcp flags for dynamic rules. 53257113Sluigi */ 53357113Sluigistruct ipfw_flow_id { 534204591Sluigi uint32_t dst_ip; 535204591Sluigi uint32_t src_ip; 536204591Sluigi uint16_t dst_port; 537204591Sluigi uint16_t src_port; 538205173Sluigi uint8_t fib; 539205173Sluigi uint8_t proto; 540205173Sluigi uint8_t _flags; /* protocol-specific flags */ 541205173Sluigi uint8_t addr_type; /* 4=ip4, 6=ip6, 1=ether ? */ 542204591Sluigi struct in6_addr dst_ip6; 543145246Sbrooks struct in6_addr src_ip6; 544204591Sluigi uint32_t flow_id6; 545205173Sluigi uint32_t extra; /* queue/pipe or frag_id */ 54685665Sjoe}; 547204591Sluigi#endif 54857113Sluigi 549145246Sbrooks#define IS_IP6_FLOW_ID(id) ((id)->addr_type == 6) 550145246Sbrooks 55157113Sluigi/* 552117240Sluigi * Dynamic ipfw rule. 55357113Sluigi */ 55498943Sluigitypedef struct _ipfw_dyn_rule ipfw_dyn_rule; 55598943Sluigi 55698943Sluigistruct _ipfw_dyn_rule { 55798943Sluigi ipfw_dyn_rule *next; /* linked list of rules. */ 55898943Sluigi struct ip_fw *rule; /* pointer to rule */ 559117240Sluigi /* 'rule' is used to pass up the rule number (from the parent) */ 560117240Sluigi 56198943Sluigi ipfw_dyn_rule *parent; /* pointer to parent rule */ 56298943Sluigi u_int64_t pcnt; /* packet match counter */ 56398943Sluigi u_int64_t bcnt; /* byte match counter */ 564115793Sticso struct ipfw_flow_id id; /* (masked) flow id */ 565115793Sticso u_int32_t expire; /* expire time */ 56698943Sluigi u_int32_t bucket; /* which bucket in hash table */ 56785665Sjoe u_int32_t state; /* state of this rule (typically a 56885665Sjoe * combination of TCP flags) 56985665Sjoe */ 570100004Sluigi u_int32_t ack_fwd; /* most recent ACKs in forward */ 571100004Sluigi u_int32_t ack_rev; /* and reverse directions (used */ 572100004Sluigi /* to generate keepalives) */ 57398943Sluigi u_int16_t dyn_type; /* rule type */ 57498943Sluigi u_int16_t count; /* refcount */ 57585665Sjoe}; 57657113Sluigi 57757113Sluigi/* 57811119Sugen * Definitions for IP option names. 57911119Sugen */ 58085665Sjoe#define IP_FW_IPOPT_LSRR 0x01 58185665Sjoe#define IP_FW_IPOPT_SSRR 0x02 58285665Sjoe#define IP_FW_IPOPT_RR 0x04 58385665Sjoe#define IP_FW_IPOPT_TS 0x08 58411119Sugen 58511119Sugen/* 58661420Sdan * Definitions for TCP option names. 58761420Sdan */ 58885665Sjoe#define IP_FW_TCPOPT_MSS 0x01 58985665Sjoe#define IP_FW_TCPOPT_WINDOW 0x02 59085665Sjoe#define IP_FW_TCPOPT_SACK 0x04 59185665Sjoe#define IP_FW_TCPOPT_TS 0x08 59285665Sjoe#define IP_FW_TCPOPT_CC 0x10 59361420Sdan 59498943Sluigi#define ICMP_REJECT_RST 0x100 /* fake ICMP code (send a TCP RST) */ 595149020Sbz#define ICMP6_UNREACH_RST 0x100 /* fake ICMPv6 code (send a TCP RST) */ 59698943Sluigi 59761420Sdan/* 598130281Sru * These are used for lookup tables. 599130281Sru */ 600232865Smelifaro 601232865Smelifaro#define IPFW_TABLE_CIDR 1 /* Table for holding IPv4/IPv6 prefixes */ 602232865Smelifaro#define IPFW_TABLE_INTERFACE 2 /* Table for holding interface names */ 603232865Smelifaro#define IPFW_TABLE_MAXTYPE 2 /* Maximum valid number */ 604232865Smelifaro 605130281Srutypedef struct _ipfw_table_entry { 606130281Sru in_addr_t addr; /* network address */ 607130281Sru u_int32_t value; /* value */ 608130281Sru u_int16_t tbl; /* table number */ 609130281Sru u_int8_t masklen; /* mask length */ 610130281Sru} ipfw_table_entry; 611130281Sru 612232865Smelifarotypedef struct _ipfw_table_xentry { 613232865Smelifaro uint16_t len; /* Total entry length */ 614232865Smelifaro uint8_t type; /* entry type */ 615232865Smelifaro uint8_t masklen; /* mask length */ 616232865Smelifaro uint16_t tbl; /* table number */ 617232865Smelifaro uint32_t value; /* value */ 618232865Smelifaro union { 619232865Smelifaro /* Longest field needs to be aligned by 4-byte boundary */ 620232865Smelifaro struct in6_addr addr6; /* IPv6 address */ 621232865Smelifaro char iface[IF_NAMESIZE]; /* interface name */ 622232865Smelifaro } k; 623232865Smelifaro} ipfw_table_xentry; 624232865Smelifaro 625130281Srutypedef struct _ipfw_table { 626130281Sru u_int32_t size; /* size of entries in bytes */ 627130281Sru u_int32_t cnt; /* # of entries */ 628130281Sru u_int16_t tbl; /* table number */ 629130281Sru ipfw_table_entry ent[0]; /* entries */ 630130281Sru} ipfw_table; 631130281Sru 632232865Smelifarotypedef struct _ipfw_xtable { 633232865Smelifaro ip_fw3_opheader opheader; /* eXtended tables are controlled via IP_FW3 */ 634232865Smelifaro uint32_t size; /* size of entries in bytes */ 635232865Smelifaro uint32_t cnt; /* # of entries */ 636232865Smelifaro uint16_t tbl; /* table number */ 637232865Smelifaro uint8_t type; /* table type */ 638232865Smelifaro ipfw_table_xentry xent[0]; /* entries */ 639232865Smelifaro} ipfw_xtable; 640232865Smelifaro 64198943Sluigi#endif /* _IPFW2_H */ 642