From 47e4cb31b2c5b8ce74c11eb366fffc6e23e78de2 Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Thu, 18 Jul 2019 09:42:11 +0200 Subject: [PATCH] util: move and improve sockaddr-specific functions Move the functions to socket.c and improve them to require and check the sockaddr length. --- nameserv.c | 7 +++- privops.c | 19 +++++----- socket.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++----- socket.h | 4 +++ util.c | 80 ----------------------------------------- util.h | 4 --- 6 files changed, 113 insertions(+), 103 deletions(-) diff --git a/nameserv.c b/nameserv.c index 97b47f8..c506b73 100644 --- a/nameserv.c +++ b/nameserv.c @@ -34,6 +34,7 @@ #include #include "nameserv.h" +#include "socket.h" #include "util.h" /* ================================================== */ @@ -156,10 +157,14 @@ DNS_IPAddress2Name(IPAddr *ip_addr, char *name, int len) #ifdef FEAT_IPV6 struct sockaddr_in6 in6; + IPSockAddr ip_saddr; socklen_t slen; char hbuf[NI_MAXHOST]; - slen = UTI_IPAndPortToSockaddr(ip_addr, 0, (struct sockaddr *)&in6); + ip_saddr.ip_addr = *ip_addr; + ip_saddr.port = 0; + + slen = SCK_IPSockAddrToSockaddr(&ip_saddr, (struct sockaddr *)&in6, sizeof (in6)); if (!getnameinfo((struct sockaddr *)&in6, slen, hbuf, sizeof (hbuf), NULL, 0, 0)) result = hbuf; #else diff --git a/privops.c b/privops.c index 844ac6c..5513bda 100644 --- a/privops.c +++ b/privops.c @@ -33,6 +33,7 @@ #include "nameserv.h" #include "logging.h" #include "privops.h" +#include "socket.h" #include "util.h" #define OP_ADJUSTTIME 1024 @@ -257,8 +258,7 @@ do_set_time(const ReqSetTime *req, PrvResponse *res) static void do_bind_socket(ReqBindSocket *req, PrvResponse *res) { - unsigned short port; - IPAddr ip; + IPSockAddr ip_saddr; int sock_fd; struct sockaddr *sa; socklen_t sa_len; @@ -267,10 +267,11 @@ do_bind_socket(ReqBindSocket *req, PrvResponse *res) sa_len = req->sa_len; sock_fd = req->sock; - UTI_SockaddrToIPAndPort(sa, &ip, &port); - if (port && port != CNF_GetNTPPort() && port != CNF_GetAcquisitionPort()) { + SCK_SockaddrToIPSockAddr(sa, sa_len, &ip_saddr); + if (ip_saddr.port != 0 && ip_saddr.port != CNF_GetNTPPort() && + ip_saddr.port != CNF_GetAcquisitionPort()) { close(sock_fd); - res_fatal(res, "Invalid port %d", port); + res_fatal(res, "Invalid port %d", ip_saddr.port); return; } @@ -573,13 +574,13 @@ PRV_SetTime(const struct timeval *tp, const struct timezone *tzp) int PRV_BindSocket(int sock, struct sockaddr *address, socklen_t address_len) { + IPSockAddr ip_saddr; PrvRequest req; PrvResponse res; - IPAddr ip; - unsigned short port; - UTI_SockaddrToIPAndPort(address, &ip, &port); - if (port && port != CNF_GetNTPPort() && port != CNF_GetAcquisitionPort()) + SCK_SockaddrToIPSockAddr(address, address_len, &ip_saddr); + if (ip_saddr.port != 0 && ip_saddr.port != CNF_GetNTPPort() && + ip_saddr.port != CNF_GetAcquisitionPort()) assert(0); if (!have_helper()) diff --git a/socket.c b/socket.c index b523abf..5a2a511 100644 --- a/socket.c +++ b/socket.c @@ -119,10 +119,23 @@ prepare_buffers(unsigned int n) /* ================================================== */ -static int -ipsockaddr_to_sockaddr(IPSockAddr *addr, union sockaddr_all *saddr) +static const char * +domain_to_string(int domain) { - return UTI_IPAndPortToSockaddr(&addr->ip_addr, addr->port, &saddr->sa); + switch (domain) { + case AF_INET: + return "IPv4"; +#ifdef AF_INET6 + case AF_INET6: + return "IPv6"; +#endif + case AF_UNIX: + return "Unix"; + case AF_UNSPEC: + return "UNSPEC"; + default: + return "?"; + } } /* ================================================== */ @@ -136,7 +149,7 @@ open_socket(int domain, int type, int flags) if (sock_fd < 0) { DEBUG_LOG("Could not open %s socket : %s", - UTI_SockaddrFamilyToString(domain), strerror(errno)); + domain_to_string(domain), strerror(errno)); return INVALID_SOCK_FD; } @@ -228,7 +241,7 @@ bind_ip_address(int sock_fd, IPSockAddr *addr, int flags) ; #endif - saddr_len = ipsockaddr_to_sockaddr(addr, &saddr); + saddr_len = SCK_IPSockAddrToSockaddr(addr, (struct sockaddr *)&saddr, sizeof (saddr)); if (saddr_len == 0) return 0; @@ -254,7 +267,7 @@ connect_ip_address(int sock_fd, IPSockAddr *addr) union sockaddr_all saddr; socklen_t saddr_len; - saddr_len = ipsockaddr_to_sockaddr(addr, &saddr); + saddr_len = SCK_IPSockAddrToSockaddr(addr, (struct sockaddr *)&saddr, sizeof (saddr)); if (saddr_len == 0) return 0; @@ -584,8 +597,7 @@ process_header(struct msghdr *msg, unsigned int msg_length, int sock_fd, SCK_Mes case AF_INET6: #endif init_message_addresses(message, SCK_ADDR_IP); - UTI_SockaddrToIPAndPort(msg->msg_name, &message->remote_addr.ip.ip_addr, - &message->remote_addr.ip.port); + SCK_SockaddrToIPSockAddr(msg->msg_name, msg->msg_namelen, &message->remote_addr.ip); break; case AF_UNIX: init_message_addresses(message, SCK_ADDR_UNIX); @@ -812,7 +824,8 @@ send_message(int sock_fd, SCK_Message *message, int flags) saddr_len = 0; break; case SCK_ADDR_IP: - saddr_len = ipsockaddr_to_sockaddr(&message->remote_addr.ip, &saddr); + saddr_len = SCK_IPSockAddrToSockaddr(&message->remote_addr.ip, + (struct sockaddr *)&saddr, sizeof (saddr)); break; case SCK_ADDR_UNIX: memset(&saddr, 0, sizeof (saddr)); @@ -1160,3 +1173,74 @@ SCK_CloseSocket(int sock_fd) { close(sock_fd); } + +/* ================================================== */ + +void +SCK_SockaddrToIPSockAddr(struct sockaddr *sa, int sa_length, IPSockAddr *ip_sa) +{ + ip_sa->ip_addr.family = IPADDR_UNSPEC; + ip_sa->port = 0; + + switch (sa->sa_family) { + case AF_INET: + if (sa_length < sizeof (struct sockaddr_in)) + return; + ip_sa->ip_addr.family = IPADDR_INET4; + ip_sa->ip_addr.addr.in4 = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr); + ip_sa->port = ntohs(((struct sockaddr_in *)sa)->sin_port); + break; +#ifdef FEAT_IPV6 + case AF_INET6: + if (sa_length < sizeof (struct sockaddr_in6)) + return; + ip_sa->ip_addr.family = IPADDR_INET6; + memcpy(&ip_sa->ip_addr.addr.in6, ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr, + sizeof (ip_sa->ip_addr.addr.in6)); + ip_sa->port = ntohs(((struct sockaddr_in6 *)sa)->sin6_port); + break; +#endif + default: + break; + } +} + +/* ================================================== */ + +int +SCK_IPSockAddrToSockaddr(IPSockAddr *ip_sa, struct sockaddr *sa, int sa_length) +{ + switch (ip_sa->ip_addr.family) { + case IPADDR_INET4: + if (sa_length < sizeof (struct sockaddr_in)) + return 0; + memset(sa, 0, sizeof (struct sockaddr_in)); + sa->sa_family = AF_INET; + ((struct sockaddr_in *)sa)->sin_addr.s_addr = htonl(ip_sa->ip_addr.addr.in4); + ((struct sockaddr_in *)sa)->sin_port = htons(ip_sa->port); +#ifdef SIN6_LEN + ((struct sockaddr_in *)sa)->sin_len = sizeof (struct sockaddr_in); +#endif + return sizeof (struct sockaddr_in); +#ifdef FEAT_IPV6 + case IPADDR_INET6: + if (sa_length < sizeof (struct sockaddr_in6)) + return 0; + memset(sa, 0, sizeof (struct sockaddr_in6)); + sa->sa_family = AF_INET6; + memcpy(&((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr, ip_sa->ip_addr.addr.in6, + sizeof (((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr)); + ((struct sockaddr_in6 *)sa)->sin6_port = htons(ip_sa->port); +#ifdef SIN6_LEN + ((struct sockaddr_in6 *)sa)->sin6_len = sizeof (struct sockaddr_in6); +#endif + return sizeof (struct sockaddr_in6); +#endif + default: + if (sa_length < sizeof (struct sockaddr)) + return 0; + memset(sa, 0, sizeof (struct sockaddr)); + sa->sa_family = AF_UNSPEC; + return 0; + } +} diff --git a/socket.h b/socket.h index 5bc317f..54ec5a6 100644 --- a/socket.h +++ b/socket.h @@ -124,4 +124,8 @@ extern int SCK_RemoveSocket(int sock_fd); /* Close the socket */ extern void SCK_CloseSocket(int sock_fd); +/* Convert between IPSockAddr and sockaddr_in/in6 */ +extern void SCK_SockaddrToIPSockAddr(struct sockaddr *sa, int sa_length, IPSockAddr *ip_sa); +extern int SCK_IPSockAddrToSockaddr(IPSockAddr *ip_sa, struct sockaddr *sa, int sa_length); + #endif diff --git a/util.c b/util.c index 6504710..e8bdea2 100644 --- a/util.c +++ b/util.c @@ -492,86 +492,6 @@ UTI_CompareIPs(IPAddr *a, IPAddr *b, IPAddr *mask) /* ================================================== */ -void -UTI_SockaddrToIPAndPort(struct sockaddr *sa, IPAddr *ip, unsigned short *port) -{ - switch (sa->sa_family) { - case AF_INET: - ip->family = IPADDR_INET4; - ip->addr.in4 = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr); - *port = ntohs(((struct sockaddr_in *)sa)->sin_port); - break; -#ifdef FEAT_IPV6 - case AF_INET6: - ip->family = IPADDR_INET6; - memcpy(ip->addr.in6, ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr, - sizeof (ip->addr.in6)); - *port = ntohs(((struct sockaddr_in6 *)sa)->sin6_port); - break; -#endif - default: - ip->family = IPADDR_UNSPEC; - *port = 0; - } -} - -/* ================================================== */ - -int -UTI_IPAndPortToSockaddr(IPAddr *ip, unsigned short port, struct sockaddr *sa) -{ - switch (ip->family) { - case IPADDR_INET4: - memset(sa, 0, sizeof (struct sockaddr_in)); - sa->sa_family = AF_INET; - ((struct sockaddr_in *)sa)->sin_addr.s_addr = htonl(ip->addr.in4); - ((struct sockaddr_in *)sa)->sin_port = htons(port); -#ifdef SIN6_LEN - ((struct sockaddr_in *)sa)->sin_len = sizeof (struct sockaddr_in); -#endif - return sizeof (struct sockaddr_in); -#ifdef FEAT_IPV6 - case IPADDR_INET6: - memset(sa, 0, sizeof (struct sockaddr_in6)); - sa->sa_family = AF_INET6; - memcpy(((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr, ip->addr.in6, - sizeof (ip->addr.in6)); - ((struct sockaddr_in6 *)sa)->sin6_port = htons(port); -#ifdef SIN6_LEN - ((struct sockaddr_in6 *)sa)->sin6_len = sizeof (struct sockaddr_in6); -#endif - return sizeof (struct sockaddr_in6); -#endif - default: - memset(sa, 0, sizeof (struct sockaddr)); - sa->sa_family = AF_UNSPEC; - return 0; - } -} - -/* ================================================== */ - -const char * -UTI_SockaddrFamilyToString(int family) -{ - switch (family) { - case AF_INET: - return "IPv4"; -#ifdef AF_INET6 - case AF_INET6: - return "IPv6"; -#endif - case AF_UNIX: - return "Unix"; - case AF_UNSPEC: - return "UNSPEC"; - default: - return "?"; - } -} - -/* ================================================== */ - char * UTI_IPSockAddrToString(IPSockAddr *sa) { diff --git a/util.h b/util.h index 90b69fd..498fa79 100644 --- a/util.h +++ b/util.h @@ -110,10 +110,6 @@ extern void UTI_IPHostToNetwork(IPAddr *src, IPAddr *dest); extern void UTI_IPNetworkToHost(IPAddr *src, IPAddr *dest); extern int UTI_CompareIPs(IPAddr *a, IPAddr *b, IPAddr *mask); -extern void UTI_SockaddrToIPAndPort(struct sockaddr *sa, IPAddr *ip, unsigned short *port); -extern int UTI_IPAndPortToSockaddr(IPAddr *ip, unsigned short port, struct sockaddr *sa); -extern const char *UTI_SockaddrFamilyToString(int family); - extern char *UTI_IPSockAddrToString(IPSockAddr *sa); extern char *UTI_TimeToLogForm(time_t t);