1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2001 Daniel Hartmeier 5 * Copyright (c) 2002 - 2008 Henning Brauer 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * - Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * - Redistributions in binary form must reproduce the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer in the documentation and/or other materials provided 17 * with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 23 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 25 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 29 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 * 32 * Effort sponsored in part by the Defense Advanced Research Projects 33 * Agency (DARPA) and Air Force Research Laboratory, Air Force 34 * Materiel Command, USAF, under agreement number F30602-01-2-0537. 35 * 36 * $OpenBSD: pf_lb.c,v 1.2 2009/02/12 02:13:15 sthen Exp $ 37 */ 38 39 #include <sys/cdefs.h> 40 #include "opt_pf.h" 41 #include "opt_inet.h" 42 #include "opt_inet6.h" 43 44 #include <sys/param.h> 45 #include <sys/lock.h> 46 #include <sys/mbuf.h> 47 #include <sys/socket.h> 48 #include <sys/sysctl.h> 49 50 #include <crypto/siphash/siphash.h> 51 52 #include <net/if.h> 53 #include <net/if_var.h> 54 #include <net/vnet.h> 55 #include <net/pfvar.h> 56 #include <net/if_pflog.h> 57 58 #ifdef INET 59 #include <netinet/in_var.h> 60 #endif /* INET */ 61 62 #ifdef INET6 63 #include <netinet6/in6_var.h> 64 #endif /* INET6 */ 65 66 67 /* 68 * Limit the amount of work we do to find a free source port for redirects that 69 * introduce a state conflict. 70 */ 71 #define V_pf_rdr_srcport_rewrite_tries VNET(pf_rdr_srcport_rewrite_tries) 72 VNET_DEFINE_STATIC(int, pf_rdr_srcport_rewrite_tries) = 16; 73 74 #define DPFPRINTF(n, x) if (V_pf_status.debug >= (n)) printf x 75 76 static uint64_t pf_hash(struct pf_addr *, struct pf_addr *, 77 struct pf_poolhashkey *, sa_family_t); 78 struct pf_krule *pf_match_translation(int, struct pf_test_ctx *); 79 static enum pf_test_status pf_step_into_translation_anchor(int, struct pf_test_ctx *, 80 struct pf_krule *); 81 static int pf_get_sport(struct pf_pdesc *, struct pf_krule *, 82 struct pf_addr *, uint16_t *, uint16_t, uint16_t, 83 struct pf_ksrc_node **, struct pf_srchash **, 84 struct pf_kpool *, struct pf_udp_mapping **, 85 pf_sn_types_t); 86 static bool pf_islinklocal(const sa_family_t, const struct pf_addr *); 87 88 static uint64_t 89 pf_hash(struct pf_addr *inaddr, struct pf_addr *hash, 90 struct pf_poolhashkey *key, sa_family_t af) 91 { 92 SIPHASH_CTX ctx; 93 #ifdef INET6 94 union { 95 uint64_t hash64; 96 uint32_t hash32[2]; 97 } h; 98 #endif /* INET6 */ 99 uint64_t res = 0; 100 101 _Static_assert(sizeof(*key) >= SIPHASH_KEY_LENGTH, ""); 102 103 switch (af) { 104 #ifdef INET 105 case AF_INET: 106 res = SipHash24(&ctx, (const uint8_t *)key, 107 &inaddr->addr32[0], sizeof(inaddr->addr32[0])); 108 hash->addr32[0] = res; 109 break; 110 #endif /* INET */ 111 #ifdef INET6 112 case AF_INET6: 113 res = SipHash24(&ctx, (const uint8_t *)key, 114 &inaddr->addr32[0], 4 * sizeof(inaddr->addr32[0])); 115 h.hash64 = res; 116 hash->addr32[0] = h.hash32[0]; 117 hash->addr32[1] = h.hash32[1]; 118 /* 119 * siphash isn't big enough, but flipping it around is 120 * good enough here. 121 */ 122 hash->addr32[2] = ~h.hash32[1]; 123 hash->addr32[3] = ~h.hash32[0]; 124 break; 125 #endif /* INET6 */ 126 default: 127 unhandled_af(af); 128 } 129 return (res); 130 } 131 132 #define PF_TEST_ATTRIB(t, a) \ 133 if (t) { \ 134 r = a; \ 135 continue; \ 136 } else do { \ 137 } while (0) 138 139 static enum pf_test_status 140 pf_match_translation_rule(int rs_num, struct pf_test_ctx *ctx, struct pf_kruleset *ruleset) 141 { 142 struct pf_krule *r; 143 struct pf_pdesc *pd = ctx->pd; 144 int rtableid = -1; 145 146 r = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr); 147 while (r != NULL) { 148 struct pf_rule_addr *src = NULL, *dst = NULL; 149 struct pf_addr_wrap *xdst = NULL; 150 151 if (r->action == PF_BINAT && pd->dir == PF_IN) { 152 src = &r->dst; 153 if (r->rdr.cur != NULL) 154 xdst = &r->rdr.cur->addr; 155 } else { 156 src = &r->src; 157 dst = &r->dst; 158 } 159 160 pf_counter_u64_add(&r->evaluations, 1); 161 PF_TEST_ATTRIB(pfi_kkif_match(r->kif, pd->kif) == r->ifnot, 162 r->skip[PF_SKIP_IFP]); 163 PF_TEST_ATTRIB(r->direction && r->direction != pd->dir, 164 r->skip[PF_SKIP_DIR]); 165 PF_TEST_ATTRIB(r->af && r->af != pd->af, 166 r->skip[PF_SKIP_AF]); 167 PF_TEST_ATTRIB(r->proto && r->proto != pd->proto, 168 r->skip[PF_SKIP_PROTO]); 169 PF_TEST_ATTRIB(PF_MISMATCHAW(&src->addr, &pd->nsaddr, pd->af, 170 src->neg, pd->kif, M_GETFIB(pd->m)), 171 r->skip[src == &r->src ? PF_SKIP_SRC_ADDR : 172 PF_SKIP_DST_ADDR]); 173 PF_TEST_ATTRIB(src->port_op && !pf_match_port(src->port_op, 174 src->port[0], src->port[1], pd->nsport), 175 r->skip[src == &r->src ? PF_SKIP_SRC_PORT : 176 PF_SKIP_DST_PORT]); 177 PF_TEST_ATTRIB(dst != NULL && 178 PF_MISMATCHAW(&dst->addr, &pd->ndaddr, pd->af, dst->neg, NULL, 179 M_GETFIB(pd->m)), 180 r->skip[PF_SKIP_DST_ADDR]); 181 PF_TEST_ATTRIB(xdst != NULL && PF_MISMATCHAW(xdst, &pd->ndaddr, pd->af, 182 0, NULL, M_GETFIB(pd->m)), 183 TAILQ_NEXT(r, entries)); 184 PF_TEST_ATTRIB(dst != NULL && dst->port_op && 185 !pf_match_port(dst->port_op, dst->port[0], 186 dst->port[1], pd->ndport), 187 r->skip[PF_SKIP_DST_PORT]); 188 PF_TEST_ATTRIB(r->match_tag && !pf_match_tag(pd->m, r, &ctx->tag, 189 pd->pf_mtag ? pd->pf_mtag->tag : 0), 190 TAILQ_NEXT(r, entries)); 191 PF_TEST_ATTRIB(r->os_fingerprint != PF_OSFP_ANY && (pd->proto != 192 IPPROTO_TCP || !pf_osfp_match(pf_osfp_fingerprint(pd, 193 &pd->hdr.tcp), r->os_fingerprint)), 194 TAILQ_NEXT(r, entries)); 195 if (r->tag) 196 ctx->tag = r->tag; 197 if (r->rtableid >= 0) 198 rtableid = r->rtableid; 199 if (r->anchor == NULL) { 200 if (r->action == PF_NONAT || 201 r->action == PF_NORDR || 202 r->action == PF_NOBINAT) { 203 *ctx->rm = NULL; 204 } else { 205 /* 206 * found matching r 207 */ 208 ctx->tr = r; 209 /* 210 * anchor, with ruleset, where r belongs to 211 */ 212 *ctx->am = ctx->a; 213 /* 214 * ruleset where r belongs to 215 */ 216 *ctx->rsm = ruleset; 217 /* 218 * ruleset, where anchor belongs to. 219 */ 220 ctx->arsm = ctx->aruleset; 221 } 222 } else { 223 ctx->a = r; /* remember anchor */ 224 ctx->aruleset = ruleset; /* and its ruleset */ 225 if (pf_step_into_translation_anchor(rs_num, ctx, 226 r) != PF_TEST_OK) { 227 break; 228 } 229 } 230 r = TAILQ_NEXT(r, entries); 231 } 232 233 if (ctx->tag > 0 && pf_tag_packet(pd, ctx->tag)) 234 return (PF_TEST_FAIL); 235 if (rtableid >= 0) 236 M_SETFIB(pd->m, rtableid); 237 238 return (PF_TEST_OK); 239 } 240 241 static enum pf_test_status 242 pf_step_into_translation_anchor(int rs_num, struct pf_test_ctx *ctx, struct pf_krule *r) 243 { 244 enum pf_test_status rv; 245 246 PF_RULES_RASSERT(); 247 248 if (ctx->depth >= PF_ANCHOR_STACK_MAX) { 249 printf("%s: anchor stack overflow on %s\n", 250 __func__, r->anchor->name); 251 return (PF_TEST_FAIL); 252 } 253 254 ctx->depth++; 255 256 if (r->anchor_wildcard) { 257 struct pf_kanchor *child; 258 rv = PF_TEST_OK; 259 RB_FOREACH(child, pf_kanchor_node, &r->anchor->children) { 260 rv = pf_match_translation_rule(rs_num, ctx, &child->ruleset); 261 if ((rv == PF_TEST_QUICK) || (rv == PF_TEST_FAIL)) { 262 /* 263 * we either hit a rule qith quick action 264 * (more likely), or hit some runtime 265 * error (e.g. pool_get() faillure). 266 */ 267 break; 268 } 269 } 270 } else { 271 rv = pf_match_translation_rule(rs_num, ctx, &r->anchor->ruleset); 272 } 273 274 ctx->depth--; 275 276 return (rv); 277 } 278 279 struct pf_krule * 280 pf_match_translation(int rs_num, struct pf_test_ctx *ctx) 281 { 282 enum pf_test_status rv; 283 284 MPASS(ctx->depth == 0); 285 rv = pf_match_translation_rule(rs_num, ctx, &pf_main_ruleset); 286 MPASS(ctx->depth == 0); 287 if (rv != PF_TEST_OK) 288 return (NULL); 289 290 return (ctx->tr); 291 } 292 293 static int 294 pf_get_sport(struct pf_pdesc *pd, struct pf_krule *r, 295 struct pf_addr *naddr, uint16_t *nport, uint16_t low, 296 uint16_t high, struct pf_ksrc_node **sn, 297 struct pf_srchash **sh, struct pf_kpool *rpool, 298 struct pf_udp_mapping **udp_mapping, pf_sn_types_t sn_type) 299 { 300 struct pf_state_key_cmp key; 301 struct pf_addr init_addr; 302 int dir = (pd->dir == PF_IN) ? PF_OUT : PF_IN; 303 int sidx = pd->sidx; 304 int didx = pd->didx; 305 306 bzero(&init_addr, sizeof(init_addr)); 307 308 if (udp_mapping) { 309 MPASS(*udp_mapping == NULL); 310 } 311 312 /* 313 * If we are UDP and have an existing mapping we can get source port 314 * from the mapping. In this case we have to look up the src_node as 315 * pf_map_addr would. 316 */ 317 if (pd->proto == IPPROTO_UDP && (rpool->opts & PF_POOL_ENDPI)) { 318 struct pf_udp_endpoint_cmp udp_source; 319 320 bzero(&udp_source, sizeof(udp_source)); 321 udp_source.af = pd->af; 322 pf_addrcpy(&udp_source.addr, &pd->nsaddr, pd->af); 323 udp_source.port = pd->nsport; 324 if (udp_mapping) { 325 *udp_mapping = pf_udp_mapping_find(&udp_source); 326 if (*udp_mapping) { 327 pf_addrcpy(naddr, 328 &(*udp_mapping)->endpoints[1].addr, 329 pd->af); 330 *nport = (*udp_mapping)->endpoints[1].port; 331 /* Try to find a src_node as per pf_map_addr(). */ 332 if (*sn == NULL && rpool->opts & PF_POOL_STICKYADDR && 333 (rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) 334 *sn = pf_find_src_node(&pd->nsaddr, r, 335 pd->af, sh, sn_type, false); 336 if (*sn != NULL) 337 PF_SRC_NODE_UNLOCK(*sn); 338 return (0); 339 } else { 340 *udp_mapping = pf_udp_mapping_create(pd->af, &pd->nsaddr, 341 pd->nsport, &init_addr, 0); 342 if (*udp_mapping == NULL) 343 return (1); 344 } 345 } 346 } 347 348 if (pf_map_addr_sn(pd->naf, r, &pd->nsaddr, naddr, NULL, &init_addr, 349 sn, sh, rpool, sn_type)) 350 goto failed; 351 352 if (pd->proto == IPPROTO_ICMP) { 353 if (pd->ndport == htons(ICMP_ECHO)) { 354 low = 1; 355 high = 65535; 356 } else 357 return (0); /* Don't try to modify non-echo ICMP */ 358 } 359 #ifdef INET6 360 if (pd->proto == IPPROTO_ICMPV6) { 361 if (pd->ndport == htons(ICMP6_ECHO_REQUEST)) { 362 low = 1; 363 high = 65535; 364 } else 365 return (0); /* Don't try to modify non-echo ICMP */ 366 } 367 #endif /* INET6 */ 368 369 bzero(&key, sizeof(key)); 370 key.af = pd->naf; 371 key.proto = pd->proto; 372 373 do { 374 pf_addrcpy(&key.addr[didx], &pd->ndaddr, key.af); 375 pf_addrcpy(&key.addr[sidx], naddr, key.af); 376 key.port[didx] = pd->ndport; 377 378 if (udp_mapping && *udp_mapping) 379 pf_addrcpy(&(*udp_mapping)->endpoints[1].addr, naddr, 380 pd->af); 381 382 /* 383 * port search; start random, step; 384 * similar 2 portloop in in_pcbbind 385 */ 386 if (pd->proto == IPPROTO_SCTP) { 387 key.port[sidx] = pd->nsport; 388 if (!pf_find_state_all_exists(&key, dir)) { 389 *nport = pd->nsport; 390 return (0); 391 } else { 392 return (1); /* Fail mapping. */ 393 } 394 } else if (!(pd->proto == IPPROTO_TCP || pd->proto == IPPROTO_UDP || 395 pd->proto == IPPROTO_ICMP) || (low == 0 && high == 0)) { 396 /* 397 * XXX bug: icmp states don't use the id on both sides. 398 * (traceroute -I through nat) 399 */ 400 key.port[sidx] = pd->nsport; 401 if (!pf_find_state_all_exists(&key, dir)) { 402 *nport = pd->nsport; 403 return (0); 404 } 405 } else if (low == high) { 406 key.port[sidx] = htons(low); 407 if (!pf_find_state_all_exists(&key, dir)) { 408 if (udp_mapping && *udp_mapping != NULL) { 409 (*udp_mapping)->endpoints[1].port = htons(low); 410 if (pf_udp_mapping_insert(*udp_mapping) == 0) { 411 *nport = htons(low); 412 return (0); 413 } 414 } else { 415 *nport = htons(low); 416 return (0); 417 } 418 } 419 } else { 420 uint32_t tmp; 421 uint16_t cut; 422 423 if (low > high) { 424 tmp = low; 425 low = high; 426 high = tmp; 427 } 428 /* low < high */ 429 cut = arc4random() % (1 + high - low) + low; 430 /* low <= cut <= high */ 431 for (tmp = cut; tmp <= high && tmp <= 0xffff; ++tmp) { 432 if (udp_mapping && *udp_mapping != NULL) { 433 (*udp_mapping)->endpoints[sidx].port = htons(tmp); 434 if (pf_udp_mapping_insert(*udp_mapping) == 0) { 435 *nport = htons(tmp); 436 return (0); 437 } 438 } else { 439 key.port[sidx] = htons(tmp); 440 if (!pf_find_state_all_exists(&key, dir)) { 441 *nport = htons(tmp); 442 return (0); 443 } 444 } 445 } 446 tmp = cut; 447 for (tmp -= 1; tmp >= low && tmp <= 0xffff; --tmp) { 448 if (pd->proto == IPPROTO_UDP && 449 (rpool->opts & PF_POOL_ENDPI && 450 udp_mapping != NULL)) { 451 (*udp_mapping)->endpoints[1].port = htons(tmp); 452 if (pf_udp_mapping_insert(*udp_mapping) == 0) { 453 *nport = htons(tmp); 454 return (0); 455 } 456 } else { 457 key.port[sidx] = htons(tmp); 458 if (!pf_find_state_all_exists(&key, dir)) { 459 *nport = htons(tmp); 460 return (0); 461 } 462 } 463 } 464 } 465 466 switch (rpool->opts & PF_POOL_TYPEMASK) { 467 case PF_POOL_RANDOM: 468 case PF_POOL_ROUNDROBIN: 469 /* 470 * pick a different source address since we're out 471 * of free port choices for the current one. 472 */ 473 (*sn) = NULL; 474 if (pf_map_addr_sn(pd->naf, r, &pd->nsaddr, naddr, NULL, 475 &init_addr, sn, sh, rpool, sn_type)) 476 return (1); 477 break; 478 case PF_POOL_NONE: 479 case PF_POOL_SRCHASH: 480 case PF_POOL_BITMASK: 481 default: 482 return (1); 483 } 484 } while (! PF_AEQ(&init_addr, naddr, pd->naf) ); 485 486 failed: 487 if (udp_mapping) { 488 uma_zfree(V_pf_udp_mapping_z, *udp_mapping); 489 *udp_mapping = NULL; 490 } 491 492 return (1); /* none available */ 493 } 494 495 static bool 496 pf_islinklocal(const sa_family_t af, const struct pf_addr *addr) 497 { 498 if (af == AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&addr->v6)) 499 return (true); 500 return (false); 501 } 502 503 static int 504 pf_get_mape_sport(struct pf_pdesc *pd, struct pf_krule *r, 505 struct pf_addr *naddr, uint16_t *nport, 506 struct pf_ksrc_node **sn, struct pf_srchash **sh, 507 struct pf_udp_mapping **udp_mapping, struct pf_kpool *rpool) 508 { 509 uint16_t psmask, low, highmask; 510 uint16_t i, ahigh, cut; 511 int ashift, psidshift; 512 513 ashift = 16 - rpool->mape.offset; 514 psidshift = ashift - rpool->mape.psidlen; 515 psmask = rpool->mape.psid & ((1U << rpool->mape.psidlen) - 1); 516 psmask = psmask << psidshift; 517 highmask = (1U << psidshift) - 1; 518 519 ahigh = (1U << rpool->mape.offset) - 1; 520 cut = arc4random() & ahigh; 521 if (cut == 0) 522 cut = 1; 523 524 for (i = cut; i <= ahigh; i++) { 525 low = (i << ashift) | psmask; 526 if (!pf_get_sport(pd, r, 527 naddr, nport, low, low | highmask, sn, sh, rpool, 528 udp_mapping, PF_SN_NAT)) 529 return (0); 530 } 531 for (i = cut - 1; i > 0; i--) { 532 low = (i << ashift) | psmask; 533 if (!pf_get_sport(pd, r, 534 naddr, nport, low, low | highmask, sn, sh, rpool, 535 udp_mapping, PF_SN_NAT)) 536 return (0); 537 } 538 return (1); 539 } 540 541 u_short 542 pf_map_addr(sa_family_t af, struct pf_krule *r, struct pf_addr *saddr, 543 struct pf_addr *naddr, struct pfi_kkif **nkif, struct pf_addr *init_addr, 544 struct pf_kpool *rpool) 545 { 546 u_short reason = PFRES_MATCH; 547 struct pf_addr *raddr = NULL, *rmask = NULL; 548 uint64_t hashidx; 549 int cnt; 550 551 mtx_lock(&rpool->mtx); 552 /* Find the route using chosen algorithm. Store the found route 553 in src_node if it was given or found. */ 554 if (rpool->cur->addr.type == PF_ADDR_NOROUTE) { 555 reason = PFRES_MAPFAILED; 556 goto done_pool_mtx; 557 } 558 if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) { 559 switch (af) { 560 #ifdef INET 561 case AF_INET: 562 if (rpool->cur->addr.p.dyn->pfid_acnt4 < 1 && 563 !PF_POOL_DYNTYPE(rpool->opts)) { 564 reason = PFRES_MAPFAILED; 565 goto done_pool_mtx; 566 } 567 raddr = &rpool->cur->addr.p.dyn->pfid_addr4; 568 rmask = &rpool->cur->addr.p.dyn->pfid_mask4; 569 break; 570 #endif /* INET */ 571 #ifdef INET6 572 case AF_INET6: 573 if (rpool->cur->addr.p.dyn->pfid_acnt6 < 1 && 574 !PF_POOL_DYNTYPE(rpool->opts)) { 575 reason = PFRES_MAPFAILED; 576 goto done_pool_mtx; 577 } 578 raddr = &rpool->cur->addr.p.dyn->pfid_addr6; 579 rmask = &rpool->cur->addr.p.dyn->pfid_mask6; 580 break; 581 #endif /* INET6 */ 582 default: 583 unhandled_af(af); 584 } 585 } else if (rpool->cur->addr.type == PF_ADDR_TABLE) { 586 if (!PF_POOL_DYNTYPE(rpool->opts)) { 587 reason = PFRES_MAPFAILED; 588 goto done_pool_mtx; /* unsupported */ 589 } 590 } else { 591 raddr = &rpool->cur->addr.v.a.addr; 592 rmask = &rpool->cur->addr.v.a.mask; 593 } 594 595 switch (rpool->opts & PF_POOL_TYPEMASK) { 596 case PF_POOL_NONE: 597 pf_addrcpy(naddr, raddr, af); 598 break; 599 case PF_POOL_BITMASK: 600 pf_poolmask(naddr, raddr, rmask, saddr, af); 601 break; 602 case PF_POOL_RANDOM: 603 if (rpool->cur->addr.type == PF_ADDR_TABLE) { 604 cnt = rpool->cur->addr.p.tbl->pfrkt_cnt; 605 if (cnt == 0) 606 rpool->tblidx = 0; 607 else 608 rpool->tblidx = (int)arc4random_uniform(cnt); 609 memset(&rpool->counter, 0, sizeof(rpool->counter)); 610 if (pfr_pool_get(rpool->cur->addr.p.tbl, 611 &rpool->tblidx, &rpool->counter, af, NULL)) { 612 reason = PFRES_MAPFAILED; 613 goto done_pool_mtx; /* unsupported */ 614 } 615 pf_addrcpy(naddr, &rpool->counter, af); 616 } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) { 617 cnt = rpool->cur->addr.p.dyn->pfid_kt->pfrkt_cnt; 618 if (cnt == 0) 619 rpool->tblidx = 0; 620 else 621 rpool->tblidx = (int)arc4random_uniform(cnt); 622 memset(&rpool->counter, 0, sizeof(rpool->counter)); 623 if (pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt, 624 &rpool->tblidx, &rpool->counter, af, 625 pf_islinklocal)) { 626 reason = PFRES_MAPFAILED; 627 goto done_pool_mtx; /* unsupported */ 628 } 629 pf_addrcpy(naddr, &rpool->counter, af); 630 } else if (init_addr != NULL && PF_AZERO(init_addr, af)) { 631 switch (af) { 632 #ifdef INET 633 case AF_INET: 634 rpool->counter.addr32[0] = arc4random(); 635 break; 636 #endif /* INET */ 637 #ifdef INET6 638 case AF_INET6: 639 if (rmask->addr32[3] != 0xffffffff) 640 rpool->counter.addr32[3] = 641 arc4random(); 642 else 643 break; 644 if (rmask->addr32[2] != 0xffffffff) 645 rpool->counter.addr32[2] = 646 arc4random(); 647 else 648 break; 649 if (rmask->addr32[1] != 0xffffffff) 650 rpool->counter.addr32[1] = 651 arc4random(); 652 else 653 break; 654 if (rmask->addr32[0] != 0xffffffff) 655 rpool->counter.addr32[0] = 656 arc4random(); 657 break; 658 #endif /* INET6 */ 659 } 660 pf_poolmask(naddr, raddr, rmask, &rpool->counter, af); 661 pf_addrcpy(init_addr, naddr, af); 662 663 } else { 664 pf_addr_inc(&rpool->counter, af); 665 pf_poolmask(naddr, raddr, rmask, &rpool->counter, af); 666 } 667 break; 668 case PF_POOL_SRCHASH: 669 { 670 unsigned char hash[16]; 671 672 hashidx = 673 pf_hash(saddr, (struct pf_addr *)&hash, &rpool->key, af); 674 if (rpool->cur->addr.type == PF_ADDR_TABLE) { 675 cnt = rpool->cur->addr.p.tbl->pfrkt_cnt; 676 if (cnt == 0) 677 rpool->tblidx = 0; 678 else 679 rpool->tblidx = (int)(hashidx % cnt); 680 memset(&rpool->counter, 0, sizeof(rpool->counter)); 681 if (pfr_pool_get(rpool->cur->addr.p.tbl, 682 &rpool->tblidx, &rpool->counter, af, NULL)) { 683 reason = PFRES_MAPFAILED; 684 goto done_pool_mtx; /* unsupported */ 685 } 686 pf_addrcpy(naddr, &rpool->counter, af); 687 } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) { 688 cnt = rpool->cur->addr.p.dyn->pfid_kt->pfrkt_cnt; 689 if (cnt == 0) 690 rpool->tblidx = 0; 691 else 692 rpool->tblidx = (int)(hashidx % cnt); 693 memset(&rpool->counter, 0, sizeof(rpool->counter)); 694 if (pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt, 695 &rpool->tblidx, &rpool->counter, af, 696 pf_islinklocal)) { 697 reason = PFRES_MAPFAILED; 698 goto done_pool_mtx; /* unsupported */ 699 } 700 pf_addrcpy(naddr, &rpool->counter, af); 701 } else { 702 pf_poolmask(naddr, raddr, rmask, 703 (struct pf_addr *)&hash, af); 704 } 705 break; 706 } 707 case PF_POOL_ROUNDROBIN: 708 { 709 struct pf_kpooladdr *acur = rpool->cur; 710 711 if (rpool->cur->addr.type == PF_ADDR_TABLE) { 712 if (!pfr_pool_get(rpool->cur->addr.p.tbl, 713 &rpool->tblidx, &rpool->counter, af, NULL)) 714 goto get_addr; 715 } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) { 716 if (!pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt, 717 &rpool->tblidx, &rpool->counter, af, pf_islinklocal)) 718 goto get_addr; 719 } else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af)) 720 goto get_addr; 721 722 try_next: 723 if (TAILQ_NEXT(rpool->cur, entries) == NULL) 724 rpool->cur = TAILQ_FIRST(&rpool->list); 725 else 726 rpool->cur = TAILQ_NEXT(rpool->cur, entries); 727 if (rpool->cur->addr.type == PF_ADDR_TABLE) { 728 if (pfr_pool_get(rpool->cur->addr.p.tbl, 729 &rpool->tblidx, &rpool->counter, af, NULL)) { 730 /* table contains no address of type 'af' */ 731 if (rpool->cur != acur) 732 goto try_next; 733 reason = PFRES_MAPFAILED; 734 goto done_pool_mtx; 735 } 736 } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) { 737 rpool->tblidx = -1; 738 if (pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt, 739 &rpool->tblidx, &rpool->counter, af, pf_islinklocal)) { 740 /* table contains no address of type 'af' */ 741 if (rpool->cur != acur) 742 goto try_next; 743 reason = PFRES_MAPFAILED; 744 goto done_pool_mtx; 745 } 746 } else { 747 raddr = &rpool->cur->addr.v.a.addr; 748 rmask = &rpool->cur->addr.v.a.mask; 749 pf_addrcpy(&rpool->counter, raddr, af); 750 } 751 752 get_addr: 753 pf_addrcpy(naddr, &rpool->counter, af); 754 if (init_addr != NULL && PF_AZERO(init_addr, af)) 755 pf_addrcpy(init_addr, naddr, af); 756 pf_addr_inc(&rpool->counter, af); 757 break; 758 } 759 } 760 761 if (nkif) 762 *nkif = rpool->cur->kif; 763 764 done_pool_mtx: 765 mtx_unlock(&rpool->mtx); 766 767 if (reason) { 768 counter_u64_add(V_pf_status.counters[reason], 1); 769 } 770 771 return (reason); 772 } 773 774 u_short 775 pf_map_addr_sn(sa_family_t af, struct pf_krule *r, struct pf_addr *saddr, 776 struct pf_addr *naddr, struct pfi_kkif **nkif, struct pf_addr *init_addr, 777 struct pf_ksrc_node **sn, struct pf_srchash **sh, struct pf_kpool *rpool, 778 pf_sn_types_t sn_type) 779 { 780 u_short reason = 0; 781 782 KASSERT(*sn == NULL, ("*sn not NULL")); 783 784 /* 785 * If this is a sticky-address rule, try to find an existing src_node. 786 * Request the sh to be unlocked if sn was not found, as we never 787 * insert a new sn when parsing the ruleset. 788 */ 789 if (rpool->opts & PF_POOL_STICKYADDR && 790 (rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) 791 *sn = pf_find_src_node(saddr, r, af, sh, sn_type, false); 792 793 if (*sn != NULL) { 794 PF_SRC_NODE_LOCK_ASSERT(*sn); 795 796 /* If the supplied address is the same as the current one we've 797 * been asked before, so tell the caller that there's no other 798 * address to be had. */ 799 if (PF_AEQ(naddr, &(*sn)->raddr, af)) { 800 reason = PFRES_MAPFAILED; 801 goto done; 802 } 803 804 pf_addrcpy(naddr, &(*sn)->raddr, af); 805 if (nkif) 806 *nkif = (*sn)->rkif; 807 if (V_pf_status.debug >= PF_DEBUG_NOISY) { 808 printf("pf_map_addr: src tracking maps "); 809 pf_print_host(saddr, 0, af); 810 printf(" to "); 811 pf_print_host(naddr, 0, af); 812 if (nkif) 813 printf("@%s", (*nkif)->pfik_name); 814 printf("\n"); 815 } 816 goto done; 817 } 818 819 /* 820 * Source node has not been found. Find a new address and store it 821 * in variables given by the caller. 822 */ 823 if (pf_map_addr(af, r, saddr, naddr, nkif, init_addr, rpool) != 0) { 824 /* pf_map_addr() sets reason counters on its own */ 825 goto done; 826 } 827 828 if (V_pf_status.debug >= PF_DEBUG_NOISY && 829 (rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) { 830 printf("pf_map_addr: selected address "); 831 pf_print_host(naddr, 0, af); 832 if (nkif) 833 printf("@%s", (*nkif)->pfik_name); 834 printf("\n"); 835 } 836 837 done: 838 if ((*sn) != NULL) 839 PF_SRC_NODE_UNLOCK(*sn); 840 841 if (reason) { 842 counter_u64_add(V_pf_status.counters[reason], 1); 843 } 844 845 return (reason); 846 } 847 848 u_short 849 pf_get_translation(struct pf_test_ctx *ctx) 850 { 851 struct pf_krule *r = NULL; 852 u_short transerror; 853 854 PF_RULES_RASSERT(); 855 KASSERT(ctx->sk == NULL, ("*skp not NULL")); 856 KASSERT(ctx->nk == NULL, ("*nkp not NULL")); 857 858 ctx->nr = NULL; 859 860 if (ctx->pd->dir == PF_OUT) { 861 r = pf_match_translation(PF_RULESET_BINAT, ctx); 862 if (r == NULL) 863 r = pf_match_translation(PF_RULESET_NAT, ctx); 864 } else { 865 r = pf_match_translation(PF_RULESET_RDR, ctx); 866 if (r == NULL) 867 r = pf_match_translation(PF_RULESET_BINAT, ctx); 868 } 869 870 if (r == NULL) 871 return (PFRES_MAX); 872 873 switch (r->action) { 874 case PF_NONAT: 875 case PF_NOBINAT: 876 case PF_NORDR: 877 return (PFRES_MAX); 878 } 879 880 transerror = pf_get_transaddr(ctx, r, r->action, &(r->rdr)); 881 if (transerror == PFRES_MATCH) 882 ctx->nr = r; 883 884 return (transerror); 885 } 886 887 u_short 888 pf_get_transaddr(struct pf_test_ctx *ctx, struct pf_krule *r, 889 uint8_t nat_action, struct pf_kpool *rpool) 890 { 891 struct pf_pdesc *pd = ctx->pd; 892 struct pf_addr *naddr; 893 struct pf_ksrc_node *sn = NULL; 894 struct pf_srchash *sh = NULL; 895 uint16_t *nportp; 896 uint16_t low, high; 897 u_short reason; 898 899 PF_RULES_RASSERT(); 900 KASSERT(r != NULL, ("r is NULL")); 901 KASSERT(!(r->rule_flag & PFRULE_AFTO), ("AFTO rule")); 902 903 if (ctx->sk == NULL && ctx->nk == NULL) { 904 if (pf_state_key_setup(pd, pd->nsport, pd->ndport, &ctx->sk, 905 &ctx->nk)) 906 return (PFRES_MEMORY); 907 } 908 909 naddr = &ctx->nk->addr[1]; 910 nportp = &ctx->nk->port[1]; 911 912 switch (nat_action) { 913 case PF_NAT: 914 if (pd->proto == IPPROTO_ICMP) { 915 low = 1; 916 high = 65535; 917 } else { 918 low = rpool->proxy_port[0]; 919 high = rpool->proxy_port[1]; 920 } 921 if (rpool->mape.offset > 0) { 922 if (pf_get_mape_sport(pd, r, naddr, nportp, &sn, 923 &sh, &ctx->udp_mapping, rpool)) { 924 DPFPRINTF(PF_DEBUG_MISC, 925 ("pf: MAP-E port allocation (%u/%u/%u)" 926 " failed\n", 927 rpool->mape.offset, 928 rpool->mape.psidlen, 929 rpool->mape.psid)); 930 reason = PFRES_MAPFAILED; 931 goto notrans; 932 } 933 } else if (pf_get_sport(pd, r, naddr, nportp, low, high, &sn, 934 &sh, rpool, &ctx->udp_mapping, PF_SN_NAT)) { 935 DPFPRINTF(PF_DEBUG_MISC, 936 ("pf: NAT proxy port allocation (%u-%u) failed\n", 937 rpool->proxy_port[0], rpool->proxy_port[1])); 938 reason = PFRES_MAPFAILED; 939 goto notrans; 940 } 941 break; 942 case PF_BINAT: 943 switch (pd->dir) { 944 case PF_OUT: 945 if (rpool->cur->addr.type == PF_ADDR_DYNIFTL){ 946 switch (pd->af) { 947 #ifdef INET 948 case AF_INET: 949 if (rpool->cur->addr.p.dyn-> 950 pfid_acnt4 < 1) { 951 reason = PFRES_MAPFAILED; 952 goto notrans; 953 } 954 pf_poolmask(naddr, 955 &rpool->cur->addr.p.dyn->pfid_addr4, 956 &rpool->cur->addr.p.dyn->pfid_mask4, 957 &pd->nsaddr, AF_INET); 958 break; 959 #endif /* INET */ 960 #ifdef INET6 961 case AF_INET6: 962 if (rpool->cur->addr.p.dyn-> 963 pfid_acnt6 < 1) { 964 reason = PFRES_MAPFAILED; 965 goto notrans; 966 } 967 pf_poolmask(naddr, 968 &rpool->cur->addr.p.dyn->pfid_addr6, 969 &rpool->cur->addr.p.dyn->pfid_mask6, 970 &pd->nsaddr, AF_INET6); 971 break; 972 #endif /* INET6 */ 973 } 974 } else 975 pf_poolmask(naddr, 976 &rpool->cur->addr.v.a.addr, 977 &rpool->cur->addr.v.a.mask, &pd->nsaddr, 978 pd->af); 979 break; 980 case PF_IN: 981 if (r->src.addr.type == PF_ADDR_DYNIFTL) { 982 switch (pd->af) { 983 #ifdef INET 984 case AF_INET: 985 if (r->src.addr.p.dyn->pfid_acnt4 < 1) { 986 reason = PFRES_MAPFAILED; 987 goto notrans; 988 } 989 pf_poolmask(naddr, 990 &r->src.addr.p.dyn->pfid_addr4, 991 &r->src.addr.p.dyn->pfid_mask4, 992 &pd->ndaddr, AF_INET); 993 break; 994 #endif /* INET */ 995 #ifdef INET6 996 case AF_INET6: 997 if (r->src.addr.p.dyn->pfid_acnt6 < 1) { 998 reason = PFRES_MAPFAILED; 999 goto notrans; 1000 } 1001 pf_poolmask(naddr, 1002 &r->src.addr.p.dyn->pfid_addr6, 1003 &r->src.addr.p.dyn->pfid_mask6, 1004 &pd->ndaddr, AF_INET6); 1005 break; 1006 #endif /* INET6 */ 1007 } 1008 } else 1009 pf_poolmask(naddr, &r->src.addr.v.a.addr, 1010 &r->src.addr.v.a.mask, &pd->ndaddr, pd->af); 1011 break; 1012 } 1013 break; 1014 case PF_RDR: { 1015 struct pf_state_key_cmp key; 1016 int tries; 1017 uint16_t cut, low, high, nport; 1018 1019 reason = pf_map_addr_sn(pd->af, r, &pd->nsaddr, naddr, NULL, 1020 NULL, &sn, &sh, rpool, PF_SN_NAT); 1021 if (reason != 0) 1022 goto notrans; 1023 if ((rpool->opts & PF_POOL_TYPEMASK) == PF_POOL_BITMASK) 1024 pf_poolmask(naddr, naddr, &rpool->cur->addr.v.a.mask, 1025 &pd->ndaddr, pd->af); 1026 1027 /* Do not change SCTP ports. */ 1028 if (pd->proto == IPPROTO_SCTP) 1029 break; 1030 1031 if (rpool->proxy_port[1]) { 1032 uint32_t tmp_nport; 1033 1034 tmp_nport = ((ntohs(pd->ndport) - ntohs(r->dst.port[0])) % 1035 (rpool->proxy_port[1] - rpool->proxy_port[0] + 1036 1)) + rpool->proxy_port[0]; 1037 1038 /* Wrap around if necessary. */ 1039 if (tmp_nport > 65535) 1040 tmp_nport -= 65535; 1041 nport = htons((uint16_t)tmp_nport); 1042 } else if (rpool->proxy_port[0]) 1043 nport = htons(rpool->proxy_port[0]); 1044 else 1045 nport = pd->ndport; 1046 1047 /* 1048 * Update the destination port. 1049 */ 1050 *nportp = nport; 1051 1052 /* 1053 * Do we have a source port conflict in the stack state? Try to 1054 * modulate the source port if so. Note that this is racy since 1055 * the state lookup may not find any matches here but will once 1056 * pf_create_state() actually instantiates the state. 1057 */ 1058 bzero(&key, sizeof(key)); 1059 key.af = pd->af; 1060 key.proto = pd->proto; 1061 key.port[0] = pd->nsport; 1062 pf_addrcpy(&key.addr[0], &pd->nsaddr, key.af); 1063 key.port[1] = nport; 1064 pf_addrcpy(&key.addr[1], naddr, key.af); 1065 1066 if (!pf_find_state_all_exists(&key, PF_OUT)) 1067 break; 1068 1069 tries = 0; 1070 1071 low = 50001; /* XXX-MJ PF_NAT_PROXY_PORT_LOW/HIGH */ 1072 high = 65535; 1073 cut = arc4random() % (1 + high - low) + low; 1074 for (uint32_t tmp = cut; 1075 tmp <= high && tmp <= UINT16_MAX && 1076 tries < V_pf_rdr_srcport_rewrite_tries; 1077 tmp++, tries++) { 1078 key.port[0] = htons(tmp); 1079 if (!pf_find_state_all_exists(&key, PF_OUT)) { 1080 /* Update the source port. */ 1081 ctx->nk->port[0] = htons(tmp); 1082 goto out; 1083 } 1084 } 1085 for (uint32_t tmp = cut - 1; 1086 tmp >= low && tries < V_pf_rdr_srcport_rewrite_tries; 1087 tmp--, tries++) { 1088 key.port[0] = htons(tmp); 1089 if (!pf_find_state_all_exists(&key, PF_OUT)) { 1090 /* Update the source port. */ 1091 ctx->nk->port[0] = htons(tmp); 1092 goto out; 1093 } 1094 } 1095 1096 /* 1097 * We failed to find a match. Push on ahead anyway, let 1098 * pf_state_insert() be the arbiter of whether the state 1099 * conflict is tolerable. In particular, with TCP connections 1100 * the state may be reused if the TCP state is terminal. 1101 */ 1102 DPFPRINTF(PF_DEBUG_MISC, 1103 ("pf: RDR source port allocation failed\n")); 1104 break; 1105 1106 out: 1107 DPFPRINTF(PF_DEBUG_MISC, 1108 ("pf: RDR source port allocation %u->%u\n", 1109 ntohs(pd->nsport), ntohs(ctx->nk->port[0]))); 1110 break; 1111 } 1112 default: 1113 panic("%s: unknown action %u", __func__, r->action); 1114 } 1115 1116 /* Return success only if translation really happened. */ 1117 if (bcmp(ctx->sk, ctx->nk, sizeof(struct pf_state_key_cmp))) { 1118 return (PFRES_MATCH); 1119 } 1120 1121 reason = PFRES_MAX; 1122 notrans: 1123 uma_zfree(V_pf_state_key_z, ctx->nk); 1124 uma_zfree(V_pf_state_key_z, ctx->sk); 1125 ctx->sk = ctx->nk = NULL; 1126 1127 return (reason); 1128 } 1129 1130 int 1131 pf_get_transaddr_af(struct pf_krule *r, struct pf_pdesc *pd) 1132 { 1133 #if defined(INET) && defined(INET6) 1134 struct pf_addr ndaddr, nsaddr, naddr; 1135 u_int16_t nport = 0; 1136 int prefixlen = 96; 1137 struct pf_srchash *sh = NULL; 1138 struct pf_ksrc_node *sns = NULL; 1139 1140 bzero(&nsaddr, sizeof(nsaddr)); 1141 bzero(&ndaddr, sizeof(ndaddr)); 1142 1143 if (V_pf_status.debug >= PF_DEBUG_MISC) { 1144 printf("pf: af-to %s %s, ", 1145 pd->naf == AF_INET ? "inet" : "inet6", 1146 TAILQ_EMPTY(&r->rdr.list) ? "nat" : "rdr"); 1147 pf_print_host(&pd->nsaddr, pd->nsport, pd->af); 1148 printf(" -> "); 1149 pf_print_host(&pd->ndaddr, pd->ndport, pd->af); 1150 printf("\n"); 1151 } 1152 1153 if (TAILQ_EMPTY(&r->nat.list)) 1154 panic("pf_get_transaddr_af: no nat pool for source address"); 1155 1156 /* get source address and port */ 1157 if (pf_get_sport(pd, r, &nsaddr, &nport, 1158 r->nat.proxy_port[0], r->nat.proxy_port[1], &sns, &sh, &r->nat, 1159 NULL, PF_SN_NAT)) { 1160 DPFPRINTF(PF_DEBUG_MISC, 1161 ("pf: af-to NAT proxy port allocation (%u-%u) failed", 1162 r->nat.proxy_port[0], r->nat.proxy_port[1])); 1163 return (-1); 1164 } 1165 1166 if (pd->proto == IPPROTO_ICMPV6 && pd->naf == AF_INET) { 1167 pd->ndport = ntohs(pd->ndport); 1168 if (pd->ndport == ICMP6_ECHO_REQUEST) 1169 pd->ndport = ICMP_ECHO; 1170 else if (pd->ndport == ICMP6_ECHO_REPLY) 1171 pd->ndport = ICMP_ECHOREPLY; 1172 pd->ndport = htons(pd->ndport); 1173 } else if (pd->proto == IPPROTO_ICMP && pd->naf == AF_INET6) { 1174 pd->nsport = ntohs(pd->nsport); 1175 if (pd->ndport == ICMP_ECHO) 1176 pd->ndport = ICMP6_ECHO_REQUEST; 1177 else if (pd->ndport == ICMP_ECHOREPLY) 1178 pd->ndport = ICMP6_ECHO_REPLY; 1179 pd->nsport = htons(pd->nsport); 1180 } 1181 1182 /* get the destination address and port */ 1183 if (! TAILQ_EMPTY(&r->rdr.list)) { 1184 if (pf_map_addr_sn(pd->naf, r, &nsaddr, &naddr, NULL, NULL, 1185 &sns, NULL, &r->rdr, PF_SN_NAT)) 1186 return (-1); 1187 if (r->rdr.proxy_port[0]) 1188 pd->ndport = htons(r->rdr.proxy_port[0]); 1189 1190 if (pd->naf == AF_INET) { 1191 /* The prefix is the IPv4 rdr address */ 1192 prefixlen = in_mask2len( 1193 (struct in_addr *)&r->rdr.cur->addr.v.a.mask); 1194 inet_nat46(pd->naf, &pd->ndaddr, &ndaddr, &naddr, 1195 prefixlen); 1196 } else { 1197 /* The prefix is the IPv6 rdr address */ 1198 prefixlen = in6_mask2len( 1199 (struct in6_addr *)&r->rdr.cur->addr.v.a.mask, NULL); 1200 inet_nat64(pd->naf, &pd->ndaddr, &ndaddr, &naddr, 1201 prefixlen); 1202 } 1203 } else { 1204 if (pd->naf == AF_INET) { 1205 /* The prefix is the IPv6 dst address */ 1206 prefixlen = in6_mask2len( 1207 (struct in6_addr *)&r->dst.addr.v.a.mask, NULL); 1208 if (prefixlen < 32) 1209 prefixlen = 96; 1210 inet_nat64(pd->naf, &pd->ndaddr, &ndaddr, &pd->ndaddr, 1211 prefixlen); 1212 } else { 1213 /* 1214 * The prefix is the IPv6 nat address 1215 * (that was stored in pd->nsaddr) 1216 */ 1217 prefixlen = in6_mask2len( 1218 (struct in6_addr *)&r->nat.cur->addr.v.a.mask, NULL); 1219 if (prefixlen > 96) 1220 prefixlen = 96; 1221 inet_nat64(pd->naf, &pd->ndaddr, &ndaddr, &nsaddr, 1222 prefixlen); 1223 } 1224 } 1225 1226 pf_addrcpy(&pd->nsaddr, &nsaddr, pd->naf); 1227 pf_addrcpy(&pd->ndaddr, &ndaddr, pd->naf); 1228 1229 if (V_pf_status.debug >= PF_DEBUG_MISC) { 1230 printf("pf: af-to %s done, prefixlen %d, ", 1231 pd->naf == AF_INET ? "inet" : "inet6", 1232 prefixlen); 1233 pf_print_host(&pd->nsaddr, pd->nsport, pd->naf); 1234 printf(" -> "); 1235 pf_print_host(&pd->ndaddr, pd->ndport, pd->naf); 1236 printf("\n"); 1237 } 1238 1239 return (0); 1240 #else 1241 return (-1); 1242 #endif 1243 } 1244