/src/ntp-dev/libntp/is_ip_address.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * is_ip_address |
3 | | * |
4 | | */ |
5 | | |
6 | | #ifdef HAVE_CONFIG_H |
7 | | # include <config.h> |
8 | | #endif |
9 | | |
10 | | #include "ntp_assert.h" |
11 | | #include "ntp_stdlib.h" |
12 | | #include "safecast.h" |
13 | | |
14 | | /* Don't include ISC's version of IPv6 variables and structures */ |
15 | | #define ISC_IPV6_H 1 |
16 | | #include <isc/netaddr.h> |
17 | | #include <isc/sockaddr.h> |
18 | | |
19 | | |
20 | | /* |
21 | | * Code to tell if we have an IP address |
22 | | * If we have then return the sockaddr structure |
23 | | * and set the return value |
24 | | * see the bind9/getaddresses.c for details |
25 | | */ |
26 | | int |
27 | | is_ip_address( |
28 | | const char * host, |
29 | | u_short af, |
30 | | sockaddr_u * addr |
31 | | ) |
32 | 0 | { |
33 | 0 | struct in_addr in4; |
34 | 0 | struct addrinfo hints; |
35 | 0 | struct addrinfo *result; |
36 | 0 | struct sockaddr_in6 *resaddr6; |
37 | 0 | char tmpbuf[128]; |
38 | 0 | char *pch; |
39 | |
|
40 | 0 | REQUIRE(host != NULL); |
41 | 0 | REQUIRE(addr != NULL); |
42 | | |
43 | 0 | ZERO_SOCK(addr); |
44 | | |
45 | | /* |
46 | | * Try IPv4, then IPv6. In order to handle the extended format |
47 | | * for IPv6 scoped addresses (address%scope_ID), we'll use a local |
48 | | * working buffer of 128 bytes. The length is an ad-hoc value, but |
49 | | * should be enough for this purpose; the buffer can contain a string |
50 | | * of at least 80 bytes for scope_ID in addition to any IPv6 numeric |
51 | | * addresses (up to 46 bytes), the delimiter character and the |
52 | | * terminating NULL character. |
53 | | */ |
54 | 0 | if (AF_UNSPEC == af || AF_INET == af) |
55 | 0 | if (inet_pton(AF_INET, host, &in4) == 1) { |
56 | 0 | AF(addr) = AF_INET; |
57 | 0 | SET_ADDR4N(addr, in4.s_addr); |
58 | |
|
59 | 0 | return TRUE; |
60 | 0 | } |
61 | | |
62 | 0 | if (AF_UNSPEC == af || AF_INET6 == af) |
63 | 0 | if (sizeof(tmpbuf) > strlen(host)) { |
64 | 0 | if ('[' == host[0]) { |
65 | 0 | strlcpy(tmpbuf, &host[1], sizeof(tmpbuf)); |
66 | 0 | pch = strchr(tmpbuf, ']'); |
67 | 0 | if (pch != NULL) |
68 | 0 | *pch = '\0'; |
69 | 0 | } else { |
70 | 0 | strlcpy(tmpbuf, host, sizeof(tmpbuf)); |
71 | 0 | } |
72 | 0 | ZERO(hints); |
73 | 0 | hints.ai_family = AF_INET6; |
74 | 0 | hints.ai_flags |= AI_NUMERICHOST; |
75 | 0 | if (getaddrinfo(tmpbuf, NULL, &hints, &result) == 0) { |
76 | 0 | AF(addr) = AF_INET6; |
77 | 0 | resaddr6 = UA_PTR(struct sockaddr_in6, result->ai_addr); |
78 | 0 | SET_ADDR6N(addr, resaddr6->sin6_addr); |
79 | 0 | SET_SCOPE(addr, resaddr6->sin6_scope_id); |
80 | |
|
81 | 0 | freeaddrinfo(result); |
82 | 0 | return TRUE; |
83 | 0 | } |
84 | 0 | } |
85 | | /* |
86 | | * If we got here it was not an IP address |
87 | | */ |
88 | 0 | return FALSE; |
89 | 0 | } |