#ifndef INCLUDED_C_SOCKADDR_H #define INCLUDED_C_SOCKADDR_H #ifndef INCLUDED_C_SOCKET_H #include #endif /*INCLUDED_C_SOCKET_H*/ /* ------------------------------------------------------------------------------------------------------------------ */ /* */ typedef struct { union { struct sockaddr_in ipv4; struct sockaddr_in6 ipv6; struct sockaddr_storage storage; }; c_size_t size; }c_SockAddr_t; /* ------------------------------------------------------------------------------------------------------------------ */ /* */ c_err_t c_SockAddr_Init(c_SockAddr_t* self, int family, const char* ip, uint16_t port) ; /** * @brief Gets the address family (AF_INET or AF_INET6) from the sockaddr variant. * @return The address family integer, or -1 on parameter error. */ C_STATIC_FORCE_INLINE int c_SockAddr_GetFamily(const c_SockAddr_t* self) { if (!self) return -1; /* Since both structure variations map the sa_family / sin_family field at byte offset 0, reading from ipv4 is universally safe across families */ return (int)self->ipv4.sin_family; } /** * @brief Safely returns the port number (in host byte order) from the sockaddr variant. * @return The port integer (0 to 65535), or 0 on error. */ C_STATIC_FORCE_INLINE uint16_t c_SockAddr_GetPort(const c_SockAddr_t* self) { if (!self) return 0; if (self->ipv4.sin_family == AF_INET) { return ntohs(self->ipv4.sin_port); } else if (self->ipv4.sin_family == AF_INET6) { return ntohs(self->ipv6.sin6_port); } return 0; } /** * @brief Converts the embedded binary IP address to a safe human-readable text string. * @param out_str Pre-allocated destination character string buffer. * @param str_cap Capacity ceiling limit of out_str (Recommended min size: INET6_ADDRSTRLEN). */ c_err_t c_SockAddr_ToString(const c_SockAddr_t* self, char* out_str, c_size_t str_cap); #endif /*INCLUDED_C_SOCKADDR_H*/