in win32/src/socket_transport_win32.c [867:1001]
int socket_transport_get_local_address(SOCKET_TRANSPORT_HANDLE socket_transport, char hostname[MAX_GET_HOST_NAME_LEN], LOCAL_ADDRESS** local_address_list, uint32_t* address_count)
{
int result;
// Codes_SOCKET_TRANSPORT_WIN32_11_001: [ If socket_transport is NULL, socket_transport_get_local_address shall fail and return a non-zero value. ]
if (socket_transport == NULL ||
// Codes_SOCKET_TRANSPORT_WIN32_11_002: [ If hostname is NULL, socket_transport_get_local_address shall fail and return a non-zero value. ]
hostname == NULL ||
// Codes_SOCKET_TRANSPORT_WIN32_11_003: [ If local_address_list is not NULL and address_count is NULL, socket_transport_get_local_address shall fail and return a non-zero value. ]
(local_address_list != NULL && address_count == NULL)
)
{
LogError("Invalid arguments: SOCKET_TRANSPORT_HANDLE socket_transport: %p, char* hostname: %p, char* local_address_list[MAX_LOCAL_ADDRESS_LEN]: %p, uint32_t* address_count: %p",
socket_transport, hostname, local_address_list, address_count);
result = MU_FAILURE;
}
else
{
// Codes_SOCKET_TRANSPORT_WIN32_11_004: [ socket_transport_get_local_address shall call sm_exec_begin ]
SM_RESULT sm_result = sm_exec_begin(socket_transport->sm);
if (sm_result != SM_EXEC_GRANTED)
{
// Codes_SOCKET_TRANSPORT_WIN32_11_011: [ If any failure is encountered, socket_transport_get_local_address shall fail and return a non-zero value. ]
LogError("sm_exec_begin failed : %" PRI_MU_ENUM, MU_ENUM_VALUE(SM_RESULT, sm_result));
result = MU_FAILURE;
}
else
{
// Codes_SOCKET_TRANSPORT_WIN32_11_005: [ socket_transport_get_local_address shall get the hostname by calling gethostname. ]
if (gethostname(hostname, MAX_GET_HOST_NAME_LEN) == SOCKET_ERROR)
{
// Codes_SOCKET_TRANSPORT_WIN32_11_011: [ If any failure is encountered, socket_transport_get_local_address shall fail and return a non-zero value. ]
LogLastError("Unable to get hostname");
result = MU_FAILURE;
}
else
{
if (local_address_list != NULL)
{
// Codes_SOCKET_TRANSPORT_WIN32_11_006: [ If local_address_list is not NULL, socket_transport_get_local_address shall call gethostbyname to get the addresses in a hostent object. ]
struct hostent* host_info = gethostbyname(hostname);
if (host_info == NULL)
{
// Codes_SOCKET_TRANSPORT_WIN32_11_011: [ If any failure is encountered, socket_transport_get_local_address shall fail and return a non-zero value. ]
LogLastError("Failure in call to gethostbyname %s", hostname);
result = MU_FAILURE;
}
else
{
if (host_info->h_addrtype == AF_INET)
{
uint32_t total_count = 0;
uint32_t address_index = 0;
struct in_addr addr;
// Count the address returned
while (host_info->h_addr_list[total_count] != 0)
{
total_count++;
}
// Allocate the array
// Codes_SOCKET_TRANSPORT_WIN32_11_007: [ socket_transport_get_local_address shall allocate a LOCAL_ADDRESS array. ]
LOCAL_ADDRESS* temp_list = malloc_2(total_count, sizeof(LOCAL_ADDRESS));
if (temp_list == NULL)
{
// Codes_SOCKET_TRANSPORT_WIN32_11_011: [ If any failure is encountered, socket_transport_get_local_address shall fail and return a non-zero value. ]
LogError("failure in malloc_2(total_count: %" PRIu32 ", sizeof(LOCAL_ADDRESS): %zu)", total_count, sizeof(LOCAL_ADDRESS));
result = MU_FAILURE;
}
else
{
bool failure = false;
// Codes_SOCKET_TRANSPORT_WIN32_11_008: [ For each IP in the hostent object, socket_transport_get_local_address shall copy the value into the LOCAL_ADDRESS address by calling inet_ntop. ]
while (host_info->h_addr_list[address_index] != 0)
{
temp_list[address_index].address_type = ADDRESS_INET;
addr.s_addr = *(u_long*)host_info->h_addr_list[address_index];
if (inet_ntop(AF_INET, &(addr.s_addr), temp_list[address_index].address, MAX_LOCAL_ADDRESS_LEN) == NULL)
{
LogLastError("failure in retreiving network name");
failure = true;
break;
}
else
{
LogInfo("IPv4 Address #: %s", temp_list[address_index].address);
address_index++;
}
}
if (failure)
{
// Codes_SOCKET_TRANSPORT_WIN32_11_011: [ If any failure is encountered, socket_transport_get_local_address shall fail and return a non-zero value. ]
free(temp_list);
result = MU_FAILURE;
}
else
{
*address_count = total_count;
*local_address_list = temp_list;
result = 0;
}
}
}
else if (host_info->h_addrtype == AF_INET6)
{
address_count = 0;
result = 0;
}
else if (host_info->h_addrtype == AF_NETBIOS)
{
address_count = 0;
result = 0;
}
else
{
// Codes_SOCKET_TRANSPORT_WIN32_11_011: [ If any failure is encountered, socket_transport_get_local_address shall fail and return a non-zero value. ]
LogError("Unknown address type h_addrtype: %d", host_info->h_addrtype);
result = MU_FAILURE;
}
}
}
else
{
// Codes_SOCKET_TRANSPORT_WIN32_11_010: [ On success socket_transport_get_local_address shall return 0. ]
result = 0;
}
}
// Codes_SOCKET_TRANSPORT_WIN32_11_009: [ socket_transport_get_local_address shall call sm_exec_end. ]
sm_exec_end(socket_transport->sm);
}
}
return result;
}