libalias.3 revision 32377
1.Dd July, 1997 2.Dt "libalias" 3 3.Os 4.Sh NAME 5.Nm "libalias" 6Packet Aliasing Library. A collection of 7functions for aliasing and de-aliasing 8of IP packets, intended for masquerading and 9network address translation (NAT). 10 11.Sh SYNOPSIS 12.Fd #include <netinet/in.h> 13.Fd #include <alias.h> 14 15Function prototypes are given in the main body 16of the text. 17 18.Sh CONTENTS 19.Bd -literal -offset left 201. Introduction 212. Initialization and Control 22 2.1 PacketAliasInit() 23 2.2 PacketAliasUninit() 24 2.3 PacketAliasSetAddress() 25 2.4 PacketAliasSetMode() 26 2.5 PacketAliasSetFWBase() 273. Packet Handling 28 3.1 PacketAliasOut() 29 3.2 PacketAliasIn() 304. Port and Address Redirection 31 4.1 PacketAliasRedirectPort() 32 4.2 PacketAliasRedirectAddr() 33 4.3 PacketAliasRedirectDelete() 345. Fragment Handling 35 5.1 PacketAliasSaveFragment() 36 5.2 PacketAliasGetFragment() 37 5.3 PacketAliasFragmentIn() 386. Miscellaneous Functions 39 6.1 PacketAliasSetTarget() 40 6.2 PacketAliasCheckNewLink() 41 6.3 PacketAliasInternetChecksum() 427. Authors 438. Acknowledgments 44 45Appendix A: Conceptual Background 46 A.1 Aliasing Links 47 A.2 Static and Dynamic Links 48 A.3 Partially Specified Links 49 A.4 Dynamic Link Creation 50.Ed 51 52.Sh 1. Introduction 53This library is a moderately portable 54set of functions designed to assist 55in the process of IP masquerading and 56network address translation. Outgoing 57packets from a local network with 58unregistered IP addresses can be aliased 59to appear as if they came from an 60accessible IP address. Incoming packets 61are then de-aliased so that they are sent 62to the correct machine on the local network. 63 64A certain amount of flexibility is built 65into the packet aliasing engine. In 66the simplest mode of operation, a 67many-to-one address mapping takes place 68between local network and the packet 69aliasing host. This is known as IP 70masquerading. In addition, one-to-one 71mappings between local and public addresses 72can also be implemented, which is known as 73static NAT. In between these extremes, 74different groups of private addresses 75can be linked to different public addresses, 76comprising several distinct many-to-one 77mappings. Also, a given public address 78and port can be staticly redirected to 79a private address/port. 80 81The packet aliasing engine was designed 82to operate in user space outside of the 83kernel, without any access to private 84kernel data structure, but the source code 85can also be ported to a kernel environment. 86 87.Sh 2. Initialization and Control 88Two specific functions, PacketAliasInit() 89and PacketAliasSetAddress(), must always be 90called before any packet handling may be 91performed. In addition, the operating mode 92of the packet aliasing engine can be customized 93by calling PacketAliasSetMode(). 94.Ss 2.1 PacketAliasInit() 95 96.Ft void 97.Fn PacketAliasInit "void" 98 99This function has no argument or return 100value and is used to initialize internal 101data structures. The following mode bits 102are always set after calling 103PacketAliasInit(). See section 2.3 for 104the meaning of these mode bits. 105.Bd -literal -offset indent 106 PKT_ALIAS_USE_SAME_PORTS 107 PKT_ALIAS_USE_SOCKETS 108 PKT_ALIAS_RESET_ON_ADDR_CHANGE 109 110.Ed 111This function will always return the packet 112aliasing engine to the same initial state. 113PacketAliasSetAddress() must be called afterwards, 114and any desired changes from the default mode 115bits listed above require a call to 116PacketAliasSetMode(). 117 118It is mandatory that this function be called 119at the beginning of a program prior to any 120packet handling. 121.Ss 2.2 PacketAliasUnInit() 122 123.Ft void 124.Fn PacketAliasUnInit "void" 125 126This function has no argument or return 127value and is used to clear any resources 128attached to internal data structures. 129 130This functions should be called when a 131program stop using the aliasing engine; 132it do, among other things, clear out any 133firewall holes. To provide backwards 134compatibility and extra security, it is 135added to the atexit() chain by 136PacketAliasInit(). Calling it multiple 137times is harmless. 138.Ss 2.3 PacketAliasSetAddress() 139 140.Ft void 141.Fn PacketAliasSetAddress "struct in_addr addr" 142 143This function sets the source address to which 144outgoing packets from the local area network 145are aliased. All outgoing packets are remapped 146to this address unless overridden by a static 147address mapping established by 148PacketAliasRedirectAddr(). 149 150If the PKT_ALIAS_RESET_ON_ADDR_CHANGE mode bit 151is set (the default mode of operation), then 152the internal aliasing link tables will be reset 153any time the aliasing address changes, as if 154PacketAliasReset() were called. This is useful 155for interfaces such as ppp where the IP 156address may or may not change on successive 157dial-up attempts. 158 159If the PKT_ALIAS_RESET_ON_ADDR_CHANGE mode bit 160is set to zero, this function can also be used to 161dynamically change the aliasing address on a 162packet to packet basis (it is a low overhead 163call). 164 165It is mandatory that this function be called 166prior to any packet handling. 167.Ss 2.4 PacketAliasSetMode() 168 169.Ft void 170.Fn PacketAliasSetMode "int mode" "int mask" 171 172This function sets or clears mode bits 173according to the value of 174.Em mode . 175Only bits marked in 176.Em mask 177are affected. The following mode bits are 178defined in alias.h: 179.Bl -hang -offset left 180.It PKT_ALIAS_LOG. 181Enables logging /var/log/alias.log. The log file 182shows total numbers of links (icmp, tcp, udp) each 183time an aliasing link is created or deleted. Mainly 184useful for debugging when the log file is viewed 185continuously with "tail -f". 186.It PKT_ALIAS_DENY_INCOMING. 187If this mode bit is set, all incoming packets 188associated with new TCP connections or new 189UDP transactions will be marked for being 190ignored (PacketAliasIn() return code 191PKT_ALIAS_IGNORED) by the calling program. 192Response packets to connections or transactions 193initiated from the packet aliasing host or 194local network will be unaffected. This mode 195bit is useful for implementing a one-way firewall. 196.It PKT_ALIAS_SAME_PORTS. 197If this mode bit is set, the packet aliasing 198engine will attempt to leave the alias port 199numbers unchanged from the actual local port 200number. This can be done as long as the 201quintuple (proto, alias addr, alias port, 202remote addr, remote port) is unique. If a 203conflict exists, an new aliasing port number is 204chosen even if this mode bit is set. 205.It PKT_ALIAS_USE_SOCKETS. 206This bit should be set when the the packet 207aliasing host originates network traffic as 208well as forwards it. When the packet aliasing 209host is waiting for a connection from an 210unknown host address or unknown port number 211(e.g. an FTP data connection), this mode bit 212specifies that a socket be allocated as a place 213holder to prevent port conflicts. Once a 214connection is extablished, usually within a 215minute or so, the socket is closed. 216.It PKT_ALIAS_UNREGISTERED_ONLY. 217If this mode bit is set, traffic on the 218local network which does not originate from 219unregistered address spaces will be ignored. 220Standard Class A, B and C unregistered addresses 221are: 222.Bd -literal -offset indent 223 10.0.0.0 -> 10.255.255.255 (Class A subnet) 224 172.16.0.0 -> 172.31.255.255 (Class B subnets) 225 192.168.0.0 -> 192.168.255.255 (Class C subnets) 226 227.Ed 228This option is useful in the case that 229packet aliasing host has both registered and 230unregistered subnets on different interfaces. 231The registered subnet is fully accessible to 232the outside world, so traffic from it doesn't 233need to be passed through the packet aliasing 234engine. 235.It PKT_ALIAS_RESET_ON_ADDR_CHANGE. 236When this mode bit is set and 237PacketAliasSetAddress() is called to change 238the aliasing address, the internal link table 239of the packet aliasing engine will be cleared. 240This operating mode is useful for ppp links 241where the interface address can sometimes 242change or remain the same between dial-ups. 243If this mode bit is not set, it the link table 244will never be reset in the event of an 245address change. 246.It PKT_ALIAS_PUNCH_FW. 247This option make libalias `punch holes' in an 248ipfw based firewall for FTP/IRC DCC connections. 249The holes punched are bound by from/to IP address 250and port; it will not be possible to use a hole 251for another connection. A hole is removed when 252the connection that use it die. To cater for 253unexpected death of a program using libalias (e.g 254kill -9), changing the state of the flag will 255clear the entire ipfw range allocated for holes. 256This will also happen on the initial call to 257PacketAliasSetFWBase(). This call must happen 258prior to setting this flag. 259 260.El 261 262.Ss 2.5 PacketAliasSetFWBase() 263 264.Ft void 265.Fn PacketAliasSetFWBase "unsigned int base" "unsigned int num" 266 267Set IPFW range allocated for punching firewall holes (with the 268PKT_ALIAS_PUNCH_FW flag). The range will be cleared for all rules on 269initialization. 270 271.Sh 3. Packet Handling 272The packet handling functions are used to 273modify incoming (remote->local) and outgoing 274(local->remote) packets. The calling program 275is responsible for receiving and sending 276packets via network interfaces. 277 278Along with PacketAliasInit() and PacketAliasSetAddress(), 279the two packet handling functions, PacketAliasIn() 280and PacketAliasOut(), comprise minimal set of functions 281needed for a basic IP masquerading implementation. 282.Ss 3.1 PacketAliasIn() 283 284.Ft int 285.Fn PacketAliasIn "char *buffer" "int maxpacketsize" 286 287An incoming packet coming from a remote machine to 288the local network is de-aliased by this function. 289The IP packet is pointed to by 290.Em buffer , 291and 292.Em maxpacketsize 293indicates the size of the data structure containing 294the packet and should be at least as large as the 295actual packet size. 296 297Return codes: 298.Bl -hang -offset left 299.It PKT_ALIAS_ERROR. 300An internal error within the packet aliasing 301engine occured. 302.It PKT_ALIAS_OK. 303The packet aliasing process was successful. 304.It PKT_ALIAS_IGNORED. 305The packet was ignored and not de-aliased. 306This can happen if the protocal is unrecognized, 307possibly an ICMP message type is not handled or 308if incoming packets for new connections are being 309ignored (see PKT_ALIAS_DENY_INCOMING in section 3102.2). 311.It PKT_ALIAS_UNRESOLVED_FRAGMENT. 312This is returned when a fragment cannot be 313resolved because the header fragment has not 314been sent yet. In this situation, fragments 315must be saved with PacketAliasSaveFragment() 316until a header fragment is found. 317.It PKT_ALIAS_FOUND_HEADER_FRAGMENT. 318The packet aliasing process was successful, 319and a header fragment was found. This is a 320signal to retrieve any unresolved fragments 321with PacketAliasGetFragment() and de-alias 322them with PacketAliasFragmentIn(). 323.El 324.Ss 3.2 PacketAliasOut() 325 326.Ft int 327.Fn PacketAliasIn "char *buffer" "int maxpacketsize" 328 329An outgoing packet coming from the local network 330to a remote machine is aliased by this function. 331The IP packet is pointed to by 332.Em buffer r, 333and 334.Em maxpacketsize 335indicates the maximum packet size permissable 336should the packet length be changed. IP encoding 337protocols place addresss and port information in 338the encapsulated data stream which have to be 339modified and can account for changes in packet 340length. Well known examples of such protocols 341are FTP and IRC DCC. 342 343Return codes: 344.Bl -hang -offset left 345.It PKT_ALIAS_ERROR. 346An internal error within the packet aliasing 347engine occured. 348.It PKT_ALIAS_OK. 349The packet aliasing process was successful. 350.It PKT_ALIAS_IGNORED. 351The packet was ignored and not de-aliased. 352This can happen if the protocal is unrecognized, 353or possibly an ICMP message type is not handled. 354.El 355 356.Sh 4. Port and Address Redirection 357The functions described in this section allow machines 358on the local network to be accessible in some degree 359to new incoming connections from the external network. 360Individual ports can be re-mapped or static network 361address translations can be designated. 362.Ss 4.1 PacketAliasRedirectPort() 363 364.Ft struct alias_link * 365.Fo PacketAliasRedirectPort 366.Fa "struct in_addr local_addr" 367.Fa "u_short local_port" 368.Fa "struct in_addr remote_addr" 369.Fa "u_short remote_port" 370.Fa "struct in_addr alias_addr" 371.Fa "u_short alias_port" 372.Fa "u_char proto" 373.Fc 374 375This function specifies that traffic from a 376given remote address/port to an alias address/port 377be redirected to a specified local address/port. 378The paramater 379.Em proto 380can be either IPPROTO_TCP or IPPROTO_UDP, as 381defined in <netinet/in.h>. 382 383If 384.Em local_addr 385or 386.Em alias_addr 387is zero, this indicates that the packet aliasing 388address as established by PacketAliasSetAddress() 389is to be used. Even if PacketAliasAddress() is 390called to change the address after PacketAliasRedirectPort() 391is called, a zero reference will track this change. 392 393If 394.Em remote_addr 395is zero, this indicates to redirect packets from 396any remote address. Likewise, if 397.Em remote_port 398is zero, this indicates to redirect packets originating 399from any remote port number. Almost always, the remote 400port specification will be zero, but non-zero remote 401addresses can be sometimes be useful for firewalling. 402If two calls to PacketAliasRedirectPort() overlap in 403their address/port specifications, then the most recent 404call will have precedence. 405 406This function returns a pointer which can subsequently 407be used by PacketAliasRedirectDelete(). If NULL is 408returned, then the function call did not complete 409successfully. 410 411All port numbers are in network address byte order, 412so it is necessary to use htons() to convert these 413parameters from internally readable numbers to 414network byte order. Addresses are also in network 415byte order, which is implicit in the use of the 416.Em struct in_addr 417data type. 418.Ss 4.2 PacketAliasRedirectAddr() 419 420.Ft struct alias_link * 421.Fo PacketAliasRedirectAddress 422.Fa "struct in_addr local_addr" 423.Fa "struct in_addr alias_addr" 424.Fc 425 426This function desgnates that all incoming 427traffic to 428.Em alias_addr 429be redirected to 430.Em local_addr. 431Similarly, all outgoing traffic from 432.Em local_addr 433is aliased to 434.Em alias_addr . 435 436If 437.Em local_addr 438or 439.Em alias_addr 440is zero, this indicates that the packet aliasing 441address as established by PacketAliasSetAddress() 442is to be used. Even if PacketAliasAddress() is 443called to change the address after PacketAliasRedirectAddr() 444is called, a zero reference will track this change. 445 446If subsequent calls to PacketAliasRedirectAddr() 447use the same aliasing address, all new incoming 448traffic to this aliasing address will be redirected 449to the local address made in the last function call, 450but new traffic all of the local machines designated 451in the several function calls will be aliased to 452the same address. Consider the following example: 453.Bd -literal -offset left 454 PacketAliasRedirectAddr(inet_aton("192.168.0.2"), 455 inet_aton("141.221.254.101")); 456 PacketAliasRedirectAddr(inet_aton("192.168.0.3"), 457 inet_aton("141.221.254.101")); 458 PacketAliasRedirectAddr(inet_aton("192.168.0.4"), 459 inet_aton("141.221.254.101")); 460.Ed 461 462Any outgoing connections such as telnet or ftp 463from 192.168.0.2, 102.168.0.3, 192.168.0.4 will 464appear to come from 141.221.254.101. Any incoming 465connections to 141.221.254.101 will be directed 466to 192.168.0.4. 467 468Any calls to PacketAliasRedirectPort() will 469have precedence over address mappings designated 470by PacketAliasRedirectAddr(). 471 472This function returns a pointer which can subsequently 473be used by PacketAliasRedirectDelete(). If NULL is 474returned, then the function call did not complete 475successfully. 476.Ss 4.3 PacketAliasRedirectDelete() 477 478.Ft void 479.Fn PacketAliasRedirectDelete "struct alias_link *ptr" 480 481This function will delete a specific static redirect 482rule entered by PacketAliasRedirectPort() or 483PacketAliasRedirectAddr(). The parameter 484.Em ptr 485is the pointer returned by either of the redirection 486functions. If an invalid pointer is passed to 487PacketAliasRedirectDelete(), then a program crash 488or unpredictable operation could result, so it is 489necessary to be careful using this function. 490 491.Sh 5. Fragment Handling 492The functions in this section are used to deal with 493incoming fragments. 494 495Outgoing fragments are handled within PacketAliasOut() 496by changing the address according to any 497applicable mapping set by PacketAliasRedirectAddress(), 498or the default aliasing address set by 499PacketAliasSetAddress(). 500 501Incoming fragments are handled in one of two ways. 502If the header of a fragmented IP packet has already 503been seen, then all subsequent fragments will be 504re-mapped in the same manner the header fragment 505was. Fragments which arrive before the header 506are saved and then retrieved once the header fragment 507has been resolved. 508.Ss 5.1 PacketAliasSaveFragment() 509 510.Ft int 511.Fn PacketAliasSaveFragment "char *ptr" 512 513When PacketAliasIn() returns 514PKT_ALIAS_UNRESOLVED_FRAGMENT, this 515function can be used to save the pointer to 516the unresolved fragment. 517 518It is implicitly assumed that 519.Em ptr 520points to a block of memory allocated by 521malloc(). If the fragment is never 522resolved, the packet aliasing engine will 523automatically free the memory after a 524timeout period. [Eventually this function 525should be modified so that a callback 526function for freeing memory is passed as 527an argument.] 528 529This function returns PKT_ALIAS_OK if it 530was successful and PKT_ALIAS_ERROR if there 531was an error. 532.Ss 5.2 PacketAliasGetNextFragment() 533 534.Ft char * 535.Fn PacketAliasGetFragment "char *buffer" 536 537This function can be used to retrieve fragment 538pointers saved by PacketAliasSaveFragment(). 539The IP header fragment pointed to by 540Em buffer 541is the header fragment indicated when 542PacketAliasIn() returns PKT_ALIAS_FOUND_HEADER_FRAGMENT. 543Once a a fragment pointer is retrieved, it 544becomes the calling program's responsibility 545to free the dynamically allocated memory for 546the fragment. 547 548PacketAliasGetFragment() can be called 549sequentially until there are no more fragments 550available, at which time it returns NULL. 551.Ss 5.3 PacketAliasFragmentIn() 552 553.Ft void 554.Fn PacketAliasFragmentIn "char *header" "char *fragment" 555 556When a fragment is retrieved with 557PacketAliasGetFragment(), it can then be 558de-aliased with a call to PacketAliasFragmentIn(). 559.Em header 560is the pointer to a header fragment used as a 561template, and 562.Em fragment 563is the pointer to the packet to be de-aliased. 564 565.Sh 6. Miscellaneous Functions 566 567.Ss 6.1 PacketAliasSetTarget() 568 569.Ft void 570.Fn PacketAliasSetTarget "struct in_addr addr" 571 572When an incoming packet not associated with 573any pre-existing aliasing link arrives at the 574host machine, it will be sent to the address 575indicated by a call to PacketAliasSetTarget(). 576 577If this function is not called, or is called 578with a zero address argument, then all new 579incoming packets go to the address set by 580PacketAliasSetAddress. 581.Ss 6.2 PacketAliasCheckNewLink() 582 583.Ft int 584.Fn PacketAliasCheckNewLink "void" 585 586This function returns a non-zero value when 587a new aliasing link is created. In circumstances 588where incoming traffic is being sequentially 589sent to different local servers, this function 590can be used to trigger when PacketAliasSetTarget() 591is called to change the default target address. 592.Ss 6.3 PacketAliasInternetChecksum() 593 594.Ft u_short 595.Fn PacketAliasInternetChecksum "char *buffer" "int nbytes" 596 597This is a utility function that does not seem 598to be available elswhere and is included as a 599convenience. It computes the internet checksum, 600which is used in both IP and protocol-specific 601headers (TCP, UDP, ICMP). 602 603.Em buffer 604points to the data block to be checksummed, and 605.Em nbytes 606is the number of bytes. The 16-bit checksum 607field should be zeroed before computing the checksum. 608 609Checksums can also be verified by operating on a block 610of data including its checksum. If the checksum is 611valid, PacketAliasInternetChecksum() will return zero. 612 613.Sh 7. Authors 614Charles Mott (cmott@srv.net), versions 1.0 - 1.8, 2.0 - 2.4. 615 616Eivind Eklund (eivind@freebsd.org), versions 1.8b, 1.9 and 6172.5. Added IRC DCC support as well as contributing a number of 618architectural improvements; added the firewall bypass 619for FTP/IRC DCC. 620 621.Sh 8. Acknowledgments 622 623Listed below, in approximate chronological 624order, are individuals who have provided 625valuable comments and/or debugging assistance. 626 627.Bl -inset -compact -offset left 628.It Gary Roberts 629.It Tom Torrance 630.It Reto Burkhalter 631.It Martin Renters 632.It Brian Somers 633.It Paul Traina 634.It Ari Suutari 635.It Dave Remien 636.It J. Fortes 637.It Andrzej Bialeki 638.It Gordon Burditt 639.El 640 641.Sh Appendix: Conceptual Background 642This appendix is intended for those who 643are planning to modify the source code or want 644to create somewhat esoteric applications using 645the packet aliasing functions. 646 647The conceptual framework under which the 648packet aliasing engine operates is described here. 649Central to the discussion is the idea of an 650"aliasing link" which describes the relationship 651for a given packet transaction between the local 652machine, aliased identity and remote machine. It 653is discussed how such links come into existence 654and are destroyed. 655.Ss A.1 Aliasing Links 656There is a notion of an "aliasing link", 657which is 7-tuple describing a specific 658translation: 659.Bd -literal -offset indent 660(local addr, local port, alias addr, alias port, 661 remote addr, remote port, protocol) 662.Ed 663 664Outgoing packets have the local address and 665port number replaced with the alias address 666and port number. Incoming packets undergo the 667reverse process. The packet aliasing engine 668attempts to match packets against an internal 669table of aliasing links to determine how to 670modify a given IP packet. Both the IP 671header and protocol dependent headers are 672modified as necessary. Aliasing links are 673created and deleted as necessary according 674to network traffic. 675 676Protocols can be TCP, UDP or even ICMP in 677certain circumstances. (Some types of ICMP 678packets can be aliased according to sequence 679or id number which acts as an equivalent port 680number for identifying how individual packets 681should be handled.) 682 683Each aliasing link must have a unique 684combination of the following five quanties: 685alias address/port, remote address/port 686and protocol. This ensures that several 687machines on a local network can share the 688same aliased IP address. In cases where 689conflicts might arise, the aliasing port 690is chosen so that uniqueness is maintained. 691.Ss A.2 Static and Dynamic Links 692Aliasing links can either be static or dynamic. 693Static links persist indefinitely and represent 694fixed rules for translating IP packets. Dynamic 695links come into existence for a specific TCP 696connection or UDP transaction or ICMP echo 697sequence. For the case of TCP, the connection 698can be monitored to see when the associated 699aliasing link should be deleted. Aliasing links 700for UDP transactions (and ICMP echo and timestamp 701equests) work on a simple timeout rule. When 702no activity is observed on a dynamic link for 703a certain amount of time it is automatically 704deleted. Timeout rules also apply to TCP 705connections which do not open or close 706properly. 707.Ss A.3 Partially Specified Aliasing Links 708Aliasing links can be partially specified, 709meaning that the remote address and/or remote 710ports are unkown. In this case, when a packet 711matching the incomplete specification is found, 712a fully specified dynamic link is created. If 713the original partially specified link is dynamic, 714it will be deleted after the fully specified link 715is created, otherwise it will persist. 716 717For instance, a partially specified link might 718be 719.Bd -literal -offset indent 720(192.168.0.4, 23, 204.228.203.215, 8066, 0, 0, tcp) 721.Ed 722 723The zeros denote unspecified components for 724the remote address and port. If this link were 725static it would have the effect of redirecting 726all incoming traffic from port 8066 of 727204.228.203.215 to port 23 (telnet) of machine 728192.168.0.4 on the local network. Each 729individual telnet connection would initiate 730the creation of a distinct dynamic link. 731.Ss A.4 Dynamic Link Creation 732In addition to aliasing links, there are 733also address mappings that can be stored 734within the internal data table of the packet 735aliasing mechanism. 736.Bd -literal -offset indent 737(local addr, alias addr) 738.Ed 739 740Address mappings are searched when creating 741new dynamic links. 742 743All outgoing packets from the local network 744automatically create a dynamic link if 745they do not match an already existing fully 746specified link. If an address mapping exists 747for the the outgoing packet, this determines 748the alias address to be used. If no mapping 749exists, then a default address, usually the 750address of the packet aliasing host, is used. 751If necessary, this default address can be 752changed as often as each indvidual packet 753arrives. 754 755The aliasing port number is determined 756such that the new dynamic link does not 757conflict with any existing links. In the 758default operating mode, the packet aliasing 759engine attempts to set the aliasing port 760equal to the local port number. If this 761results in a conflict, then port numbers 762are randomly chosen until a unique aliasing 763link can be established. In an alternate 764operating mode, the first choice of an 765aliasing port is also random and unrelated 766to the local port number. 767 768