2 * decodenetnum - return a net number (this is crude, but careful)
7 #ifdef HAVE_SYS_SOCKET_H
8 #include <sys/socket.h>
10 #ifdef HAVE_NETINET_IN_H
11 #include <netinet/in.h>
15 #include "ntp_stdlib.h"
16 #include "ntp_assert.h"
18 #define PORTSTR(x) _PORTSTR(x)
19 #define _PORTSTR(x) #x
26 while (*s >= '0' && *s <= '9')
32 * decodenetnum convert text IP address and port to sockaddr_u
34 * Returns 0 for failure, 1 for success.
42 static const char * const servicename = "ntp";
43 static const char * const serviceport = PORTSTR(NTP_PORT);
45 struct addrinfo hints, *ai = NULL;
55 if (strlen(num) >= sizeof(nbuf)) {
56 printf("length error\n");
60 port_str = servicename;
63 * to distinguish IPv6 embedded colons from a port
64 * specification on an IPv4 address, assume all
65 * legal IPv6 addresses have at least two colons.
67 pp = strchr(num, ':');
69 host_str = num; /* no colons */
70 else if (NULL != strchr(pp + 1, ':'))
71 host_str = num; /* two or more colons */
72 else { /* one colon */
73 strlcpy(nbuf, num, sizeof(nbuf));
75 pp = strchr(nbuf, ':');
81 while (*++num && ']' != *num)
84 if (']' == num[0] && ':' == num[1] && '\0' != num[2])
90 port_str = servicename;
93 hints.ai_flags |= Z_AI_NUMERICHOST;
94 if (isnumstr(port_str))
95 hints.ai_flags |= Z_AI_NUMERICSERV;
96 err = getaddrinfo(host_str, port_str, &hints, &ai);
97 /* retry with default service name if the service lookup failed */
98 if (err == EAI_SERVICE && strcmp(port_str, servicename)) {
99 hints.ai_flags &= ~Z_AI_NUMERICSERV;
100 port_str = servicename;
101 err = getaddrinfo(host_str, port_str, &hints, &ai);
103 /* retry another time with default service port if the service lookup failed */
104 if (err == EAI_SERVICE && strcmp(port_str, serviceport)) {
105 hints.ai_flags |= Z_AI_NUMERICSERV;
106 port_str = serviceport;
107 err = getaddrinfo(host_str, port_str, &hints, &ai);
112 INSIST(ai->ai_addrlen <= sizeof(*netnum));
114 memcpy(netnum, ai->ai_addr, ai->ai_addrlen);