/src/ntp-dev/libntp/decodenetnum.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * decodenetnum - return a net number (this is crude, but careful) |
3 | | */ |
4 | | #include <config.h> |
5 | | #include <sys/types.h> |
6 | | #include <ctype.h> |
7 | | #ifdef HAVE_SYS_SOCKET_H |
8 | | #include <sys/socket.h> |
9 | | #endif |
10 | | #ifdef HAVE_NETINET_IN_H |
11 | | #include <netinet/in.h> |
12 | | #endif |
13 | | |
14 | | #include "ntp.h" |
15 | | #include "ntp_stdlib.h" |
16 | | #include "ntp_assert.h" |
17 | | |
18 | | /* |
19 | | * decodenetnum convert text IP address and port to sockaddr_u |
20 | | * |
21 | | * Returns 0 for failure, 1 for success. |
22 | | */ |
23 | | int |
24 | | decodenetnum( |
25 | | const char *num, |
26 | | sockaddr_u *netnum |
27 | | ) |
28 | 662 | { |
29 | 662 | struct addrinfo hints, *ai = NULL; |
30 | 662 | int err; |
31 | 662 | u_short port; |
32 | 662 | const char *cp; |
33 | 662 | const char *port_str; |
34 | 662 | char *pp; |
35 | 662 | char *np; |
36 | 662 | char name[80]; |
37 | | |
38 | 662 | REQUIRE(num != NULL); |
39 | | |
40 | 662 | if (strlen(num) >= sizeof(name)) { |
41 | 1 | return 0; |
42 | 1 | } |
43 | | |
44 | 661 | port_str = NULL; |
45 | 661 | if ('[' != num[0]) { |
46 | | /* |
47 | | * to distinguish IPv6 embedded colons from a port |
48 | | * specification on an IPv4 address, assume all |
49 | | * legal IPv6 addresses have at least two colons. |
50 | | */ |
51 | 594 | pp = strchr(num, ':'); |
52 | 594 | if (NULL == pp) |
53 | 238 | cp = num; /* no colons */ |
54 | 356 | else if (NULL != strchr(pp + 1, ':')) |
55 | 317 | cp = num; /* two or more colons */ |
56 | 39 | else { /* one colon */ |
57 | 39 | strlcpy(name, num, sizeof(name)); |
58 | 39 | cp = name; |
59 | 39 | pp = strchr(cp, ':'); |
60 | 39 | *pp = '\0'; |
61 | 39 | port_str = pp + 1; |
62 | 39 | } |
63 | 594 | } else { |
64 | 67 | cp = num + 1; |
65 | 67 | np = name; |
66 | 295 | while (*cp && ']' != *cp) |
67 | 228 | *np++ = *cp++; |
68 | 67 | *np = 0; |
69 | 67 | if (']' == cp[0] && ':' == cp[1] && '\0' != cp[2]) |
70 | 13 | port_str = &cp[2]; |
71 | 67 | cp = name; |
72 | 67 | } |
73 | 661 | ZERO(hints); |
74 | 661 | hints.ai_flags = Z_AI_NUMERICHOST; |
75 | 661 | err = getaddrinfo(cp, "ntp", &hints, &ai); |
76 | 661 | if (err != 0) |
77 | 661 | return 0; |
78 | 0 | INSIST(ai->ai_addrlen <= sizeof(*netnum)); |
79 | 0 | ZERO(*netnum); |
80 | 0 | memcpy(netnum, ai->ai_addr, ai->ai_addrlen); |
81 | 0 | freeaddrinfo(ai); |
82 | 0 | if (NULL == port_str || 1 != sscanf(port_str, "%hu", &port)) |
83 | 0 | port = NTP_PORT; |
84 | 0 | SET_PORT(netnum, port); |
85 | 0 | return 1; |
86 | 661 | } |