util: move and improve sockaddr-specific functions
Move the functions to socket.c and improve them to require and check the sockaddr length.
This commit is contained in:
parent
91da65a782
commit
47e4cb31b2
6 changed files with 113 additions and 103 deletions
|
@ -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
|
||||
|
|
19
privops.c
19
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())
|
||||
|
|
102
socket.c
102
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;
|
||||
}
|
||||
}
|
||||
|
|
4
socket.h
4
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
|
||||
|
|
80
util.c
80
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)
|
||||
{
|
||||
|
|
4
util.h
4
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);
|
||||
|
|
Loading…
Reference in a new issue