From 55a22656b82ff91ee2fe92a9851e0a03d792ff57 Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Fri, 26 Sep 2014 17:49:07 +0200 Subject: [PATCH] util: use common functions to convert to/from sockaddr --- client.c | 15 ++---------- cmdmon.c | 33 +++++-------------------- nameserv.c | 27 ++++----------------- ntp_io.c | 70 ++++++++---------------------------------------------- util.c | 59 +++++++++++++++++++++++++++++++++++++++++++++ util.h | 3 +++ 6 files changed, 84 insertions(+), 123 deletions(-) diff --git a/client.c b/client.c index 73cdf6e..0b08de6 100644 --- a/client.c +++ b/client.c @@ -124,32 +124,21 @@ open_io(const char *hostname, int port) exit(1); } - memset(&his_addr, 0, sizeof (his_addr)); - switch (ip.family) { case IPADDR_INET4: sock_fd = socket(AF_INET, SOCK_DGRAM, 0); - - his_addr.in4.sin_family = AF_INET; - his_addr.in4.sin_addr.s_addr = htonl(ip.addr.in4); - his_addr.in4.sin_port = htons(port); - his_addr_len = sizeof (his_addr.in4); break; #ifdef FEAT_IPV6 case IPADDR_INET6: sock_fd = socket(AF_INET6, SOCK_DGRAM, 0); - - his_addr.in6.sin6_family = AF_INET6; - memcpy(his_addr.in6.sin6_addr.s6_addr, ip.addr.in6, - sizeof (his_addr.in6.sin6_addr.s6_addr)); - his_addr.in6.sin6_port = htons(port); - his_addr_len = sizeof (his_addr.in6); break; #endif default: assert(0); } + his_addr_len = UTI_IPAndPort2Sockaddr(&ip, port, &his_addr.u); + if (sock_fd < 0) { perror("Can't create socket"); exit(1); diff --git a/cmdmon.c b/cmdmon.c index 8406087..e9d96c2 100644 --- a/cmdmon.c +++ b/cmdmon.c @@ -706,23 +706,7 @@ transmit_reply(CMD_Reply *msg, union sockaddr_in46 *where_to, int auth_len) unsigned short port; IPAddr ip; - switch (where_to->u.sa_family) { - case AF_INET: - ip.family = IPADDR_INET4; - ip.addr.in4 = ntohl(where_to->in4.sin_addr.s_addr); - port = ntohs(where_to->in4.sin_port); - break; -#ifdef FEAT_IPV6 - case AF_INET6: - ip.family = IPADDR_INET6; - memcpy(ip.addr.in6, (where_to->in6.sin6_addr.s6_addr), sizeof(ip.addr.in6)); - port = ntohs(where_to->in6.sin6_port); - break; -#endif - default: - assert(0); - } - + UTI_Sockaddr2IPAndPort(&where_to->u, &ip, &port); DEBUG_LOG(LOGF_CmdMon, "Could not send response to %s:%hu", UTI_IPToString(&ip), port); } } @@ -1653,19 +1637,14 @@ read_from_cmd_socket(void *anything) LCL_ReadRawTime(&now); LCL_CookTime(&now, &cooked_now, NULL); - switch (where_from.u.sa_family) { - case AF_INET: - remote_ip.family = IPADDR_INET4; - remote_ip.addr.in4 = ntohl(where_from.in4.sin_addr.s_addr); - remote_port = ntohs(where_from.in4.sin_port); + UTI_Sockaddr2IPAndPort(&where_from.u, &remote_ip, &remote_port); + + switch (remote_ip.family) { + case IPADDR_INET4: localhost = (remote_ip.addr.in4 == 0x7f000001UL); break; #ifdef FEAT_IPV6 - case AF_INET6: - remote_ip.family = IPADDR_INET6; - memcpy(&remote_ip.addr.in6, where_from.in6.sin6_addr.s6_addr, - sizeof (remote_ip.addr.in6)); - remote_port = ntohs(where_from.in6.sin6_port); + case IPADDR_INET6: /* Check for ::1 */ for (localhost = 0; localhost < 16; localhost++) if (remote_ip.addr.in6[localhost] != 0) diff --git a/nameserv.c b/nameserv.c index 56a3a4a..f977bd6 100644 --- a/nameserv.c +++ b/nameserv.c @@ -116,32 +116,13 @@ DNS_IPAddress2Name(IPAddr *ip_addr, char *name, int len) char *result = NULL; #ifdef FEAT_IPV6 - struct sockaddr_in in4; struct sockaddr_in6 in6; + socklen_t slen; char hbuf[NI_MAXHOST]; - switch (ip_addr->family) { - case IPADDR_INET4: - memset(&in4, 0, sizeof (in4)); -#ifdef SIN6_LEN - in4.sin_len = sizeof (in4); -#endif - in4.sin_family = AF_INET; - in4.sin_addr.s_addr = htonl(ip_addr->addr.in4); - if (!getnameinfo((const struct sockaddr *)&in4, sizeof (in4), hbuf, sizeof (hbuf), NULL, 0, 0)) - result = hbuf; - break; - case IPADDR_INET6: - memset(&in6, 0, sizeof (in6)); -#ifdef SIN6_LEN - in6.sin6_len = sizeof (in6); -#endif - in6.sin6_family = AF_INET6; - memcpy(&in6.sin6_addr.s6_addr, ip_addr->addr.in6, sizeof (in6.sin6_addr.s6_addr)); - if (!getnameinfo((const struct sockaddr *)&in6, sizeof (in6), hbuf, sizeof (hbuf), NULL, 0, 0)) - result = hbuf; - break; - } + slen = UTI_IPAndPort2Sockaddr(ip_addr, 0, (struct sockaddr *)&in6); + if (!getnameinfo((struct sockaddr *)&in6, slen, hbuf, sizeof (hbuf), NULL, 0, 0)) + result = hbuf; #else struct hostent *host; uint32_t addr; diff --git a/ntp_io.c b/ntp_io.c index 1af88a2..7dc20de 100644 --- a/ntp_io.c +++ b/ntp_io.c @@ -243,27 +243,9 @@ connect_socket(int sock_fd, NTP_Remote_Address *remote_addr) union sockaddr_in46 addr; socklen_t addr_len; - memset(&addr, 0, sizeof (addr)); + addr_len = UTI_IPAndPort2Sockaddr(&remote_addr->ip_addr, remote_addr->port, &addr.u); - switch (remote_addr->ip_addr.family) { - case IPADDR_INET4: - addr_len = sizeof (addr.in4); - addr.in4.sin_family = AF_INET; - addr.in4.sin_addr.s_addr = htonl(remote_addr->ip_addr.addr.in4); - addr.in4.sin_port = htons(remote_addr->port); - break; -#ifdef FEAT_IPV6 - case IPADDR_INET6: - addr_len = sizeof (addr.in6); - addr.in6.sin6_family = AF_INET6; - memcpy(addr.in6.sin6_addr.s6_addr, remote_addr->ip_addr.addr.in6, - sizeof (addr.in6.sin6_addr.s6_addr)); - addr.in6.sin6_port = htons(remote_addr->port); - break; -#endif - default: - assert(0); - } + assert(addr_len); if (connect(sock_fd, &addr.u, addr_len) < 0) { DEBUG_LOG(LOGF_NtpIO, "Could not connect NTP socket to %s:%d : %s", @@ -484,23 +466,7 @@ read_from_socket(void *anything) if (msg.msg_namelen > sizeof (where_from)) LOG_FATAL(LOGF_NtpIO, "Truncated source address"); - switch (where_from.u.sa_family) { - case AF_INET: - remote_addr.ip_addr.family = IPADDR_INET4; - remote_addr.ip_addr.addr.in4 = ntohl(where_from.in4.sin_addr.s_addr); - remote_addr.port = ntohs(where_from.in4.sin_port); - break; -#ifdef FEAT_IPV6 - case AF_INET6: - remote_addr.ip_addr.family = IPADDR_INET6; - memcpy(&remote_addr.ip_addr.addr.in6, where_from.in6.sin6_addr.s6_addr, - sizeof (remote_addr.ip_addr.addr.in6)); - remote_addr.port = ntohs(where_from.in6.sin6_port); - break; -#endif - default: - assert(0); - } + UTI_Sockaddr2IPAndPort(&where_from.u, &remote_addr.ip_addr, &remote_addr.port); local_addr.ip_addr.family = IPADDR_UNSPEC; local_addr.sock_fd = sock_fd; @@ -578,31 +544,15 @@ send_packet(void *packet, int packetlen, NTP_Remote_Address *remote_addr, NTP_Lo return 0; } - switch (remote_addr->ip_addr.family) { - case IPADDR_INET4: - /* Don't set address with connected socket */ - if (local_addr->sock_fd != server_sock_fd4 && separate_client_sockets) - break; - memset(&remote.in4, 0, sizeof (remote.in4)); - addrlen = sizeof (remote.in4); - remote.in4.sin_family = AF_INET; - remote.in4.sin_port = htons(remote_addr->port); - remote.in4.sin_addr.s_addr = htonl(remote_addr->ip_addr.addr.in4); - break; + /* Don't set address with connected socket */ + if (local_addr->sock_fd == server_sock_fd4 || #ifdef FEAT_IPV6 - case IPADDR_INET6: - /* Don't set address with connected socket */ - if (local_addr->sock_fd != server_sock_fd6 && separate_client_sockets) - break; - memset(&remote.in6, 0, sizeof (remote.in6)); - addrlen = sizeof (remote.in6); - remote.in6.sin6_family = AF_INET6; - remote.in6.sin6_port = htons(remote_addr->port); - memcpy(&remote.in6.sin6_addr.s6_addr, &remote_addr->ip_addr.addr.in6, - sizeof (remote.in6.sin6_addr.s6_addr)); - break; + local_addr->sock_fd == server_sock_fd6 || #endif - default: + !separate_client_sockets) { + addrlen = UTI_IPAndPort2Sockaddr(&remote_addr->ip_addr, remote_addr->port, + &remote.u); + if (!addrlen) return 0; } diff --git a/util.c b/util.c index 7a39ffb..cc2318c 100644 --- a/util.c +++ b/util.c @@ -426,6 +426,65 @@ UTI_CompareIPs(IPAddr *a, IPAddr *b, IPAddr *mask) /* ================================================== */ +void +UTI_Sockaddr2IPAndPort(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_IPAndPort2Sockaddr(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; + } +} + +/* ================================================== */ + char * UTI_TimeToLogForm(time_t t) { diff --git a/util.h b/util.h index a0a688d..8202254 100644 --- a/util.h +++ b/util.h @@ -86,6 +86,9 @@ 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_Sockaddr2IPAndPort(struct sockaddr *sa, IPAddr *ip, unsigned short *port); +extern int UTI_IPAndPort2Sockaddr(IPAddr *ip, unsigned short port, struct sockaddr *sa); + extern char *UTI_TimeToLogForm(time_t t); /* Adjust time following a frequency/offset change */