char *sockaddr_to_string_with_port (char addrbuf[INET6_ADDRSTRLEN_EXTENDED], const os_sockaddr_storage *src) { int pos; switch (src->ss_family) { case AF_INET: os_sockaddrAddressToString ((const os_sockaddr *) src, addrbuf, INET6_ADDRSTRLEN); pos = (int) strlen (addrbuf); snprintf (addrbuf + pos, INET6_ADDRSTRLEN_EXTENDED - pos, ":%u", ntohs (((os_sockaddr_in *) src)->sin_port)); break; #if OS_SOCKET_HAS_IPV6 case AF_INET6: addrbuf[0] = '['; os_sockaddrAddressToString ((const os_sockaddr *) src, addrbuf + 1, INET6_ADDRSTRLEN); pos = (int) strlen (addrbuf); snprintf (addrbuf + pos, INET6_ADDRSTRLEN_EXTENDED - pos, "]:%u", ntohs (((os_sockaddr_in6 *) src)->sin6_port)); break; #endif default: NN_WARNING0 ("sockaddr_to_string_with_port: unknown address family\n"); strcpy (addrbuf, "???"); break; } return addrbuf; }
os_int nw_socketGetDefaultLoopbackAddress( os_int sockfd, os_sockaddr_storage *sockAddr) { /* Statics for storing the result */ static os_sockaddr_storage sockAddrFound; static os_int hadSuccessBefore = SK_FALSE; /* Normal variables for retrieving the result */ os_int success; sk_interfaceInfo *interfaceList; os_uint nofInterfaces; char addressStr[INET6_ADDRSTRLEN]; if (!hadSuccessBefore) { success = sk_interfaceInfoRetrieveAllLoopback(&interfaceList, &nofInterfaces, sockfd); if (success) { sockAddrFound = *(os_sockaddr_storage *)sk_interfaceInfoGetPrimaryAddress( interfaceList[0]); hadSuccessBefore = SK_TRUE; /* Diagnostics */ NW_TRACE_2(Configuration, 2, "Identified loopback enabled interface %s " "having primary address %s", sk_interfaceInfoGetName(interfaceList[0]), os_sockaddrAddressToString((os_sockaddr*) &sockAddrFound, addressStr, sizeof(addressStr))); /* Free mem used */ sk_interfaceInfoFreeAll(interfaceList, nofInterfaces); } } if (hadSuccessBefore) { *sockAddr = sockAddrFound; } return hadSuccessBefore; }
char *sockaddr_to_string_no_port (char addrbuf[INET6_ADDRSTRLEN_EXTENDED], const os_sockaddr_storage *src) { return os_sockaddrAddressToString ((const os_sockaddr *) src, addrbuf, INET6_ADDRSTRLEN); }
os_result os_sockQueryIPv6Interfaces( os_ifAttributes *ifList, os_uint32 listSize, os_uint32 *validElements) { os_result result = os_resultSuccess; os_result addressInfoResult =0; unsigned long returnedBytes; unsigned int listIndex; os_socket ifcs; int retVal, done; char* errorMessage; os_sockErrno errNo; PIP_ADAPTER_ADDRESSES pAddresses = NULL; PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL; PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL; unsigned long outBufLen = 0; /* Set the flags to pass to GetAdaptersAddresses*/ unsigned long flags = GAA_FLAG_INCLUDE_PREFIX; int i = 0; /* IPv6 addition */ SOCKET_ADDRESS_LIST* ipv6InterfaceList; *validElements = 0; listIndex = 0; outBufLen = sizeof (IP_ADAPTER_ADDRESSES); pAddresses = (IP_ADAPTER_ADDRESSES *) os_malloc(outBufLen); if (GetAdaptersAddresses(AF_INET6, flags, NULL, pAddresses, &outBufLen) == ERROR_BUFFER_OVERFLOW) { os_free(pAddresses); pAddresses = (IP_ADAPTER_ADDRESSES *) os_malloc(outBufLen); } addressInfoResult = GetAdaptersAddresses(AF_INET6, flags, NULL, pAddresses, &outBufLen); /* Now do the IPv6 interfaces */ ifcs = os_sockNew (AF_INET6, SOCK_DGRAM); if (ifcs != INVALID_SOCKET) { /* List returned from this control code query will need to be sized as 1 * SOCKET_ADDRESS_LIST + n * SOCKET_ADDRESS */ ipv6InterfaceList = os_malloc(sizeof(SOCKET_ADDRESS_LIST) + ((MAX_INTERFACES - 1) * sizeof(SOCKET_ADDRESS))); memset(ipv6InterfaceList, 0, sizeof(SOCKET_ADDRESS_LIST) + ((MAX_INTERFACES - 1) * sizeof(SOCKET_ADDRESS))); retVal = WSAIoctl(ifcs, SIO_ADDRESS_LIST_QUERY, NULL, 0, ipv6InterfaceList, sizeof(SOCKET_ADDRESS_LIST) + ((MAX_INTERFACES - 1) * sizeof(SOCKET_ADDRESS)), &returnedBytes, 0, 0); if (retVal == SOCKET_ERROR && WSAGetLastError() == WSAEFAULT) { /* The buffer wasn't big enough. returnedBytes will now contain the required size so we can reallocate & try again */ os_free(ipv6InterfaceList); ipv6InterfaceList = os_malloc(returnedBytes); memset(ipv6InterfaceList, 0, returnedBytes); retVal = WSAIoctl(ifcs, SIO_ADDRESS_LIST_QUERY, NULL, 0, ipv6InterfaceList, returnedBytes, &returnedBytes, 0, 0); } if (retVal == SOCKET_ERROR) { errNo = os_sockError(); errorMessage = os_sockErrnoToString(errNo); os_report(OS_ERROR, "os_sockQueryInterfaces", __FILE__, __LINE__, 0, "Socket error calling WSAIoctl for IPv6 interfaces: %d %s", errNo, errorMessage); os_free(errorMessage); /* @todo Is it right to return a fail here ? Need to check on box w/ no IPv6 interfaces */ result = os_resultFail; } else { for (i = 0; i < ipv6InterfaceList->iAddressCount; ++i) { if (ipv6InterfaceList->Address[i].lpSockaddr->sa_family == AF_INET6 && ! (IN6_IS_ADDR_UNSPECIFIED(&((os_sockaddr_in6 *)&ipv6InterfaceList->Address[i].lpSockaddr)->sin6_addr))) { done = 0; if (addressInfoResult == NO_ERROR) { pCurrAddresses = pAddresses; while (pCurrAddresses && !done) { /* adapter needs to be enabled*/ if (pCurrAddresses->OperStatus == IfOperStatusUp) { pUnicast = pCurrAddresses->FirstUnicastAddress; while (pUnicast && !done) { /* check if interface ip matches adapter ip */ if (os_sockaddrIPAddressEqual((os_sockaddr*) ipv6InterfaceList->Address[i].lpSockaddr, (os_sockaddr*) pUnicast->Address.lpSockaddr)) { snprintf(ifList[listIndex].name, OS_IFNAMESIZE, "%wS", pCurrAddresses->FriendlyName); ifList[listIndex].interfaceIndexNo = (os_uint) pCurrAddresses->Ipv6IfIndex; done = 1; } pUnicast = pUnicast->Next; } } pCurrAddresses = pCurrAddresses->Next; } } /* if no name was found set this interface name to string representation of the IPv6 address */ if (!done) { os_sockaddrAddressToString((os_sockaddr*) ipv6InterfaceList->Address[i].lpSockaddr, ifList[listIndex].name, OS_IFNAMESIZE); os_report(OS_WARNING, "os_sockQueryInterfaces", __FILE__, __LINE__, 0, "Unable to determine IPv6 adapter name. Setting instead to adapter address %s", ifList[listIndex].name); } ifList[listIndex].flags = 0; ifList[listIndex].address = *((os_sockaddr_storage*) ipv6InterfaceList->Address[i].lpSockaddr); listIndex++; ++(*validElements); } } } os_sockFree (ifcs); } if (addressInfoResult == NO_ERROR) { os_free(pAddresses); } return result; }