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