Winsock Address Family Specific Structures

This section details the structures used by Windows Sockets (Winsock) to represent network addresses for various address families, such as IPv4 and IPv6. Understanding these structures is crucial for developing network-aware applications.

Overview

Winsock uses a set of structures to store and manipulate network address information. The specific structure used depends on the address family of the socket. The most common address families are:

The primary structure for handling addresses in Winsock is the SOCKADDR structure, which is a generic structure. For specific address families, more specialized structures are used, such as SOCKADDR_IN for IPv4 and SOCKADDR_IN6 for IPv6. These specialized structures are often cast to SOCKADDR* when passed to Winsock functions.

SOCKADDR_IN (IPv4)

The SOCKADDR_IN structure is used to specify an IPv4 endpoint address. It contains the address family, port number, and the IPv4 address itself.

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;

typedef struct sockaddr_in {
    short int          sin_family;   // Address family (AF_INET)
    u_short            sin_port;     // Port number
    struct in_addr     sin_addr;     // IPv4 address
    char               sin_zero[8];  // Reserved for future use
} SOCKADDR_IN, *PSOCKADDR_IN;

Members:

SOCKADDR_IN6 (IPv6)

The SOCKADDR_IN6 structure is used to specify an IPv6 endpoint address. It's more complex than SOCKADDR_IN due to the larger size of IPv6 addresses.

typedef struct in6_addr {
    union {
        u_char   u8[16];
        u_short  u16[8];
        u_long   u32[4];
    } u;
} IN6_ADDR, *PIN6_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;

Members:

SOCKADDR (Generic)

The SOCKADDR structure is a generic structure that can hold addresses of any family. It is often used as a common type when passing address information to Winsock functions, where the actual structure type is determined by the sa_family field.

typedef struct sockaddr {
    u_short sa_family;      // Address family (e.g., AF_INET, AF_INET6)
    char    sa_data[14];    // Socket address (variable length)
} SOCKADDR, *PSOCKADDR;

When using SOCKADDR, you typically cast it to the appropriate specific structure (SOCKADDR_IN* or SOCKADDR_IN6*) after checking the sa_family field to access the correct members.

Related Structures

Beyond the primary address structures, Winsock defines other related structures:

Structure Name Description
IN_PKTINFO Provides information about an IPv4 packet, including the interface and destination address.
IN6_PKTINFO Provides information about an IPv6 packet, including the interface and destination address.
WSAPOLLFD Used with the WSAPoll function to describe sockets to monitor for events.

Byte Ordering

It's important to remember that network protocols use a specific byte order (big-endian, also known as network byte order). Winsock functions that deal with port numbers and IP addresses often require these values to be in network byte order. Use the following functions to convert between host byte order and network byte order:

For example, when setting the sin_port or sin6_port fields, you should always call htons() on the port number.