1 /* $OpenBSD: pfvar.h,v 1.63 2002/02/14 23:53:32 dhartmei Exp $ */ 2 3 /* 4 * Copyright (c) 2001 Daniel Hartmeier 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * - Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * - Redistributions in binary form must reproduce the above 14 * copyright notice, this list of conditions and the following 15 * disclaimer in the documentation and/or other materials provided 16 * with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 * 31 */ 32 33 #ifndef _NET_PFVAR_H_ 34 #define _NET_PFVAR_H_ 35 36 #include <sys/types.h> 37 #include <sys/queue.h> 38 39 enum { PF_IN=0, PF_OUT=1 }; 40 enum { PF_PASS=0, PF_DROP=1, PF_SCRUB=2 }; 41 enum { PF_OP_IRG=1, PF_OP_EQ=2, PF_OP_NE=3, PF_OP_LT=4, 42 PF_OP_LE=5, PF_OP_GT=6, PF_OP_GE=7, PF_OP_XRG=8 }; 43 enum { PF_DEBUG_NONE=0, PF_DEBUG_URGENT=1, PF_DEBUG_MISC=2 }; 44 enum { PF_CHANGE_ADD_HEAD=1, PF_CHANGE_ADD_TAIL=2, 45 PF_CHANGE_ADD_BEFORE=3, PF_CHANGE_ADD_AFTER=4, 46 PF_CHANGE_REMOVE=5 }; 47 enum { PFTM_TCP_FIRST_PACKET=0, PFTM_TCP_OPENING=1, PFTM_TCP_ESTABLISHED=2, 48 PFTM_TCP_CLOSING=3, PFTM_TCP_FIN_WAIT=4, PFTM_TCP_CLOSED=5, 49 PFTM_UDP_FIRST_PACKET=6, PFTM_UDP_SINGLE=7, PFTM_UDP_MULTIPLE=8, 50 PFTM_ICMP_FIRST_PACKET=9, PFTM_ICMP_ERROR_REPLY=10, 51 PFTM_OTHER_FIRST_PACKET=11, PFTM_OTHER_SINGLE=12, 52 PFTM_OTHER_MULTIPLE=13, PFTM_FRAG=14, PFTM_INTERVAL=15, PFTM_MAX=16 }; 53 enum { PF_FASTROUTE=1, PF_ROUTETO=2, PF_DUPTO=3 }; 54 55 struct pf_addr { 56 union { 57 struct in_addr v4; 58 struct in6_addr v6; 59 u_int8_t addr8[16]; 60 u_int16_t addr16[8]; 61 u_int32_t addr32[4]; 62 } pfa; /* 128-bit address */ 63 #define v4 pfa.v4 64 #define v6 pfa.v6 65 #define addr8 pfa.addr8 66 #define addr16 pfa.addr16 67 #define addr32 pfa.addr32 68 }; 69 70 /* 71 * Address manipulation macros 72 */ 73 74 #ifdef _KERNEL 75 76 #ifdef INET 77 #ifndef INET6 78 #define PF_INET_ONLY 79 #endif /* ! INET6 */ 80 #endif /* INET */ 81 82 #ifdef INET6 83 #ifndef INET 84 #define PF_INET6_ONLY 85 #endif /* ! INET */ 86 #endif /* INET6 */ 87 88 #ifdef INET 89 #ifdef INET6 90 #define PF_INET_INET6 91 #endif /* INET6 */ 92 #endif /* INET */ 93 94 #else 95 96 #define PF_INET_INET6 97 98 #endif /* _KERNEL */ 99 100 /* Both IPv4 and IPv6 */ 101 #ifdef PF_INET_INET6 102 103 #define PF_AEQ(a, b, c) \ 104 ((c == AF_INET && (a)->addr32[0] == (b)->addr32[0]) || \ 105 (c == AF_INET6 && (a)->addr32[0] == (b)->addr32[0] && \ 106 (a)->addr32[1] == (b)->addr32[1] && \ 107 (a)->addr32[2] == (b)->addr32[2] && \ 108 (a)->addr32[3] == (b)->addr32[3])) \ 109 110 #define PF_ANEQ(a, b, c) \ 111 ((c == AF_INET && (a)->addr32[0] != (b)->addr32[0]) || \ 112 (c == AF_INET6 && ((a)->addr32[0] != (b)->addr32[0] || \ 113 (a)->addr32[1] != (b)->addr32[1] || \ 114 (a)->addr32[2] != (b)->addr32[2] || \ 115 (a)->addr32[3] != (b)->addr32[3]))) \ 116 117 #define PF_AZERO(a, c) \ 118 ((c == AF_INET && !(a)->addr32[0]) || \ 119 (c == AF_INET6 && !(a)->addr32[0] && \ 120 !(a)->addr32[1] && !(a)->addr32[2] && \ 121 !(a)->addr32[3] )) \ 122 123 #define PF_MATCHA(n, a, m, b, f) \ 124 pf_match_addr(n, a, m, b, f) 125 126 #define PF_ACPY(a, b, f) \ 127 pf_addrcpy(a, b, f) 128 129 #else 130 131 /* Just IPv6 */ 132 #ifdef PF_INET6_ONLY 133 134 #define PF_AEQ(a, b, c) \ 135 ((a)->addr32[0] == (b)->addr32[0] && \ 136 (a)->addr32[1] == (b)->addr32[1] && \ 137 (a)->addr32[2] == (b)->addr32[2] && \ 138 (a)->addr32[3] == (b)->addr32[3]) \ 139 140 #define PF_ANEQ(a, b, c) \ 141 ((a)->addr32[0] != (b)->addr32[0] || \ 142 (a)->addr32[1] != (b)->addr32[1] || \ 143 (a)->addr32[2] != (b)->addr32[2] || \ 144 (a)->addr32[3] != (b)->addr32[3]) \ 145 146 #define PF_AZERO(a, c) \ 147 (!(a)->addr32[0] && \ 148 !(a)->addr32[1] && \ 149 !(a)->addr32[2] && \ 150 !(a)->addr32[3] ) \ 151 152 #define PF_MATCHA(n, a, m, b, f) \ 153 pf_match_addr(n, a, m, b, f) 154 155 #define PF_ACPY(a, b, f) \ 156 pf_addrcpy(a, b, f) 157 158 #else 159 160 /* Just IPv4 */ 161 #ifdef PF_INET_ONLY 162 163 #define PF_AEQ(a, b, c) \ 164 ((a)->addr32[0] == (b)->addr32[0]) 165 166 #define PF_ANEQ(a, b, c) \ 167 ((a)->addr32[0] != (b)->addr32[0]) 168 169 #define PF_AZERO(a, c) \ 170 (!(a)->addr32[0]) 171 172 #define PF_MATCHA(n, a, m, b, f) \ 173 pf_match_addr(n, a, m, b, f) 174 175 #define PF_ACPY(a, b, f) \ 176 (a)->v4.s_addr = (b)->v4.s_addr 177 178 179 #endif /* PF_INET_ONLY */ 180 #endif /* PF_INET6_ONLY */ 181 #endif /* PF_INET_INET6 */ 182 183 struct pf_rule_addr { 184 struct pf_addr addr; 185 struct pf_addr mask; 186 u_int16_t port[2]; 187 u_int8_t not; 188 u_int8_t port_op; 189 }; 190 191 struct pf_rule { 192 char ifname[IFNAMSIZ]; 193 char rt_ifname[IFNAMSIZ]; 194 #define PF_RULE_LABEL_SIZE 32 195 char label[PF_RULE_LABEL_SIZE]; 196 struct ifnet *ifp; 197 struct ifnet *rt_ifp; 198 struct pf_rule_addr src; 199 struct pf_rule_addr dst; 200 struct pf_addr rt_addr; 201 202 #define PF_SKIP_ACTION 0 203 #define PF_SKIP_IFP 1 204 #define PF_SKIP_DIR 2 205 #define PF_SKIP_AF 3 206 #define PF_SKIP_PROTO 4 207 #define PF_SKIP_SRC_ADDR 5 208 #define PF_SKIP_SRC_PORT 6 209 #define PF_SKIP_DST_ADDR 7 210 #define PF_SKIP_DST_PORT 8 211 #define PF_SKIP_COUNT 9 212 struct pf_rule *skip[PF_SKIP_COUNT]; 213 TAILQ_ENTRY(pf_rule) entries; 214 215 u_int64_t evaluations; 216 u_int64_t packets; 217 u_int64_t bytes; 218 219 u_int16_t nr; 220 u_int16_t return_icmp; 221 222 u_int8_t action; 223 u_int8_t direction; 224 u_int8_t log; 225 u_int8_t quick; 226 227 #define PF_STATE_NORMAL 0x1 228 #define PF_STATE_MODULATE 0x2 229 u_int8_t keep_state; 230 u_int8_t af; 231 u_int8_t proto; 232 u_int8_t type; 233 u_int8_t code; 234 235 u_int8_t flags; 236 u_int8_t flagset; 237 238 u_int8_t rule_flag; 239 u_int8_t min_ttl; /* minimum ttl for packet normalize */ 240 u_int8_t allow_opts; 241 u_int8_t rt; 242 }; 243 244 #define PFRULE_RETURNRST 0x01 245 #define PFRULE_NODF 0x02 246 247 struct pf_state_host { 248 struct pf_addr addr; 249 u_int16_t port; 250 u_int16_t pad; 251 }; 252 253 struct pf_state_peer { 254 u_int32_t seqlo; /* Max sequence number sent */ 255 u_int32_t seqhi; /* Max the other end ACKd + win */ 256 u_int32_t seqdiff; /* Sequence number modulator */ 257 u_int16_t max_win; 258 u_int8_t state; 259 u_int8_t pad; 260 }; 261 262 struct pf_state { 263 TAILQ_ENTRY(pf_state) entries; 264 struct pf_state_host lan; 265 struct pf_state_host gwy; 266 struct pf_state_host ext; 267 struct pf_state_peer src; 268 struct pf_state_peer dst; 269 struct pf_rule *rule; 270 u_int32_t creation; 271 u_int32_t expire; 272 u_int32_t packets; 273 u_int32_t bytes; 274 u_int8_t af; 275 u_int8_t proto; 276 u_int8_t direction; 277 u_int8_t log; 278 u_int8_t allow_opts; 279 }; 280 281 struct pf_nat { 282 char ifname[IFNAMSIZ]; 283 struct ifnet *ifp; 284 TAILQ_ENTRY(pf_nat) entries; 285 struct pf_addr saddr; 286 struct pf_addr smask; 287 struct pf_addr daddr; 288 struct pf_addr dmask; 289 struct pf_addr raddr; 290 u_int8_t af; 291 u_int8_t proto; 292 u_int8_t snot; 293 u_int8_t dnot; 294 u_int8_t ifnot; 295 u_int8_t no; 296 }; 297 298 struct pf_binat { 299 char ifname[IFNAMSIZ]; 300 struct ifnet *ifp; 301 TAILQ_ENTRY(pf_binat) entries; 302 struct pf_addr saddr; 303 struct pf_addr daddr; 304 struct pf_addr dmask; 305 struct pf_addr raddr; 306 u_int8_t af; 307 u_int8_t proto; 308 u_int8_t dnot; 309 u_int8_t no; 310 }; 311 312 struct pf_rdr { 313 char ifname[IFNAMSIZ]; 314 struct ifnet *ifp; 315 TAILQ_ENTRY(pf_rdr) entries; 316 struct pf_addr saddr; 317 struct pf_addr smask; 318 struct pf_addr daddr; 319 struct pf_addr dmask; 320 struct pf_addr raddr; 321 u_int16_t dport; 322 u_int16_t dport2; 323 u_int16_t rport; 324 u_int8_t af; 325 u_int8_t proto; 326 u_int8_t snot; 327 u_int8_t dnot; 328 u_int8_t ifnot; 329 u_int8_t opts; 330 u_int8_t no; 331 }; 332 333 struct pf_tree_key { 334 struct pf_addr addr[2]; 335 u_int16_t port[2]; 336 u_int8_t proto; 337 u_int8_t af; 338 }; 339 340 TAILQ_HEAD(pf_rulequeue, pf_rule); 341 342 struct pf_pdesc { 343 u_int64_t tot_len; /* Make Mickey money */ 344 union { 345 struct tcphdr *tcp; 346 struct udphdr *udp; 347 struct icmp *icmp; 348 #ifdef INET6 349 struct icmp6_hdr *icmp6; 350 #endif /* INET6 */ 351 void *any; 352 } hdr; 353 struct pf_addr *src; 354 struct pf_addr *dst; 355 u_int16_t *ip_sum; 356 u_int32_t p_len; /* total length of payload */ 357 u_int16_t flags; /* Let SCRUB trigger behavior in 358 * state code. Easier than tags */ 359 u_int8_t af; 360 u_int8_t proto; 361 }; 362 363 /* flags for RDR options */ 364 #define PF_DPORT_RANGE 0x01 /* Dest port uses range */ 365 #define PF_RPORT_RANGE 0x02 /* RDR'ed port uses range */ 366 367 /* Reasons code for passing/dropping a packet */ 368 #define PFRES_MATCH 0 /* Explicit match of a rule */ 369 #define PFRES_BADOFF 1 /* Bad offset for pull_hdr */ 370 #define PFRES_FRAG 2 /* Dropping following fragment */ 371 #define PFRES_SHORT 3 /* Dropping short packet */ 372 #define PFRES_NORM 4 /* Dropping by normalizer */ 373 #define PFRES_MEMORY 5 /* Dropped due to lacking mem */ 374 #define PFRES_MAX 6 /* total+1 */ 375 376 #define PFRES_NAMES { \ 377 "match", \ 378 "bad-offset", \ 379 "fragment", \ 380 "short", \ 381 "normalize", \ 382 "memory", \ 383 NULL \ 384 } 385 386 #define FCNT_STATE_SEARCH 0 387 #define FCNT_STATE_INSERT 1 388 #define FCNT_STATE_REMOVALS 2 389 #define FCNT_MAX 3 390 391 #define FCNT_NAMES { \ 392 "state searches", \ 393 "state inserts", \ 394 "state removals", \ 395 NULL \ 396 } 397 398 #define ACTION_SET(a, x) \ 399 do { \ 400 if ((a) != NULL) \ 401 *(a) = (x); \ 402 } while (0) 403 404 #define REASON_SET(a, x) \ 405 do { \ 406 if ((a) != NULL) \ 407 *(a) = (x); \ 408 if (x < PFRES_MAX) \ 409 pf_status.counters[x]++; \ 410 } while (0) 411 412 struct pf_status { 413 u_int64_t counters[PFRES_MAX]; 414 u_int64_t fcounters[FCNT_MAX]; 415 u_int64_t pcounters[2][2][3]; 416 u_int64_t bcounters[2][2]; 417 u_int32_t running; 418 u_int32_t states; 419 u_int32_t since; 420 u_int32_t debug; 421 }; 422 423 /* 424 * ioctl parameter structures 425 */ 426 427 struct pfioc_rule { 428 u_int32_t ticket; 429 u_int32_t nr; 430 struct pf_rule rule; 431 }; 432 433 struct pfioc_changerule { 434 u_int32_t action; 435 struct pf_rule oldrule; 436 struct pf_rule newrule; 437 }; 438 439 struct pfioc_nat { 440 u_int32_t ticket; 441 u_int32_t nr; 442 struct pf_nat nat; 443 }; 444 445 struct pfioc_changenat { 446 u_int32_t action; 447 struct pf_nat oldnat; 448 struct pf_nat newnat; 449 }; 450 451 struct pfioc_natlook { 452 struct pf_addr saddr; 453 struct pf_addr daddr; 454 struct pf_addr rsaddr; 455 struct pf_addr rdaddr; 456 u_int16_t sport; 457 u_int16_t dport; 458 u_int16_t rsport; 459 u_int16_t rdport; 460 u_int8_t af; 461 u_int8_t proto; 462 u_int8_t direction; 463 }; 464 465 struct pfioc_binat { 466 u_int32_t ticket; 467 u_int32_t nr; 468 struct pf_binat binat; 469 }; 470 471 struct pfioc_changebinat { 472 u_int32_t action; 473 struct pf_binat oldbinat; 474 struct pf_binat newbinat; 475 }; 476 477 struct pfioc_rdr { 478 u_int32_t ticket; 479 u_int32_t nr; 480 struct pf_rdr rdr; 481 }; 482 483 struct pfioc_changerdr { 484 u_int32_t action; 485 struct pf_rdr oldrdr; 486 struct pf_rdr newrdr; 487 }; 488 489 struct pfioc_state { 490 u_int32_t nr; 491 struct pf_state state; 492 }; 493 494 struct pfioc_states { 495 int ps_len; 496 union { 497 caddr_t psu_buf; 498 struct pf_state *psu_states; 499 } ps_u; 500 #define ps_buf ps_u.psu_buf 501 #define ps_states ps_u.psu_states 502 }; 503 504 struct pfioc_if { 505 char ifname[IFNAMSIZ]; 506 }; 507 508 struct pfioc_tm { 509 int timeout; 510 int seconds; 511 }; 512 513 /* 514 * ioctl operations 515 */ 516 517 #define DIOCSTART _IO ('D', 1) 518 #define DIOCSTOP _IO ('D', 2) 519 #define DIOCBEGINRULES _IOWR('D', 3, u_int32_t) 520 #define DIOCADDRULE _IOWR('D', 4, struct pfioc_rule) 521 #define DIOCCOMMITRULES _IOWR('D', 5, u_int32_t) 522 #define DIOCGETRULES _IOWR('D', 6, struct pfioc_rule) 523 #define DIOCGETRULE _IOWR('D', 7, struct pfioc_rule) 524 #define DIOCBEGINNATS _IOWR('D', 8, u_int32_t) 525 #define DIOCADDNAT _IOWR('D', 9, struct pfioc_nat) 526 #define DIOCCOMMITNATS _IOWR('D', 10, u_int32_t) 527 #define DIOCGETNATS _IOWR('D', 11, struct pfioc_nat) 528 #define DIOCGETNAT _IOWR('D', 12, struct pfioc_nat) 529 #define DIOCBEGINRDRS _IOWR('D', 13, u_int32_t) 530 #define DIOCADDRDR _IOWR('D', 14, struct pfioc_rdr) 531 #define DIOCCOMMITRDRS _IOWR('D', 15, u_int32_t) 532 #define DIOCGETRDRS _IOWR('D', 16, struct pfioc_rdr) 533 #define DIOCGETRDR _IOWR('D', 17, struct pfioc_rdr) 534 #define DIOCCLRSTATES _IO ('D', 18) 535 #define DIOCGETSTATE _IOWR('D', 19, struct pfioc_state) 536 #define DIOCSETSTATUSIF _IOWR('D', 20, struct pfioc_if) 537 #define DIOCGETSTATUS _IOWR('D', 21, struct pf_status) 538 #define DIOCCLRSTATUS _IO ('D', 22) 539 #define DIOCNATLOOK _IOWR('D', 23, struct pfioc_natlook) 540 #define DIOCSETDEBUG _IOWR('D', 24, u_int32_t) 541 #define DIOCGETSTATES _IOWR('D', 25, struct pfioc_states) 542 #define DIOCCHANGERULE _IOWR('D', 26, struct pfioc_changerule) 543 #define DIOCCHANGENAT _IOWR('D', 27, struct pfioc_changenat) 544 #define DIOCCHANGERDR _IOWR('D', 28, struct pfioc_changerdr) 545 #define DIOCSETTIMEOUT _IOWR('D', 29, struct pfioc_tm) 546 #define DIOCGETTIMEOUT _IOWR('D', 30, struct pfioc_tm) 547 #define DIOCBEGINBINATS _IOWR('D', 31, u_int32_t) 548 #define DIOCADDBINAT _IOWR('D', 32, struct pfioc_binat) 549 #define DIOCCOMMITBINATS _IOWR('D', 33, u_int32_t) 550 #define DIOCGETBINATS _IOWR('D', 34, struct pfioc_binat) 551 #define DIOCGETBINAT _IOWR('D', 35, struct pfioc_binat) 552 #define DIOCCHANGEBINAT _IOWR('D', 36, struct pfioc_changebinat) 553 #define DIOCADDSTATE _IOWR('D', 37, struct pfioc_state) 554 #define DIOCCLRRULECTRS _IO ('D', 38) 555 556 #ifdef _KERNEL 557 558 #ifdef INET 559 int pf_test(int, struct ifnet *, struct mbuf **); 560 #endif /* INET */ 561 562 #ifdef INET6 563 int pf_test6(int, struct ifnet *, struct mbuf **); 564 #endif /* INET */ 565 566 struct pf_tree_node; 567 struct pf_state 568 *pf_find_state(struct pf_tree_node *, struct pf_tree_key *); 569 int pf_tree_insert(struct pf_tree_node **, struct pf_tree_node *, 570 struct pf_tree_key *, struct pf_state *); 571 int pf_tree_remove(struct pf_tree_node **, struct pf_tree_node *, 572 struct pf_tree_key *); 573 574 int pflog_packet(struct ifnet *, struct mbuf *, int, u_short, u_short, 575 struct pf_rule *); 576 int pf_match_addr(u_int8_t, struct pf_addr *, struct pf_addr *, 577 struct pf_addr *, int); 578 int pf_match_port(u_int8_t, u_int16_t, u_int16_t, u_int16_t); 579 580 void pf_normalize_init(void); 581 int pf_normalize_ip(struct mbuf **, int, struct ifnet *, u_short *); 582 void pf_purge_expired_fragments(void); 583 584 extern struct pf_rulequeue *pf_rules_active; 585 extern struct pf_status pf_status; 586 #endif /* _KERNEL */ 587 588 #endif /* _NET_PFVAR_H_ */ 589