/* For terms of usage/redistribution/modification see the LICENSE file */ /* For authors and contributors see the AUTHORS file */ #include "iptraf-ng-compat.h" void sockaddr_make_ipv4(struct sockaddr_storage *sockaddr, u_int32_t addr) { if (!sockaddr) die("%s(): sockaddr == NULL", __FUNCTION__); memset(sockaddr, 0, sizeof(*sockaddr)); struct sockaddr_in *sockaddr_in = (struct sockaddr_in *)sockaddr; sockaddr_in->sin_family = AF_INET; sockaddr_in->sin_port = 0; sockaddr_in->sin_addr.s_addr = addr; } void sockaddr_make_ipv6(struct sockaddr_storage *sockaddr, struct in6_addr *addr) { if (!sockaddr) die("%s(): sockaddr == NULL", __FUNCTION__); if (!addr) die("%s(): addr == NULL", __FUNCTION__); memset(sockaddr, 0, sizeof(*sockaddr)); struct sockaddr_in6 *sockaddr_in6 = (struct sockaddr_in6 *)sockaddr; sockaddr_in6->sin6_family = AF_INET6; sockaddr_in6->sin6_port = 0; sockaddr_in6->sin6_addr = *addr; sockaddr_in6->sin6_flowinfo = 0; sockaddr_in6->sin6_scope_id = 0; } in_port_t sockaddr_get_port(struct sockaddr_storage *sockaddr) { if (!sockaddr) die("%s(): sockaddr == NULL", __FUNCTION__); switch (sockaddr->ss_family) { case AF_INET: return ((struct sockaddr_in *)sockaddr)->sin_port; case AF_INET6: return ((struct sockaddr_in6 *)sockaddr)->sin6_port; default: die("%s(): Unknown address family", __FUNCTION__); } } void sockaddr_set_port(struct sockaddr_storage *sockaddr, in_port_t port) { if (!sockaddr) die("%s(): sockaddr == NULL", __FUNCTION__); switch (sockaddr->ss_family) { case AF_INET: ((struct sockaddr_in *)sockaddr)->sin_port = port; break; case AF_INET6: ((struct sockaddr_in6 *)sockaddr)->sin6_port = port; break; default: die("%s(): Unknown address family", __FUNCTION__); } } int sockaddr_is_equal(struct sockaddr_storage *addr1, struct sockaddr_storage *addr2) { if (!addr1) die("%s(): addr1 == NULL", __FUNCTION__); if (!addr2) die("%s(): addr2 == NULL", __FUNCTION__); if (addr1->ss_family != addr2->ss_family) return 0; switch (addr1->ss_family) { case AF_INET: { struct sockaddr_in *sa1 = (struct sockaddr_in *)addr1; struct sockaddr_in *sa2 = (struct sockaddr_in *)addr2; if ((sa1->sin_addr.s_addr == sa2->sin_addr.s_addr) && (sa1->sin_port == sa2->sin_port)) return 1; else return 0; } case AF_INET6: { struct sockaddr_in6 *sa1 = (struct sockaddr_in6 *)addr1; struct sockaddr_in6 *sa2 = (struct sockaddr_in6 *)addr2; if ((sa1->sin6_port == sa2->sin6_port) && (sa1->sin6_flowinfo == sa2->sin6_flowinfo) && (sa1->sin6_scope_id == sa2->sin6_scope_id) && (memcmp(&sa1->sin6_addr, &sa2->sin6_addr, sizeof(sa1->sin6_addr)) == 0)) return 1; else return 0; } default: die("%s(): Unknown address family", __FUNCTION__); } } void sockaddr_ntop(struct sockaddr_storage *addr, char *buf, size_t buflen) { if(!addr) die("%s(): addr == NULL", __FUNCTION__); const char *ret; size_t minlen; memset(buf, 0, buflen); switch (addr->ss_family) { case AF_INET: minlen = INET_ADDRSTRLEN; ret = inet_ntop(AF_INET, &((struct sockaddr_in *)addr)->sin_addr, buf, buflen - 1); break; case AF_INET6: minlen = INET6_ADDRSTRLEN; ret = inet_ntop(AF_INET6, &((struct sockaddr_in6 *)addr)->sin6_addr, buf, buflen - 1); break; default: die("%s(): Unknown address family", __FUNCTION__); } if (ret == NULL) { switch (errno) { case ENOSPC: die("%s(): buffer too small (must be at least %zu bytes)", __FUNCTION__, minlen); case EAFNOSUPPORT: die("%s(): Unknown address family", __FUNCTION__); } } } struct hostent *sockaddr_gethostbyaddr(struct sockaddr_storage *addr) { if(!addr) die("%s(): addr == NULL", __FUNCTION__); switch (addr->ss_family) { case AF_INET: return gethostbyaddr(&((struct sockaddr_in *)addr)->sin_addr, sizeof(struct in_addr), AF_INET); case AF_INET6: return gethostbyaddr(&((struct sockaddr_in6 *)addr)->sin6_addr, sizeof(struct in6_addr), AF_INET6); default: die("%s(): Unknown address family", __FUNCTION__); } } void sockaddr_copy(struct sockaddr_storage *dest, struct sockaddr_storage *src) { if (!src) die("%s(): src == NULL", __FUNCTION__); if (!dest) die("%s(): dest == NULL", __FUNCTION__); memcpy(dest, src, sizeof(struct sockaddr_storage)); }