1 /* 2 * is_ip_address 3 * 4 */ 5 6 #ifdef HAVE_CONFIG_H 7 # include <config.h> 8 #endif 9 10 #if 0 11 #include <stdio.h> 12 #include <signal.h> 13 #ifdef HAVE_FNMATCH_H 14 # include <fnmatch.h> 15 # if !defined(FNM_CASEFOLD) && defined(FNM_IGNORECASE) 16 # define FNM_CASEFOLD FNM_IGNORECASE 17 # endif 18 #endif 19 #ifdef HAVE_SYS_PARAM_H 20 # include <sys/param.h> 21 #endif 22 #ifdef HAVE_SYS_IOCTL_H 23 # include <sys/ioctl.h> 24 #endif 25 #ifdef HAVE_SYS_SOCKIO_H /* UXPV: SIOC* #defines (Frank Vance <fvance@waii.com>) */ 26 # include <sys/sockio.h> 27 #endif 28 #ifdef HAVE_SYS_UIO_H 29 # include <sys/uio.h> 30 #endif 31 #endif 32 33 #include "ntp_assert.h" 34 #include "ntp_stdlib.h" 35 #include "safecast.h" 36 37 #if 0 38 #include "ntp_machine.h" 39 #include "ntpd.h" 40 #include "ntp_io.h" 41 #include "iosignal.h" 42 #include "ntp_lists.h" 43 #include "ntp_refclock.h" 44 #include "ntp_worker.h" 45 #include "ntp_request.h" 46 #include "timevalops.h" 47 #include "timespecops.h" 48 #include "ntpd-opts.h" 49 #endif 50 51 /* Don't include ISC's version of IPv6 variables and structures */ 52 #define ISC_IPV6_H 1 53 #include <isc/mem.h> 54 #include <isc/interfaceiter.h> 55 #include <isc/netaddr.h> 56 #include <isc/result.h> 57 #include <isc/sockaddr.h> 58 59 60 /* 61 * Code to tell if we have an IP address 62 * If we have then return the sockaddr structure 63 * and set the return value 64 * see the bind9/getaddresses.c for details 65 */ 66 int 67 is_ip_address( 68 const char * host, 69 u_short af, 70 sockaddr_u * addr 71 ) 72 { 73 struct in_addr in4; 74 struct addrinfo hints; 75 struct addrinfo *result; 76 struct sockaddr_in6 *resaddr6; 77 char tmpbuf[128]; 78 char *pch; 79 80 REQUIRE(host != NULL); 81 REQUIRE(addr != NULL); 82 83 ZERO_SOCK(addr); 84 85 /* 86 * Try IPv4, then IPv6. In order to handle the extended format 87 * for IPv6 scoped addresses (address%scope_ID), we'll use a local 88 * working buffer of 128 bytes. The length is an ad-hoc value, but 89 * should be enough for this purpose; the buffer can contain a string 90 * of at least 80 bytes for scope_ID in addition to any IPv6 numeric 91 * addresses (up to 46 bytes), the delimiter character and the 92 * terminating NULL character. 93 */ 94 if (AF_UNSPEC == af || AF_INET == af) 95 if (inet_pton(AF_INET, host, &in4) == 1) { 96 AF(addr) = AF_INET; 97 SET_ADDR4N(addr, in4.s_addr); 98 99 return TRUE; 100 } 101 102 if (AF_UNSPEC == af || AF_INET6 == af) 103 if (sizeof(tmpbuf) > strlen(host)) { 104 if ('[' == host[0]) { 105 strlcpy(tmpbuf, &host[1], sizeof(tmpbuf)); 106 pch = strchr(tmpbuf, ']'); 107 if (pch != NULL) 108 *pch = '\0'; 109 } else { 110 strlcpy(tmpbuf, host, sizeof(tmpbuf)); 111 } 112 ZERO(hints); 113 hints.ai_family = AF_INET6; 114 hints.ai_flags |= AI_NUMERICHOST; 115 if (getaddrinfo(tmpbuf, NULL, &hints, &result) == 0) { 116 AF(addr) = AF_INET6; 117 resaddr6 = UA_PTR(struct sockaddr_in6, result->ai_addr); 118 SET_ADDR6N(addr, resaddr6->sin6_addr); 119 SET_SCOPE(addr, resaddr6->sin6_scope_id); 120 121 freeaddrinfo(result); 122 return TRUE; 123 } 124 } 125 /* 126 * If we got here it was not an IP address 127 */ 128 return FALSE; 129 } 130