While these are good answers, they broke my compile with -pedantic -std=c99 -Werror
.
From man 7 socket
To allow any type of socket address to be passed to interfaces in the sockets API, the type struct sockaddr
is defined. The purpose of
this type is purely to allow casting of domain-specific socket address
types to a "generic" type, so as to avoid compiler warnings about type
mismatches in calls to the sockets API.
To get all the relevant data in this page, from glibc-2.17 (RHEL7) I see
/* Structure describing a generic socket address. */
struct sockaddr
{
__SOCKADDR_COMMON (sa_); /* Common data: address family and length. */
char sa_data[14]; /* Address data. */
};
where SOCKADDR_COMMON is a uint16_t
. So total size is 16B.
IP (internet protocol) Domain specific, from man 7 ip:
struct sockaddr_in {
sa_family_t sin_family; /* address family: AF_INET */
in_port_t sin_port; /* port in network byte order */
struct in_addr sin_addr; /* internet address */
};
/* Internet address. */
struct in_addr {
uint32_t s_addr; /* address in network byte order */
};
First try
inet_ntoa( ((struct sockaddr_in) peer_addr).sin_addr )
Problem
error: conversion to non-scalar type requested
Second try
inet_ntoa( ((struct sockaddr_in *) &peer_addr)->sin_addr ) ));
Problem
error: dereferencing type-punned pointer might break strict-aliasing rules [-Werror=strict-aliasing]
Thrid try: inet_pton, more modern anyways, thread safe, takes void*
char peer_addr_str[ INET_ADDRSTRLEN ];
inet_ntop( AF_INET, &peer_addr, peer_addr_str, INET_ADDRSTRLEN );
ok, works. Human readable decimal-and-dots string is in peer_addr_str
.