| 561 | unused triplets: (dest addr, dest port, alias port). */ |
| 562 | |
| 563 | static int |
| 564 | GetNewPort(struct libalias *la, struct alias_link *lnk, int alias_port_param) |
| 565 | { |
| 566 | int i; |
| 567 | int max_trials; |
| 568 | u_short port_sys; |
| 569 | u_short port_net; |
| 570 | |
| 571 | LIBALIAS_LOCK_ASSERT(la); |
| 572 | /* |
| 573 | Description of alias_port_param for GetNewPort(). When |
| 574 | this parameter is zero or positive, it precisely specifies |
| 575 | the port number. GetNewPort() will return this number |
| 576 | without check that it is in use. |
| 577 | |
| 578 | When this parameter is GET_ALIAS_PORT, it indicates to get a randomly |
| 579 | selected port number. |
| 580 | */ |
| 581 | |
| 582 | if (alias_port_param == GET_ALIAS_PORT) { |
| 583 | /* |
| 584 | * The aliasing port is automatically selected by one of |
| 585 | * two methods below: |
| 586 | */ |
| 587 | max_trials = GET_NEW_PORT_MAX_ATTEMPTS; |
| 588 | |
| 589 | if (la->packetAliasMode & PKT_ALIAS_SAME_PORTS) { |
| 590 | /* |
| 591 | * When the PKT_ALIAS_SAME_PORTS option is chosen, |
| 592 | * the first try will be the actual source port. If |
| 593 | * this is already in use, the remainder of the |
| 594 | * trials will be random. |
| 595 | */ |
| 596 | port_net = lnk->src_port; |
| 597 | port_sys = ntohs(port_net); |
| 598 | } else { |
| 599 | /* First trial and all subsequent are random. */ |
| 600 | port_sys = arc4random() & ALIAS_PORT_MASK; |
| 601 | port_sys += ALIAS_PORT_BASE; |
| 602 | port_net = htons(port_sys); |
| 603 | } |
| 604 | } else if (alias_port_param >= 0 && alias_port_param < 0x10000) { |
| 605 | lnk->alias_port = (u_short) alias_port_param; |
| 606 | return (0); |
| 607 | } else { |
| 608 | #ifdef LIBALIAS_DEBUG |
| 609 | fprintf(stderr, "PacketAlias/GetNewPort(): "); |
| 610 | fprintf(stderr, "input parameter error\n"); |
| 611 | #endif |
| 612 | return (-1); |
| 613 | } |
| 614 | |
| 615 | /* Port number search */ |
| 616 | for (i = 0; i < max_trials; i++) { |
| 617 | int go_ahead; |
| 618 | struct alias_link *search_result; |
| 619 | |
| 620 | search_result = FindLinkIn(la, lnk->dst_addr, lnk->alias_addr, |
no test coverage detected