1 /** @file 2 Copyright (c) 2012, Intel Corporation. All rights reserved.<BR> 3 This program and the accompanying materials are licensed and made available under 4 the terms and conditions of the BSD License that accompanies this distribution. 5 The full text of the license may be found at 6 http://opensource.org/licenses/bsd-license.php. 7 8 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 9 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 10 11 * Portions copyright (c) 1999, 2000 12 * Intel Corporation. 13 * All rights reserved. 14 * 15 * Redistribution and use in source and binary forms, with or without 16 * modification, are permitted provided that the following conditions 17 * are met: 18 * 19 * 1. Redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer. 21 * 22 * 2. Redistributions in binary form must reproduce the above copyright 23 * notice, this list of conditions and the following disclaimer in the 24 * documentation and/or other materials provided with the distribution. 25 * 26 * 3. All advertising materials mentioning features or use of this software 27 * must display the following acknowledgement: 28 * 29 * This product includes software developed by Intel Corporation and 30 * its contributors. 31 * 32 * 4. Neither the name of Intel Corporation or its contributors may be 33 * used to endorse or promote products derived from this software 34 * without specific prior written permission. 35 * 36 * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS'' 37 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 39 * ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE 40 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 41 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 42 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 43 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 44 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 46 * THE POSSIBILITY OF SUCH DAMAGE. 47 * 48 * Copyright (c) 1996 by Internet Software Consortium. 49 * 50 * Permission to use, copy, modify, and distribute this software for any 51 * purpose with or without fee is hereby granted, provided that the above 52 * copyright notice and this permission notice appear in all copies. 53 * 54 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS 55 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 56 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE 57 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 58 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 59 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 60 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 61 * SOFTWARE. 62 **/ 63 64 #include <sys/types.h> 65 66 #include <netinet/in.h> 67 #include <arpa/nameser.h> 68 69 #include <errno.h> 70 #include <resolv.h> 71 #include <string.h> 72 73 /* These need to be in the same order as the nres.h:ns_flag enum. */ 74 struct _ns_flagdata _ns_flagdata[16] = { 75 { 0x8000, 15 }, /* qr. */ 76 { 0x7800, 11 }, /* opcode. */ 77 { 0x0400, 10 }, /* aa. */ 78 { 0x0200, 9 }, /* tc. */ 79 { 0x0100, 8 }, /* rd. */ 80 { 0x0080, 7 }, /* ra. */ 81 { 0x0040, 6 }, /* z. */ 82 { 0x0020, 5 }, /* ad. */ 83 { 0x0010, 4 }, /* cd. */ 84 { 0x000f, 0 }, /* rcode. */ 85 { 0x0000, 0 }, /* expansion (1/6). */ 86 { 0x0000, 0 }, /* expansion (2/6). */ 87 { 0x0000, 0 }, /* expansion (3/6). */ 88 { 0x0000, 0 }, /* expansion (4/6). */ 89 { 0x0000, 0 }, /* expansion (5/6). */ 90 { 0x0000, 0 }, /* expansion (6/6). */ 91 }; 92 93 static int 94 skiprr(const u_char *ptr, const u_char *eom, ns_sect section, int count) { 95 const u_char *optr = ptr; 96 97 for ((void)NULL; count > 0; count--) { 98 int b, rdlength; 99 100 b = dn_skipname(ptr, eom); 101 if (b < 0) 102 goto emsgsize; 103 ptr += b/*Name*/ + NS_INT16SZ/*Type*/ + NS_INT16SZ/*Class*/; 104 if (section != ns_s_qd) { 105 if (ptr + NS_INT32SZ > eom) 106 goto emsgsize; 107 ptr += NS_INT32SZ/*TTL*/; 108 if (ptr + NS_INT16SZ > eom) 109 goto emsgsize; 110 NS_GET16(rdlength, ptr); 111 ptr += rdlength/*RData*/; 112 } 113 } 114 if (ptr > eom) 115 goto emsgsize; 116 return ((int)(ptr - optr)); 117 emsgsize: 118 errno = EMSGSIZE; 119 return (-1); 120 } 121 122 int 123 ns_initparse(const u_char *msg, int msglen, ns_msg *handle) { 124 const u_char *eom = msg + msglen; 125 int i; 126 127 memset(handle, 0x5e, sizeof *handle); 128 handle->_msg = msg; 129 handle->_eom = eom; 130 if (msg + NS_INT16SZ > eom) 131 goto emsgsize; 132 NS_GET16(handle->_id, msg); 133 if (msg + NS_INT16SZ > eom) 134 goto emsgsize; 135 NS_GET16(handle->_flags, msg); 136 for (i = 0; i < ns_s_max; i++) { 137 if (msg + NS_INT16SZ > eom) 138 goto emsgsize; 139 NS_GET16(handle->_counts[i], msg); 140 } 141 for (i = 0; i < ns_s_max; i++) 142 if (handle->_counts[i] == 0) 143 handle->_sections[i] = NULL; 144 else { 145 int b = skiprr(msg, eom, (ns_sect)i, 146 handle->_counts[i]); 147 148 if (b < 0) 149 return (-1); 150 handle->_sections[i] = msg; 151 msg += b; 152 } 153 if (msg != eom) 154 goto emsgsize; 155 handle->_sect = ns_s_max; 156 handle->_rrnum = -1; 157 handle->_msg_ptr = NULL; 158 return (0); 159 emsgsize: 160 errno = EMSGSIZE; 161 return (-1); 162 } 163 164 int 165 ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) { 166 int b; 167 168 /* Make section right. */ 169 if ((unsigned int)section >= ns_s_max) 170 goto enodev; 171 if ((int)section != (int)handle->_sect) { 172 handle->_sect = section; 173 handle->_rrnum = 0; 174 handle->_msg_ptr = handle->_sections[(int)section]; 175 } 176 177 /* Make rrnum right. */ 178 if (rrnum == -1) 179 rrnum = handle->_rrnum; 180 if (rrnum < 0 || rrnum >= handle->_counts[(int)section]) 181 goto enodev; 182 if (rrnum < handle->_rrnum) { 183 handle->_rrnum = 0; 184 handle->_msg_ptr = handle->_sections[(int)section]; 185 } 186 187 b = skiprr(handle->_msg, handle->_eom, section, 188 rrnum - handle->_rrnum); 189 if (b < 0) 190 return (-1); 191 handle->_msg_ptr += b; 192 handle->_rrnum = rrnum; 193 194 /* Do the parse. */ 195 b = dn_expand(handle->_msg, handle->_eom, 196 handle->_msg_ptr, rr->name, NS_MAXDNAME); 197 if (b < 0) 198 return (-1); 199 handle->_msg_ptr += b; 200 if (handle->_msg_ptr + NS_INT16SZ > handle->_eom) 201 goto emsgsize; 202 NS_GET16(rr->type, handle->_msg_ptr); 203 if (handle->_msg_ptr + NS_INT16SZ > handle->_eom) 204 goto emsgsize; 205 NS_GET16(rr->rr_class, handle->_msg_ptr); 206 if (section == ns_s_qd) { 207 rr->ttl = 0; 208 rr->rdlength = 0; 209 rr->rdata = NULL; 210 } else { 211 if (handle->_msg_ptr + NS_INT32SZ > handle->_eom) 212 goto emsgsize; 213 NS_GET32(rr->ttl, handle->_msg_ptr); 214 if (handle->_msg_ptr + NS_INT16SZ > handle->_eom) 215 goto emsgsize; 216 NS_GET16(rr->rdlength, handle->_msg_ptr); 217 if (handle->_msg_ptr + rr->rdlength > handle->_eom) 218 goto emsgsize; 219 rr->rdata = handle->_msg_ptr; 220 handle->_msg_ptr += rr->rdlength; 221 } 222 handle->_rrnum++; 223 224 /* All done. */ 225 return (0); 226 enodev: 227 errno = ENODEV; 228 return (-1); 229 emsgsize: 230 errno = EMSGSIZE; 231 return (-1); 232 } 233