Annotation of embedaddon/dhcp/minires/ns_parse.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (c) 2009-2010 by Internet Systems Consortium, Inc. ("ISC")
! 3: * Copyright (c) 2004
! 4: * Copyright (c) 1996-2003 by Internet Software Consortium
! 5: *
! 6: * Permission to use, copy, modify, and distribute this software for any
! 7: * purpose with or without fee is hereby granted, provided that the above
! 8: * copyright notice and this permission notice appear in all copies.
! 9: *
! 10: * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
! 11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
! 12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
! 13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
! 14: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
! 15: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
! 16: * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
! 17: *
! 18: * Internet Systems Consortium, Inc.
! 19: * 950 Charter Street
! 20: * Redwood City, CA 94063
! 21: * <info@isc.org>
! 22: * https://www.isc.org/
! 23: */
! 24:
! 25: #ifndef lint
! 26: static const char rcsid[] = "$Id: ns_parse.c,v 1.3.786.3 2010-07-27 21:23:34 sar Exp $";
! 27: #endif
! 28:
! 29: /* Import. */
! 30:
! 31: #include <sys/types.h>
! 32:
! 33: #include <netinet/in.h>
! 34: #include <sys/socket.h>
! 35:
! 36: #include <errno.h>
! 37: #include <string.h>
! 38:
! 39: #include "minires/minires.h"
! 40: #include "arpa/nameser.h"
! 41:
! 42: /* Forward. */
! 43:
! 44: static void setsection(ns_msg *msg, ns_sect sect);
! 45:
! 46: /* Macros. */
! 47:
! 48: /* Public. */
! 49:
! 50: /* These need to be in the same order as the nres.h:ns_flag enum. */
! 51: struct _ns_flagdata _ns_flagdata[16] = {
! 52: { 0x8000, 15 }, /* qr. */
! 53: { 0x7800, 11 }, /* opcode. */
! 54: { 0x0400, 10 }, /* aa. */
! 55: { 0x0200, 9 }, /* tc. */
! 56: { 0x0100, 8 }, /* rd. */
! 57: { 0x0080, 7 }, /* ra. */
! 58: { 0x0040, 6 }, /* z. */
! 59: { 0x0020, 5 }, /* ad. */
! 60: { 0x0010, 4 }, /* cd. */
! 61: { 0x000f, 0 }, /* rcode. */
! 62: { 0x0000, 0 }, /* expansion (1/6). */
! 63: { 0x0000, 0 }, /* expansion (2/6). */
! 64: { 0x0000, 0 }, /* expansion (3/6). */
! 65: { 0x0000, 0 }, /* expansion (4/6). */
! 66: { 0x0000, 0 }, /* expansion (5/6). */
! 67: { 0x0000, 0 }, /* expansion (6/6). */
! 68: };
! 69:
! 70: isc_result_t
! 71: ns_skiprr(const u_char *ptr, const u_char *eom, ns_sect section, int count,
! 72: int *rc) {
! 73: const u_char *optr = ptr;
! 74:
! 75: for ((void)NULL; count > 0; count--) {
! 76: int b, rdlength;
! 77:
! 78: b = dn_skipname(ptr, eom);
! 79: if (b < 0)
! 80: return ISC_R_INCOMPLETE;
! 81: ptr += b/*Name*/ + NS_INT16SZ/*Type*/ + NS_INT16SZ/*Class*/;
! 82: if (section != ns_s_qd) {
! 83: if (ptr + NS_INT32SZ + NS_INT16SZ > eom)
! 84: return ISC_R_INCOMPLETE;
! 85: ptr += NS_INT32SZ/*TTL*/;
! 86: rdlength = getUShort(ptr);
! 87: ptr += 2;
! 88: ptr += rdlength/*RData*/;
! 89: }
! 90: }
! 91: if (ptr > eom)
! 92: return ISC_R_INCOMPLETE;
! 93: if (rc)
! 94: *rc = ptr - optr;
! 95: return ISC_R_SUCCESS;
! 96: }
! 97:
! 98: isc_result_t
! 99: ns_initparse(const u_char *msg, unsigned msglen, ns_msg *handle) {
! 100: const u_char *eom = msg + msglen;
! 101: int i;
! 102:
! 103: memset(handle, 0x5e, sizeof *handle);
! 104: handle->_msg = msg;
! 105: handle->_eom = eom;
! 106: if (msg + NS_INT16SZ > eom)
! 107: return ISC_R_INCOMPLETE;
! 108: handle->_id = getUShort (msg);
! 109: msg += 2;
! 110: if (msg + NS_INT16SZ > eom)
! 111: return ISC_R_INCOMPLETE;
! 112: handle->_flags = getUShort (msg);
! 113: msg += 2;
! 114: for (i = 0; i < ns_s_max; i++) {
! 115: if (msg + NS_INT16SZ > eom)
! 116: return ISC_R_INCOMPLETE;
! 117: handle->_counts[i] = getUShort (msg);
! 118: msg += 2;
! 119: }
! 120: for (i = 0; i < ns_s_max; i++)
! 121: if (handle->_counts[i] == 0)
! 122: handle->_sections[i] = NULL;
! 123: else {
! 124: int b;
! 125: isc_result_t status =
! 126: ns_skiprr(msg, eom, (ns_sect)i,
! 127: handle->_counts[i], &b);
! 128:
! 129: if (status != ISC_R_SUCCESS)
! 130: return status;
! 131: handle->_sections[i] = msg;
! 132: msg += b;
! 133: }
! 134: if (msg != eom)
! 135: return ISC_R_INCOMPLETE;
! 136: setsection(handle, ns_s_max);
! 137: return ISC_R_SUCCESS;
! 138: }
! 139:
! 140: isc_result_t
! 141: ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) {
! 142: int b;
! 143: isc_result_t status;
! 144:
! 145: /* Make section right. */
! 146: if (section < 0 || section >= ns_s_max)
! 147: return ISC_R_NOTIMPLEMENTED;
! 148: if (section != handle->_sect)
! 149: setsection(handle, section);
! 150:
! 151: /* Make rrnum right. */
! 152: if (rrnum == -1)
! 153: rrnum = handle->_rrnum;
! 154: if (rrnum < 0 || rrnum >= handle->_counts[(int)section])
! 155: return ISC_R_UNKNOWNATTRIBUTE;
! 156: if (rrnum < handle->_rrnum)
! 157: setsection(handle, section);
! 158: if (rrnum > handle->_rrnum) {
! 159: status = ns_skiprr(handle->_ptr, handle->_eom, section,
! 160: rrnum - handle->_rrnum, &b);
! 161:
! 162: if (status != ISC_R_SUCCESS)
! 163: return status;
! 164: handle->_ptr += b;
! 165: handle->_rrnum = rrnum;
! 166: }
! 167:
! 168: /* Do the parse. */
! 169: b = dn_expand(handle->_msg, handle->_eom,
! 170: handle->_ptr, rr->name, NS_MAXDNAME);
! 171: if (b < 0)
! 172: return ISC_R_FORMERR;
! 173: handle->_ptr += b;
! 174: if (handle->_ptr + NS_INT16SZ + NS_INT16SZ > handle->_eom)
! 175: return ISC_R_INCOMPLETE;
! 176: rr->type = getUShort (handle->_ptr);
! 177: handle -> _ptr += 2;
! 178: rr->rr_class = getUShort (handle->_ptr);
! 179: handle -> _ptr += 2;
! 180: if (section == ns_s_qd) {
! 181: rr->ttl = 0;
! 182: rr->rdlength = 0;
! 183: rr->rdata = NULL;
! 184: } else {
! 185: if (handle->_ptr + NS_INT32SZ + NS_INT16SZ > handle->_eom)
! 186: return ISC_R_INCOMPLETE;
! 187: rr->ttl = getULong (handle->_ptr);
! 188: handle -> _ptr += 4;
! 189: rr->rdlength = getUShort (handle->_ptr);
! 190: handle -> _ptr += 2;
! 191: if (handle->_ptr + rr->rdlength > handle->_eom)
! 192: return ISC_R_INCOMPLETE;
! 193: rr->rdata = handle->_ptr;
! 194: handle->_ptr += rr->rdlength;
! 195: }
! 196: if (++handle->_rrnum > handle->_counts[(int)section])
! 197: setsection(handle, (ns_sect)((int)section + 1));
! 198:
! 199: /* All done. */
! 200: return ISC_R_SUCCESS;
! 201: }
! 202:
! 203: /* Private. */
! 204:
! 205: static void
! 206: setsection(ns_msg *msg, ns_sect sect) {
! 207: msg->_sect = sect;
! 208: if (sect == ns_s_max) {
! 209: msg->_rrnum = -1;
! 210: msg->_ptr = NULL;
! 211: } else {
! 212: msg->_rrnum = 0;
! 213: msg->_ptr = msg->_sections[(int)sect];
! 214: }
! 215: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>