Re: gethostname returns loginname on "Pather Server" version
Re: gethostname returns loginname on "Pather Server" version
- Subject: Re: gethostname returns loginname on "Pather Server" version
- From: Zack Morris <email@hidden>
- Date: Sat, 07 Feb 2004 18:28:28 -0700
>
But, to answer your question... Using BSD calls the recommended API
>
would be getifaddrs(3) to get the addresses (yes, plural) and then
>
"pick one". If you want to step up a layer you can use the
>
SystemConfiguration.framework APIs to capture what we believe to be the
>
"primary" IP address. ... and many other APIs exist.
Here is the code I use. The routines of interest are:
GetHostIPAddresses();
main();
It is pulled from various files in my engine, so is untested, you will most
likely have to include some open transport and framework loading files. I
am posting for a selfish reason - can someone please look at my
GetHostIPAddresses() routine and see if there are some other cases I can
exclude? On my computer it properly reports the ethernet and airport IPs,
but on others there might be more service types that I am not aware of. I
know that I could use the SCF OS X method at:
http://developer.apple.com/technotes/tn/tn1145.html
But I am trying to make a standardized sockets library I can use on all
OS's. I included code for emulating the sockets call getifaddrs() on OS 9,
and I include many more in my engine so that I can use sockets on 9, which I
have not included here. If you are only using X, ignore the OS 9 section.
I heard that codewarrior has a multithreaded version of sockets now, is this
true? Are there any drawbacks to using it? I use this code in CW, haven't
used xcode yet. The file is called GetIPs.c and is also here:
http://homepage.mac.com/zmorris
GetIPs.c
Well, thanx for your help,
----------------------------------------------------------------------------
Zack Morris Z Sculpt Entertainment This Space
email@hidden
http://www.zsculpt.com For Rent
----------------------------------------------------------------------------
If the doors of perception were cleansed, everything would appear to man as
it is, infinite. -William Blake, The Marriage of Heaven and Hell
//************************ begin file GetIPs.c ************************
// types gathered from various unix inlude files like #include
<sys/socket.h>
/*
* Address families.
*/
#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
#define AF_INET6 30 /* IPv6 */
#define IFF_UP 0x1 /* interface is up */
#define IFF_LOOPBACK 0x8 /* is a loopback net */
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned int u_int;
typedef u_int32_t in_addr_t; /* base type for internet address */
/*
* Internet address (a structure for historical reasons)
*/
struct in_addr {
in_addr_t s_addr;
};
/*
* Structure used by kernel to store most
* addresses.
*/
struct sockaddr {
u_char sa_len; /* total length */
u_char sa_family; /* address family */
char sa_data[14]; /* actually longer; address value */
};
/*
* Socket address, internet style.
*/
struct sockaddr_in {
u_char sin_len;
u_char sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
// struct used by getifaddrs to return the list of interfaces on a machine
struct ifaddrs {
struct ifaddrs *ifa_next;
char *ifa_name;
u_int ifa_flags;
struct sockaddr *ifa_addr;
struct sockaddr *ifa_netmask;
struct sockaddr *ifa_dstaddr;
void *ifa_data;
};
int *getifaddrs( struct ifaddrs **ifap );
void *freeifaddrs( struct ifaddrs *ifap );
//******************** get IP address list of this machine *******
#define kMaxGetHostIPAddresses 10
// copies up to kMaxGetHostIPAddresses adresses into addr
// the address is held in in_addr[].s_addr
// pass nil or nothing to just return a count of the IPs
// returns the number of addresses
int GetHostIPAddresses( in_addr_t *addr )
{
ifaddrs *addrs;
int total = 0;
if( getifaddrs( &addrs ) == noErr )
{
while( addrs && total < kMaxGetHostIPAddresses )
{
if( (addrs->ifa_flags & IFF_UP) &&
!(addrs->ifa_flags & IFF_LOOPBACK) &&
addrs->ifa_addr->sa_family == AF_INET &&
(addrs->ifa_addr->sa_family & AF_INET6) != AF_INET6 &&
addrs->ifa_addr != nil )
{
addr[total] = ((sockaddr_in*)
addrs->ifa_addr)->sin_addr.s_addr;
total++;
}
addrs = addrs->ifa_next;
}
freeifaddrs( addrs );
}
return( total );
}
void InitSockets( void );
void main( void )
{
in_addr_t addr[kMaxGetHostIPAddresses];
int total;
InitSockets();
total = GetHostIPAddresses( addr );
if( total )
{
char str[256];
for( int i = 0; i < total; i++ )
{
OTInetHostToString( addr[i], str ); // the first address is
usually the main one
cout << str;
}
}
else
cout << "127.0.0.1"; // let the user know that they are not
connected to the network or the tcp stack is not loaded
}
#pragma mark -
//************ OS 9 compatiblity section, for emulating sockets *******
typedef InetHost **InetHostHandle;
static OSStatus AddSecondaryAddresses(
InetInterfaceInfo* interfaceInfo,
SInt32 interfaceIndex,
InetHostHandle addrList)
{
OSStatus err;
InetHost *addrBuf;
UInt32 addrCount;
addrBuf = NULL;
addrCount = interfaceInfo->fIPSecondaryCount;
// Allocate a buffer for the secondary address info.
addrBuf = (InetHost *) NewPtr(addrCount * sizeof(InetHost));
if (addrBuf == NULL) {
err = kENOMEMErr;
}
// Ask OT for the list of secondary addresses on this
// interface and add each secondary address to the list.
if (err == noErr) {
err = OTInetGetSecondaryAddresses(addrBuf,
&addrCount,
interfaceIndex);
}
if (err == noErr) {
err = PtrAndHand(addrBuf,
(Handle) addrList,
addrCount * sizeof(InetHost));
}
// Clean up.
if (addrBuf != NULL) {
DisposePtr( (Ptr) addrBuf );
}
return err;
}
enum
{
kOTIPSingleLinkMultihomingVersion = 0x01300000
};
static OSStatus GetIPAddressListOT(InetHostHandle addrList)
{
OSStatus err;
Boolean haveIPSingleLinkMultihoming;
NumVersionVariant otVersion;
SInt32 interfaceIndex;
InetInterfaceInfo info;
Boolean done;
// Must be running at system task time.
#ifdef dvlopCODE
if( TaskLevel() != 0 ) ErrorDialog( "\pMust call GetIPAddressListOT() at
system task time" );
#endif
SetHandleSize( (Handle) addrList, 0 );
#ifdef dvlopCODE
if( MemError() != noErr ) ErrorDialog( "\pA bad handle was passed to
GetIPAddressListOT()" );
#endif
haveIPSingleLinkMultihoming =
( Gestalt(gestaltOpenTptVersions, (long *) &otVersion) == noErr
&& (otVersion.whole >= kOTIPSingleLinkMultihomingVersion )
&& ( OTInetGetSecondaryAddresses
!= (void *) kUnresolvedCFragSymbolAddress));
err = noErr;
done = false;
interfaceIndex = 0;
do {
done = ( OTInetGetInterfaceInfo(&info, interfaceIndex) != noErr );
if ( ! done ) {
// If all interfaces are disabled Mac OS X
// returns a single interface with a 0
// address, so we specifically exclude that.
// Otherwise just add the IP address of this
// interface to the list.
if (info.fAddress != kOTAnyInetAddress) {
err = PtrAndHand(&info.fAddress,
(Handle) addrList,
sizeof(InetHost));
}
// Now add any secondary addresses.
if ( err == noErr
&& haveIPSingleLinkMultihoming
&& info.fIPSecondaryCount > 0 ) {
err = AddSecondaryAddresses(&info,
interfaceIndex,
addrList);
}
interfaceIndex += 1;
}
} while (err == noErr && !done);
return err;
}
int MYgetifaddrs( struct ifaddrs **ifap )
{
OSStatus err;
static InetHostHandle hosts = (InetHost**) NewHandle( 0 );
if( !hosts )
{
//errno = ENOMEM;
return( -1 );
}
err = GetIPAddressListOT( hosts );
if( err )
{
DisposeHandle( hosts );
//errno = ENOMEM;
return( -1 );
}
int count = GetHandleSize( hosts )/sizeof(
InetHost );
if( count )
{
*ifap = (ifaddrs *) NewPtrClear( count * (sizeof(ifaddrs) + sizeof(
sockaddr_in )) ); // for now, only the ifa_addr is allocated
if( !*ifap )
{
DisposeHandle( hosts );
//errno = ENOMEM;
return( -1 );
}
ifaddrs *theEntry = *ifap;
sockaddr_in *theAddr = (sockaddr_in*) ((char*)
theEntry + count * sizeof(ifaddrs)); // the addresses are at the end of
the buffer
for( int i = 0; i < count; i++ )
{
theAddr[i].sin_len = 4;
theAddr[i].sin_family = AF_INET;
theAddr[i].sin_addr = ((in_addr*) (*hosts))[i];
theEntry[i].ifa_addr = (sockaddr*) &(theAddr[i]);
theEntry[i].ifa_flags = IFF_UP;
theEntry[i].ifa_next = &(theEntry[i+1]);
}
theEntry[count-1].ifa_next = nil;
}
else
*ifap = nil;
DisposeHandle( hosts );
return( noErr );
}
void MYfreeifaddrs( struct ifaddrs *ifap )
{
if( ifap ) DisposePtr( ifap );
}
CFBundleRef curBUNDLE;
Boolean osxMODE;
// untested code, probably must learn how bundles import to get working
void InitSockets( void )
{
OSStatus err = noErr;
//Check to see if we are running MacOS X
long systemVersion = 0;
OSStatus err = Gestalt( gestaltSystemVersion, &systemVersion );
if( err ) ErrorDialog( "\pUnable to get the system version" );
if( systemVersion > 0x09FF) // we are running OS X or better
osxMODE = true;
else
osxMODE = false;
if( osxMODE )
{
err = LoadFrameworkBundle( CFSTR("System.framework"), &curBUNDLE );
if( err ) ErrorDialog( "\pCouldn't load the System.framework
bundle." );
getifaddrs = (void*) CFBundleGetFunctionPointerForName( curBUNDLE,
CFSTR( "getifaddrs" ) );
if( !getifaddrs ) ErrorDialog( "\pCouldn't find getifaddrs" );
getifaddrs = (void*) CFBundleGetFunctionPointerForName( curBUNDLE,
CFSTR( "freeifaddrs" ) );
if( !getifaddrs ) ErrorDialog( "\pCouldn't find freeifaddrs" );
}
else
{
getifaddrs = MYgetifaddrs;
freeifaddrs = MYfreeifaddrs;
}
}
_______________________________________________
macnetworkprog mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/macnetworkprog
Do not post admin requests to the list. They will be ignored.