Network I/O: Address
This section details the structures, functions, and concepts related to network addresses in the Windows API.
Address Structures
Network addresses are represented by various structures depending on the protocol family and address type. Key structures include:
SOCKADDR and SOCKADDR_STORAGE
The SOCKADDR structure is a generic, protocol-independent structure used to hold address information. SOCKADDR_STORAGE is a larger, more flexible version that can accommodate various address family structures.
typedef struct sockaddr {
u_short sa_family; // Address family
char sa_data[14]; // Protocol-specific address information
} SOCKADDR, *PSOCKADDR, FAR *LPSOCKADDR;
typedef struct sockaddr_storage {
short int ss_family; // Address family
unsigned char __ss_padding[128 - sizeof (u_short)]; // Padding for alignment
// Additional fields for specific protocols may follow
} SOCKADDR_STORAGE, *PSOCKADDR_STORAGE;
SOCKADDR_IN (IPv4)
This structure is used to represent an IPv4 endpoint address. It includes the address family, port number, and IP address.
typedef struct in_addr {
union {
struct {
u_char s_b1, s_b2, s_b3, s_b4;
} S_un_b;
struct {
u_short s_w1, s_w2;
} S_un_w;
u_long S_addr;
} S_un;
} IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;
typedef struct sockaddr_in {
short int sin_family; // Address family (AF_INET)
u_short sin_port; // Port number
struct in_addr sin_addr; // IP address
char sin_zero[8]; // Not used
} SOCKADDR_IN, *PSOCKADDR_IN, FAR *LPSOCKADDR_IN;
SOCKADDR_IN6 (IPv6)
This structure is used for IPv6 addresses, supporting the larger address space and IPv6-specific features.
typedef struct in6_addr {
union {
u_char Byte[16];
u_short Word[8];
} u;
} IN6_ADDR, *PIN6_ADDR, FAR *LPIN6_ADDR;
typedef struct sockaddr_in6 {
short int sin6_family; // Address family (AF_INET6)
u_short sin6_port; // Port number
u_long sin6_flowinfo; // Flow information
struct in6_addr sin6_addr; // IPv6 address
u_long sin6_scope_id; // Scope identifier
} SOCKADDR_IN6, *PSOCKADDR_IN6, FAR *LPSOCKADDR_IN6;
Common Address Functions
getaddrinfo
A modern and versatile function for resolving hostnames and service names into a list of address structures.
INT WSAAPI getaddrinfo(
[in] PCSTR pNodeName,
[in] PCSTR pServiceName,
[in] const ADDRINFOA *pHints,
[out] PADDRINFOA *ppResult
);
getaddrinfo for new development as it supports both IPv4 and IPv6 and provides more flexibility than older functions like gethostbyname.
getnameinfo
The inverse of getaddrinfo, used to translate a socket address structure into a hostname and service name.
INT WSAAPI getnameinfo(
[in] const SOCKADDR *pSockaddr,
[in] SOCKLEN_T SockaddrLength,
[out] PSTR pNodeBuffer,
[in] SIZE_T NodeBufferSize,
[out] PSTR pServiceBuffer,
[in] SIZE_T ServiceBufferSize,
[in] INT Flags
);
inet_pton and inet_ntop
Functions for converting between IP address string representations (like "192.168.1.1") and their binary network formats.
// IPv4/IPv6 to binary
int inet_pton(
int Family,
PCSTR pszAddrString,
PVOID pAddrBuf
);
// Binary to IPv4/IPv6
PCSTR inet_ntop(
int Family,
PVOID pAddrBuf,
PSTR pszBuf,
size_t Size
);
Address Resolution
The process of resolving a human-readable name (like a hostname or domain name) into a numerical IP address is a fundamental part of network communication. This typically involves:
- DNS (Domain Name System): The primary mechanism for name resolution on the internet.
- Local Hosts File:
hostsfile on the local machine for static mappings. - NetBIOS Name Resolution: Used in older Windows networking environments.
Address Types
- Unicast Addresses: A single network interface.
- Multicast Addresses: A group of network interfaces.
- Broadcast Addresses: All interfaces on a subnet.