1 /* 2 * decodenetnum - return a net number (this is crude, but careful) 3 */ 4 #include <config.h> 5 #include <sys/types.h> 6 #include <ctype.h> 7 #ifdef HAVE_SYS_SOCKET_H 8 #include <sys/socket.h> 9 #endif 10 #ifdef HAVE_NETINET_IN_H 11 #include <netinet/in.h> 12 #endif 13 14 #include "ntp.h" 15 #include "ntp_stdlib.h" 16 #include "ntp_assert.h" 17 18 /* 19 * decodenetnum convert text IP address and port to sockaddr_u 20 * 21 * Returns 0 for failure, 1 for success. 22 */ 23 int 24 decodenetnum( 25 const char *num, 26 sockaddr_u *netnum 27 ) 28 { 29 struct addrinfo hints, *ai = NULL; 30 int err; 31 u_short port; 32 const char *cp; 33 const char *port_str; 34 char *pp; 35 char *np; 36 char name[80]; 37 38 NTP_REQUIRE(num != NULL); 39 NTP_REQUIRE(strlen(num) < sizeof(name)); 40 41 port_str = NULL; 42 if ('[' != num[0]) { 43 /* 44 * to distinguish IPv6 embedded colons from a port 45 * specification on an IPv4 address, assume all 46 * legal IPv6 addresses have at least two colons. 47 */ 48 pp = strchr(num, ':'); 49 if (NULL == pp) 50 cp = num; /* no colons */ 51 else if (NULL != strchr(pp + 1, ':')) 52 cp = num; /* two or more colons */ 53 else { /* one colon */ 54 strlcpy(name, num, sizeof(name)); 55 cp = name; 56 pp = strchr(cp, ':'); 57 *pp = '\0'; 58 port_str = pp + 1; 59 } 60 } else { 61 cp = num + 1; 62 np = name; 63 while (*cp && ']' != *cp) 64 *np++ = *cp++; 65 *np = 0; 66 if (']' == cp[0] && ':' == cp[1] && '\0' != cp[2]) 67 port_str = &cp[2]; 68 cp = name; 69 } 70 ZERO(hints); 71 hints.ai_flags = Z_AI_NUMERICHOST; 72 err = getaddrinfo(cp, "ntp", &hints, &ai); 73 if (err != 0) 74 return 0; 75 NTP_INSIST(ai->ai_addrlen <= sizeof(*netnum)); 76 ZERO(*netnum); 77 memcpy(netnum, ai->ai_addr, ai->ai_addrlen); 78 freeaddrinfo(ai); 79 if (NULL == port_str || 1 != sscanf(port_str, "%hu", &port)) 80 port = NTP_PORT; 81 SET_PORT(netnum, port); 82 return 1; 83 } 84