/* * * @APPLE_LICENSE_HEADER_START@ * * Copyright (c) 1999-2001 Apple Computer, Inc. All Rights Reserved. The * contents of this file constitute Original Code as defined in and are * subject to the Apple Public Source License Version 1.2 (the 'License'). * You may not use this file except in compliance with the License. Please * obtain a copy of the License at http://www.apple.com/publicsource and * read it before using this file. * * This 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 #include #include #include #include #include #include #include #include #endif #include #include #include #include #if __solaris__ #include #include #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 unsigned long 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__) 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); //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; }