decodenetnum.c revision 290000
1203053Sdelphij/* 2203053Sdelphij * decodenetnum - return a net number (this is crude, but careful) 3203053Sdelphij */ 4203053Sdelphij#include <config.h> 5203053Sdelphij#include <sys/types.h> 6203053Sdelphij#include <ctype.h> 7203053Sdelphij#ifdef HAVE_SYS_SOCKET_H 8203053Sdelphij#include <sys/socket.h> 9203053Sdelphij#endif 10203053Sdelphij#ifdef HAVE_NETINET_IN_H 11203053Sdelphij#include <netinet/in.h> 12203053Sdelphij#endif 13203053Sdelphij 14203053Sdelphij#include "ntp.h" 15203053Sdelphij#include "ntp_stdlib.h" 16203053Sdelphij#include "ntp_assert.h" 17203053Sdelphij 18203053Sdelphij/* 19203053Sdelphij * decodenetnum convert text IP address and port to sockaddr_u 20203053Sdelphij * 21203053Sdelphij * Returns 0 for failure, 1 for success. 22203053Sdelphij */ 23203053Sdelphijint 24203053Sdelphijdecodenetnum( 25203053Sdelphij const char *num, 26203053Sdelphij sockaddr_u *netnum 27203053Sdelphij ) 28203053Sdelphij{ 29203684Sgavin struct addrinfo hints, *ai = NULL; 30203684Sgavin int err; 31203053Sdelphij u_short port; 32203053Sdelphij const char *cp; 33203053Sdelphij const char *port_str; 34203053Sdelphij char *pp; 35203053Sdelphij char *np; 36203053Sdelphij char name[80]; 37203053Sdelphij 38203053Sdelphij REQUIRE(num != NULL); 39203053Sdelphij 40203053Sdelphij if (strlen(num) >= sizeof(name)) { 41203053Sdelphij return 0; 42203053Sdelphij } 43203053Sdelphij 44203053Sdelphij port_str = NULL; 45203053Sdelphij if ('[' != num[0]) { 46203053Sdelphij /* 47203053Sdelphij * to distinguish IPv6 embedded colons from a port 48203053Sdelphij * specification on an IPv4 address, assume all 49203053Sdelphij * legal IPv6 addresses have at least two colons. 50203053Sdelphij */ 51203053Sdelphij pp = strchr(num, ':'); 52203053Sdelphij if (NULL == pp) 53203053Sdelphij cp = num; /* no colons */ 54203053Sdelphij else if (NULL != strchr(pp + 1, ':')) 55203053Sdelphij cp = num; /* two or more colons */ 56203053Sdelphij else { /* one colon */ 57203053Sdelphij strlcpy(name, num, sizeof(name)); 58203053Sdelphij cp = name; 59203053Sdelphij pp = strchr(cp, ':'); 60203053Sdelphij *pp = '\0'; 61203053Sdelphij port_str = pp + 1; 62203053Sdelphij } 63203053Sdelphij } else { 64203053Sdelphij cp = num + 1; 65203053Sdelphij np = name; 66203053Sdelphij while (*cp && ']' != *cp) 67203053Sdelphij *np++ = *cp++; 68203053Sdelphij *np = 0; 69203053Sdelphij if (']' == cp[0] && ':' == cp[1] && '\0' != cp[2]) 70203053Sdelphij port_str = &cp[2]; 71203053Sdelphij cp = name; 72203053Sdelphij } 73203053Sdelphij ZERO(hints); 74203053Sdelphij hints.ai_flags = Z_AI_NUMERICHOST; 75203053Sdelphij err = getaddrinfo(cp, "ntp", &hints, &ai); 76203053Sdelphij if (err != 0) 77203053Sdelphij return 0; 78203053Sdelphij INSIST(ai->ai_addrlen <= sizeof(*netnum)); 79203053Sdelphij ZERO(*netnum); 80203053Sdelphij memcpy(netnum, ai->ai_addr, ai->ai_addrlen); 81203053Sdelphij freeaddrinfo(ai); 82203053Sdelphij if (NULL == port_str || 1 != sscanf(port_str, "%hu", &port)) 83203053Sdelphij port = NTP_PORT; 84203053Sdelphij SET_PORT(netnum, port); 85203053Sdelphij return 1; 86203053Sdelphij} 87203053Sdelphij