1c398230bSWarner Losh /*- 24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 3fe267a55SPedro F. Giffuni * 4b87ce554SLuigi Rizzo * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa 5100ba1a6SJordan K. Hubbard * 69758b77fSLuigi Rizzo * Redistribution and use in source and binary forms, with or without 79758b77fSLuigi Rizzo * modification, are permitted provided that the following conditions 89758b77fSLuigi Rizzo * are met: 99758b77fSLuigi Rizzo * 1. Redistributions of source code must retain the above copyright 109758b77fSLuigi Rizzo * notice, this list of conditions and the following disclaimer. 119758b77fSLuigi Rizzo * 2. Redistributions in binary form must reproduce the above copyright 129758b77fSLuigi Rizzo * notice, this list of conditions and the following disclaimer in the 139758b77fSLuigi Rizzo * documentation and/or other materials provided with the distribution. 14100ba1a6SJordan K. Hubbard * 159758b77fSLuigi Rizzo * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 169758b77fSLuigi Rizzo * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 179758b77fSLuigi Rizzo * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 189758b77fSLuigi Rizzo * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 199758b77fSLuigi Rizzo * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 209758b77fSLuigi Rizzo * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 219758b77fSLuigi Rizzo * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 229758b77fSLuigi Rizzo * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 239758b77fSLuigi Rizzo * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 249758b77fSLuigi Rizzo * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 259758b77fSLuigi Rizzo * SUCH DAMAGE. 26100ba1a6SJordan K. Hubbard */ 27100ba1a6SJordan K. Hubbard 289758b77fSLuigi Rizzo #ifndef _IPFW2_H 299758b77fSLuigi Rizzo #define _IPFW2_H 309b932e9eSAndre Oppermann 31e4676ba6SJulian Elischer /* 32eb29d14cSRoman Kurakin * The default rule number. By the design of ip_fw, the default rule 33eb29d14cSRoman Kurakin * is the last one, so its number can also serve as the highest number 34eb29d14cSRoman Kurakin * allowed for a rule. The ip_fw code relies on both meanings of this 35eb29d14cSRoman Kurakin * constant. 368191aa7cSRoman Kurakin */ 378191aa7cSRoman Kurakin #define IPFW_DEFAULT_RULE 65535 388191aa7cSRoman Kurakin 397e767c79SAlexander V. Chernikov #define RESVD_SET 31 /*set for default and persistent rules*/ 407e767c79SAlexander V. Chernikov #define IPFW_MAX_SETS 32 /* Number of sets supported by ipfw*/ 41b074b7bbSAlexander V. Chernikov 42b074b7bbSAlexander V. Chernikov /* 4374b22066SAlexander V. Chernikov * Compat values for old clients 44f7b5554eSRoman Kurakin */ 4574b22066SAlexander V. Chernikov #ifndef _KERNEL 46732d27b3SAlexander V. Chernikov #define IPFW_TABLES_MAX 65535 47732d27b3SAlexander V. Chernikov #define IPFW_TABLES_DEFAULT 128 4874b22066SAlexander V. Chernikov #endif 49f7b5554eSRoman Kurakin 50f7b5554eSRoman Kurakin /* 51b87ce554SLuigi Rizzo * Most commands (queue, pipe, tag, untag, limit...) can have a 16-bit 521940fa77SAlexander V. Chernikov * argument between 1 and 65534. The value 0 (IP_FW_TARG) is used 531940fa77SAlexander V. Chernikov * to represent 'tablearg' value, e.g. indicate the use of a 'tablearg' 54b87ce554SLuigi Rizzo * result of the most recent table() lookup. 55b87ce554SLuigi Rizzo * Note that 16bit is only a historical limit, resulting from 56b87ce554SLuigi Rizzo * the use of a 16-bit fields for that value. In reality, we can have 571940fa77SAlexander V. Chernikov * 2^32 pipes, queues, tag values and so on. 58b87ce554SLuigi Rizzo */ 59b87ce554SLuigi Rizzo #define IPFW_ARG_MIN 1 60b87ce554SLuigi Rizzo #define IPFW_ARG_MAX 65534 611940fa77SAlexander V. Chernikov #define IP_FW_TABLEARG 65535 /* Compat value for old clients */ 621940fa77SAlexander V. Chernikov #define IP_FW_TARG 0 /* Current tablearg value */ 63d6eb9b02SAndrey V. Elsukov #define IP_FW_NAT44_GLOBAL 65535 /* arg1 value for "nat global" */ 64b87ce554SLuigi Rizzo 65b87ce554SLuigi Rizzo /* 669527ec6eSAndrey V. Elsukov * Number of entries in the call stack of the call/return commands. 679527ec6eSAndrey V. Elsukov * Call stack currently is an uint16_t array with rule numbers. 689527ec6eSAndrey V. Elsukov */ 699527ec6eSAndrey V. Elsukov #define IPFW_CALLSTACK_SIZE 16 709527ec6eSAndrey V. Elsukov 71f8bee51aSAlexander V. Chernikov /* IP_FW3 header/opcodes */ 72f8bee51aSAlexander V. Chernikov typedef struct _ip_fw3_opheader { 73f8bee51aSAlexander V. Chernikov uint16_t opcode; /* Operation opcode */ 74d3a4f924SAlexander V. Chernikov uint16_t version; /* Opcode version */ 75d3a4f924SAlexander V. Chernikov uint16_t reserved[2]; /* Align to 64-bit boundary */ 76f8bee51aSAlexander V. Chernikov } ip_fw3_opheader; 77f8bee51aSAlexander V. Chernikov 78*4a77657cSAndrey V. Elsukov #define IP_FW3_OPVER_0 0 79*4a77657cSAndrey V. Elsukov #define IP_FW3_OPVER_1 1 /* 32bit rulenum */ 80*4a77657cSAndrey V. Elsukov #define IP_FW3_OPVER IP_FW3_OPVER_1 81*4a77657cSAndrey V. Elsukov 8218ad4197SAlexander V. Chernikov /* IP_FW3 opcodes */ 83f8bee51aSAlexander V. Chernikov #define IP_FW_TABLE_XADD 86 /* add entry */ 84f8bee51aSAlexander V. Chernikov #define IP_FW_TABLE_XDEL 87 /* delete entry */ 85d3a4f924SAlexander V. Chernikov #define IP_FW_TABLE_XGETSIZE 88 /* get table size (deprecated) */ 86f8bee51aSAlexander V. Chernikov #define IP_FW_TABLE_XLIST 89 /* list table contents */ 87d3a4f924SAlexander V. Chernikov #define IP_FW_TABLE_XDESTROY 90 /* destroy table */ 889490a627SAlexander V. Chernikov #define IP_FW_TABLES_XLIST 92 /* list all tables */ 899490a627SAlexander V. Chernikov #define IP_FW_TABLE_XINFO 93 /* request info for one table */ 909490a627SAlexander V. Chernikov #define IP_FW_TABLE_XFLUSH 94 /* flush table data */ 919490a627SAlexander V. Chernikov #define IP_FW_TABLE_XCREATE 95 /* create new table */ 92adf3b2b9SAlexander V. Chernikov #define IP_FW_TABLE_XMODIFY 96 /* modify existing table */ 93563b5ab1SAlexander V. Chernikov #define IP_FW_XGET 97 /* Retrieve configuration */ 94a73d728dSAlexander V. Chernikov #define IP_FW_XADD 98 /* add rule */ 95a73d728dSAlexander V. Chernikov #define IP_FW_XDEL 99 /* del rule */ 96a73d728dSAlexander V. Chernikov #define IP_FW_XMOVE 100 /* move rules to different set */ 97a73d728dSAlexander V. Chernikov #define IP_FW_XZERO 101 /* clear accounting */ 98a73d728dSAlexander V. Chernikov #define IP_FW_XRESETLOG 102 /* zero rules logs */ 99a73d728dSAlexander V. Chernikov #define IP_FW_SET_SWAP 103 /* Swap between 2 sets */ 100a73d728dSAlexander V. Chernikov #define IP_FW_SET_MOVE 104 /* Move one set to another one */ 101a73d728dSAlexander V. Chernikov #define IP_FW_SET_ENABLE 105 /* Enable/disable sets */ 102a73d728dSAlexander V. Chernikov #define IP_FW_TABLE_XFIND 106 /* finds an entry */ 103a73d728dSAlexander V. Chernikov #define IP_FW_XIFLIST 107 /* list tracked interfaces */ 104a73d728dSAlexander V. Chernikov #define IP_FW_TABLES_ALIST 108 /* list table algorithms */ 105a73d728dSAlexander V. Chernikov #define IP_FW_TABLE_XSWAP 109 /* swap two tables */ 1060cba2b28SAlexander V. Chernikov #define IP_FW_TABLE_VLIST 110 /* dump table value hash */ 107d3a4f924SAlexander V. Chernikov 108d6164b77SAlexander V. Chernikov #define IP_FW_NAT44_XCONFIG 111 /* Create/modify NAT44 instance */ 109d6164b77SAlexander V. Chernikov #define IP_FW_NAT44_DESTROY 112 /* Destroys NAT44 instance */ 110d6164b77SAlexander V. Chernikov #define IP_FW_NAT44_XGETCONFIG 113 /* Get NAT44 instance config */ 111d6164b77SAlexander V. Chernikov #define IP_FW_NAT44_LIST_NAT 114 /* List all NAT44 instances */ 112d6164b77SAlexander V. Chernikov #define IP_FW_NAT44_XGETLOG 115 /* Get log from NAT44 instance */ 113d6164b77SAlexander V. Chernikov 114be8bc457SAlexander V. Chernikov #define IP_FW_DUMP_SOPTCODES 116 /* Dump available sopts/versions */ 1155dc5a0e0SAndrey V. Elsukov #define IP_FW_DUMP_SRVOBJECTS 117 /* Dump existing named objects */ 116*4a77657cSAndrey V. Elsukov #define IP_FW_SKIPTO_CACHE 118 /* Manage skipto cache */ 117be8bc457SAlexander V. Chernikov 118d8caf56eSAndrey V. Elsukov #define IP_FW_NAT64STL_CREATE 130 /* Create stateless NAT64 instance */ 119d8caf56eSAndrey V. Elsukov #define IP_FW_NAT64STL_DESTROY 131 /* Destroy stateless NAT64 instance */ 120d8caf56eSAndrey V. Elsukov #define IP_FW_NAT64STL_CONFIG 132 /* Modify stateless NAT64 instance */ 121d8caf56eSAndrey V. Elsukov #define IP_FW_NAT64STL_LIST 133 /* List stateless NAT64 instances */ 122d8caf56eSAndrey V. Elsukov #define IP_FW_NAT64STL_STATS 134 /* Get NAT64STL instance statistics */ 123d8caf56eSAndrey V. Elsukov #define IP_FW_NAT64STL_RESET_STATS 135 /* Reset NAT64STL instance statistics */ 124d8caf56eSAndrey V. Elsukov 125d8caf56eSAndrey V. Elsukov #define IP_FW_NAT64LSN_CREATE 140 /* Create stateful NAT64 instance */ 126d8caf56eSAndrey V. Elsukov #define IP_FW_NAT64LSN_DESTROY 141 /* Destroy stateful NAT64 instance */ 127d8caf56eSAndrey V. Elsukov #define IP_FW_NAT64LSN_CONFIG 142 /* Modify stateful NAT64 instance */ 128d8caf56eSAndrey V. Elsukov #define IP_FW_NAT64LSN_LIST 143 /* List stateful NAT64 instances */ 129d8caf56eSAndrey V. Elsukov #define IP_FW_NAT64LSN_STATS 144 /* Get NAT64LSN instance statistics */ 130d8caf56eSAndrey V. Elsukov #define IP_FW_NAT64LSN_LIST_STATES 145 /* Get stateful NAT64 states */ 131d8caf56eSAndrey V. Elsukov #define IP_FW_NAT64LSN_RESET_STATS 146 /* Reset NAT64LSN instance statistics */ 132d8caf56eSAndrey V. Elsukov 133b867e84eSAndrey V. Elsukov #define IP_FW_NPTV6_CREATE 150 /* Create NPTv6 instance */ 134b867e84eSAndrey V. Elsukov #define IP_FW_NPTV6_DESTROY 151 /* Destroy NPTv6 instance */ 135b867e84eSAndrey V. Elsukov #define IP_FW_NPTV6_CONFIG 152 /* Modify NPTv6 instance */ 136b867e84eSAndrey V. Elsukov #define IP_FW_NPTV6_LIST 153 /* List NPTv6 instances */ 137b867e84eSAndrey V. Elsukov #define IP_FW_NPTV6_STATS 154 /* Get NPTv6 instance statistics */ 13857fb3b7aSAndrey V. Elsukov #define IP_FW_NPTV6_RESET_STATS 155 /* Reset NPTv6 instance statistics */ 139b867e84eSAndrey V. Elsukov 1405c04f73eSAndrey V. Elsukov #define IP_FW_NAT64CLAT_CREATE 160 /* Create clat NAT64 instance */ 1415c04f73eSAndrey V. Elsukov #define IP_FW_NAT64CLAT_DESTROY 161 /* Destroy clat NAT64 instance */ 1425c04f73eSAndrey V. Elsukov #define IP_FW_NAT64CLAT_CONFIG 162 /* Modify clat NAT64 instance */ 1435c04f73eSAndrey V. Elsukov #define IP_FW_NAT64CLAT_LIST 163 /* List clat NAT64 instances */ 1445c04f73eSAndrey V. Elsukov #define IP_FW_NAT64CLAT_STATS 164 /* Get NAT64CLAT instance statistics */ 1455c04f73eSAndrey V. Elsukov #define IP_FW_NAT64CLAT_RESET_STATS 165 /* Reset NAT64CLAT instance statistics */ 1465c04f73eSAndrey V. Elsukov 147d3a4f924SAlexander V. Chernikov /* 1489758b77fSLuigi Rizzo * The kernel representation of ipfw rules is made of a list of 1499758b77fSLuigi Rizzo * 'instructions' (for all practical purposes equivalent to BPF 1509758b77fSLuigi Rizzo * instructions), which specify which fields of the packet 151330462a3SBernd Walter * (or its metadata) should be analysed. 152e4676ba6SJulian Elischer * 1539758b77fSLuigi Rizzo * Each instruction is stored in a structure which begins with 1549758b77fSLuigi Rizzo * "ipfw_insn", and can contain extra fields depending on the 1559758b77fSLuigi Rizzo * instruction type (listed below). 156330462a3SBernd Walter * Note that the code is written so that individual instructions 157330462a3SBernd Walter * have a size which is a multiple of 32 bits. This means that, if 158330462a3SBernd Walter * such structures contain pointers or other 64-bit entities, 159330462a3SBernd Walter * (there is just one instance now) they may end up unaligned on 160330462a3SBernd Walter * 64-bit architectures, so the must be handled with care. 1619758b77fSLuigi Rizzo * 1629758b77fSLuigi Rizzo * "enum ipfw_opcodes" are the opcodes supported. We can have up 16331c88a30SChristian S.J. Peron * to 256 different opcodes. When adding new opcodes, they should 16431c88a30SChristian S.J. Peron * be appended to the end of the opcode list before O_LAST_OPCODE, 16531c88a30SChristian S.J. Peron * this will prevent the ABI from being broken, otherwise users 16631c88a30SChristian S.J. Peron * will have to recompile ipfw(8) when they update the kernel. 167e4676ba6SJulian Elischer */ 168e4676ba6SJulian Elischer 1699758b77fSLuigi Rizzo enum ipfw_opcodes { /* arguments (4 byte each) */ 1709758b77fSLuigi Rizzo O_NOP, 1719758b77fSLuigi Rizzo 1729758b77fSLuigi Rizzo O_IP_SRC, /* u32 = IP */ 1739758b77fSLuigi Rizzo O_IP_SRC_MASK, /* ip = IP/mask */ 1749758b77fSLuigi Rizzo O_IP_SRC_ME, /* none */ 1759758b77fSLuigi Rizzo O_IP_SRC_SET, /* u32=base, arg1=len, bitmap */ 1769758b77fSLuigi Rizzo 1779758b77fSLuigi Rizzo O_IP_DST, /* u32 = IP */ 1789758b77fSLuigi Rizzo O_IP_DST_MASK, /* ip = IP/mask */ 1799758b77fSLuigi Rizzo O_IP_DST_ME, /* none */ 1809758b77fSLuigi Rizzo O_IP_DST_SET, /* u32=base, arg1=len, bitmap */ 1819758b77fSLuigi Rizzo 1829758b77fSLuigi Rizzo O_IP_SRCPORT, /* (n)port list:mask 4 byte ea */ 1839758b77fSLuigi Rizzo O_IP_DSTPORT, /* (n)port list:mask 4 byte ea */ 1849758b77fSLuigi Rizzo O_PROTO, /* arg1=protocol */ 1859758b77fSLuigi Rizzo 1869758b77fSLuigi Rizzo O_MACADDR2, /* 2 mac addr:mask */ 1879758b77fSLuigi Rizzo O_MAC_TYPE, /* same as srcport */ 1889758b77fSLuigi Rizzo 1899758b77fSLuigi Rizzo O_LAYER2, /* none */ 1909758b77fSLuigi Rizzo O_IN, /* none */ 1919758b77fSLuigi Rizzo O_FRAG, /* none */ 1929758b77fSLuigi Rizzo 1939758b77fSLuigi Rizzo O_RECV, /* none */ 1949758b77fSLuigi Rizzo O_XMIT, /* none */ 1959758b77fSLuigi Rizzo O_VIA, /* none */ 1969758b77fSLuigi Rizzo 1979758b77fSLuigi Rizzo O_IPOPT, /* arg1 = 2*u8 bitmap */ 1989758b77fSLuigi Rizzo O_IPLEN, /* arg1 = len */ 1999758b77fSLuigi Rizzo O_IPID, /* arg1 = id */ 2009758b77fSLuigi Rizzo 2019758b77fSLuigi Rizzo O_IPTOS, /* arg1 = id */ 2025e43aef8SLuigi Rizzo O_IPPRECEDENCE, /* arg1 = precedence << 5 */ 2039758b77fSLuigi Rizzo O_IPTTL, /* arg1 = TTL */ 2049758b77fSLuigi Rizzo 2059758b77fSLuigi Rizzo O_IPVER, /* arg1 = version */ 2069758b77fSLuigi Rizzo O_UID, /* u32 = id */ 2079758b77fSLuigi Rizzo O_GID, /* u32 = id */ 2089758b77fSLuigi Rizzo O_ESTAB, /* none (tcp established) */ 2099758b77fSLuigi Rizzo O_TCPFLAGS, /* arg1 = 2*u8 bitmap */ 2109758b77fSLuigi Rizzo O_TCPWIN, /* arg1 = desired win */ 2119758b77fSLuigi Rizzo O_TCPSEQ, /* u32 = desired seq. */ 2129758b77fSLuigi Rizzo O_TCPACK, /* u32 = desired seq. */ 2139758b77fSLuigi Rizzo O_ICMPTYPE, /* u32 = icmp bitmap */ 2149758b77fSLuigi Rizzo O_TCPOPTS, /* arg1 = 2*u8 bitmap */ 2159758b77fSLuigi Rizzo 216010dabb0SCrist J. Clark O_VERREVPATH, /* none */ 21722b5770bSAndre Oppermann O_VERSRCREACH, /* none */ 218010dabb0SCrist J. Clark 219*4a77657cSAndrey V. Elsukov O_PROBE_STATE, /* v0:arg1=kidx, v1:kidx=kidx */ 220*4a77657cSAndrey V. Elsukov O_KEEP_STATE, /* v0:arg1=kidx, v1:kidx=kidx */ 2219758b77fSLuigi Rizzo O_LIMIT, /* ipfw_insn_limit */ 2229758b77fSLuigi Rizzo O_LIMIT_PARENT, /* dyn_type, not an opcode. */ 223f030c151SLuigi Rizzo 2249758b77fSLuigi Rizzo /* 225f030c151SLuigi Rizzo * These are really 'actions'. 2269758b77fSLuigi Rizzo */ 2279758b77fSLuigi Rizzo 2289758b77fSLuigi Rizzo O_LOG, /* ipfw_insn_log */ 2299758b77fSLuigi Rizzo O_PROB, /* u32 = match probability */ 2309758b77fSLuigi Rizzo 231*4a77657cSAndrey V. Elsukov O_CHECK_STATE, /* v0:arg1=kidx, v1:kidx=kidx */ 2329758b77fSLuigi Rizzo O_ACCEPT, /* none */ 2339758b77fSLuigi Rizzo O_DENY, /* none */ 2349758b77fSLuigi Rizzo O_REJECT, /* arg1=icmp arg (same as deny) */ 2359758b77fSLuigi Rizzo O_COUNT, /* none */ 236*4a77657cSAndrey V. Elsukov O_SKIPTO, /* v0:arg1=next rule number */ 237*4a77657cSAndrey V. Elsukov /* v1:kidx= next rule number */ 2389758b77fSLuigi Rizzo O_PIPE, /* arg1=pipe number */ 2399758b77fSLuigi Rizzo O_QUEUE, /* arg1=queue number */ 2409758b77fSLuigi Rizzo O_DIVERT, /* arg1=port number */ 2419758b77fSLuigi Rizzo O_TEE, /* arg1=port number */ 2429758b77fSLuigi Rizzo O_FORWARD_IP, /* fwd sockaddr */ 2439758b77fSLuigi Rizzo O_FORWARD_MAC, /* fwd mac */ 244ff2f6fe8SPaolo Pisati O_NAT, /* nope */ 245eb2e4119SPaolo Pisati O_REASS, /* none */ 246f030c151SLuigi Rizzo 247f030c151SLuigi Rizzo /* 248f030c151SLuigi Rizzo * More opcodes. 249f030c151SLuigi Rizzo */ 250f030c151SLuigi Rizzo O_IPSEC, /* has ipsec history */ 251*4a77657cSAndrey V. Elsukov O_IP_SRC_LOOKUP, /* v0:arg1=table number, u32=value */ 252*4a77657cSAndrey V. Elsukov /* v1:kidx=name, u32=value, arg1=key */ 253cd8b5ae0SRuslan Ermilov O_IP_DST_LOOKUP, /* arg1=table number, u32=value */ 254*4a77657cSAndrey V. Elsukov /* v1:kidx=name, u32=value, arg1=key */ 2555af87d0eSDavid E. O'Brien O_ANTISPOOF, /* none */ 25631c88a30SChristian S.J. Peron O_JAIL, /* u32 = id */ 257974dfe30SBrian Feldman O_ALTQ, /* u32 = altq classif. qid */ 2586daf7ebdSBrian Feldman O_DIVERTED, /* arg1=bitmap (1:loop, 2:out) */ 259c99ee9e0SBrian Feldman O_TCPDATALEN, /* arg1 = tcp data len */ 2608195404bSBrooks Davis O_IP6_SRC, /* address without mask */ 2618195404bSBrooks Davis O_IP6_SRC_ME, /* my addresses */ 2628195404bSBrooks Davis O_IP6_SRC_MASK, /* address with the mask */ 2638195404bSBrooks Davis O_IP6_DST, 2648195404bSBrooks Davis O_IP6_DST_ME, 2658195404bSBrooks Davis O_IP6_DST_MASK, 2668195404bSBrooks Davis O_FLOW6ID, /* for flow id tag in the ipv6 pkt */ 2678195404bSBrooks Davis O_ICMP6TYPE, /* icmp6 packet type filtering */ 2688195404bSBrooks Davis O_EXT_HDR, /* filtering for ipv6 extension header */ 2698195404bSBrooks Davis O_IP6, 270f030c151SLuigi Rizzo 271670742a1SGleb Smirnoff /* 272670742a1SGleb Smirnoff * actions for ng_ipfw 273670742a1SGleb Smirnoff */ 274670742a1SGleb Smirnoff O_NETGRAPH, /* send to ng_ipfw */ 275670742a1SGleb Smirnoff O_NGTEE, /* copy to ng_ipfw */ 276670742a1SGleb Smirnoff 27757cd6d26SMax Laier O_IP4, 27857cd6d26SMax Laier 2799066356bSBjoern A. Zeeb O_UNREACH6, /* arg1=icmpv6 code arg (deny) */ 2809066356bSBjoern A. Zeeb 2816a7d5cb6SOleg Bulyzhin O_TAG, /* arg1=tag number */ 2826a7d5cb6SOleg Bulyzhin O_TAGGED, /* arg1=tag number */ 2836a7d5cb6SOleg Bulyzhin 2848b07e49aSJulian Elischer O_SETFIB, /* arg1=FIB number */ 2858b07e49aSJulian Elischer O_FIB, /* arg1=FIB desired fib number */ 2868b07e49aSJulian Elischer 287ae99fd0eSLuigi Rizzo O_SOCKARG, /* socket argument */ 288ae99fd0eSLuigi Rizzo 289*4a77657cSAndrey V. Elsukov O_CALLRETURN, /* v0:arg1=called rule number */ 290*4a77657cSAndrey V. Elsukov /* v1:kidx=called rule number */ 2919527ec6eSAndrey V. Elsukov 2928a006adbSBjoern A. Zeeb O_FORWARD_IP6, /* fwd sockaddr_in6 */ 2938a006adbSBjoern A. Zeeb 294ae01d73cSAlexander V. Chernikov O_DSCP, /* 2 u32 = DSCP mask */ 295ae01d73cSAlexander V. Chernikov O_SETDSCP, /* arg1=DSCP value */ 296*4a77657cSAndrey V. Elsukov O_IP_FLOW_LOOKUP, /* v0:arg1=table number, u32=value */ 297*4a77657cSAndrey V. Elsukov /* v1:kidx=name, u32=value */ 298ae01d73cSAlexander V. Chernikov 299*4a77657cSAndrey V. Elsukov O_EXTERNAL_ACTION, /* v0:arg1=id of external action handler */ 300*4a77657cSAndrey V. Elsukov /* v1:kidx=id of external action handler */ 301*4a77657cSAndrey V. Elsukov O_EXTERNAL_INSTANCE, /* v0:arg1=id of eaction handler instance */ 302*4a77657cSAndrey V. Elsukov /* v1:kidx=id of eaction handler instance */ 30311c56650SAndrey V. Elsukov O_EXTERNAL_DATA, /* variable length data */ 3042acdf79fSAndrey V. Elsukov 305f7c4fdeeSAndrey V. Elsukov O_SKIP_ACTION, /* none */ 306978f2d17SAndrey V. Elsukov O_TCPMSS, /* arg1=MSS value */ 307f7c4fdeeSAndrey V. Elsukov 308*4a77657cSAndrey V. Elsukov O_MAC_SRC_LOOKUP, /* kidx=name, u32=value, arg1=key */ 309*4a77657cSAndrey V. Elsukov O_MAC_DST_LOOKUP, /* kidx=name, u32=value, arg1=key */ 31081cac390SArseny Smalyuk 311fc727ad6SBoris Lytochkin O_SETMARK, /* u32 = value */ 312fc727ad6SBoris Lytochkin O_MARK, /* 2 u32 = value, bitmask */ 313fc727ad6SBoris Lytochkin 3149758b77fSLuigi Rizzo O_LAST_OPCODE /* not an opcode! */ 315e4676ba6SJulian Elischer }; 316e4676ba6SJulian Elischer 317100ba1a6SJordan K. Hubbard /* 3188195404bSBrooks Davis * The extension header are filtered only for presence using a bit 3198195404bSBrooks Davis * vector with a flag for each header. 3208195404bSBrooks Davis */ 3218195404bSBrooks Davis #define EXT_FRAGMENT 0x1 3228195404bSBrooks Davis #define EXT_HOPOPTS 0x2 3238195404bSBrooks Davis #define EXT_ROUTING 0x4 3248195404bSBrooks Davis #define EXT_AH 0x8 3258195404bSBrooks Davis #define EXT_ESP 0x10 3269066356bSBjoern A. Zeeb #define EXT_DSTOPTS 0x20 3277a92401aSBjoern A. Zeeb #define EXT_RTHDR0 0x40 3287a92401aSBjoern A. Zeeb #define EXT_RTHDR2 0x80 3298195404bSBrooks Davis 3308195404bSBrooks Davis /* 3319758b77fSLuigi Rizzo * Template for instructions. 332100ba1a6SJordan K. Hubbard * 3339758b77fSLuigi Rizzo * ipfw_insn is used for all instructions which require no operands, 3349758b77fSLuigi Rizzo * a single 16-bit value (arg1), or a couple of 8-bit values. 3359758b77fSLuigi Rizzo * 3369758b77fSLuigi Rizzo * For other instructions which require different/larger arguments 3379758b77fSLuigi Rizzo * we have derived structures, ipfw_insn_*. 3389758b77fSLuigi Rizzo * 3399758b77fSLuigi Rizzo * The size of the instruction (in 32-bit words) is in the low 3409758b77fSLuigi Rizzo * 6 bits of "len". The 2 remaining bits are used to implement 3419758b77fSLuigi Rizzo * NOT and OR on individual instructions. Given a type, you can 3429758b77fSLuigi Rizzo * compute the length to be put in "len" using F_INSN_SIZE(t) 3439758b77fSLuigi Rizzo * 3449758b77fSLuigi Rizzo * F_NOT negates the match result of the instruction. 3459758b77fSLuigi Rizzo * 3469758b77fSLuigi Rizzo * F_OR is used to build or blocks. By default, instructions 3479758b77fSLuigi Rizzo * are evaluated as part of a logical AND. An "or" block 3489758b77fSLuigi Rizzo * { X or Y or Z } contains F_OR set in all but the last 3499758b77fSLuigi Rizzo * instruction of the block. A match will cause the code 3509758b77fSLuigi Rizzo * to skip past the last instruction of the block. 3519758b77fSLuigi Rizzo * 3529758b77fSLuigi Rizzo * NOTA BENE: in a couple of places we assume that 3539758b77fSLuigi Rizzo * sizeof(ipfw_insn) == sizeof(u_int32_t) 3549758b77fSLuigi Rizzo * this needs to be fixed. 3559758b77fSLuigi Rizzo * 356100ba1a6SJordan K. Hubbard */ 3579758b77fSLuigi Rizzo typedef struct _ipfw_insn { /* template for instructions */ 358a81c165bSAlex Richardson _Alignas(_Alignof(u_int32_t)) u_int8_t opcode; 3591f6ef666SRobert Watson u_int8_t len; /* number of 32-bit words */ 3609758b77fSLuigi Rizzo #define F_NOT 0x80 3619758b77fSLuigi Rizzo #define F_OR 0x40 3629758b77fSLuigi Rizzo #define F_LEN_MASK 0x3f 3639758b77fSLuigi Rizzo #define F_LEN(cmd) ((cmd)->len & F_LEN_MASK) 3649758b77fSLuigi Rizzo 3659758b77fSLuigi Rizzo u_int16_t arg1; 3669758b77fSLuigi Rizzo } ipfw_insn; 367100ba1a6SJordan K. Hubbard 368d60315beSLuigi Rizzo /* 3699758b77fSLuigi Rizzo * The F_INSN_SIZE(type) computes the size, in 4-byte words, of 3709758b77fSLuigi Rizzo * a given type. 371d60315beSLuigi Rizzo */ 3729758b77fSLuigi Rizzo #define F_INSN_SIZE(t) ((sizeof (t))/sizeof(u_int32_t)) 373d60315beSLuigi Rizzo 3749758b77fSLuigi Rizzo /* 3759758b77fSLuigi Rizzo * This is used to store an array of 16-bit entries (ports etc.) 3769758b77fSLuigi Rizzo */ 3779758b77fSLuigi Rizzo typedef struct _ipfw_insn_u16 { 3789758b77fSLuigi Rizzo ipfw_insn o; 3799758b77fSLuigi Rizzo u_int16_t ports[2]; /* there may be more */ 3809758b77fSLuigi Rizzo } ipfw_insn_u16; 381d60315beSLuigi Rizzo 3829758b77fSLuigi Rizzo /* 3839758b77fSLuigi Rizzo * This is used to store an array of 32-bit entries 3849758b77fSLuigi Rizzo * (uid, single IPv4 addresses etc.) 3859758b77fSLuigi Rizzo */ 3869758b77fSLuigi Rizzo typedef struct _ipfw_insn_u32 { 3879758b77fSLuigi Rizzo ipfw_insn o; 3889758b77fSLuigi Rizzo u_int32_t d[1]; /* one or more */ 3899758b77fSLuigi Rizzo } ipfw_insn_u32; 3909758b77fSLuigi Rizzo 391*4a77657cSAndrey V. Elsukov typedef struct _ipfw_insn_kidx { 392*4a77657cSAndrey V. Elsukov ipfw_insn o; 393*4a77657cSAndrey V. Elsukov uint32_t kidx; 394*4a77657cSAndrey V. Elsukov } ipfw_insn_kidx; 395*4a77657cSAndrey V. Elsukov 3969758b77fSLuigi Rizzo /* 3979758b77fSLuigi Rizzo * This is used to store IP addr-mask pairs. 3989758b77fSLuigi Rizzo */ 3999758b77fSLuigi Rizzo typedef struct _ipfw_insn_ip { 4009758b77fSLuigi Rizzo ipfw_insn o; 4019758b77fSLuigi Rizzo struct in_addr addr; 4029758b77fSLuigi Rizzo struct in_addr mask; 4039758b77fSLuigi Rizzo } ipfw_insn_ip; 4049758b77fSLuigi Rizzo 405*4a77657cSAndrey V. Elsukov typedef struct _ipfw_insn_table { 406*4a77657cSAndrey V. Elsukov ipfw_insn o; /* arg1 is optional lookup key */ 407*4a77657cSAndrey V. Elsukov uint32_t kidx; /* table name index */ 408*4a77657cSAndrey V. Elsukov uint32_t value; /* table value */ 409*4a77657cSAndrey V. Elsukov } ipfw_insn_table; 410*4a77657cSAndrey V. Elsukov 411*4a77657cSAndrey V. Elsukov #define IPFW_LOOKUP_TYPE_MASK 0x00FF 412*4a77657cSAndrey V. Elsukov #define IPFW_LOOKUP_TYPE(insn) ((insn)->arg1 & IPFW_LOOKUP_TYPE_MASK) 413*4a77657cSAndrey V. Elsukov #define IPFW_SET_LOOKUP_TYPE(insn, type) do { \ 414*4a77657cSAndrey V. Elsukov (insn)->arg1 &= ~IPFW_LOOKUP_TYPE_MASK; \ 415*4a77657cSAndrey V. Elsukov (insn)->arg1 |= (type) & IPFW_LOOKUP_TYPE_MASK; \ 416*4a77657cSAndrey V. Elsukov } while (0) 417*4a77657cSAndrey V. Elsukov 418*4a77657cSAndrey V. Elsukov /* 419*4a77657cSAndrey V. Elsukov * Defines key types used by lookup instruction 420*4a77657cSAndrey V. Elsukov */ 421*4a77657cSAndrey V. Elsukov enum ipfw_table_lookup_type { 422*4a77657cSAndrey V. Elsukov LOOKUP_NONE = 0, 423*4a77657cSAndrey V. Elsukov LOOKUP_DST_IP, 424*4a77657cSAndrey V. Elsukov LOOKUP_SRC_IP, 425*4a77657cSAndrey V. Elsukov LOOKUP_DST_PORT, 426*4a77657cSAndrey V. Elsukov LOOKUP_SRC_PORT, 427*4a77657cSAndrey V. Elsukov LOOKUP_UID, 428*4a77657cSAndrey V. Elsukov LOOKUP_JAIL, 429*4a77657cSAndrey V. Elsukov LOOKUP_DSCP, 430*4a77657cSAndrey V. Elsukov LOOKUP_DST_MAC, 431*4a77657cSAndrey V. Elsukov LOOKUP_SRC_MAC, 432*4a77657cSAndrey V. Elsukov LOOKUP_MARK, 433*4a77657cSAndrey V. Elsukov LOOKUP_RULENUM, 434*4a77657cSAndrey V. Elsukov }; 435*4a77657cSAndrey V. Elsukov 436*4a77657cSAndrey V. Elsukov enum ipfw_return_type { 437*4a77657cSAndrey V. Elsukov RETURN_NEXT_RULENUM = 0, 438*4a77657cSAndrey V. Elsukov RETURN_NEXT_RULE, 439*4a77657cSAndrey V. Elsukov }; 440*4a77657cSAndrey V. Elsukov 441*4a77657cSAndrey V. Elsukov enum ipfw_skipto_cache_op { 442*4a77657cSAndrey V. Elsukov SKIPTO_CACHE_DISABLE = 0, 443*4a77657cSAndrey V. Elsukov SKIPTO_CACHE_ENABLE, 444*4a77657cSAndrey V. Elsukov }; 445*4a77657cSAndrey V. Elsukov 4469758b77fSLuigi Rizzo /* 447f030c151SLuigi Rizzo * This is used to forward to a given address (ip). 4489758b77fSLuigi Rizzo */ 4499758b77fSLuigi Rizzo typedef struct _ipfw_insn_sa { 4509758b77fSLuigi Rizzo ipfw_insn o; 4519758b77fSLuigi Rizzo struct sockaddr_in sa; 4529758b77fSLuigi Rizzo } ipfw_insn_sa; 4539758b77fSLuigi Rizzo 4549758b77fSLuigi Rizzo /* 4558a006adbSBjoern A. Zeeb * This is used to forward to a given address (ipv6). 4568a006adbSBjoern A. Zeeb */ 4578a006adbSBjoern A. Zeeb typedef struct _ipfw_insn_sa6 { 4588a006adbSBjoern A. Zeeb ipfw_insn o; 4598a006adbSBjoern A. Zeeb struct sockaddr_in6 sa; 4608a006adbSBjoern A. Zeeb } ipfw_insn_sa6; 4618a006adbSBjoern A. Zeeb 4628a006adbSBjoern A. Zeeb /* 4639758b77fSLuigi Rizzo * This is used for MAC addr-mask pairs. 4649758b77fSLuigi Rizzo */ 4659758b77fSLuigi Rizzo typedef struct _ipfw_insn_mac { 4669758b77fSLuigi Rizzo ipfw_insn o; 4679758b77fSLuigi Rizzo u_char addr[12]; /* dst[6] + src[6] */ 4689758b77fSLuigi Rizzo u_char mask[12]; /* dst[6] + src[6] */ 4699758b77fSLuigi Rizzo } ipfw_insn_mac; 4709758b77fSLuigi Rizzo 4719758b77fSLuigi Rizzo /* 472f030c151SLuigi Rizzo * This is used for interface match rules (recv xx, xmit xx). 4739758b77fSLuigi Rizzo */ 4749758b77fSLuigi Rizzo typedef struct _ipfw_insn_if { 4759758b77fSLuigi Rizzo ipfw_insn o; 476830cc178SLuigi Rizzo union { 4779758b77fSLuigi Rizzo struct in_addr ip; 4789bf40edeSBrooks Davis int glob; 479*4a77657cSAndrey V. Elsukov uint16_t kidx_v0; 480*4a77657cSAndrey V. Elsukov uint32_t kidx; 4819758b77fSLuigi Rizzo } p; 4829758b77fSLuigi Rizzo char name[IFNAMSIZ]; 4839758b77fSLuigi Rizzo } ipfw_insn_if; 484830cc178SLuigi Rizzo 4859758b77fSLuigi Rizzo /* 486974dfe30SBrian Feldman * This is used for storing an altq queue id number. 487974dfe30SBrian Feldman */ 488974dfe30SBrian Feldman typedef struct _ipfw_insn_altq { 489974dfe30SBrian Feldman ipfw_insn o; 490974dfe30SBrian Feldman u_int32_t qid; 491974dfe30SBrian Feldman } ipfw_insn_altq; 492974dfe30SBrian Feldman 493974dfe30SBrian Feldman /* 4949758b77fSLuigi Rizzo * This is used for limit rules. 49525549c00SJosef Karthauser */ 4969758b77fSLuigi Rizzo typedef struct _ipfw_insn_limit { 4979758b77fSLuigi Rizzo ipfw_insn o; 498*4a77657cSAndrey V. Elsukov u_int32_t kidx; 4999758b77fSLuigi Rizzo u_int8_t _pad; 5009758b77fSLuigi Rizzo u_int8_t limit_mask; /* combination of DYN_* below */ 501830cc178SLuigi Rizzo #define DYN_SRC_ADDR 0x1 502830cc178SLuigi Rizzo #define DYN_SRC_PORT 0x2 503830cc178SLuigi Rizzo #define DYN_DST_ADDR 0x4 504830cc178SLuigi Rizzo #define DYN_DST_PORT 0x8 50525549c00SJosef Karthauser 5069758b77fSLuigi Rizzo u_int16_t conn_limit; 5079758b77fSLuigi Rizzo } ipfw_insn_limit; 508e4676ba6SJulian Elischer 509*4a77657cSAndrey V. Elsukov /* MAC/InfiniBand/etc address length */ 510*4a77657cSAndrey V. Elsukov #define IPFW_MAX_L2_ADDR_LEN 20 511*4a77657cSAndrey V. Elsukov 51206dae58bSJosef Karthauser /* 513f030c151SLuigi Rizzo * This is used for log instructions. 5149758b77fSLuigi Rizzo */ 5159758b77fSLuigi Rizzo typedef struct _ipfw_insn_log { 5169758b77fSLuigi Rizzo ipfw_insn o; 5179758b77fSLuigi Rizzo u_int32_t max_log; /* how many do we log -- 0 = all */ 5189758b77fSLuigi Rizzo u_int32_t log_left; /* how many left to log */ 5199758b77fSLuigi Rizzo } ipfw_insn_log; 5209758b77fSLuigi Rizzo 521*4a77657cSAndrey V. Elsukov /* ipfw_insn_log->o.arg1 bitmasks */ 522*4a77657cSAndrey V. Elsukov #define IPFW_LOG_DEFAULT 0x0000 523*4a77657cSAndrey V. Elsukov #define IPFW_LOG_SYSLOG (1 << 15) 524*4a77657cSAndrey V. Elsukov #define IPFW_LOG_IPFW0 (1 << 14) 525*4a77657cSAndrey V. Elsukov #define IPFW_LOG_RTSOCK (1 << 13) 526*4a77657cSAndrey V. Elsukov 527*4a77657cSAndrey V. Elsukov typedef struct _ipfwlog_rtsock_hdr_v2 { 528*4a77657cSAndrey V. Elsukov uint32_t rulenum; 529*4a77657cSAndrey V. Elsukov uint32_t tablearg; 530*4a77657cSAndrey V. Elsukov ipfw_insn cmd; 531*4a77657cSAndrey V. Elsukov u_char ether_shost[IPFW_MAX_L2_ADDR_LEN]; 532*4a77657cSAndrey V. Elsukov u_char ether_dhost[IPFW_MAX_L2_ADDR_LEN]; 533*4a77657cSAndrey V. Elsukov uint32_t mark; 534*4a77657cSAndrey V. Elsukov char comment[0]; 535*4a77657cSAndrey V. Elsukov } ipfwlog_rtsock_hdr_v2; 536*4a77657cSAndrey V. Elsukov 537d6164b77SAlexander V. Chernikov /* Legacy NAT structures, compat only */ 538d6164b77SAlexander V. Chernikov #ifndef _KERNEL 539bb5081a7SRobert Watson /* 540bb5081a7SRobert Watson * Data structures required by both ipfw(8) and ipfw(4) but not part of the 541bcf5b9faSRobert Watson * management API are protected by IPFW_INTERNAL. 542bb5081a7SRobert Watson */ 543bb5081a7SRobert Watson #ifdef IPFW_INTERNAL 544ff2f6fe8SPaolo Pisati /* Server pool support (LSNAT). */ 545ff2f6fe8SPaolo Pisati struct cfg_spool { 546ff2f6fe8SPaolo Pisati LIST_ENTRY(cfg_spool) _next; /* chain of spool instances */ 547ff2f6fe8SPaolo Pisati struct in_addr addr; 548ff2f6fe8SPaolo Pisati u_short port; 549ff2f6fe8SPaolo Pisati }; 550bb5081a7SRobert Watson #endif 551ff2f6fe8SPaolo Pisati 552ff2f6fe8SPaolo Pisati /* Redirect modes id. */ 553ff2f6fe8SPaolo Pisati #define REDIR_ADDR 0x01 554ff2f6fe8SPaolo Pisati #define REDIR_PORT 0x02 555ff2f6fe8SPaolo Pisati #define REDIR_PROTO 0x04 556ff2f6fe8SPaolo Pisati 557bb5081a7SRobert Watson #ifdef IPFW_INTERNAL 558ff2f6fe8SPaolo Pisati /* Nat redirect configuration. */ 559ff2f6fe8SPaolo Pisati struct cfg_redir { 560ff2f6fe8SPaolo Pisati LIST_ENTRY(cfg_redir) _next; /* chain of redir instances */ 561ff2f6fe8SPaolo Pisati u_int16_t mode; /* type of redirect mode */ 562ff2f6fe8SPaolo Pisati struct in_addr laddr; /* local ip address */ 563ff2f6fe8SPaolo Pisati struct in_addr paddr; /* public ip address */ 564ff2f6fe8SPaolo Pisati struct in_addr raddr; /* remote ip address */ 565ff2f6fe8SPaolo Pisati u_short lport; /* local port */ 566ff2f6fe8SPaolo Pisati u_short pport; /* public port */ 567ff2f6fe8SPaolo Pisati u_short rport; /* remote port */ 568ff2f6fe8SPaolo Pisati u_short pport_cnt; /* number of public ports */ 569ff2f6fe8SPaolo Pisati u_short rport_cnt; /* number of remote ports */ 570ff2f6fe8SPaolo Pisati int proto; /* protocol: tcp/udp */ 571ff2f6fe8SPaolo Pisati struct alias_link **alink; 572ff2f6fe8SPaolo Pisati /* num of entry in spool chain */ 573ff2f6fe8SPaolo Pisati u_int16_t spool_cnt; 574ff2f6fe8SPaolo Pisati /* chain of spool instances */ 575ff2f6fe8SPaolo Pisati LIST_HEAD(spool_chain, cfg_spool) spool_chain; 576ff2f6fe8SPaolo Pisati }; 577bb5081a7SRobert Watson #endif 578ff2f6fe8SPaolo Pisati 579bb5081a7SRobert Watson #ifdef IPFW_INTERNAL 580ff2f6fe8SPaolo Pisati /* Nat configuration data struct. */ 581ff2f6fe8SPaolo Pisati struct cfg_nat { 582ff2f6fe8SPaolo Pisati /* chain of nat instances */ 583ff2f6fe8SPaolo Pisati LIST_ENTRY(cfg_nat) _next; 584ff2f6fe8SPaolo Pisati int id; /* nat id */ 585ff2f6fe8SPaolo Pisati struct in_addr ip; /* nat ip address */ 586ff2f6fe8SPaolo Pisati char if_name[IF_NAMESIZE]; /* interface name */ 587ff2f6fe8SPaolo Pisati int mode; /* aliasing mode */ 588ff2f6fe8SPaolo Pisati struct libalias *lib; /* libalias instance */ 589ff2f6fe8SPaolo Pisati /* number of entry in spool chain */ 590ff2f6fe8SPaolo Pisati int redir_cnt; 591ff2f6fe8SPaolo Pisati /* chain of redir instances */ 592ff2f6fe8SPaolo Pisati LIST_HEAD(redir_chain, cfg_redir) redir_chain; 593ff2f6fe8SPaolo Pisati }; 594bb5081a7SRobert Watson #endif 595ff2f6fe8SPaolo Pisati 596ff2f6fe8SPaolo Pisati #define SOF_NAT sizeof(struct cfg_nat) 597ff2f6fe8SPaolo Pisati #define SOF_REDIR sizeof(struct cfg_redir) 598ff2f6fe8SPaolo Pisati #define SOF_SPOOL sizeof(struct cfg_spool) 599ff2f6fe8SPaolo Pisati 600d6164b77SAlexander V. Chernikov #endif /* ifndef _KERNEL */ 601d6164b77SAlexander V. Chernikov 602d6164b77SAlexander V. Chernikov struct nat44_cfg_spool { 603d6164b77SAlexander V. Chernikov struct in_addr addr; 604d6164b77SAlexander V. Chernikov uint16_t port; 605d6164b77SAlexander V. Chernikov uint16_t spare; 606d6164b77SAlexander V. Chernikov }; 607d6164b77SAlexander V. Chernikov #define NAT44_REDIR_ADDR 0x01 608d6164b77SAlexander V. Chernikov #define NAT44_REDIR_PORT 0x02 609d6164b77SAlexander V. Chernikov #define NAT44_REDIR_PROTO 0x04 610d6164b77SAlexander V. Chernikov 611d6164b77SAlexander V. Chernikov /* Nat redirect configuration. */ 612d6164b77SAlexander V. Chernikov struct nat44_cfg_redir { 613d6164b77SAlexander V. Chernikov struct in_addr laddr; /* local ip address */ 614d6164b77SAlexander V. Chernikov struct in_addr paddr; /* public ip address */ 615d6164b77SAlexander V. Chernikov struct in_addr raddr; /* remote ip address */ 616d6164b77SAlexander V. Chernikov uint16_t lport; /* local port */ 617d6164b77SAlexander V. Chernikov uint16_t pport; /* public port */ 618d6164b77SAlexander V. Chernikov uint16_t rport; /* remote port */ 619d6164b77SAlexander V. Chernikov uint16_t pport_cnt; /* number of public ports */ 620d6164b77SAlexander V. Chernikov uint16_t rport_cnt; /* number of remote ports */ 621d6164b77SAlexander V. Chernikov uint16_t mode; /* type of redirect mode */ 622d6164b77SAlexander V. Chernikov uint16_t spool_cnt; /* num of entry in spool chain */ 623d6164b77SAlexander V. Chernikov uint16_t spare; 624d6164b77SAlexander V. Chernikov uint32_t proto; /* protocol: tcp/udp */ 625d6164b77SAlexander V. Chernikov }; 626d6164b77SAlexander V. Chernikov 627d6164b77SAlexander V. Chernikov /* Nat configuration data struct. */ 628d6164b77SAlexander V. Chernikov struct nat44_cfg_nat { 629d6164b77SAlexander V. Chernikov char name[64]; /* nat name */ 630d6164b77SAlexander V. Chernikov char if_name[64]; /* interface name */ 631d6164b77SAlexander V. Chernikov uint32_t size; /* structure size incl. redirs */ 632d6164b77SAlexander V. Chernikov struct in_addr ip; /* nat IPv4 address */ 633d6164b77SAlexander V. Chernikov uint32_t mode; /* aliasing mode */ 634d6164b77SAlexander V. Chernikov uint32_t redir_cnt; /* number of entry in spool chain */ 635a08cdb6cSNeel Chauhan u_short alias_port_lo; /* low range for port aliasing */ 636a08cdb6cSNeel Chauhan u_short alias_port_hi; /* high range for port aliasing */ 637d6164b77SAlexander V. Chernikov }; 638d6164b77SAlexander V. Chernikov 639ff2f6fe8SPaolo Pisati /* Nat command. */ 640ff2f6fe8SPaolo Pisati typedef struct _ipfw_insn_nat { 641ff2f6fe8SPaolo Pisati ipfw_insn o; 642ff2f6fe8SPaolo Pisati struct cfg_nat *nat; 643ff2f6fe8SPaolo Pisati } ipfw_insn_nat; 644ff2f6fe8SPaolo Pisati 6458195404bSBrooks Davis /* Apply ipv6 mask on ipv6 addr */ 6465786c6b9SAndrey V. Elsukov #define APPLY_MASK(addr,mask) do { \ 6478195404bSBrooks Davis (addr)->__u6_addr.__u6_addr32[0] &= (mask)->__u6_addr.__u6_addr32[0]; \ 6488195404bSBrooks Davis (addr)->__u6_addr.__u6_addr32[1] &= (mask)->__u6_addr.__u6_addr32[1]; \ 6498195404bSBrooks Davis (addr)->__u6_addr.__u6_addr32[2] &= (mask)->__u6_addr.__u6_addr32[2]; \ 6505786c6b9SAndrey V. Elsukov (addr)->__u6_addr.__u6_addr32[3] &= (mask)->__u6_addr.__u6_addr32[3]; \ 6515786c6b9SAndrey V. Elsukov } while (0) 6528195404bSBrooks Davis 6538195404bSBrooks Davis /* Structure for ipv6 */ 6548195404bSBrooks Davis typedef struct _ipfw_insn_ip6 { 6558195404bSBrooks Davis ipfw_insn o; 6568195404bSBrooks Davis struct in6_addr addr6; 6578195404bSBrooks Davis struct in6_addr mask6; 6588195404bSBrooks Davis } ipfw_insn_ip6; 6598195404bSBrooks Davis 6608195404bSBrooks Davis /* Used to support icmp6 types */ 6618195404bSBrooks Davis typedef struct _ipfw_insn_icmp6 { 6628195404bSBrooks Davis ipfw_insn o; 6638195404bSBrooks Davis uint32_t d[7]; /* XXX This number si related to the netinet/icmp6.h 6648195404bSBrooks Davis * define ICMP6_MAXTYPE 6658195404bSBrooks Davis * as follows: n = ICMP6_MAXTYPE/32 + 1 6668195404bSBrooks Davis * Actually is 203 6678195404bSBrooks Davis */ 6688195404bSBrooks Davis } ipfw_insn_icmp6; 6698195404bSBrooks Davis 670*4a77657cSAndrey V. Elsukov /* Convert pointer to instruction with specified type */ 671*4a77657cSAndrey V. Elsukov #define insntod(p, type) ((ipfw_insn_ ## type *)(p)) 672*4a77657cSAndrey V. Elsukov #define insntoc(p, type) ((const ipfw_insn_ ## type *)(p)) 673*4a77657cSAndrey V. Elsukov 6749758b77fSLuigi Rizzo /* 6759758b77fSLuigi Rizzo * Here we have the structure representing an ipfw rule. 67632f967a3SLuigi Rizzo * 6777e767c79SAlexander V. Chernikov * Layout: 6787e767c79SAlexander V. Chernikov * struct ip_fw_rule 6797e767c79SAlexander V. Chernikov * [ counter block, size = rule->cntr_len ] 6807e767c79SAlexander V. Chernikov * [ one or more instructions, size = rule->cmd_len * 4 ] 6817e767c79SAlexander V. Chernikov * 6827e767c79SAlexander V. Chernikov * It starts with a general area (with link fields). 6837e767c79SAlexander V. Chernikov * Counter block may be next (if rule->cntr_len > 0), 6849758b77fSLuigi Rizzo * followed by an array of one or more instructions, which the code 6857e767c79SAlexander V. Chernikov * accesses as an array of 32-bit values. rule->cmd_len represents 6867e767c79SAlexander V. Chernikov * the total instructions legth in u32 worrd, while act_ofs represents 6877e767c79SAlexander V. Chernikov * rule action offset in u32 words. 6889758b77fSLuigi Rizzo * 6899758b77fSLuigi Rizzo * When assembling instruction, remember the following: 6909758b77fSLuigi Rizzo * 6919758b77fSLuigi Rizzo * + if a rule has a "keep-state" (or "limit") option, then the 6929758b77fSLuigi Rizzo * first instruction (at r->cmd) MUST BE an O_PROBE_STATE 6939758b77fSLuigi Rizzo * + if a rule has a "log" option, then the first action 6949758b77fSLuigi Rizzo * (at ACTION_PTR(r)) MUST be O_LOG 695974dfe30SBrian Feldman * + if a rule has an "altq" option, it comes after "log" 6966a7d5cb6SOleg Bulyzhin * + if a rule has an O_TAG option, it comes after "log" and "altq" 6979758b77fSLuigi Rizzo * 6987e767c79SAlexander V. Chernikov * 6997e767c79SAlexander V. Chernikov * All structures (excluding instructions) are u64-aligned. 7007e767c79SAlexander V. Chernikov * Please keep this. 70132f967a3SLuigi Rizzo */ 70232f967a3SLuigi Rizzo 7037e767c79SAlexander V. Chernikov struct ip_fw_rule { 7047e767c79SAlexander V. Chernikov uint16_t act_ofs; /* offset of action in 32-bit units */ 7057e767c79SAlexander V. Chernikov uint16_t cmd_len; /* # of 32-bit words in cmd */ 7067e767c79SAlexander V. Chernikov uint16_t spare; 7077e767c79SAlexander V. Chernikov uint8_t set; /* rule set (0..31) */ 7087e767c79SAlexander V. Chernikov uint8_t flags; /* rule flags */ 7097e767c79SAlexander V. Chernikov uint32_t rulenum; /* rule number */ 7107e767c79SAlexander V. Chernikov uint32_t id; /* rule id */ 7117e767c79SAlexander V. Chernikov 7127e767c79SAlexander V. Chernikov ipfw_insn cmd[1]; /* storage for commands */ 7137e767c79SAlexander V. Chernikov }; 7147e767c79SAlexander V. Chernikov #define IPFW_RULE_NOOPT 0x01 /* Has no options in body */ 715094d6f8dSAndrey V. Elsukov #define IPFW_RULE_JUSTOPTS 0x02 /* new format of rule body */ 7167e767c79SAlexander V. Chernikov 7177e767c79SAlexander V. Chernikov /* Unaligned version */ 7187e767c79SAlexander V. Chernikov 7197e767c79SAlexander V. Chernikov /* Base ipfw rule counter block. */ 7207e767c79SAlexander V. Chernikov struct ip_fw_bcounter { 7217e767c79SAlexander V. Chernikov uint16_t size; /* Size of counter block, bytes */ 7227e767c79SAlexander V. Chernikov uint8_t flags; /* flags for given block */ 7237e767c79SAlexander V. Chernikov uint8_t spare; 7247e767c79SAlexander V. Chernikov uint32_t timestamp; /* tv_sec of last match */ 7257e767c79SAlexander V. Chernikov uint64_t pcnt; /* Packet counter */ 7267e767c79SAlexander V. Chernikov uint64_t bcnt; /* Byte counter */ 7277e767c79SAlexander V. Chernikov }; 7287e767c79SAlexander V. Chernikov 7297e767c79SAlexander V. Chernikov #ifndef _KERNEL 7307e767c79SAlexander V. Chernikov /* 7317e767c79SAlexander V. Chernikov * Legacy rule format 7327e767c79SAlexander V. Chernikov */ 7339758b77fSLuigi Rizzo struct ip_fw { 734de240d10SLuigi Rizzo struct ip_fw *x_next; /* linked list of rules */ 735a8c102a2SLuigi Rizzo struct ip_fw *next_rule; /* ptr to next [skipto] rule */ 736f030c151SLuigi Rizzo /* 'next_rule' is used to pass up 'set_disable' status */ 737f030c151SLuigi Rizzo 738dda10d62SOleg Bulyzhin uint16_t act_ofs; /* offset of action in 32-bit units */ 739dda10d62SOleg Bulyzhin uint16_t cmd_len; /* # of 32-bit words in cmd */ 740dda10d62SOleg Bulyzhin uint16_t rulenum; /* rule number */ 741dda10d62SOleg Bulyzhin uint8_t set; /* rule set (0..31) */ 742dda10d62SOleg Bulyzhin uint8_t _pad; /* padding */ 743dda10d62SOleg Bulyzhin uint32_t id; /* rule id */ 7449758b77fSLuigi Rizzo 7459758b77fSLuigi Rizzo /* These fields are present in all rules. */ 746dda10d62SOleg Bulyzhin uint64_t pcnt; /* Packet counter */ 747dda10d62SOleg Bulyzhin uint64_t bcnt; /* Byte counter */ 748dda10d62SOleg Bulyzhin uint32_t timestamp; /* tv_sec of last match */ 7499758b77fSLuigi Rizzo 7509758b77fSLuigi Rizzo ipfw_insn cmd[1]; /* storage for commands */ 7519758b77fSLuigi Rizzo }; 7527e767c79SAlexander V. Chernikov #endif 7539758b77fSLuigi Rizzo 7549758b77fSLuigi Rizzo #define ACTION_PTR(rule) \ 7559758b77fSLuigi Rizzo (ipfw_insn *)( (u_int32_t *)((rule)->cmd) + ((rule)->act_ofs) ) 7569758b77fSLuigi Rizzo 7577e767c79SAlexander V. Chernikov #define RULESIZE(rule) (sizeof(*(rule)) + (rule)->cmd_len * 4 - 4) 7587e767c79SAlexander V. Chernikov 759f9f7bde3SLuigi Rizzo #if 1 // should be moved to in.h 760100ba1a6SJordan K. Hubbard /* 7619758b77fSLuigi Rizzo * This structure is used as a flow mask and a flow id for various 7629758b77fSLuigi Rizzo * parts of the code. 763f9f7bde3SLuigi Rizzo * addr_type is used in userland and kernel to mark the address type. 764f9f7bde3SLuigi Rizzo * fib is used in the kernel to record the fib in use. 765f9f7bde3SLuigi Rizzo * _flags is used in the kernel to store tcp flags for dynamic rules. 76603c61266SLuigi Rizzo */ 76703c61266SLuigi Rizzo struct ipfw_flow_id { 768cc4d3c30SLuigi Rizzo uint32_t dst_ip; 769cc4d3c30SLuigi Rizzo uint32_t src_ip; 770cc4d3c30SLuigi Rizzo uint16_t dst_port; 771cc4d3c30SLuigi Rizzo uint16_t src_port; 772b99a6823SAndrey V. Elsukov uint8_t fib; /* XXX: must be uint16_t */ 773cc4d3c30SLuigi Rizzo uint8_t proto; 774f9f7bde3SLuigi Rizzo uint8_t _flags; /* protocol-specific flags */ 775f9f7bde3SLuigi Rizzo uint8_t addr_type; /* 4=ip4, 6=ip6, 1=ether ? */ 776cc4d3c30SLuigi Rizzo struct in6_addr dst_ip6; 7778195404bSBrooks Davis struct in6_addr src_ip6; 778cc4d3c30SLuigi Rizzo uint32_t flow_id6; 779f9f7bde3SLuigi Rizzo uint32_t extra; /* queue/pipe or frag_id */ 78003c61266SLuigi Rizzo }; 781cc4d3c30SLuigi Rizzo #endif 78203c61266SLuigi Rizzo 783b99a6823SAndrey V. Elsukov #define IS_IP4_FLOW_ID(id) ((id)->addr_type == 4) 7848195404bSBrooks Davis #define IS_IP6_FLOW_ID(id) ((id)->addr_type == 6) 7858195404bSBrooks Davis 78603c61266SLuigi Rizzo /* 787f030c151SLuigi Rizzo * Dynamic ipfw rule. 78803c61266SLuigi Rizzo */ 789*4a77657cSAndrey V. Elsukov #define IPFW_DYN_ORPHANED 0x40000 /* state's parent rule was deleted */ 7909758b77fSLuigi Rizzo 791*4a77657cSAndrey V. Elsukov typedef struct _ipfw_dyn_rule { 792330462a3SBernd Walter struct ipfw_flow_id id; /* (masked) flow id */ 793*4a77657cSAndrey V. Elsukov uint8_t set; 794*4a77657cSAndrey V. Elsukov uint8_t type; /* rule type */ 795*4a77657cSAndrey V. Elsukov uint16_t pad; 796*4a77657cSAndrey V. Elsukov uint32_t expire; /* expire time */ 797*4a77657cSAndrey V. Elsukov uint32_t rulenum; /* parent's rule number */ 798*4a77657cSAndrey V. Elsukov uint32_t kidx; /* index of named object */ 799*4a77657cSAndrey V. Elsukov uint64_t pcnt; /* packet match counter */ 800*4a77657cSAndrey V. Elsukov uint64_t bcnt; /* byte match counter */ 801*4a77657cSAndrey V. Elsukov uint32_t hashval; /* hash value */ 802*4a77657cSAndrey V. Elsukov union { 803*4a77657cSAndrey V. Elsukov uint32_t state; /* state of this rule (typically a 80425549c00SJosef Karthauser * combination of TCP flags) 80525549c00SJosef Karthauser */ 806*4a77657cSAndrey V. Elsukov uint32_t count; /* number of linked states */ 807*4a77657cSAndrey V. Elsukov }; 808*4a77657cSAndrey V. Elsukov uint32_t ack_fwd; /* most recent ACKs in forward */ 809*4a77657cSAndrey V. Elsukov uint32_t ack_rev; /* and reverse directions (used */ 810a8c102a2SLuigi Rizzo /* to generate keepalives) */ 811*4a77657cSAndrey V. Elsukov } __packed __aligned(8) ipfw_dyn_rule; 81203c61266SLuigi Rizzo 81303c61266SLuigi Rizzo /* 81437afa1e8SUgen J.S. Antsilevich * Definitions for IP option names. 81537afa1e8SUgen J.S. Antsilevich */ 81637afa1e8SUgen J.S. Antsilevich #define IP_FW_IPOPT_LSRR 0x01 81737afa1e8SUgen J.S. Antsilevich #define IP_FW_IPOPT_SSRR 0x02 81837afa1e8SUgen J.S. Antsilevich #define IP_FW_IPOPT_RR 0x04 81937afa1e8SUgen J.S. Antsilevich #define IP_FW_IPOPT_TS 0x08 82037afa1e8SUgen J.S. Antsilevich 82137afa1e8SUgen J.S. Antsilevich /* 8229714563dSDan Moschuk * Definitions for TCP option names. 8239714563dSDan Moschuk */ 8249714563dSDan Moschuk #define IP_FW_TCPOPT_MSS 0x01 8259714563dSDan Moschuk #define IP_FW_TCPOPT_WINDOW 0x02 8269714563dSDan Moschuk #define IP_FW_TCPOPT_SACK 0x04 8279714563dSDan Moschuk #define IP_FW_TCPOPT_TS 0x08 8289714563dSDan Moschuk #define IP_FW_TCPOPT_CC 0x10 8299714563dSDan Moschuk 8309758b77fSLuigi Rizzo #define ICMP_REJECT_RST 0x100 /* fake ICMP code (send a TCP RST) */ 8319066356bSBjoern A. Zeeb #define ICMP6_UNREACH_RST 0x100 /* fake ICMPv6 code (send a TCP RST) */ 832665c8a2eSMichael Tuexen #define ICMP_REJECT_ABORT 0x101 /* fake ICMP code (send an SCTP ABORT) */ 833665c8a2eSMichael Tuexen #define ICMP6_UNREACH_ABORT 0x101 /* fake ICMPv6 code (send an SCTP ABORT) */ 8349758b77fSLuigi Rizzo 8359714563dSDan Moschuk /* 836cd8b5ae0SRuslan Ermilov * These are used for lookup tables. 837cd8b5ae0SRuslan Ermilov */ 838f8bee51aSAlexander V. Chernikov 839c21034b7SAlexander V. Chernikov #define IPFW_TABLE_ADDR 1 /* Table for holding IPv4/IPv6 prefixes */ 840f8bee51aSAlexander V. Chernikov #define IPFW_TABLE_INTERFACE 2 /* Table for holding interface names */ 841b23d5de9SAlexander V. Chernikov #define IPFW_TABLE_NUMBER 3 /* Table for holding ports/uid/gid/etc */ 842914bffb6SAlexander V. Chernikov #define IPFW_TABLE_FLOW 4 /* Table for holding flow data */ 84381cac390SArseny Smalyuk #define IPFW_TABLE_MAC 5 /* Table for holding mac address prefixes */ 84481cac390SArseny Smalyuk #define IPFW_TABLE_MAXTYPE 5 /* Maximum valid number */ 845ac35ff17SAlexander V. Chernikov 846c21034b7SAlexander V. Chernikov #define IPFW_TABLE_CIDR IPFW_TABLE_ADDR /* compat */ 847c21034b7SAlexander V. Chernikov 848adf3b2b9SAlexander V. Chernikov /* Value types */ 8490cba2b28SAlexander V. Chernikov #define IPFW_VTYPE_LEGACY 0xFFFFFFFF /* All data is filled in */ 8500cba2b28SAlexander V. Chernikov #define IPFW_VTYPE_SKIPTO 0x00000001 /* skipto/call/callreturn */ 8510cba2b28SAlexander V. Chernikov #define IPFW_VTYPE_PIPE 0x00000002 /* pipe/queue */ 8520cba2b28SAlexander V. Chernikov #define IPFW_VTYPE_FIB 0x00000004 /* setfib */ 8530cba2b28SAlexander V. Chernikov #define IPFW_VTYPE_NAT 0x00000008 /* nat */ 8540cba2b28SAlexander V. Chernikov #define IPFW_VTYPE_DSCP 0x00000010 /* dscp */ 8550cba2b28SAlexander V. Chernikov #define IPFW_VTYPE_TAG 0x00000020 /* tag/untag */ 8560cba2b28SAlexander V. Chernikov #define IPFW_VTYPE_DIVERT 0x00000040 /* divert/tee */ 8570cba2b28SAlexander V. Chernikov #define IPFW_VTYPE_NETGRAPH 0x00000080 /* netgraph/ngtee */ 8582530ed9eSAndrey V. Elsukov #define IPFW_VTYPE_LIMIT 0x00000100 /* limit */ 8590cba2b28SAlexander V. Chernikov #define IPFW_VTYPE_NH4 0x00000200 /* IPv4 nexthop */ 8600cba2b28SAlexander V. Chernikov #define IPFW_VTYPE_NH6 0x00000400 /* IPv6 nexthop */ 861fc727ad6SBoris Lytochkin #define IPFW_VTYPE_MARK 0x00000800 /* [fw]mark */ 862f8bee51aSAlexander V. Chernikov 863f8bee51aSAlexander V. Chernikov typedef struct _ipfw_table_xentry { 864f8bee51aSAlexander V. Chernikov uint16_t len; /* Total entry length */ 865f8bee51aSAlexander V. Chernikov uint8_t type; /* entry type */ 866f8bee51aSAlexander V. Chernikov uint8_t masklen; /* mask length */ 867f8bee51aSAlexander V. Chernikov uint16_t tbl; /* table number */ 868c3015737SAlexander V. Chernikov uint16_t flags; /* record flags */ 869f8bee51aSAlexander V. Chernikov uint32_t value; /* value */ 870f8bee51aSAlexander V. Chernikov union { 871f8bee51aSAlexander V. Chernikov /* Longest field needs to be aligned by 4-byte boundary */ 872f8bee51aSAlexander V. Chernikov struct in6_addr addr6; /* IPv6 address */ 873f8bee51aSAlexander V. Chernikov char iface[IF_NAMESIZE]; /* interface name */ 874f8bee51aSAlexander V. Chernikov } k; 875f8bee51aSAlexander V. Chernikov } ipfw_table_xentry; 876c3015737SAlexander V. Chernikov #define IPFW_TCF_INET 0x01 /* CIDR flags: IPv4 record */ 877f8bee51aSAlexander V. Chernikov 878f8bee51aSAlexander V. Chernikov typedef struct _ipfw_xtable { 879b074b7bbSAlexander V. Chernikov ip_fw3_opheader opheader; /* IP_FW3 opcode */ 880f8bee51aSAlexander V. Chernikov uint32_t size; /* size of entries in bytes */ 881f8bee51aSAlexander V. Chernikov uint32_t cnt; /* # of entries */ 882f8bee51aSAlexander V. Chernikov uint16_t tbl; /* table number */ 883f8bee51aSAlexander V. Chernikov uint8_t type; /* table type */ 884f8bee51aSAlexander V. Chernikov ipfw_table_xentry xent[0]; /* entries */ 885f8bee51aSAlexander V. Chernikov } ipfw_xtable; 886f8bee51aSAlexander V. Chernikov 8879f7d47b0SAlexander V. Chernikov typedef struct _ipfw_obj_tlv { 888b074b7bbSAlexander V. Chernikov uint16_t type; /* TLV type */ 889ac35ff17SAlexander V. Chernikov uint16_t flags; /* TLV-specific flags */ 890563b5ab1SAlexander V. Chernikov uint32_t length; /* Total length, aligned to u64 */ 8919f7d47b0SAlexander V. Chernikov } ipfw_obj_tlv; 892563b5ab1SAlexander V. Chernikov #define IPFW_TLV_TBL_NAME 1 893563b5ab1SAlexander V. Chernikov #define IPFW_TLV_TBLNAME_LIST 2 894563b5ab1SAlexander V. Chernikov #define IPFW_TLV_RULE_LIST 3 8956447bae6SAlexander V. Chernikov #define IPFW_TLV_DYNSTATE_LIST 4 896ac35ff17SAlexander V. Chernikov #define IPFW_TLV_TBL_ENT 5 8976447bae6SAlexander V. Chernikov #define IPFW_TLV_DYN_ENT 6 8987e767c79SAlexander V. Chernikov #define IPFW_TLV_RULE_ENT 7 89968394ec8SAlexander V. Chernikov #define IPFW_TLV_TBLENT_LIST 8 900a73d728dSAlexander V. Chernikov #define IPFW_TLV_RANGE 9 9012acdf79fSAndrey V. Elsukov #define IPFW_TLV_EACTION 10 902b867e84eSAndrey V. Elsukov #define IPFW_TLV_COUNTERS 11 903d8caf56eSAndrey V. Elsukov #define IPFW_TLV_OBJDATA 12 904ed22e564SAndrey V. Elsukov #define IPFW_TLV_STATE_NAME 14 9052acdf79fSAndrey V. Elsukov 9062acdf79fSAndrey V. Elsukov #define IPFW_TLV_EACTION_BASE 1000 9072acdf79fSAndrey V. Elsukov #define IPFW_TLV_EACTION_NAME(arg) (IPFW_TLV_EACTION_BASE + (arg)) 908b074b7bbSAlexander V. Chernikov 909d8caf56eSAndrey V. Elsukov typedef struct _ipfw_obj_data { 910d8caf56eSAndrey V. Elsukov ipfw_obj_tlv head; 911d8caf56eSAndrey V. Elsukov void *data[0]; 912d8caf56eSAndrey V. Elsukov } ipfw_obj_data; 913d8caf56eSAndrey V. Elsukov 914b074b7bbSAlexander V. Chernikov /* Object name TLV */ 9159f7d47b0SAlexander V. Chernikov typedef struct _ipfw_obj_ntlv { 9169f7d47b0SAlexander V. Chernikov ipfw_obj_tlv head; /* TLV header */ 917*4a77657cSAndrey V. Elsukov uint32_t idx; /* Name index */ 9182685841bSAndrey V. Elsukov uint8_t set; /* set, if applicable */ 919ac35ff17SAlexander V. Chernikov uint8_t type; /* object type, if applicable */ 920*4a77657cSAndrey V. Elsukov uint16_t spare; /* unused */ 921b074b7bbSAlexander V. Chernikov char name[64]; /* Null-terminated name */ 9229f7d47b0SAlexander V. Chernikov } ipfw_obj_ntlv; 923b074b7bbSAlexander V. Chernikov 924914bffb6SAlexander V. Chernikov /* IPv4/IPv6 L4 flow description */ 925914bffb6SAlexander V. Chernikov struct tflow_entry { 926914bffb6SAlexander V. Chernikov uint8_t af; 927914bffb6SAlexander V. Chernikov uint8_t proto; 928914bffb6SAlexander V. Chernikov uint16_t spare; 929914bffb6SAlexander V. Chernikov uint16_t sport; 930914bffb6SAlexander V. Chernikov uint16_t dport; 931914bffb6SAlexander V. Chernikov union { 932914bffb6SAlexander V. Chernikov struct { 933914bffb6SAlexander V. Chernikov struct in_addr sip; 934914bffb6SAlexander V. Chernikov struct in_addr dip; 935914bffb6SAlexander V. Chernikov } a4; 936914bffb6SAlexander V. Chernikov struct { 937914bffb6SAlexander V. Chernikov struct in6_addr sip6; 938914bffb6SAlexander V. Chernikov struct in6_addr dip6; 939914bffb6SAlexander V. Chernikov } a6; 940914bffb6SAlexander V. Chernikov } a; 941914bffb6SAlexander V. Chernikov }; 942914bffb6SAlexander V. Chernikov 943*4a77657cSAndrey V. Elsukov #define IPFW_TVALUE_TYPE_MASK 0xFF00 944*4a77657cSAndrey V. Elsukov #define IPFW_TVALUE_TYPE(insn) (((insn)->arg1 & IPFW_TVALUE_TYPE_MASK) >> 8) 945*4a77657cSAndrey V. Elsukov #define IPFW_SET_TVALUE_TYPE(insn, type) do { \ 946*4a77657cSAndrey V. Elsukov (insn)->arg1 &= ~IPFW_TVALUE_TYPE_MASK; \ 947*4a77657cSAndrey V. Elsukov (insn)->arg1 |= ((type) << 8) & IPFW_TVALUE_TYPE_MASK; \ 948*4a77657cSAndrey V. Elsukov } while (0) 949*4a77657cSAndrey V. Elsukov 950*4a77657cSAndrey V. Elsukov enum ipfw_table_value_type { 951*4a77657cSAndrey V. Elsukov TVALUE_TAG = 0, 952*4a77657cSAndrey V. Elsukov TVALUE_PIPE, 953*4a77657cSAndrey V. Elsukov TVALUE_DIVERT, 954*4a77657cSAndrey V. Elsukov TVALUE_SKIPTO, 955*4a77657cSAndrey V. Elsukov TVALUE_NETGRAPH, 956*4a77657cSAndrey V. Elsukov TVALUE_FIB, 957*4a77657cSAndrey V. Elsukov TVALUE_NAT, 958*4a77657cSAndrey V. Elsukov TVALUE_NH4, 959*4a77657cSAndrey V. Elsukov TVALUE_DSCP, 960*4a77657cSAndrey V. Elsukov TVALUE_LIMIT, 961*4a77657cSAndrey V. Elsukov TVALUE_MARK, 962*4a77657cSAndrey V. Elsukov }; 963*4a77657cSAndrey V. Elsukov 964fc727ad6SBoris Lytochkin /* 64-byte structure representing multi-field table value */ 9650cba2b28SAlexander V. Chernikov typedef struct _ipfw_table_value { 9660cba2b28SAlexander V. Chernikov uint32_t tag; /* O_TAG/O_TAGGED */ 967*4a77657cSAndrey V. Elsukov uint16_t pipe; /* O_PIPE/O_QUEUE */ 9680cba2b28SAlexander V. Chernikov uint16_t divert; /* O_DIVERT/O_TEE */ 969*4a77657cSAndrey V. Elsukov uint32_t skipto; /* skipto, CALLRET */ 9700cba2b28SAlexander V. Chernikov uint32_t netgraph; /* O_NETGRAPH/O_NGTEE */ 9710cba2b28SAlexander V. Chernikov uint32_t nat; /* O_NAT */ 9720cba2b28SAlexander V. Chernikov uint32_t nh4; 973*4a77657cSAndrey V. Elsukov uint16_t fib; /* O_SETFIB */ 9740cba2b28SAlexander V. Chernikov uint8_t dscp; 9752530ed9eSAndrey V. Elsukov uint8_t spare0; 976*4a77657cSAndrey V. Elsukov uint32_t kidx; /* value kernel index */ 9770cba2b28SAlexander V. Chernikov struct in6_addr nh6; 9780cba2b28SAlexander V. Chernikov uint32_t limit; /* O_LIMIT */ 9792530ed9eSAndrey V. Elsukov uint32_t zoneid; /* scope zone id for nh6 */ 980fc727ad6SBoris Lytochkin uint32_t mark; /* O_SETMARK/O_MARK */ 981fc727ad6SBoris Lytochkin uint32_t refcnt; /* XXX 64-bit in kernel */ 9820cba2b28SAlexander V. Chernikov } ipfw_table_value; 9830cba2b28SAlexander V. Chernikov 984ac35ff17SAlexander V. Chernikov /* Table entry TLV */ 985ac35ff17SAlexander V. Chernikov typedef struct _ipfw_obj_tentry { 986ac35ff17SAlexander V. Chernikov ipfw_obj_tlv head; /* TLV header */ 987ac35ff17SAlexander V. Chernikov uint8_t subtype; /* subtype (IPv4,IPv6) */ 988ac35ff17SAlexander V. Chernikov uint8_t masklen; /* mask length */ 9893a845e10SAlexander V. Chernikov uint8_t result; /* request result */ 9903a845e10SAlexander V. Chernikov uint8_t spare0; 991*4a77657cSAndrey V. Elsukov uint32_t idx; /* Table name index */ 992ac35ff17SAlexander V. Chernikov union { 993ac35ff17SAlexander V. Chernikov /* Longest field needs to be aligned by 8-byte boundary */ 994ac35ff17SAlexander V. Chernikov struct in_addr addr; /* IPv4 address */ 995ac35ff17SAlexander V. Chernikov uint32_t key; /* uid/gid/port */ 996ac35ff17SAlexander V. Chernikov struct in6_addr addr6; /* IPv6 address */ 997ac35ff17SAlexander V. Chernikov char iface[IF_NAMESIZE]; /* interface name */ 99881cac390SArseny Smalyuk u_char mac[IPFW_MAX_L2_ADDR_LEN]; /* MAC address */ 999914bffb6SAlexander V. Chernikov struct tflow_entry flow; 1000ac35ff17SAlexander V. Chernikov } k; 10014bbd1577SAlexander V. Chernikov union { 10020cba2b28SAlexander V. Chernikov ipfw_table_value value; /* value data */ 10030cba2b28SAlexander V. Chernikov uint32_t kidx; /* value kernel index */ 10044bbd1577SAlexander V. Chernikov } v; 1005ac35ff17SAlexander V. Chernikov } ipfw_obj_tentry; 1006ac35ff17SAlexander V. Chernikov #define IPFW_TF_UPDATE 0x01 /* Update record if exists */ 10073a845e10SAlexander V. Chernikov /* Container TLV */ 10083a845e10SAlexander V. Chernikov #define IPFW_CTF_ATOMIC 0x01 /* Perform atomic operation */ 10093a845e10SAlexander V. Chernikov /* Operation results */ 10103a845e10SAlexander V. Chernikov #define IPFW_TR_IGNORED 0 /* Entry was ignored (rollback) */ 1011a4641f4eSPedro F. Giffuni #define IPFW_TR_ADDED 1 /* Entry was successfully added */ 1012a4641f4eSPedro F. Giffuni #define IPFW_TR_UPDATED 2 /* Entry was successfully updated*/ 1013a4641f4eSPedro F. Giffuni #define IPFW_TR_DELETED 3 /* Entry was successfully deleted*/ 10143a845e10SAlexander V. Chernikov #define IPFW_TR_LIMIT 4 /* Entry was ignored (limit) */ 10153a845e10SAlexander V. Chernikov #define IPFW_TR_NOTFOUND 5 /* Entry was not found */ 10163a845e10SAlexander V. Chernikov #define IPFW_TR_EXISTS 6 /* Entry already exists */ 10173a845e10SAlexander V. Chernikov #define IPFW_TR_ERROR 7 /* Request has failed (unknown) */ 1018ac35ff17SAlexander V. Chernikov 10196447bae6SAlexander V. Chernikov typedef struct _ipfw_obj_dyntlv { 10206447bae6SAlexander V. Chernikov ipfw_obj_tlv head; 10216447bae6SAlexander V. Chernikov ipfw_dyn_rule state; 10226447bae6SAlexander V. Chernikov } ipfw_obj_dyntlv; 10236447bae6SAlexander V. Chernikov #define IPFW_DF_LAST 0x01 /* Last state in chain */ 10246447bae6SAlexander V. Chernikov 1025563b5ab1SAlexander V. Chernikov /* Containter TLVs */ 1026563b5ab1SAlexander V. Chernikov typedef struct _ipfw_obj_ctlv { 1027563b5ab1SAlexander V. Chernikov ipfw_obj_tlv head; /* TLV header */ 1028563b5ab1SAlexander V. Chernikov uint32_t count; /* Number of sub-TLVs */ 10297e767c79SAlexander V. Chernikov uint16_t objsize; /* Single object size */ 10307e767c79SAlexander V. Chernikov uint8_t version; /* TLV version */ 10313a845e10SAlexander V. Chernikov uint8_t flags; /* TLV-specific flags */ 1032563b5ab1SAlexander V. Chernikov } ipfw_obj_ctlv; 1033563b5ab1SAlexander V. Chernikov 1034a73d728dSAlexander V. Chernikov /* Range TLV */ 1035a73d728dSAlexander V. Chernikov typedef struct _ipfw_range_tlv { 1036a73d728dSAlexander V. Chernikov ipfw_obj_tlv head; /* TLV header */ 1037a73d728dSAlexander V. Chernikov uint32_t flags; /* Range flags */ 1038*4a77657cSAndrey V. Elsukov uint32_t start_rule; /* Range start */ 1039*4a77657cSAndrey V. Elsukov uint32_t end_rule; /* Range end */ 1040a73d728dSAlexander V. Chernikov uint32_t set; /* Range set to match */ 1041a73d728dSAlexander V. Chernikov uint32_t new_set; /* New set to move/swap to */ 1042a73d728dSAlexander V. Chernikov } ipfw_range_tlv; 1043a73d728dSAlexander V. Chernikov #define IPFW_RCFLAG_RANGE 0x01 /* rule range is set */ 1044a73d728dSAlexander V. Chernikov #define IPFW_RCFLAG_ALL 0x02 /* match ALL rules */ 1045a73d728dSAlexander V. Chernikov #define IPFW_RCFLAG_SET 0x04 /* match rules in given set */ 1046d66f9c86SAndrey V. Elsukov #define IPFW_RCFLAG_DYNAMIC 0x08 /* match only dynamic states */ 10472930362fSAlexander V. Chernikov /* User-settable flags */ 10482930362fSAlexander V. Chernikov #define IPFW_RCFLAG_USER (IPFW_RCFLAG_RANGE | IPFW_RCFLAG_ALL | \ 1049d66f9c86SAndrey V. Elsukov IPFW_RCFLAG_SET | IPFW_RCFLAG_DYNAMIC) 10502930362fSAlexander V. Chernikov /* Internally used flags */ 105178e4dbc3SGordon Bergling #define IPFW_RCFLAG_DEFAULT 0x0100 /* Do not skip default rule */ 1052a73d728dSAlexander V. Chernikov 10535f379342SAlexander V. Chernikov typedef struct _ipfw_ta_tinfo { 1054914bffb6SAlexander V. Chernikov uint32_t flags; /* Format flags */ 10555f379342SAlexander V. Chernikov uint32_t spare; 10565f379342SAlexander V. Chernikov uint8_t taclass4; /* algorithm class */ 10575f379342SAlexander V. Chernikov uint8_t spare4; 10585f379342SAlexander V. Chernikov uint16_t itemsize4; /* item size in runtime */ 10595f379342SAlexander V. Chernikov uint32_t size4; /* runtime structure size */ 10605f379342SAlexander V. Chernikov uint32_t count4; /* number of items in runtime */ 10615f379342SAlexander V. Chernikov uint8_t taclass6; /* algorithm class */ 10625f379342SAlexander V. Chernikov uint8_t spare6; 10635f379342SAlexander V. Chernikov uint16_t itemsize6; /* item size in runtime */ 10645f379342SAlexander V. Chernikov uint32_t size6; /* runtime structure size */ 10655f379342SAlexander V. Chernikov uint32_t count6; /* number of items in runtime */ 10665f379342SAlexander V. Chernikov } ipfw_ta_tinfo; 1067914bffb6SAlexander V. Chernikov #define IPFW_TACLASS_HASH 1 /* algo is based on hash */ 1068914bffb6SAlexander V. Chernikov #define IPFW_TACLASS_ARRAY 2 /* algo is based on array */ 1069914bffb6SAlexander V. Chernikov #define IPFW_TACLASS_RADIX 3 /* algo is based on radix tree */ 1070914bffb6SAlexander V. Chernikov 1071914bffb6SAlexander V. Chernikov #define IPFW_TATFLAGS_DATA 0x0001 /* Has data filled in */ 10725f379342SAlexander V. Chernikov #define IPFW_TATFLAGS_AFDATA 0x0002 /* Separate data per AF */ 10735f379342SAlexander V. Chernikov #define IPFW_TATFLAGS_AFITEM 0x0004 /* diff. items per AF */ 1074914bffb6SAlexander V. Chernikov 10759f7d47b0SAlexander V. Chernikov typedef struct _ipfw_xtable_info { 1076c21034b7SAlexander V. Chernikov uint8_t type; /* table type (addr,iface,..) */ 1077914bffb6SAlexander V. Chernikov uint8_t tflags; /* type flags */ 1078adf3b2b9SAlexander V. Chernikov uint16_t mflags; /* modification flags */ 10794f43138aSAlexander V. Chernikov uint16_t flags; /* generic table flags */ 10800cba2b28SAlexander V. Chernikov uint16_t spare[3]; 10810cba2b28SAlexander V. Chernikov uint32_t vmask; /* bitmask with value types */ 10829f7d47b0SAlexander V. Chernikov uint32_t set; /* set table is in */ 10839f7d47b0SAlexander V. Chernikov uint32_t kidx; /* kernel index */ 10849f7d47b0SAlexander V. Chernikov uint32_t refcnt; /* number of references */ 10859f7d47b0SAlexander V. Chernikov uint32_t count; /* Number of records */ 1086914bffb6SAlexander V. Chernikov uint32_t size; /* Total size of records(export)*/ 10874c0c07a5SAlexander V. Chernikov uint32_t limit; /* Max number of records */ 10889f7d47b0SAlexander V. Chernikov char tablename[64]; /* table name */ 1089914bffb6SAlexander V. Chernikov char algoname[64]; /* algorithm name */ 10905f379342SAlexander V. Chernikov ipfw_ta_tinfo ta_info; /* additional algo stats */ 10919f7d47b0SAlexander V. Chernikov } ipfw_xtable_info; 10924f43138aSAlexander V. Chernikov /* Generic table flags */ 10934f43138aSAlexander V. Chernikov #define IPFW_TGFLAGS_LOCKED 0x01 /* Tables is locked from changes*/ 10944f43138aSAlexander V. Chernikov /* Table type-specific flags */ 1095914bffb6SAlexander V. Chernikov #define IPFW_TFFLAG_SRCIP 0x01 1096914bffb6SAlexander V. Chernikov #define IPFW_TFFLAG_DSTIP 0x02 1097914bffb6SAlexander V. Chernikov #define IPFW_TFFLAG_SRCPORT 0x04 1098914bffb6SAlexander V. Chernikov #define IPFW_TFFLAG_DSTPORT 0x08 1099914bffb6SAlexander V. Chernikov #define IPFW_TFFLAG_PROTO 0x10 11004f43138aSAlexander V. Chernikov /* Table modification flags */ 11014f43138aSAlexander V. Chernikov #define IPFW_TMFLAGS_LIMIT 0x0002 /* Change limit value */ 11024f43138aSAlexander V. Chernikov #define IPFW_TMFLAGS_LOCK 0x0004 /* Change table lock state */ 11039f7d47b0SAlexander V. Chernikov 110468394ec8SAlexander V. Chernikov typedef struct _ipfw_iface_info { 110568394ec8SAlexander V. Chernikov char ifname[64]; /* interface name */ 110668394ec8SAlexander V. Chernikov uint32_t ifindex; /* interface index */ 110768394ec8SAlexander V. Chernikov uint32_t flags; /* flags */ 110868394ec8SAlexander V. Chernikov uint32_t refcnt; /* number of references */ 110968394ec8SAlexander V. Chernikov uint32_t gencnt; /* number of changes */ 111068394ec8SAlexander V. Chernikov uint64_t spare; 111168394ec8SAlexander V. Chernikov } ipfw_iface_info; 111268394ec8SAlexander V. Chernikov #define IPFW_IFFLAG_RESOLVED 0x01 /* Interface exists */ 111368394ec8SAlexander V. Chernikov 11149d099b4fSAlexander V. Chernikov typedef struct _ipfw_ta_info { 1115914bffb6SAlexander V. Chernikov char algoname[64]; /* algorithm name */ 11169d099b4fSAlexander V. Chernikov uint32_t type; /* lookup type */ 11179d099b4fSAlexander V. Chernikov uint32_t flags; 11189d099b4fSAlexander V. Chernikov uint32_t refcnt; 11199d099b4fSAlexander V. Chernikov uint32_t spare0; 11209d099b4fSAlexander V. Chernikov uint64_t spare1; 11219d099b4fSAlexander V. Chernikov } ipfw_ta_info; 11229d099b4fSAlexander V. Chernikov 1123*4a77657cSAndrey V. Elsukov typedef struct _ipfw_cmd_header { /* control command header */ 1124*4a77657cSAndrey V. Elsukov ip_fw3_opheader opheader; /* IP_FW3 opcode */ 1125*4a77657cSAndrey V. Elsukov uint32_t size; /* Total size (incl. header) */ 1126*4a77657cSAndrey V. Elsukov uint32_t cmd; /* command */ 1127*4a77657cSAndrey V. Elsukov } ipfw_cmd_header; 1128*4a77657cSAndrey V. Elsukov 1129b074b7bbSAlexander V. Chernikov typedef struct _ipfw_obj_header { 1130b074b7bbSAlexander V. Chernikov ip_fw3_opheader opheader; /* IP_FW3 opcode */ 1131*4a77657cSAndrey V. Elsukov uint32_t idx; /* object name index */ 1132*4a77657cSAndrey V. Elsukov uint16_t spare; 11339f7d47b0SAlexander V. Chernikov uint8_t objtype; /* object type */ 11349f7d47b0SAlexander V. Chernikov uint8_t objsubtype; /* object subtype */ 11359f7d47b0SAlexander V. Chernikov ipfw_obj_ntlv ntlv; /* object name tlv */ 1136b074b7bbSAlexander V. Chernikov } ipfw_obj_header; 11379f7d47b0SAlexander V. Chernikov 11389f7d47b0SAlexander V. Chernikov typedef struct _ipfw_obj_lheader { 11399f7d47b0SAlexander V. Chernikov ip_fw3_opheader opheader; /* IP_FW3 opcode */ 1140ac35ff17SAlexander V. Chernikov uint32_t set_mask; /* disabled set mask */ 11419f7d47b0SAlexander V. Chernikov uint32_t count; /* Total objects count */ 114268394ec8SAlexander V. Chernikov uint32_t size; /* Total size (incl. header) */ 11439f7d47b0SAlexander V. Chernikov uint32_t objsize; /* Size of one object */ 11449f7d47b0SAlexander V. Chernikov } ipfw_obj_lheader; 1145b074b7bbSAlexander V. Chernikov 11467e767c79SAlexander V. Chernikov #define IPFW_CFG_GET_STATIC 0x01 11477e767c79SAlexander V. Chernikov #define IPFW_CFG_GET_STATES 0x02 11487e767c79SAlexander V. Chernikov #define IPFW_CFG_GET_COUNTERS 0x04 1149563b5ab1SAlexander V. Chernikov typedef struct _ipfw_cfg_lheader { 1150563b5ab1SAlexander V. Chernikov ip_fw3_opheader opheader; /* IP_FW3 opcode */ 1151ac35ff17SAlexander V. Chernikov uint32_t set_mask; /* enabled set mask */ 11527e767c79SAlexander V. Chernikov uint32_t spare; 1153563b5ab1SAlexander V. Chernikov uint32_t flags; /* Request flags */ 1154563b5ab1SAlexander V. Chernikov uint32_t size; /* neded buffer size */ 1155563b5ab1SAlexander V. Chernikov uint32_t start_rule; 1156563b5ab1SAlexander V. Chernikov uint32_t end_rule; 1157563b5ab1SAlexander V. Chernikov } ipfw_cfg_lheader; 1158563b5ab1SAlexander V. Chernikov 1159a73d728dSAlexander V. Chernikov typedef struct _ipfw_range_header { 1160a73d728dSAlexander V. Chernikov ip_fw3_opheader opheader; /* IP_FW3 opcode */ 1161a73d728dSAlexander V. Chernikov ipfw_range_tlv range; 1162a73d728dSAlexander V. Chernikov } ipfw_range_header; 1163a73d728dSAlexander V. Chernikov 1164be8bc457SAlexander V. Chernikov typedef struct _ipfw_sopt_info { 1165be8bc457SAlexander V. Chernikov uint16_t opcode; 1166be8bc457SAlexander V. Chernikov uint8_t version; 1167be8bc457SAlexander V. Chernikov uint8_t dir; 1168be8bc457SAlexander V. Chernikov uint8_t spare; 1169be8bc457SAlexander V. Chernikov uint64_t refcnt; 1170be8bc457SAlexander V. Chernikov } ipfw_sopt_info; 1171be8bc457SAlexander V. Chernikov 11729758b77fSLuigi Rizzo #endif /* _IPFW2_H */ 1173