]> CyberLeo.Net >> Repos - FreeBSD/releng/9.3.git/blob - contrib/ntp/libntp/is_ip_address.c
Fix BIND remote denial of service vulnerability. [SA-16:08]
[FreeBSD/releng/9.3.git] / contrib / ntp / libntp / is_ip_address.c
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 }