getnameinfo Function

Defined in: ws2tcpip.h
Included in: Winsock2.h

The getnameinfo function retrieves a name and a port number for a specified socket address.

Syntax

int getnameinfo( _In_ const sockaddr *Sa, _In_ socklen_t SaSize, _Out_writes_opt_(NI_MAXHOST) char *NodeBuffer, _In_ DWORD NodeBufferSize, _Out_writes_opt_(NI_MAXSERV) char *ServiceBuffer, _In_ DWORD ServiceBufferSize, _In_ int Flags );

Parameters

Parameter Description
Sa A pointer to a sockaddr structure that contains the socket address to query.
SaSize The size, in bytes, of the structure pointed to by the Sa parameter.
NodeBuffer A buffer to receive the null-terminated host name. If this parameter is NULL, the host name is not retrieved.
NodeBufferSize The size, in bytes, of the buffer pointed to by the NodeBuffer parameter. If NodeBuffer is not NULL, this value must be large enough to hold the host name and a null terminator. The maximum possible size is NI_MAXHOST.
ServiceBuffer A buffer to receive the null-terminated port number (as a service name or port number string). If this parameter is NULL, the service name or port number is not retrieved.
ServiceBufferSize The size, in bytes, of the buffer pointed to by the ServiceBuffer parameter. If ServiceBuffer is not NULL, this value must be large enough to hold the port number string and a null terminator. The maximum possible size is NI_MAXSERV.
Flags Flags that control the name resolution process. This parameter can be zero or a combination of the following values:
  • NI_NOFQDN: Returns the namespace label only (e.g., "hostname" instead of "hostname.example.com").
  • NI_NUMERICHOST: Returns the numeric form of the host name.
  • NI_NAMEREQD: Returns the name for the host if the name is required. If the name cannot be resolved, an error is returned.
  • NI_NUMERICSERV: Returns the numeric form of the service.
  • NI_DNS_SEARCH: Performs a DNS search for the hostname.

Return Value

On success, getnameinfo returns zero. On failure, it returns a non-zero error code.

Common error codes include:

  • NI_ASYNC: The request is asynchronous.
  • NI_SALENOTVALID: The length of the socket address structure is not valid.
  • NI_LOOKUPFAILED: The name lookup failed.
  • NI_SYS_ERR: A system error occurred.

Use the WSAGetLastError function to retrieve the specific error code.

Remarks

The getnameinfo function is used to translate a socket address structure into a host name and a service name or port number.

The function is designed to be an IPv6-aware replacement for older functions like gethostbyaddr and getservbyport.

When resolving host names, getnameinfo uses the naming services configured on the system, which may include DNS, WINS, or the local hosts file.

Important: If NI_NAMEREQD is set and the host name cannot be resolved, getnameinfo will return an error. Without this flag, it will return the numeric IP address if the name cannot be resolved.

Example


#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>

#pragma comment(lib, "Ws2_32.lib")

int main() {
    WSADATA wsaData;
    SOCKET sock = INVALID_SOCKET;
    struct sockaddr_in6 sa_server; // Using IPv6 structure for generality
    char host_buffer[NI_MAXHOST];
    char service_buffer[NI_MAXSERV];
    int result;

    // Initialize Winsock
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        printf("WSAStartup failed.\n");
        return 1;
    }

    // Example: An IPv6 address (e.g., localhost)
    // IN6ADDR_LOOPBACK_INIT(&sa_server.sin6_addr); // This macro is for IPv6
    // inet_pton(AF_INET6, "::1", &sa_server.sin6_addr); // Alternative for IPv6
    
    // Example: An IPv4 address (using sockaddr_in within a generic sockaddr)
    struct sockaddr_in sa_ipv4;
    inet_pton(AF_INET, "127.0.0.1", &sa_ipv4.sin_addr);
    sa_ipv4.sin_family = AF_INET;
    sa_ipv4.sin_port = htons(80); // Example port for HTTP

    // Cast to sockaddr for getnameinfo
    struct sockaddr* sa_ptr = (struct sockaddr*)&sa_ipv4;
    socklen_t sa_len = sizeof(sa_ipv4);


    // Call getnameinfo
    result = getnameinfo(sa_ptr, sa_len,
                         host_buffer, sizeof(host_buffer),
                         service_buffer, sizeof(service_buffer),
                         NI_NUMERICHOST | NI_NUMERICSERV); // Example flags

    if (result != 0) {
        printf("getnameinfo failed with error: %d\n", result);
        WSACleanup();
        return 1;
    }

    printf("Host: %s\n", host_buffer);
    printf("Service: %s\n", service_buffer);

    WSACleanup();
    return 0;
}