From d54cfbdce4a9878ef65216dea36b62cf6646b84b Mon Sep 17 00:00:00 2001 From: roberto Date: Wed, 4 Dec 2013 21:33:17 +0000 Subject: Virgin import of ntpd 4.2.6p5. When the series of commits is complete, things like https://cert.litnet.lt/en/docs/ntp-distributed-reflection-dos-attacks should be fixed. PR: bin/148836 (except that we import a newer version) Asked by: Too many MFC after: 2 weeks --- libntp/decodenetnum.c | 72 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 58 insertions(+), 14 deletions(-) (limited to 'libntp/decodenetnum.c') diff --git a/libntp/decodenetnum.c b/libntp/decodenetnum.c index 746c855..f265dae 100644 --- a/libntp/decodenetnum.c +++ b/libntp/decodenetnum.c @@ -1,39 +1,83 @@ /* * decodenetnum - return a net number (this is crude, but careful) */ +#include #include #include +#ifdef HAVE_SYS_SOCKET_H #include +#endif +#ifdef HAVE_NETINET_IN_H #include +#endif +#include "ntp.h" #include "ntp_stdlib.h" +#include "ntp_assert.h" +/* + * decodenetnum convert text IP address and port to sockaddr_u + * + * Returns 0 for failure, 1 for success. + */ int decodenetnum( const char *num, - struct sockaddr_storage *netnum + sockaddr_u *netnum ) { struct addrinfo hints, *ai = NULL; - register int err, i; - register const char *cp; + int err; + u_short port; + const char *cp; + const char *port_str; + char *pp; + char *np; char name[80]; - cp = num; + NTP_REQUIRE(num != NULL); + NTP_REQUIRE(strlen(num) < sizeof(name)); - if (*cp == '[') { - cp++; - for (i = 0; *cp != ']'; cp++, i++) - name[i] = *cp; - name[i] = '\0'; - num = name; + port_str = NULL; + if ('[' != num[0]) { + /* + * to distinguish IPv6 embedded colons from a port + * specification on an IPv4 address, assume all + * legal IPv6 addresses have at least two colons. + */ + pp = strchr(num, ':'); + if (NULL == pp) + cp = num; /* no colons */ + else if (NULL != strchr(pp + 1, ':')) + cp = num; /* two or more colons */ + else { /* one colon */ + strncpy(name, num, sizeof(name)); + name[sizeof(name) - 1] = '\0'; + cp = name; + pp = strchr(cp, ':'); + *pp = '\0'; + port_str = pp + 1; + } + } else { + cp = num + 1; + np = name; + while (*cp && ']' != *cp) + *np++ = *cp++; + *np = 0; + if (']' == cp[0] && ':' == cp[1] && '\0' != cp[2]) + port_str = &cp[2]; + cp = name; } - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_flags = AI_NUMERICHOST; - err = getaddrinfo(num, NULL, &hints, &ai); + ZERO(hints); + hints.ai_flags = Z_AI_NUMERICHOST; + err = getaddrinfo(cp, "ntp", &hints, &ai); if (err != 0) return 0; - memcpy(netnum, (struct sockaddr_storage *)ai->ai_addr, ai->ai_addrlen); + NTP_INSIST(ai->ai_addrlen <= sizeof(*netnum)); + memcpy(netnum, ai->ai_addr, ai->ai_addrlen); freeaddrinfo(ai); + if (NULL == port_str || 1 != sscanf(port_str, "%hu", &port)) + port = NTP_PORT; + SET_PORT(netnum, port); return 1; } -- cgit v1.1