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 REQUIRE(num != NULL); 39 40 if (strlen(num) >= sizeof(name)) { 41 return 0; 42 } 43 44 port_str = NULL; 45 if ('[' != num[0]) { 46 /* 47 * to distinguish IPv6 embedded colons from a port 48 * specification on an IPv4 address, assume all 49 * legal IPv6 addresses have at least two colons. 50 */ 51 pp = strchr(num, ':'); 52 if (NULL == pp) 53 cp = num; /* no colons */ 54 else if (NULL != strchr(pp + 1, ':')) 55 cp = num; /* two or more colons */ 56 else { /* one colon */ 57 strlcpy(name, num, sizeof(name)); 58 cp = name; 59 pp = strchr(cp, ':'); 60 *pp = '\0'; 61 port_str = pp + 1; 62 } 63 } else { 64 cp = num + 1; 65 np = name; 66 while (*cp && ']' != *cp) 67 *np++ = *cp++; 68 *np = 0; 69 if (']' == cp[0] && ':' == cp[1] && '\0' != cp[2]) 70 port_str = &cp[2]; 71 cp = name; 72 } 73 ZERO(hints); 74 hints.ai_flags = Z_AI_NUMERICHOST; 75 err = getaddrinfo(cp, "ntp", &hints, &ai); 76 if (err != 0) 77 return 0; 78 INSIST(ai->ai_addrlen <= sizeof(*netnum)); 79 ZERO(*netnum); 80 memcpy(netnum, ai->ai_addr, ai->ai_addrlen); 81 freeaddrinfo(ai); 82 if (NULL == port_str || 1 != sscanf(port_str, "%hu", &port)) 83 port = NTP_PORT; 84 SET_PORT(netnum, port); 85 return 1; 86 } 87