IP Address Notes
With Open Transport's support for reconfiguration without
reboot and "on demand" address acquisition (for example,
DHCP), you must be careful not to assume that the machine
has a single static IP address. Specifically:
- If
OTInetGetInterfaceInfo returns an
error when you pass it an index of 0, the TCP/IP stack is
not currently loaded. In this state, the computer
does not have an IP address. You can
force the machine to acquire an IP addresses by loading
the TCP/IP stack, but this may have adverse consequences.
See No Nuisance Calls,
Please.
- The machine may have more than one IP
address. A computer running stock Mac OS can
currently only have more than one IP address in the
"single link multi-homing" case (multiple IP addresses on
the same physical interface), although future versions of
Open Transport may support multi-link multi-homing, and
you can enable multi-link multi-homing today using third-
party software. You can determine the list of IP
addresses for the machine using the calls
OTGetInterfaceInfo and
OTInetGetSecondaryAddresses , as shown in the
code snippet below.
- The machine's list of IP addresses may change over
time. Currently there is no way to detect this change, so
you must avoid caching the list of local IP
addresses for extended periods. Your software
should not get the machine's IP address once it's
launched and use the same address until it quits.
Instead, it must reacquire the address each time it's
needed.
- The "correct" IP address for the machine may
depend on whom you're talking to. This situation
is described in detail in a
later
section.
Getting a List of All IP Addresses
The following code snippet shows how to determine the
list of IP addresses for the machine using the calls
OTGetInterfaceInfo and
OTInetGetSecondaryAddresses .
enum
{
kOTIPSingleLinkMultihomingVersion = 0x01300000
};
static OSStatus PrintIPAddresses(void)
{
OSStatus err;
Boolean haveIPSingleLinkMultihoming;
NumVersionVariant otVersion;
Boolean done;
SInt32 interfaceIndex;
InetInterfaceInfo info;
haveIPSingleLinkMultihoming =
( Gestalt(gestaltOpenTptVersions, (long *) &otVersion) == noErr
&& ( otVersion.whole >=
kOTIPSingleLinkMultihomingVersion )
&& ( OTInetGetSecondaryAddresses !=
(void *) kUnresolvedCFragSymbolAddress));
err = noErr;
interfaceIndex = 0;
do {
done = ( OTInetGetInterfaceInfo(&info, interfaceIndex) != noErr );
if ( ! done ) {
printf("fAddress = %08lx\n", info.fAddress);
if ( haveIPSingleLinkMultihoming ) {
err = PrintSecondaryAddresses(&info, interfaceIndex);
}
interfaceIndex += 1;
}
} while (err == noErr && !done);
return err;
}
|
IMPORTANT:
OTInetGetSecondaryAddresses is not
implemented prior to Open Transport 1.3. To work
correctly with systems prior to that, you must weak-
link with the OpenTptInternetLib and check for its
existence by comparing its address to
kUnresolvedCFragSymbolAddress . For
more information about weak-linking, you should
read Technote 1083:
Weak-Linking
to a Code Fragment Manager-based Shared
Library.
|
static OSStatus PrintSecondaryAddresses(InetInterfaceInfo* interfaceInfo,
SInt32 interfaceIndex)
{
OSStatus err;
InetHost *secondaryAddressBuffer;
UInt32 numberOfSecondaryAddresses;
UInt32 addressIndex;
secondaryAddressBuffer = nil;
numberOfSecondaryAddresses = interfaceInfo->fIPSecondaryCount;
if ( err == noErr && numberOfSecondaryAddresses > 0 ) {
// Allocate a buffer for the secondary address info.
secondaryAddressBuffer =
(InetHost *) OTAllocMem( numberOfSecondaryAddresses
* sizeof(InetHost) );
if (secondaryAddressBuffer == nil) {
err = kENOMEMErr;
}
// Ask OT for the list of secondary addresses on this interface.
if (err == noErr) {
err = OTInetGetSecondaryAddresses(secondaryAddressBuffer,
&numberOfSecondaryAddresses,
interfaceIndex);
}
// Start a server for each secondary address.
for (addressIndex = 0; addressIndex < numberOfSecondaryAddresses;
addressIndex++) {
printf("secondaryAddressBuffer[%ld] = %08lx\n",
addressIndex,
secondaryAddressBuffer[addressIndex]);
}
}
// Clean up.
if (secondaryAddressBuffer != nil) {
OTFreeMem(secondaryAddressBuffer);
}
return err;
}
|
Multi-homing and IP Addresses
On a multi-link multi-homed computer, it's possible for
the "correct" IP address of the machine to depend on the IP
address of the machine you're communicating with.
For example, consider a machine with two Ethernet cards,
one connected to the public Internet and one connected to a
private network. Each card has an IP address but the machine
does not forward IP packets between the cards. This
situation is illustrated below:

Now consider an FTP client running on this computer. One
of the (mis)features of the FTP protocol is that, when it
opens a data connection, the FTP client
must open a port on the local machine and send (through the
control connection) the port number and the
local IP address to the server in a PORT command. However,
machines on the public Internet can only communicate with
17.100.55.7, and machines on the private network can only
communicate with 17.200.37.41. So how does the FTP client
work out which IP address to send?
The answer is that the OTGetProtAddress call
will return the correct local IP address for a connected
endpoint. So the FTP client can call
OTGetProtAddress on the control connection to
determine the correct local address to use for the data
connection.
The following code snippet uses
OTGetProtAddress to find the correct local IP
address to send based on a connected endpoint.
static OSStatus GetLocalIPAddressForConnection(EndpointRef ep,
InetAddress *localAddr)
{
OSStatus err;
TBind localBind;
OTAssert("GetLocalIPAddressForConnection: Only works while connected",
OTGetEndpointState(ep) == T_DATAXFER);
OTMemzero(&localBind, sizeof(TBind));
localBind.addr.buf = (UInt8 *) localAddr;
localBind.addr.maxlen = sizeof(InetAddress);
err = OTGetProtAddress(ep, &localBind, nil);
return err;
}
|
Note:
This routine asserts that the endpoint is in the
T_DATAXFER state because, if the
endpoint is not connected,
OTGetProtAddress will simply return
the address to which the endpoint was bound, which
is generally not at all helpful.
|
IMPORTANT:
Due to limitations in the current Open Transport
architecture, the IP address returned by the above
may not be in the list of all IP addresses
generated by the code in the
previous
section.
|
|