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>