]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
util: move and improve sockaddr-specific functions
authorMiroslav Lichvar <mlichvar@redhat.com>
Thu, 18 Jul 2019 07:42:11 +0000 (09:42 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Thu, 18 Jul 2019 15:29:44 +0000 (17:29 +0200)
Move the functions to socket.c and improve them to require and check the
sockaddr length.

nameserv.c
privops.c
socket.c
socket.h
util.c
util.h

index 97b47f8897b707d320b430044164d107a2053e4c..c506b73b7527e4d2f04ba9cd447b31d2ecb6a8ab 100644 (file)
@@ -34,6 +34,7 @@
 #include <resolv.h>
 
 #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
index 844ac6c42f53fec27831a0f60f456f4c30010c3d..5513bdaad9f7d58981185582e7c759e05b5eb9d8 100644 (file)
--- 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())
index b523abfe7caf98ef0eadb886ec19fb999d18942f..5a2a51140c5bc357ce88b075e447ff1a2a100be8 100644 (file)
--- 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;
+  }
+}
index 5bc317f76d72dbcae76d55622ac943e8bf254817..54ec5a6ea7f2914371b1a43c10dd9a4b7dccd02b 100644 (file)
--- 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 6504710e4e6aa7efe653480dad5b4682585e7d1e..e8bdea297bc9853e5f79ec2c6b44a5e1e87189d4 100644 (file)
--- 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 90b69fd8475193216880b98cd557d9e7faa57586..498fa7944a74550db69c699a76fb9e66c5ff5ba6 100644 (file)
--- 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);