ip_fw.h revision 183012
1126277Sdes/*- 299046Sdes * Copyright (c) 2002 Luigi Rizzo, Universita` di Pisa 392559Sdes * 465668Skris * Redistribution and use in source and binary forms, with or without 565668Skris * modification, are permitted provided that the following conditions 665668Skris * are met: 765668Skris * 1. Redistributions of source code must retain the above copyright 865668Skris * notice, this list of conditions and the following disclaimer. 965668Skris * 2. Redistributions in binary form must reproduce the above copyright 1065668Skris * notice, this list of conditions and the following disclaimer in the 1165668Skris * documentation and/or other materials provided with the distribution. 1265668Skris * 1365668Skris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1465668Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1565668Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1665668Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1765668Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1865668Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 1965668Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2065668Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2165668Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2265668Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2365668Skris * SUCH DAMAGE. 2465668Skris * 2565668Skris * $FreeBSD: head/sys/netinet/ip_fw.h 183012 2008-09-14 06:14:06Z rik $ 2669587Sgreen */ 2765668Skris 2892559Sdes#ifndef _IPFW2_H 2960573Skris#define _IPFW2_H 3060573Skris 3160573Skris/* 3292559Sdes * The default rule number. By the design of ip_fw, the default rule 3392559Sdes * is the last one, so its number can also serve as the highest number 3476259Sgreen * allowed for a rule. The ip_fw code relies on both meanings of this 3576259Sgreen * constant. 3676259Sgreen */ 3776259Sgreen#define IPFW_DEFAULT_RULE 65535 3876259Sgreen 3976259Sgreen/* 4076259Sgreen * The kernel representation of ipfw rules is made of a list of 4176259Sgreen * 'instructions' (for all practical purposes equivalent to BPF 4292559Sdes * instructions), which specify which fields of the packet 4392559Sdes * (or its metadata) should be analysed. 4492559Sdes * 4576259Sgreen * Each instruction is stored in a structure which begins with 4669587Sgreen * "ipfw_insn", and can contain extra fields depending on the 4798684Sdes * instruction type (listed below). 4892559Sdes * Note that the code is written so that individual instructions 4992559Sdes * have a size which is a multiple of 32 bits. This means that, if 5069587Sgreen * such structures contain pointers or other 64-bit entities, 5192559Sdes * (there is just one instance now) they may end up unaligned on 52124211Sdes * 64-bit architectures, so the must be handled with care. 53124211Sdes * 5492559Sdes * "enum ipfw_opcodes" are the opcodes supported. We can have up 5592559Sdes * to 256 different opcodes. When adding new opcodes, they should 56126277Sdes * be appended to the end of the opcode list before O_LAST_OPCODE, 57124211Sdes * this will prevent the ABI from being broken, otherwise users 5892559Sdes * will have to recompile ipfw(8) when they update the kernel. 59124211Sdes */ 6092559Sdes 6192559Sdesenum ipfw_opcodes { /* arguments (4 byte each) */ 6276259Sgreen O_NOP, 6392559Sdes 6476259Sgreen O_IP_SRC, /* u32 = IP */ 6592559Sdes O_IP_SRC_MASK, /* ip = IP/mask */ 6692559Sdes O_IP_SRC_ME, /* none */ 6792559Sdes O_IP_SRC_SET, /* u32=base, arg1=len, bitmap */ 6892559Sdes 6992559Sdes O_IP_DST, /* u32 = IP */ 7092559Sdes O_IP_DST_MASK, /* ip = IP/mask */ 71124211Sdes O_IP_DST_ME, /* none */ 7269587Sgreen O_IP_DST_SET, /* u32=base, arg1=len, bitmap */ 73124211Sdes 74124211Sdes O_IP_SRCPORT, /* (n)port list:mask 4 byte ea */ 75124211Sdes O_IP_DSTPORT, /* (n)port list:mask 4 byte ea */ 76124211Sdes O_PROTO, /* arg1=protocol */ 77124211Sdes 78124211Sdes O_MACADDR2, /* 2 mac addr:mask */ 7969587Sgreen O_MAC_TYPE, /* same as srcport */ 8098684Sdes 8198684Sdes O_LAYER2, /* none */ 8298684Sdes O_IN, /* none */ 8398684Sdes O_FRAG, /* none */ 8498684Sdes 8598684Sdes O_RECV, /* none */ 8676259Sgreen O_XMIT, /* none */ 8792559Sdes O_VIA, /* none */ 8892559Sdes 8992559Sdes O_IPOPT, /* arg1 = 2*u8 bitmap */ 9092559Sdes O_IPLEN, /* arg1 = len */ 9192559Sdes O_IPID, /* arg1 = id */ 9276259Sgreen 9392559Sdes O_IPTOS, /* arg1 = id */ 9492559Sdes O_IPPRECEDENCE, /* arg1 = precedence << 5 */ 9592559Sdes O_IPTTL, /* arg1 = TTL */ 9692559Sdes 9792559Sdes O_IPVER, /* arg1 = version */ 9892559Sdes O_UID, /* u32 = id */ 9992559Sdes O_GID, /* u32 = id */ 10092559Sdes O_ESTAB, /* none (tcp established) */ 10192559Sdes O_TCPFLAGS, /* arg1 = 2*u8 bitmap */ 10276259Sgreen O_TCPWIN, /* arg1 = desired win */ 10398684Sdes O_TCPSEQ, /* u32 = desired seq. */ 10476259Sgreen O_TCPACK, /* u32 = desired seq. */ 10592559Sdes O_ICMPTYPE, /* u32 = icmp bitmap */ 10676259Sgreen O_TCPOPTS, /* arg1 = 2*u8 bitmap */ 107126277Sdes 10892559Sdes O_VERREVPATH, /* none */ 109126277Sdes O_VERSRCREACH, /* none */ 11098684Sdes 11198684Sdes O_PROBE_STATE, /* none */ 11298684Sdes O_KEEP_STATE, /* none */ 11398684Sdes O_LIMIT, /* ipfw_insn_limit */ 11476259Sgreen O_LIMIT_PARENT, /* dyn_type, not an opcode. */ 11598684Sdes 11698684Sdes /* 11798684Sdes * These are really 'actions'. 11898684Sdes */ 11992559Sdes 120106130Sdes O_LOG, /* ipfw_insn_log */ 12192559Sdes O_PROB, /* u32 = match probability */ 12292559Sdes 123126277Sdes O_CHECK_STATE, /* none */ 12492559Sdes O_ACCEPT, /* none */ 12576259Sgreen O_DENY, /* none */ 126126277Sdes O_REJECT, /* arg1=icmp arg (same as deny) */ 127126277Sdes O_COUNT, /* none */ 128126277Sdes O_SKIPTO, /* arg1=next rule number */ 129126277Sdes O_PIPE, /* arg1=pipe number */ 130126277Sdes O_QUEUE, /* arg1=queue number */ 131126277Sdes O_DIVERT, /* arg1=port number */ 13298941Sdes O_TEE, /* arg1=port number */ 133126277Sdes O_FORWARD_IP, /* fwd sockaddr */ 13498941Sdes O_FORWARD_MAC, /* fwd mac */ 135126277Sdes O_NAT, /* nope */ 136126277Sdes 13760573Skris /* 13892559Sdes * More opcodes. 13992559Sdes */ 14092559Sdes O_IPSEC, /* has ipsec history */ 14160573Skris O_IP_SRC_LOOKUP, /* arg1=table number, u32=value */ 14298684Sdes O_IP_DST_LOOKUP, /* arg1=table number, u32=value */ 14398684Sdes O_ANTISPOOF, /* none */ 14498684Sdes O_JAIL, /* u32 = id */ 14598684Sdes O_ALTQ, /* u32 = altq classif. qid */ 14692559Sdes O_DIVERTED, /* arg1=bitmap (1:loop, 2:out) */ 14792559Sdes O_TCPDATALEN, /* arg1 = tcp data len */ 14898684Sdes O_IP6_SRC, /* address without mask */ 14998684Sdes O_IP6_SRC_ME, /* my addresses */ 15098684Sdes O_IP6_SRC_MASK, /* address with the mask */ 15198684Sdes O_IP6_DST, 15260573Skris O_IP6_DST_ME, 15392559Sdes O_IP6_DST_MASK, 15498684Sdes O_FLOW6ID, /* for flow id tag in the ipv6 pkt */ 15576259Sgreen O_ICMP6TYPE, /* icmp6 packet type filtering */ 15692559Sdes O_EXT_HDR, /* filtering for ipv6 extension header */ 15792559Sdes O_IP6, 158112870Sdes 15976259Sgreen /* 16092559Sdes * actions for ng_ipfw 16192559Sdes */ 16292559Sdes O_NETGRAPH, /* send to ng_ipfw */ 16392559Sdes O_NGTEE, /* copy to ng_ipfw */ 16492559Sdes 16592559Sdes O_IP4, 16692559Sdes 16792559Sdes O_UNREACH6, /* arg1=icmpv6 code arg (deny) */ 16892559Sdes 16992559Sdes O_TAG, /* arg1=tag number */ 17092559Sdes O_TAGGED, /* arg1=tag number */ 17198684Sdes 17298684Sdes O_SETFIB, /* arg1=FIB number */ 17398684Sdes O_FIB, /* arg1=FIB desired fib number */ 17498684Sdes 17598684Sdes O_LAST_OPCODE /* not an opcode! */ 17698684Sdes}; 17798684Sdes 17898684Sdes/* 17998684Sdes * The extension header are filtered only for presence using a bit 18098684Sdes * vector with a flag for each header. 18198684Sdes */ 182124211Sdes#define EXT_FRAGMENT 0x1 183124211Sdes#define EXT_HOPOPTS 0x2 18460573Skris#define EXT_ROUTING 0x4 18560573Skris#define EXT_AH 0x8 18660573Skris#define EXT_ESP 0x10 18760573Skris#define EXT_DSTOPTS 0x20 18899046Sdes#define EXT_RTHDR0 0x40 18999046Sdes#define EXT_RTHDR2 0x80 19099046Sdes 19199046Sdes/* 19298941Sdes * Template for instructions. 19360573Skris * 19499046Sdes * ipfw_insn is used for all instructions which require no operands, 19599046Sdes * a single 16-bit value (arg1), or a couple of 8-bit values. 19699046Sdes * 197 * For other instructions which require different/larger arguments 198 * we have derived structures, ipfw_insn_*. 199 * 200 * The size of the instruction (in 32-bit words) is in the low 201 * 6 bits of "len". The 2 remaining bits are used to implement 202 * NOT and OR on individual instructions. Given a type, you can 203 * compute the length to be put in "len" using F_INSN_SIZE(t) 204 * 205 * F_NOT negates the match result of the instruction. 206 * 207 * F_OR is used to build or blocks. By default, instructions 208 * are evaluated as part of a logical AND. An "or" block 209 * { X or Y or Z } contains F_OR set in all but the last 210 * instruction of the block. A match will cause the code 211 * to skip past the last instruction of the block. 212 * 213 * NOTA BENE: in a couple of places we assume that 214 * sizeof(ipfw_insn) == sizeof(u_int32_t) 215 * this needs to be fixed. 216 * 217 */ 218typedef struct _ipfw_insn { /* template for instructions */ 219 enum ipfw_opcodes opcode:8; 220 u_int8_t len; /* numer of 32-byte words */ 221#define F_NOT 0x80 222#define F_OR 0x40 223#define F_LEN_MASK 0x3f 224#define F_LEN(cmd) ((cmd)->len & F_LEN_MASK) 225 226 u_int16_t arg1; 227} ipfw_insn; 228 229/* 230 * The F_INSN_SIZE(type) computes the size, in 4-byte words, of 231 * a given type. 232 */ 233#define F_INSN_SIZE(t) ((sizeof (t))/sizeof(u_int32_t)) 234 235#define MTAG_IPFW 1148380143 /* IPFW-tagged cookie */ 236 237/* 238 * This is used to store an array of 16-bit entries (ports etc.) 239 */ 240typedef struct _ipfw_insn_u16 { 241 ipfw_insn o; 242 u_int16_t ports[2]; /* there may be more */ 243} ipfw_insn_u16; 244 245/* 246 * This is used to store an array of 32-bit entries 247 * (uid, single IPv4 addresses etc.) 248 */ 249typedef struct _ipfw_insn_u32 { 250 ipfw_insn o; 251 u_int32_t d[1]; /* one or more */ 252} ipfw_insn_u32; 253 254/* 255 * This is used to store IP addr-mask pairs. 256 */ 257typedef struct _ipfw_insn_ip { 258 ipfw_insn o; 259 struct in_addr addr; 260 struct in_addr mask; 261} ipfw_insn_ip; 262 263/* 264 * This is used to forward to a given address (ip). 265 */ 266typedef struct _ipfw_insn_sa { 267 ipfw_insn o; 268 struct sockaddr_in sa; 269} ipfw_insn_sa; 270 271/* 272 * This is used for MAC addr-mask pairs. 273 */ 274typedef struct _ipfw_insn_mac { 275 ipfw_insn o; 276 u_char addr[12]; /* dst[6] + src[6] */ 277 u_char mask[12]; /* dst[6] + src[6] */ 278} ipfw_insn_mac; 279 280/* 281 * This is used for interface match rules (recv xx, xmit xx). 282 */ 283typedef struct _ipfw_insn_if { 284 ipfw_insn o; 285 union { 286 struct in_addr ip; 287 int glob; 288 } p; 289 char name[IFNAMSIZ]; 290} ipfw_insn_if; 291 292/* 293 * This is used for storing an altq queue id number. 294 */ 295typedef struct _ipfw_insn_altq { 296 ipfw_insn o; 297 u_int32_t qid; 298} ipfw_insn_altq; 299 300/* 301 * This is used for limit rules. 302 */ 303typedef struct _ipfw_insn_limit { 304 ipfw_insn o; 305 u_int8_t _pad; 306 u_int8_t limit_mask; /* combination of DYN_* below */ 307#define DYN_SRC_ADDR 0x1 308#define DYN_SRC_PORT 0x2 309#define DYN_DST_ADDR 0x4 310#define DYN_DST_PORT 0x8 311 312 u_int16_t conn_limit; 313} ipfw_insn_limit; 314 315/* 316 * This is used for log instructions. 317 */ 318typedef struct _ipfw_insn_log { 319 ipfw_insn o; 320 u_int32_t max_log; /* how many do we log -- 0 = all */ 321 u_int32_t log_left; /* how many left to log */ 322} ipfw_insn_log; 323 324/* 325 * Data structures required by both ipfw(8) and ipfw(4) but not part of the 326 * management API are protected by IPFW_INTERNAL. 327 */ 328#ifdef IPFW_INTERNAL 329/* Server pool support (LSNAT). */ 330struct cfg_spool { 331 LIST_ENTRY(cfg_spool) _next; /* chain of spool instances */ 332 struct in_addr addr; 333 u_short port; 334}; 335#endif 336 337/* Redirect modes id. */ 338#define REDIR_ADDR 0x01 339#define REDIR_PORT 0x02 340#define REDIR_PROTO 0x04 341 342#ifdef IPFW_INTERNAL 343/* Nat redirect configuration. */ 344struct cfg_redir { 345 LIST_ENTRY(cfg_redir) _next; /* chain of redir instances */ 346 u_int16_t mode; /* type of redirect mode */ 347 struct in_addr laddr; /* local ip address */ 348 struct in_addr paddr; /* public ip address */ 349 struct in_addr raddr; /* remote ip address */ 350 u_short lport; /* local port */ 351 u_short pport; /* public port */ 352 u_short rport; /* remote port */ 353 u_short pport_cnt; /* number of public ports */ 354 u_short rport_cnt; /* number of remote ports */ 355 int proto; /* protocol: tcp/udp */ 356 struct alias_link **alink; 357 /* num of entry in spool chain */ 358 u_int16_t spool_cnt; 359 /* chain of spool instances */ 360 LIST_HEAD(spool_chain, cfg_spool) spool_chain; 361}; 362#endif 363 364#define NAT_BUF_LEN 1024 365 366#ifdef IPFW_INTERNAL 367/* Nat configuration data struct. */ 368struct cfg_nat { 369 /* chain of nat instances */ 370 LIST_ENTRY(cfg_nat) _next; 371 int id; /* nat id */ 372 struct in_addr ip; /* nat ip address */ 373 char if_name[IF_NAMESIZE]; /* interface name */ 374 int mode; /* aliasing mode */ 375 struct libalias *lib; /* libalias instance */ 376 /* number of entry in spool chain */ 377 int redir_cnt; 378 /* chain of redir instances */ 379 LIST_HEAD(redir_chain, cfg_redir) redir_chain; 380}; 381#endif 382 383#define SOF_NAT sizeof(struct cfg_nat) 384#define SOF_REDIR sizeof(struct cfg_redir) 385#define SOF_SPOOL sizeof(struct cfg_spool) 386 387/* Nat command. */ 388typedef struct _ipfw_insn_nat { 389 ipfw_insn o; 390 struct cfg_nat *nat; 391} ipfw_insn_nat; 392 393/* Apply ipv6 mask on ipv6 addr */ 394#define APPLY_MASK(addr,mask) \ 395 (addr)->__u6_addr.__u6_addr32[0] &= (mask)->__u6_addr.__u6_addr32[0]; \ 396 (addr)->__u6_addr.__u6_addr32[1] &= (mask)->__u6_addr.__u6_addr32[1]; \ 397 (addr)->__u6_addr.__u6_addr32[2] &= (mask)->__u6_addr.__u6_addr32[2]; \ 398 (addr)->__u6_addr.__u6_addr32[3] &= (mask)->__u6_addr.__u6_addr32[3]; 399 400/* Structure for ipv6 */ 401typedef struct _ipfw_insn_ip6 { 402 ipfw_insn o; 403 struct in6_addr addr6; 404 struct in6_addr mask6; 405} ipfw_insn_ip6; 406 407/* Used to support icmp6 types */ 408typedef struct _ipfw_insn_icmp6 { 409 ipfw_insn o; 410 uint32_t d[7]; /* XXX This number si related to the netinet/icmp6.h 411 * define ICMP6_MAXTYPE 412 * as follows: n = ICMP6_MAXTYPE/32 + 1 413 * Actually is 203 414 */ 415} ipfw_insn_icmp6; 416 417/* 418 * Here we have the structure representing an ipfw rule. 419 * 420 * It starts with a general area (with link fields and counters) 421 * followed by an array of one or more instructions, which the code 422 * accesses as an array of 32-bit values. 423 * 424 * Given a rule pointer r: 425 * 426 * r->cmd is the start of the first instruction. 427 * ACTION_PTR(r) is the start of the first action (things to do 428 * once a rule matched). 429 * 430 * When assembling instruction, remember the following: 431 * 432 * + if a rule has a "keep-state" (or "limit") option, then the 433 * first instruction (at r->cmd) MUST BE an O_PROBE_STATE 434 * + if a rule has a "log" option, then the first action 435 * (at ACTION_PTR(r)) MUST be O_LOG 436 * + if a rule has an "altq" option, it comes after "log" 437 * + if a rule has an O_TAG option, it comes after "log" and "altq" 438 * 439 * NOTE: we use a simple linked list of rules because we never need 440 * to delete a rule without scanning the list. We do not use 441 * queue(3) macros for portability and readability. 442 */ 443 444struct ip_fw { 445 struct ip_fw *next; /* linked list of rules */ 446 struct ip_fw *next_rule; /* ptr to next [skipto] rule */ 447 /* 'next_rule' is used to pass up 'set_disable' status */ 448 449 u_int16_t act_ofs; /* offset of action in 32-bit units */ 450 u_int16_t cmd_len; /* # of 32-bit words in cmd */ 451 u_int16_t rulenum; /* rule number */ 452 u_int8_t set; /* rule set (0..31) */ 453#define RESVD_SET 31 /* set for default and persistent rules */ 454 u_int8_t _pad; /* padding */ 455 456 /* These fields are present in all rules. */ 457 u_int64_t pcnt; /* Packet counter */ 458 u_int64_t bcnt; /* Byte counter */ 459 u_int32_t timestamp; /* tv_sec of last match */ 460 461 ipfw_insn cmd[1]; /* storage for commands */ 462}; 463 464#define ACTION_PTR(rule) \ 465 (ipfw_insn *)( (u_int32_t *)((rule)->cmd) + ((rule)->act_ofs) ) 466 467#define RULESIZE(rule) (sizeof(struct ip_fw) + \ 468 ((struct ip_fw *)(rule))->cmd_len * 4 - 4) 469 470/* 471 * This structure is used as a flow mask and a flow id for various 472 * parts of the code. 473 */ 474struct ipfw_flow_id { 475 u_int32_t dst_ip; 476 u_int32_t src_ip; 477 u_int16_t dst_port; 478 u_int16_t src_port; 479 u_int8_t fib; 480 u_int8_t proto; 481 u_int8_t flags; /* protocol-specific flags */ 482 uint8_t addr_type; /* 4 = ipv4, 6 = ipv6, 1=ether ? */ 483 struct in6_addr dst_ip6; /* could also store MAC addr! */ 484 struct in6_addr src_ip6; 485 u_int32_t flow_id6; 486 u_int32_t frag_id6; 487}; 488 489#define IS_IP6_FLOW_ID(id) ((id)->addr_type == 6) 490 491/* 492 * Dynamic ipfw rule. 493 */ 494typedef struct _ipfw_dyn_rule ipfw_dyn_rule; 495 496struct _ipfw_dyn_rule { 497 ipfw_dyn_rule *next; /* linked list of rules. */ 498 struct ip_fw *rule; /* pointer to rule */ 499 /* 'rule' is used to pass up the rule number (from the parent) */ 500 501 ipfw_dyn_rule *parent; /* pointer to parent rule */ 502 u_int64_t pcnt; /* packet match counter */ 503 u_int64_t bcnt; /* byte match counter */ 504 struct ipfw_flow_id id; /* (masked) flow id */ 505 u_int32_t expire; /* expire time */ 506 u_int32_t bucket; /* which bucket in hash table */ 507 u_int32_t state; /* state of this rule (typically a 508 * combination of TCP flags) 509 */ 510 u_int32_t ack_fwd; /* most recent ACKs in forward */ 511 u_int32_t ack_rev; /* and reverse directions (used */ 512 /* to generate keepalives) */ 513 u_int16_t dyn_type; /* rule type */ 514 u_int16_t count; /* refcount */ 515}; 516 517/* 518 * Definitions for IP option names. 519 */ 520#define IP_FW_IPOPT_LSRR 0x01 521#define IP_FW_IPOPT_SSRR 0x02 522#define IP_FW_IPOPT_RR 0x04 523#define IP_FW_IPOPT_TS 0x08 524 525/* 526 * Definitions for TCP option names. 527 */ 528#define IP_FW_TCPOPT_MSS 0x01 529#define IP_FW_TCPOPT_WINDOW 0x02 530#define IP_FW_TCPOPT_SACK 0x04 531#define IP_FW_TCPOPT_TS 0x08 532#define IP_FW_TCPOPT_CC 0x10 533 534#define ICMP_REJECT_RST 0x100 /* fake ICMP code (send a TCP RST) */ 535#define ICMP6_UNREACH_RST 0x100 /* fake ICMPv6 code (send a TCP RST) */ 536 537/* 538 * These are used for lookup tables. 539 */ 540typedef struct _ipfw_table_entry { 541 in_addr_t addr; /* network address */ 542 u_int32_t value; /* value */ 543 u_int16_t tbl; /* table number */ 544 u_int8_t masklen; /* mask length */ 545} ipfw_table_entry; 546 547typedef struct _ipfw_table { 548 u_int32_t size; /* size of entries in bytes */ 549 u_int32_t cnt; /* # of entries */ 550 u_int16_t tbl; /* table number */ 551 ipfw_table_entry ent[0]; /* entries */ 552} ipfw_table; 553 554#define IP_FW_TABLEARG 65535 555 556/* 557 * Main firewall chains definitions and global var's definitions. 558 */ 559#ifdef _KERNEL 560 561/* Return values from ipfw_chk() */ 562enum { 563 IP_FW_PASS = 0, 564 IP_FW_DENY, 565 IP_FW_DIVERT, 566 IP_FW_TEE, 567 IP_FW_DUMMYNET, 568 IP_FW_NETGRAPH, 569 IP_FW_NGTEE, 570 IP_FW_NAT, 571}; 572 573/* flags for divert mtag */ 574#define IP_FW_DIVERT_LOOPBACK_FLAG 0x00080000 575#define IP_FW_DIVERT_OUTPUT_FLAG 0x00100000 576 577/* 578 * Structure for collecting parameters to dummynet for ip6_output forwarding 579 */ 580struct _ip6dn_args { 581 struct ip6_pktopts *opt_or; 582 struct route_in6 ro_or; 583 int flags_or; 584 struct ip6_moptions *im6o_or; 585 struct ifnet *origifp_or; 586 struct ifnet *ifp_or; 587 struct sockaddr_in6 dst_or; 588 u_long mtu_or; 589 struct route_in6 ro_pmtu_or; 590}; 591 592/* 593 * Arguments for calling ipfw_chk() and dummynet_io(). We put them 594 * all into a structure because this way it is easier and more 595 * efficient to pass variables around and extend the interface. 596 */ 597struct ip_fw_args { 598 struct mbuf *m; /* the mbuf chain */ 599 struct ifnet *oif; /* output interface */ 600 struct sockaddr_in *next_hop; /* forward address */ 601 struct ip_fw *rule; /* matching rule */ 602 struct ether_header *eh; /* for bridged packets */ 603 604 struct ipfw_flow_id f_id; /* grabbed from IP header */ 605 u_int32_t cookie; /* a cookie depending on rule action */ 606 struct inpcb *inp; 607 608 struct _ip6dn_args dummypar; /* dummynet->ip6_output */ 609 struct sockaddr_in hopstore; /* store here if cannot use a pointer */ 610}; 611 612/* 613 * Function definitions. 614 */ 615 616/* Firewall hooks */ 617struct sockopt; 618struct dn_flow_set; 619 620int ipfw_check_in(void *, struct mbuf **, struct ifnet *, int, struct inpcb *inp); 621int ipfw_check_out(void *, struct mbuf **, struct ifnet *, int, struct inpcb *inp); 622 623int ipfw_chk(struct ip_fw_args *); 624 625int ipfw_init(void); 626void ipfw_destroy(void); 627 628typedef int ip_fw_ctl_t(struct sockopt *); 629extern ip_fw_ctl_t *ip_fw_ctl_ptr; 630extern int fw_one_pass; 631extern int fw_enable; 632#ifdef INET6 633extern int fw6_enable; 634#endif 635 636/* For kernel ipfw_ether and ipfw_bridge. */ 637typedef int ip_fw_chk_t(struct ip_fw_args *args); 638extern ip_fw_chk_t *ip_fw_chk_ptr; 639#define IPFW_LOADED (ip_fw_chk_ptr != NULL) 640 641#ifdef IPFW_INTERNAL 642 643#define IPFW_TABLES_MAX 128 644struct ip_fw_chain { 645 struct ip_fw *rules; /* list of rules */ 646 struct ip_fw *reap; /* list of rules to reap */ 647 LIST_HEAD(, cfg_nat) nat; /* list of nat entries */ 648 struct radix_node_head *tables[IPFW_TABLES_MAX]; 649 struct rwlock rwmtx; 650}; 651#define IPFW_LOCK_INIT(_chain) \ 652 rw_init(&(_chain)->rwmtx, "IPFW static rules") 653#define IPFW_LOCK_DESTROY(_chain) rw_destroy(&(_chain)->rwmtx) 654#define IPFW_WLOCK_ASSERT(_chain) rw_assert(&(_chain)->rwmtx, RA_WLOCKED) 655 656#define IPFW_RLOCK(p) rw_rlock(&(p)->rwmtx) 657#define IPFW_RUNLOCK(p) rw_runlock(&(p)->rwmtx) 658#define IPFW_WLOCK(p) rw_wlock(&(p)->rwmtx) 659#define IPFW_WUNLOCK(p) rw_wunlock(&(p)->rwmtx) 660 661#define LOOKUP_NAT(l, i, p) do { \ 662 LIST_FOREACH((p), &(l.nat), _next) { \ 663 if ((p)->id == (i)) { \ 664 break; \ 665 } \ 666 } \ 667 } while (0) 668 669typedef int ipfw_nat_t(struct ip_fw_args *, struct cfg_nat *, struct mbuf *); 670typedef int ipfw_nat_cfg_t(struct sockopt *); 671#endif 672 673#endif /* _KERNEL */ 674#endif /* _IPFW2_H */ 675