See image below

There are 6 different possible outputs
abcdab
abcdef
abcdcd
ababef
abcdef
ababcd
abcdef
abcdab
ababef
abcdcd
ababcd
abcdef
The type of getaddrinfo is:
int getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints,
struct addrinfo **res);
Observe that the output argument of the function: struct addrinfo **res is a linked list of addrinfo struct containing sockaddr struct that is itself protocol-independent (unlike non-generic sockaddr_in struct that has fields like sin_port, sin_addr, and sin_zero[8]):
The structures mentioned are shown below and the all-caped texts are for further explanations.
struct addrinfo {
int ai_flags; /* Hints argument flags */
int ai_family; /* First arg to socket function */
int ai_socktype; /* Second arg to socket function */
int ai_protocol; /* Third arg to socket function */
char *ai_canonname; /* Canonical host name */
size_t ai_addrlen; /* Size of ai_addr struct */
// LOOK AT THIS LINE. THE TYPE IS `sockaddr`, NOT `sockaddr_in`
// WHICH MEANS IT IS GENERIC
struct sockaddr *ai_addr; /* Ptr to socket address structure */
struct addrinfo *ai_next; /* Ptr to next item in linked list */
};
// THIS IS GENERIC
struct sockaddr {
uint16_t sa_family; /* Protocol family */
char sa_data[14]; /* Address data */
};
// THIS IS NOT GENERIC
struct sockaddr_in {
uint16_t sin_family; /* Protocol family (always AF_INET) */
uint16_t sin_port; /* Port num in network byte order */
struct in_addr sin_addr; /* IP addr in network byte order */
unsigned char sin_zero[8]; /* Pad to sizeof(struct sockaddr) */
};
Because sockaddr is generic, the returning argument struct addrinfo **res from function getaddrinfo is protocol-independent (support any protocol including IPv4 and IPv6). Therefore getaddrinfo can be used with any protocol.
Table of Content