ares_parse_aaaa_reply.c (3145B)
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 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 }