X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=lib%2Fsockunion.c;h=af4f41f37ca380ec45a2f11267ef78cff7df7bf4;hb=01b4cb3ed6181d7200f66e0187b1e5c5db6c0e5a;hp=423ad20441efad4a4a912f2c74e2037b1bea64b4;hpb=b440fe5c82f73a4f34ebc59ac07e95f56e1193e0;p=mirror_frr.git diff --git a/lib/sockunion.c b/lib/sockunion.c index 423ad2044..af4f41f37 100644 --- a/lib/sockunion.c +++ b/lib/sockunion.c @@ -26,718 +26,659 @@ #include "memory.h" #include "log.h" #include "jhash.h" +#include "lib_errors.h" DEFINE_MTYPE_STATIC(LIB, SOCKUNION, "Socket union") -const char * -inet_sutop (const union sockunion *su, char *str) +const char *inet_sutop(const union sockunion *su, char *str) { - switch (su->sa.sa_family) - { - case AF_INET: - inet_ntop (AF_INET, &su->sin.sin_addr, str, INET_ADDRSTRLEN); - break; - case AF_INET6: - inet_ntop (AF_INET6, &su->sin6.sin6_addr, str, INET6_ADDRSTRLEN); - break; - } - return str; + switch (su->sa.sa_family) { + case AF_INET: + inet_ntop(AF_INET, &su->sin.sin_addr, str, INET_ADDRSTRLEN); + break; + case AF_INET6: + inet_ntop(AF_INET6, &su->sin6.sin6_addr, str, INET6_ADDRSTRLEN); + break; + } + return str; } -int -str2sockunion (const char *str, union sockunion *su) +int str2sockunion(const char *str, union sockunion *su) { - int ret; + int ret; + + if (str == NULL) + return -1; - memset (su, 0, sizeof (union sockunion)); + memset(su, 0, sizeof(union sockunion)); - ret = inet_pton (AF_INET, str, &su->sin.sin_addr); - if (ret > 0) /* Valid IPv4 address format. */ - { - su->sin.sin_family = AF_INET; + ret = inet_pton(AF_INET, str, &su->sin.sin_addr); + if (ret > 0) /* Valid IPv4 address format. */ + { + su->sin.sin_family = AF_INET; #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - su->sin.sin_len = sizeof(struct sockaddr_in); + su->sin.sin_len = sizeof(struct sockaddr_in); #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ - return 0; - } - ret = inet_pton (AF_INET6, str, &su->sin6.sin6_addr); - if (ret > 0) /* Valid IPv6 address format. */ - { - su->sin6.sin6_family = AF_INET6; + return 0; + } + ret = inet_pton(AF_INET6, str, &su->sin6.sin6_addr); + if (ret > 0) /* Valid IPv6 address format. */ + { + su->sin6.sin6_family = AF_INET6; #ifdef SIN6_LEN - su->sin6.sin6_len = sizeof(struct sockaddr_in6); + su->sin6.sin6_len = sizeof(struct sockaddr_in6); #endif /* SIN6_LEN */ - return 0; - } - return -1; + return 0; + } + return -1; } -const char * -sockunion2str (const union sockunion *su, char *buf, size_t len) +const char *sockunion2str(const union sockunion *su, char *buf, size_t len) { - switch (sockunion_family(su)) - { - case AF_UNSPEC: - snprintf (buf, len, "(unspec)"); - return buf; - case AF_INET: - return inet_ntop (AF_INET, &su->sin.sin_addr, buf, len); - case AF_INET6: - return inet_ntop (AF_INET6, &su->sin6.sin6_addr, buf, len); - } - snprintf (buf, len, "(af %d)", sockunion_family(su)); - return buf; + switch (sockunion_family(su)) { + case AF_UNSPEC: + snprintf(buf, len, "(unspec)"); + return buf; + case AF_INET: + return inet_ntop(AF_INET, &su->sin.sin_addr, buf, len); + case AF_INET6: + return inet_ntop(AF_INET6, &su->sin6.sin6_addr, buf, len); + } + snprintf(buf, len, "(af %d)", sockunion_family(su)); + return buf; } -union sockunion * -sockunion_str2su (const char *str) +union sockunion *sockunion_str2su(const char *str) { - union sockunion *su = XCALLOC (MTYPE_SOCKUNION, sizeof (union sockunion)); - - if (!str2sockunion (str, su)) - return su; - - XFREE (MTYPE_SOCKUNION, su); - return NULL; + union sockunion *su = XCALLOC(MTYPE_SOCKUNION, sizeof(union sockunion)); + + if (!str2sockunion(str, su)) + return su; + + XFREE(MTYPE_SOCKUNION, su); + return NULL; } /* Convert IPv4 compatible IPv6 address to IPv4 address. */ -static void -sockunion_normalise_mapped (union sockunion *su) -{ - struct sockaddr_in sin; - - if (su->sa.sa_family == AF_INET6 - && IN6_IS_ADDR_V4MAPPED (&su->sin6.sin6_addr)) - { - memset (&sin, 0, sizeof (struct sockaddr_in)); - sin.sin_family = AF_INET; - sin.sin_port = su->sin6.sin6_port; - memcpy (&sin.sin_addr, ((char *)&su->sin6.sin6_addr) + 12, 4); - memcpy (su, &sin, sizeof (struct sockaddr_in)); - } +static void sockunion_normalise_mapped(union sockunion *su) +{ + struct sockaddr_in sin; + + if (su->sa.sa_family == AF_INET6 + && IN6_IS_ADDR_V4MAPPED(&su->sin6.sin6_addr)) { + memset(&sin, 0, sizeof(struct sockaddr_in)); + sin.sin_family = AF_INET; + sin.sin_port = su->sin6.sin6_port; + memcpy(&sin.sin_addr, ((char *)&su->sin6.sin6_addr) + 12, 4); + memcpy(su, &sin, sizeof(struct sockaddr_in)); + } } /* return sockunion structure : this function should be revised. */ -static const char * -sockunion_log (const union sockunion *su, char *buf, size_t len) +static const char *sockunion_log(const union sockunion *su, char *buf, + size_t len) { - switch (su->sa.sa_family) - { - case AF_INET: - return inet_ntop(AF_INET, &su->sin.sin_addr, buf, len); + switch (su->sa.sa_family) { + case AF_INET: + return inet_ntop(AF_INET, &su->sin.sin_addr, buf, len); - case AF_INET6: - return inet_ntop(AF_INET6, &(su->sin6.sin6_addr), buf, len); - break; + case AF_INET6: + return inet_ntop(AF_INET6, &(su->sin6.sin6_addr), buf, len); + break; - default: - snprintf (buf, len, "af_unknown %d ", su->sa.sa_family); - return buf; - } + default: + snprintf(buf, len, "af_unknown %d ", su->sa.sa_family); + return buf; + } } /* Return socket of sockunion. */ -int -sockunion_socket (const union sockunion *su) +int sockunion_socket(const union sockunion *su) { - int sock; + int sock; - sock = socket (su->sa.sa_family, SOCK_STREAM, 0); - if (sock < 0) - { - char buf[SU_ADDRSTRLEN]; - zlog_warn("Can't make socket for %s : %s", - sockunion_log(su, buf, SU_ADDRSTRLEN), safe_strerror(errno)); - return -1; - } + sock = socket(su->sa.sa_family, SOCK_STREAM, 0); + if (sock < 0) { + char buf[SU_ADDRSTRLEN]; + flog_err(EC_LIB_SOCKET, "Can't make socket for %s : %s", + sockunion_log(su, buf, SU_ADDRSTRLEN), + safe_strerror(errno)); + return -1; + } - return sock; + return sock; } /* Return accepted new socket file descriptor. */ -int -sockunion_accept (int sock, union sockunion *su) +int sockunion_accept(int sock, union sockunion *su) { - socklen_t len; - int client_sock; + socklen_t len; + int client_sock; - len = sizeof (union sockunion); - client_sock = accept (sock, (struct sockaddr *) su, &len); - - sockunion_normalise_mapped (su); - return client_sock; + len = sizeof(union sockunion); + client_sock = accept(sock, (struct sockaddr *)su, &len); + + sockunion_normalise_mapped(su); + return client_sock; } /* Return sizeof union sockunion. */ -static int -sockunion_sizeof (const union sockunion *su) -{ - int ret; - - ret = 0; - switch (su->sa.sa_family) - { - case AF_INET: - ret = sizeof (struct sockaddr_in); - break; - case AF_INET6: - ret = sizeof (struct sockaddr_in6); - break; - } - return ret; -} - -/* sockunion_connect returns - -1 : error occured - 0 : connect success - 1 : connect is in progress */ -enum connect_result -sockunion_connect (int fd, const union sockunion *peersu, unsigned short port, - ifindex_t ifindex) -{ - int ret; - int val; - union sockunion su; - - memcpy (&su, peersu, sizeof (union sockunion)); - - switch (su.sa.sa_family) - { - case AF_INET: - su.sin.sin_port = port; - break; - case AF_INET6: - su.sin6.sin6_port = port; -#ifdef KAME - if (IN6_IS_ADDR_LINKLOCAL(&su.sin6.sin6_addr) && ifindex) - { - su.sin6.sin6_scope_id = ifindex; - SET_IN6_LINKLOCAL_IFINDEX (su.sin6.sin6_addr, ifindex); +static int sockunion_sizeof(const union sockunion *su) +{ + int ret; + + ret = 0; + switch (su->sa.sa_family) { + case AF_INET: + ret = sizeof(struct sockaddr_in); + break; + case AF_INET6: + ret = sizeof(struct sockaddr_in6); + break; } + return ret; +} + +/* Performs a non-blocking connect(). */ +enum connect_result sockunion_connect(int fd, const union sockunion *peersu, + unsigned short port, ifindex_t ifindex) +{ + int ret; + union sockunion su; + + memcpy(&su, peersu, sizeof(union sockunion)); + + switch (su.sa.sa_family) { + case AF_INET: + su.sin.sin_port = port; + break; + case AF_INET6: + su.sin6.sin6_port = port; +#ifdef KAME + if (IN6_IS_ADDR_LINKLOCAL(&su.sin6.sin6_addr) && ifindex) { + su.sin6.sin6_scope_id = ifindex; + SET_IN6_LINKLOCAL_IFINDEX(su.sin6.sin6_addr, ifindex); + } #endif /* KAME */ - break; - } - - /* Make socket non-block. */ - val = fcntl (fd, F_GETFL, 0); - fcntl (fd, F_SETFL, val|O_NONBLOCK); - - /* Call connect function. */ - ret = connect (fd, (struct sockaddr *) &su, sockunion_sizeof (&su)); - - /* Immediate success */ - if (ret == 0) - { - fcntl (fd, F_SETFL, val); - return connect_success; - } - - /* If connect is in progress then return 1 else it's real error. */ - if (ret < 0) - { - if (errno != EINPROGRESS) - { - char str[SU_ADDRSTRLEN]; - zlog_info ("can't connect to %s fd %d : %s", - sockunion_log (&su, str, sizeof str), - fd, safe_strerror (errno)); - return connect_error; + break; } - } - fcntl (fd, F_SETFL, val); + /* Call connect function. */ + ret = connect(fd, (struct sockaddr *)&su, sockunion_sizeof(&su)); + + /* Immediate success */ + if (ret == 0) + return connect_success; + + /* If connect is in progress then return 1 else it's real error. */ + if (ret < 0) { + if (errno != EINPROGRESS) { + char str[SU_ADDRSTRLEN]; + zlog_info("can't connect to %s fd %d : %s", + sockunion_log(&su, str, sizeof str), fd, + safe_strerror(errno)); + return connect_error; + } + } - return connect_in_progress; + return connect_in_progress; } /* Make socket from sockunion union. */ -int -sockunion_stream_socket (union sockunion *su) +int sockunion_stream_socket(union sockunion *su) { - int sock; + int sock; - if (su->sa.sa_family == 0) - su->sa.sa_family = AF_INET_UNION; + if (su->sa.sa_family == 0) + su->sa.sa_family = AF_INET_UNION; - sock = socket (su->sa.sa_family, SOCK_STREAM, 0); + sock = socket(su->sa.sa_family, SOCK_STREAM, 0); - if (sock < 0) - zlog_warn("can't make socket sockunion_stream_socket"); + if (sock < 0) + flog_err(EC_LIB_SOCKET, + "can't make socket sockunion_stream_socket"); - return sock; + return sock; } /* Bind socket to specified address. */ -int -sockunion_bind (int sock, union sockunion *su, unsigned short port, - union sockunion *su_addr) +int sockunion_bind(int sock, union sockunion *su, unsigned short port, + union sockunion *su_addr) { - int size = 0; - int ret; + int size = 0; + int ret; - if (su->sa.sa_family == AF_INET) - { - size = sizeof (struct sockaddr_in); - su->sin.sin_port = htons (port); + if (su->sa.sa_family == AF_INET) { + size = sizeof(struct sockaddr_in); + su->sin.sin_port = htons(port); #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - su->sin.sin_len = size; + su->sin.sin_len = size; #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ - if (su_addr == NULL) - sockunion2ip (su) = htonl (INADDR_ANY); - } - else if (su->sa.sa_family == AF_INET6) - { - size = sizeof (struct sockaddr_in6); - su->sin6.sin6_port = htons (port); + if (su_addr == NULL) + sockunion2ip(su) = htonl(INADDR_ANY); + } else if (su->sa.sa_family == AF_INET6) { + size = sizeof(struct sockaddr_in6); + su->sin6.sin6_port = htons(port); #ifdef SIN6_LEN - su->sin6.sin6_len = size; + su->sin6.sin6_len = size; #endif /* SIN6_LEN */ - if (su_addr == NULL) - { + if (su_addr == NULL) { #ifdef LINUX_IPV6 - memset (&su->sin6.sin6_addr, 0, sizeof (struct in6_addr)); + memset(&su->sin6.sin6_addr, 0, sizeof(struct in6_addr)); #else - su->sin6.sin6_addr = in6addr_any; + su->sin6.sin6_addr = in6addr_any; #endif /* LINUX_IPV6 */ + } } - } - ret = bind (sock, (struct sockaddr *)su, size); - if (ret < 0) - { - char buf[SU_ADDRSTRLEN]; - zlog_warn("can't bind socket for %s : %s", - sockunion_log(su, buf, SU_ADDRSTRLEN), safe_strerror(errno)); - } + ret = bind(sock, (struct sockaddr *)su, size); + if (ret < 0) { + char buf[SU_ADDRSTRLEN]; + flog_err(EC_LIB_SOCKET, "can't bind socket for %s : %s", + sockunion_log(su, buf, SU_ADDRSTRLEN), + safe_strerror(errno)); + } - return ret; + return ret; } -int -sockopt_reuseaddr (int sock) +int sockopt_reuseaddr(int sock) { - int ret; - int on = 1; + int ret; + int on = 1; - ret = setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, - (void *) &on, sizeof (on)); - if (ret < 0) - { - zlog_warn("can't set sockopt SO_REUSEADDR to socket %d", sock); - return -1; - } - return 0; + ret = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, + sizeof(on)); + if (ret < 0) { + flog_err(EC_LIB_SOCKET, + "can't set sockopt SO_REUSEADDR to socket %d", sock); + return -1; + } + return 0; } #ifdef SO_REUSEPORT -int -sockopt_reuseport (int sock) +int sockopt_reuseport(int sock) { - int ret; - int on = 1; + int ret; + int on = 1; - ret = setsockopt (sock, SOL_SOCKET, SO_REUSEPORT, - (void *) &on, sizeof (on)); - if (ret < 0) - { - zlog_warn("can't set sockopt SO_REUSEPORT to socket %d", sock); - return -1; - } - return 0; + ret = setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (void *)&on, + sizeof(on)); + if (ret < 0) { + flog_err(EC_LIB_SOCKET, + "can't set sockopt SO_REUSEPORT to socket %d", sock); + return -1; + } + return 0; } #else -int -sockopt_reuseport (int sock) +int sockopt_reuseport(int sock) { - return 0; + return 0; } #endif /* 0 */ -int -sockopt_ttl (int family, int sock, int ttl) +int sockopt_ttl(int family, int sock, int ttl) { - int ret; + int ret; #ifdef IP_TTL - if (family == AF_INET) - { - ret = setsockopt (sock, IPPROTO_IP, IP_TTL, - (void *) &ttl, sizeof (int)); - if (ret < 0) - { - zlog_warn("can't set sockopt IP_TTL %d to socket %d", ttl, sock); - return -1; + if (family == AF_INET) { + ret = setsockopt(sock, IPPROTO_IP, IP_TTL, (void *)&ttl, + sizeof(int)); + if (ret < 0) { + flog_err(EC_LIB_SOCKET, + "can't set sockopt IP_TTL %d to socket %d", + ttl, sock); + return -1; + } + return 0; } - return 0; - } #endif /* IP_TTL */ - if (family == AF_INET6) - { - ret = setsockopt (sock, IPPROTO_IPV6, IPV6_UNICAST_HOPS, - (void *) &ttl, sizeof (int)); - if (ret < 0) - { - zlog_warn("can't set sockopt IPV6_UNICAST_HOPS %d to socket %d", - ttl, sock); - return -1; + if (family == AF_INET6) { + ret = setsockopt(sock, IPPROTO_IPV6, IPV6_UNICAST_HOPS, + (void *)&ttl, sizeof(int)); + if (ret < 0) { + flog_err( + EC_LIB_SOCKET, + "can't set sockopt IPV6_UNICAST_HOPS %d to socket %d", + ttl, sock); + return -1; + } + return 0; } - return 0; - } - return 0; + return 0; } -int -sockopt_cork (int sock, int onoff) +/* + * This function called setsockopt(.., TCP_CORK,...) + * Which on linux is a no-op since it is enabled by + * default and on BSD it uses TCP_NOPUSH to do + * the same thing( which it was not configured to + * use). This cleanup of the api occurred on 8/1/17 + * I imagine if after more than 1 year of no-one + * complaining, and a major upgrade release we + * can deprecate and remove this function call + */ +int sockopt_cork(int sock, int onoff) { -#ifdef TCP_CORK - return setsockopt (sock, IPPROTO_TCP, TCP_CORK, &onoff, sizeof(onoff)); -#else - return 0; -#endif + return 0; } int sockopt_mark_default(int sock, int mark, struct zebra_privs_t *cap) { #ifdef SO_MARK - int ret; - - if ( cap->change (ZPRIVS_RAISE) ) - zlog_err ("routing_socket: Can't raise privileges"); - - ret = setsockopt(sock, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)); - - if ( cap->change (ZPRIVS_LOWER) ) - zlog_err ("routing_socket: Can't lower privileges"); + int ret; - return ret; + frr_elevate_privs(cap) { + ret = setsockopt(sock, SOL_SOCKET, SO_MARK, &mark, + sizeof(mark)); + } + return ret; #else - return 0; + return 0; #endif } -int -sockopt_minttl (int family, int sock, int minttl) +int sockopt_minttl(int family, int sock, int minttl) { #ifdef IP_MINTTL - if (family == AF_INET) - { - int ret = setsockopt (sock, IPPROTO_IP, IP_MINTTL, &minttl, sizeof(minttl)); - if (ret < 0) - zlog_warn("can't set sockopt IP_MINTTL to %d on socket %d: %s", - minttl, sock, safe_strerror(errno)); - return ret; - } + if (family == AF_INET) { + int ret = setsockopt(sock, IPPROTO_IP, IP_MINTTL, &minttl, + sizeof(minttl)); + if (ret < 0) + flog_err( + EC_LIB_SOCKET, + "can't set sockopt IP_MINTTL to %d on socket %d: %s", + minttl, sock, safe_strerror(errno)); + return ret; + } #endif /* IP_MINTTL */ #ifdef IPV6_MINHOPCOUNT - if (family == AF_INET6) - { - int ret = setsockopt (sock, IPPROTO_IPV6, IPV6_MINHOPCOUNT, &minttl, sizeof(minttl)); - if (ret < 0) - zlog_warn("can't set sockopt IPV6_MINHOPCOUNT to %d on socket %d: %s", - minttl, sock, safe_strerror(errno)); - return ret; - } + if (family == AF_INET6) { + int ret = setsockopt(sock, IPPROTO_IPV6, IPV6_MINHOPCOUNT, + &minttl, sizeof(minttl)); + if (ret < 0) + flog_err( + EC_LIB_SOCKET, + "can't set sockopt IPV6_MINHOPCOUNT to %d on socket %d: %s", + minttl, sock, safe_strerror(errno)); + return ret; + } #endif - errno = EOPNOTSUPP; - return -1; + errno = EOPNOTSUPP; + return -1; } -int -sockopt_v6only (int family, int sock) +int sockopt_v6only(int family, int sock) { - int ret, on = 1; + int ret, on = 1; #ifdef IPV6_V6ONLY - if (family == AF_INET6) - { - ret = setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, - (void *) &on, sizeof (int)); - if (ret < 0) - { - zlog_warn("can't set sockopt IPV6_V6ONLY " "to socket %d", - sock); - return -1; + if (family == AF_INET6) { + ret = setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&on, + sizeof(int)); + if (ret < 0) { + flog_err(EC_LIB_SOCKET, + "can't set sockopt IPV6_V6ONLY " + "to socket %d", + sock); + return -1; + } + return 0; } - return 0; - } #endif /* IPV6_V6ONLY */ - return 0; + return 0; } /* If same family and same prefix return 1. */ -int -sockunion_same (const union sockunion *su1, const union sockunion *su2) -{ - int ret = 0; - - if (su1->sa.sa_family != su2->sa.sa_family) - return 0; - - switch (su1->sa.sa_family) - { - case AF_INET: - ret = memcmp (&su1->sin.sin_addr, &su2->sin.sin_addr, - sizeof (struct in_addr)); - break; - case AF_INET6: - ret = memcmp (&su1->sin6.sin6_addr, &su2->sin6.sin6_addr, - sizeof (struct in6_addr)); - if ((ret == 0) && IN6_IS_ADDR_LINKLOCAL(&su1->sin6.sin6_addr)) - { - /* compare interface indices */ - if (su1->sin6.sin6_scope_id && su2->sin6.sin6_scope_id) - ret = (su1->sin6.sin6_scope_id == su2->sin6.sin6_scope_id) ? 0 : 1; +int sockunion_same(const union sockunion *su1, const union sockunion *su2) +{ + int ret = 0; + + if (su1->sa.sa_family != su2->sa.sa_family) + return 0; + + switch (su1->sa.sa_family) { + case AF_INET: + ret = memcmp(&su1->sin.sin_addr, &su2->sin.sin_addr, + sizeof(struct in_addr)); + break; + case AF_INET6: + ret = memcmp(&su1->sin6.sin6_addr, &su2->sin6.sin6_addr, + sizeof(struct in6_addr)); + if ((ret == 0) && IN6_IS_ADDR_LINKLOCAL(&su1->sin6.sin6_addr)) { + /* compare interface indices */ + if (su1->sin6.sin6_scope_id && su2->sin6.sin6_scope_id) + ret = (su1->sin6.sin6_scope_id + == su2->sin6.sin6_scope_id) + ? 0 + : 1; + } + break; } - break; - } - if (ret == 0) - return 1; - else - return 0; + if (ret == 0) + return 1; + else + return 0; } -unsigned int -sockunion_hash (const union sockunion *su) +unsigned int sockunion_hash(const union sockunion *su) { - switch (sockunion_family(su)) - { - case AF_INET: - return jhash_1word(su->sin.sin_addr.s_addr, 0); - case AF_INET6: - return jhash2(su->sin6.sin6_addr.s6_addr32, ZEBRA_NUM_OF(su->sin6.sin6_addr.s6_addr32), 0); - } - return 0; + switch (sockunion_family(su)) { + case AF_INET: + return jhash_1word(su->sin.sin_addr.s_addr, 0); + case AF_INET6: + return jhash2(su->sin6.sin6_addr.s6_addr32, + ZEBRA_NUM_OF(su->sin6.sin6_addr.s6_addr32), 0); + } + return 0; } -size_t -family2addrsize(int family) +size_t family2addrsize(int family) { - switch (family) - { - case AF_INET: - return sizeof(struct in_addr); - case AF_INET6: - return sizeof(struct in6_addr); - } - return 0; + switch (family) { + case AF_INET: + return sizeof(struct in_addr); + case AF_INET6: + return sizeof(struct in6_addr); + } + return 0; } -size_t -sockunion_get_addrlen(const union sockunion *su) +size_t sockunion_get_addrlen(const union sockunion *su) { - return family2addrsize(sockunion_family(su)); + return family2addrsize(sockunion_family(su)); } -const u_char * -sockunion_get_addr(const union sockunion *su) +const uint8_t *sockunion_get_addr(const union sockunion *su) { - switch (sockunion_family(su)) - { - case AF_INET: - return (const u_char *) &su->sin.sin_addr.s_addr; - case AF_INET6: - return (const u_char *) &su->sin6.sin6_addr; - } - return NULL; + switch (sockunion_family(su)) { + case AF_INET: + return (const uint8_t *)&su->sin.sin_addr.s_addr; + case AF_INET6: + return (const uint8_t *)&su->sin6.sin6_addr; + } + return NULL; } -void -sockunion_set(union sockunion *su, int family, const u_char *addr, size_t bytes) +void sockunion_set(union sockunion *su, int family, const uint8_t *addr, + size_t bytes) { - if (family2addrsize(family) != bytes) - return; + if (family2addrsize(family) != bytes) + return; - sockunion_family(su) = family; - switch (family) - { - case AF_INET: - memcpy(&su->sin.sin_addr.s_addr, addr, bytes); - break; - case AF_INET6: - memcpy(&su->sin6.sin6_addr, addr, bytes); - break; - } + sockunion_family(su) = family; + switch (family) { + case AF_INET: + memcpy(&su->sin.sin_addr.s_addr, addr, bytes); + break; + case AF_INET6: + memcpy(&su->sin6.sin6_addr, addr, bytes); + break; + } } /* After TCP connection is established. Get local address and port. */ -union sockunion * -sockunion_getsockname (int fd) -{ - int ret; - socklen_t len; - union - { - struct sockaddr sa; - struct sockaddr_in sin; - struct sockaddr_in6 sin6; - char tmp_buffer[128]; - } name; - union sockunion *su; - - memset (&name, 0, sizeof name); - len = sizeof name; - - ret = getsockname (fd, (struct sockaddr *)&name, &len); - if (ret < 0) - { - zlog_warn ("Can't get local address and port by getsockname: %s", - safe_strerror (errno)); - return NULL; - } - - if (name.sa.sa_family == AF_INET) - { - su = XCALLOC (MTYPE_SOCKUNION, sizeof (union sockunion)); - memcpy (su, &name, sizeof (struct sockaddr_in)); - return su; - } - if (name.sa.sa_family == AF_INET6) - { - su = XCALLOC (MTYPE_SOCKUNION, sizeof (union sockunion)); - memcpy (su, &name, sizeof (struct sockaddr_in6)); - sockunion_normalise_mapped (su); - return su; - } - return NULL; +union sockunion *sockunion_getsockname(int fd) +{ + int ret; + socklen_t len; + union { + struct sockaddr sa; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + char tmp_buffer[128]; + } name; + union sockunion *su; + + memset(&name, 0, sizeof name); + len = sizeof name; + + ret = getsockname(fd, (struct sockaddr *)&name, &len); + if (ret < 0) { + flog_err(EC_LIB_SOCKET, + "Can't get local address and port by getsockname: %s", + safe_strerror(errno)); + return NULL; + } + + if (name.sa.sa_family == AF_INET) { + su = XCALLOC(MTYPE_SOCKUNION, sizeof(union sockunion)); + memcpy(su, &name, sizeof(struct sockaddr_in)); + return su; + } + if (name.sa.sa_family == AF_INET6) { + su = XCALLOC(MTYPE_SOCKUNION, sizeof(union sockunion)); + memcpy(su, &name, sizeof(struct sockaddr_in6)); + sockunion_normalise_mapped(su); + return su; + } + return NULL; } /* After TCP connection is established. Get remote address and port. */ -union sockunion * -sockunion_getpeername (int fd) -{ - int ret; - socklen_t len; - union - { - struct sockaddr sa; - struct sockaddr_in sin; - struct sockaddr_in6 sin6; - char tmp_buffer[128]; - } name; - union sockunion *su; - - memset (&name, 0, sizeof name); - len = sizeof name; - ret = getpeername (fd, (struct sockaddr *)&name, &len); - if (ret < 0) - { - zlog_warn("Can't get remote address and port: %s", safe_strerror(errno)); - return NULL; - } - - if (name.sa.sa_family == AF_INET) - { - su = XCALLOC (MTYPE_SOCKUNION, sizeof (union sockunion)); - memcpy (su, &name, sizeof (struct sockaddr_in)); - return su; - } - if (name.sa.sa_family == AF_INET6) - { - su = XCALLOC (MTYPE_SOCKUNION, sizeof (union sockunion)); - memcpy (su, &name, sizeof (struct sockaddr_in6)); - sockunion_normalise_mapped (su); - return su; - } - return NULL; +union sockunion *sockunion_getpeername(int fd) +{ + int ret; + socklen_t len; + union { + struct sockaddr sa; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + char tmp_buffer[128]; + } name; + union sockunion *su; + + memset(&name, 0, sizeof name); + len = sizeof name; + ret = getpeername(fd, (struct sockaddr *)&name, &len); + if (ret < 0) { + flog_err(EC_LIB_SOCKET, "Can't get remote address and port: %s", + safe_strerror(errno)); + return NULL; + } + + if (name.sa.sa_family == AF_INET) { + su = XCALLOC(MTYPE_SOCKUNION, sizeof(union sockunion)); + memcpy(su, &name, sizeof(struct sockaddr_in)); + return su; + } + if (name.sa.sa_family == AF_INET6) { + su = XCALLOC(MTYPE_SOCKUNION, sizeof(union sockunion)); + memcpy(su, &name, sizeof(struct sockaddr_in6)); + sockunion_normalise_mapped(su); + return su; + } + return NULL; } /* Print sockunion structure */ -static void __attribute__ ((unused)) -sockunion_print (const union sockunion *su) -{ - if (su == NULL) - return; - - switch (su->sa.sa_family) - { - case AF_INET: - printf ("%s\n", inet_ntoa (su->sin.sin_addr)); - break; - case AF_INET6: - { - char buf [SU_ADDRSTRLEN]; - - printf ("%s\n", inet_ntop (AF_INET6, &(su->sin6.sin6_addr), - buf, sizeof (buf))); - } - break; +static void __attribute__((unused)) sockunion_print(const union sockunion *su) +{ + if (su == NULL) + return; + + switch (su->sa.sa_family) { + case AF_INET: + printf("%s\n", inet_ntoa(su->sin.sin_addr)); + break; + case AF_INET6: { + char buf[SU_ADDRSTRLEN]; + + printf("%s\n", inet_ntop(AF_INET6, &(su->sin6.sin6_addr), buf, + sizeof(buf))); + } break; #ifdef AF_LINK - case AF_LINK: - { - struct sockaddr_dl *sdl; - - sdl = (struct sockaddr_dl *)&(su->sa); - printf ("link#%d\n", sdl->sdl_index); - } - break; + case AF_LINK: { + struct sockaddr_dl *sdl; + + sdl = (struct sockaddr_dl *)&(su->sa); + printf("link#%d\n", sdl->sdl_index); + } break; #endif /* AF_LINK */ - default: - printf ("af_unknown %d\n", su->sa.sa_family); - break; - } + default: + printf("af_unknown %d\n", su->sa.sa_family); + break; + } } -static int -in6addr_cmp (const struct in6_addr *addr1, const struct in6_addr *addr2) +static int in6addr_cmp(const struct in6_addr *addr1, + const struct in6_addr *addr2) { - unsigned int i; - const u_char *p1, *p2; + unsigned int i; + const uint8_t *p1, *p2; - p1 = (const u_char *)addr1; - p2 = (const u_char *)addr2; + p1 = (const uint8_t *)addr1; + p2 = (const uint8_t *)addr2; - for (i = 0; i < sizeof (struct in6_addr); i++) - { - if (p1[i] > p2[i]) - return 1; - else if (p1[i] < p2[i]) - return -1; - } - return 0; + for (i = 0; i < sizeof(struct in6_addr); i++) { + if (p1[i] > p2[i]) + return 1; + else if (p1[i] < p2[i]) + return -1; + } + return 0; } -int -sockunion_cmp (const union sockunion *su1, const union sockunion *su2) +int sockunion_cmp(const union sockunion *su1, const union sockunion *su2) { - if (su1->sa.sa_family > su2->sa.sa_family) - return 1; - if (su1->sa.sa_family < su2->sa.sa_family) - return -1; + if (su1->sa.sa_family > su2->sa.sa_family) + return 1; + if (su1->sa.sa_family < su2->sa.sa_family) + return -1; - if (su1->sa.sa_family == AF_INET) - { - if (ntohl (sockunion2ip (su1)) == ntohl (sockunion2ip (su2))) + if (su1->sa.sa_family == AF_INET) { + if (ntohl(sockunion2ip(su1)) == ntohl(sockunion2ip(su2))) + return 0; + if (ntohl(sockunion2ip(su1)) > ntohl(sockunion2ip(su2))) + return 1; + else + return -1; + } + if (su1->sa.sa_family == AF_INET6) + return in6addr_cmp(&su1->sin6.sin6_addr, &su2->sin6.sin6_addr); return 0; - if (ntohl (sockunion2ip (su1)) > ntohl (sockunion2ip (su2))) - return 1; - else - return -1; - } - if (su1->sa.sa_family == AF_INET6) - return in6addr_cmp (&su1->sin6.sin6_addr, &su2->sin6.sin6_addr); - return 0; } /* Duplicate sockunion. */ -union sockunion * -sockunion_dup (const union sockunion *su) +union sockunion *sockunion_dup(const union sockunion *su) { - union sockunion *dup = XCALLOC (MTYPE_SOCKUNION, sizeof (union sockunion)); - memcpy (dup, su, sizeof (union sockunion)); - return dup; + union sockunion *dup = + XCALLOC(MTYPE_SOCKUNION, sizeof(union sockunion)); + memcpy(dup, su, sizeof(union sockunion)); + return dup; } -void -sockunion_free (union sockunion *su) +void sockunion_free(union sockunion *su) { - XFREE (MTYPE_SOCKUNION, su); + XFREE(MTYPE_SOCKUNION, su); } -void -sockunion_init (union sockunion *su) +void sockunion_init(union sockunion *su) { - memset(su, 0, sizeof(union sockunion)); + memset(su, 0, sizeof(union sockunion)); }