(linenum→info "unix/slp.c:2238")

glibc/2.7/resolv/ns_parse.c

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