ares_expand_name.c (3082B)
1 /* MIT License 2 * 3 * Copyright (c) 1998, 2011 Massachusetts Institute of Technology 4 * Copyright (c) The c-ares project and its contributors 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the next 14 * paragraph) shall be included in all copies or substantial portions of the 15 * Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 * SOFTWARE. 24 * 25 * SPDX-License-Identifier: MIT 26 */ 27 28 #include "ares_private.h" 29 30 #ifdef HAVE_NETINET_IN_H 31 # include <netinet/in.h> 32 #endif 33 34 #include "ares_nameser.h" 35 36 ares_status_t ares_expand_name_validated(const unsigned char *encoded, 37 const unsigned char *abuf, size_t alen, 38 char **s, size_t *enclen, 39 ares_bool_t is_hostname) 40 { 41 ares_status_t status; 42 ares_buf_t *buf = NULL; 43 size_t start_len; 44 45 if (encoded == NULL || abuf == NULL || alen == 0 || enclen == NULL) { 46 return ARES_EBADNAME; /* EFORMERR would be better */ 47 } 48 49 if (encoded < abuf || encoded >= abuf + alen) { 50 return ARES_EBADNAME; /* EFORMERR would be better */ 51 } 52 53 *enclen = 0; 54 55 /* NOTE: we allow 's' to be NULL to skip it */ 56 if (s) { 57 *s = NULL; 58 } 59 60 buf = ares_buf_create_const(abuf, alen); 61 62 if (buf == NULL) { 63 return ARES_ENOMEM; 64 } 65 66 status = ares_buf_set_position(buf, (size_t)(encoded - abuf)); 67 if (status != ARES_SUCCESS) { 68 goto done; 69 } 70 71 start_len = ares_buf_len(buf); 72 status = ares_dns_name_parse(buf, s, is_hostname); 73 if (status != ARES_SUCCESS) { 74 goto done; 75 } 76 77 *enclen = start_len - ares_buf_len(buf); 78 79 done: 80 ares_buf_destroy(buf); 81 return status; 82 } 83 84 int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf, 85 int alen, char **s, long *enclen) 86 { 87 /* Keep public API compatible */ 88 size_t enclen_temp = 0; 89 ares_status_t status; 90 91 if (encoded == NULL || abuf == NULL || alen <= 0 || enclen == NULL) { 92 return ARES_EBADNAME; 93 } 94 95 status = ares_expand_name_validated(encoded, abuf, (size_t)alen, s, 96 &enclen_temp, ARES_FALSE); 97 *enclen = (long)enclen_temp; 98 return (int)status; 99 }