Darwin-Streaming-Server/PlaylistBroadcaster.tproj/GetLocalIPAddressString.c

166 lines
4.7 KiB
C
Raw Permalink Normal View History

/*
*
* @APPLE_LICENSE_HEADER_START@
*
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*
*/
#include "GetLocalIPAddressString.h"
#ifdef __MACOS__
#include "BogusDefs.h"
#else
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <net/if.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include "SafeStdLib.h"
#include <unistd.h>
#include <string.h>
#if __solaris__ || __sgi__
#include <sys/sockio.h>
#include <stropts.h>
#endif
short GetLocalIPAddressString(char *returnStr, short maxSize)
{
short result = 0;
int err = -1;
char defaultAddress[] = "255.255.255.255";
char* addr = defaultAddress;
do
{
//Most of this code is similar to the SIOCGIFCONF code presented in Stevens,
//Unix Network Programming, section 16.6
//Use the SIOCGIFCONF ioctl call to iterate through the network interfaces
static const UInt32 kMaxAddrBufferSize = 2048;
char* ifReqIter = NULL;
struct ifconf ifc;
struct ifreq* ifr;
char buffer[kMaxAddrBufferSize];
int tempSocket = socket(AF_INET, SOCK_DGRAM, 0);
if (tempSocket == -1) break;
ifc.ifc_len = kMaxAddrBufferSize;
ifc.ifc_buf = buffer;
#if (__linux__ || __MacOSX__ || __MACOS__ || __linuxppc__ || __solaris__ || __sgi__)
err = ioctl(tempSocket, SIOCGIFCONF, (char*)&ifc);
#elif __FreeBSD__
err = ioctl(tempSocket, OSIOCGIFCONF, (char*)&ifc);
#else
#error
#endif
if (err == -1) break;
#if __FreeBSD__
{
int netdev1, netdev2;
struct ifreq *netdevifr;
netdevifr = ifc.ifc_req;
netdev1 = ifc.ifc_len / sizeof(struct ifreq);
for (netdev2=netdev1-1; netdev2>=0; netdev2--)
{
if (ioctl(tempSocket, SIOCGIFADDR, &netdevifr[netdev2]) != 0)
continue;
}
}
#endif
close(tempSocket);
tempSocket = -1;
// int numIPAddrs = 0;
for (ifReqIter = buffer; ifReqIter < (buffer + ifc.ifc_len);)
{
ifr = (struct ifreq*)ifReqIter;
#if __MacOSX__
ifReqIter += sizeof(ifr->ifr_name) + ifr->ifr_addr.sa_len;
if (ifr->ifr_addr.sa_len == 0)
{
switch (ifr->ifr_addr.sa_family)
{
case AF_INET:
ifReqIter += sizeof(struct sockaddr_in);
break;
default:
ifReqIter += sizeof(struct sockaddr);
}
}
#else
ifReqIter += sizeof(ifr->ifr_name) + 0;
switch (ifr->ifr_addr.sa_family)
{
case AF_INET:
ifReqIter += sizeof(struct sockaddr_in);
break;
default:
ifReqIter += sizeof(struct sockaddr);
}
#endif
//Only count interfaces in the AF_INET family.
//And don't count localhost, loopback interfaces
if ((ifr->ifr_addr.sa_family == AF_INET) && (strncmp(ifr->ifr_name, "lo", 2) != 0))
{
struct sockaddr_in* addrPtr = (struct sockaddr_in*)&ifr->ifr_addr;
addr = inet_ntoa(addrPtr->sin_addr);
//qtss_printf("found local address: %s\n", addr);
err = 0;
break;
}
}
} while (0);
result = strlen(addr);
if (maxSize < result)
{ err = -1;
}
else
strcpy(returnStr, addr);
return err;
}