1 /* MIT License
2 *
3 * Copyright (c) 1998 Massachusetts Institute of Technology
4 * Copyright (c) 2005 Dominick Meglio
5 * Copyright (c) 2019 Andrew Selivanov
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE.
25 *
26 * SPDX-License-Identifier: MIT
27 */
28
29 #include "ares_private.h"
30
31 #ifdef HAVE_NETINET_IN_H
32 # include <netinet/in.h>
33 #endif
34 #ifdef HAVE_NETDB_H
35 # include <netdb.h>
36 #endif
37 #ifdef HAVE_ARPA_INET_H
38 # include <arpa/inet.h>
39 #endif
40
41 #ifdef HAVE_STRINGS_H
42 # include <strings.h>
43 #endif
44
45 #ifdef HAVE_LIMITS_H
46 # include <limits.h>
47 #endif
48
49 #include "ares_inet_net_pton.h"
50
ares_parse_aaaa_reply(const unsigned char * abuf,int alen,struct hostent ** host,struct ares_addr6ttl * addrttls,int * naddrttls)51 int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
52 struct hostent **host, struct ares_addr6ttl *addrttls,
53 int *naddrttls)
54 {
55 struct ares_addrinfo ai;
56 char *question_hostname = NULL;
57 ares_status_t status;
58 size_t req_naddrttls = 0;
59 ares_dns_record_t *dnsrec = NULL;
60
61 if (alen < 0) {
62 return ARES_EBADRESP;
63 }
64
65 if (naddrttls) {
66 req_naddrttls = (size_t)*naddrttls;
67 *naddrttls = 0;
68 }
69
70 memset(&ai, 0, sizeof(ai));
71
72 status = ares_dns_parse(abuf, (size_t)alen, 0, &dnsrec);
73 if (status != ARES_SUCCESS) {
74 goto fail;
75 }
76
77 status = ares_parse_into_addrinfo(dnsrec, 0, 0, &ai);
78 if (status != ARES_SUCCESS && status != ARES_ENODATA) {
79 goto fail;
80 }
81
82 if (host != NULL) {
83 *host = NULL;
84 status = ares_addrinfo2hostent(&ai, AF_INET6, host);
85 if (status != ARES_SUCCESS && status != ARES_ENODATA) {
86 goto fail; /* LCOV_EXCL_LINE: DefensiveCoding */
87 }
88 }
89
90 if (addrttls != NULL && req_naddrttls) {
91 size_t temp_naddrttls = 0;
92 ares_addrinfo2addrttl(&ai, AF_INET6, req_naddrttls, NULL, addrttls,
93 &temp_naddrttls);
94 *naddrttls = (int)temp_naddrttls;
95 }
96
97 fail:
98 ares_freeaddrinfo_cnames(ai.cnames);
99 ares_freeaddrinfo_nodes(ai.nodes);
100 ares_free(question_hostname);
101 ares_free(ai.name);
102 ares_dns_record_destroy(dnsrec);
103
104 if (status == ARES_EBADNAME) {
105 status = ARES_EBADRESP;
106 }
107
108 return (int)status;
109 }
110