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

glibc/2.7/resolv/res_mkquery.c

    1: /*
    2:  * Copyright (c) 1985, 1993
    3:  *    The Regents of the University of California.  All rights reserved.
    4:  *
    5:  * Redistribution and use in source and binary forms, with or without
    6:  * modification, are permitted provided that the following conditions
    7:  * are met:
    8:  * 1. Redistributions of source code must retain the above copyright
    9:  *    notice, this list of conditions and the following disclaimer.
   10:  * 2. Redistributions in binary form must reproduce the above copyright
   11:  *    notice, this list of conditions and the following disclaimer in the
   12:  *    documentation and/or other materials provided with the distribution.
   13:  * 4. Neither the name of the University nor the names of its contributors
   14:  *    may be used to endorse or promote products derived from this software
   15:  *    without specific prior written permission.
   16:  *
   17:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   18:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   21:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   25:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27:  * SUCH DAMAGE.
   28:  */
   29: 
   30: /*
   31:  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
   32:  *
   33:  * Permission to use, copy, modify, and distribute this software for any
   34:  * purpose with or without fee is hereby granted, provided that the above
   35:  * copyright notice and this permission notice appear in all copies, and that
   36:  * the name of Digital Equipment Corporation not be used in advertising or
   37:  * publicity pertaining to distribution of the document or software without
   38:  * specific, written prior permission.
   39:  *
   40:  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
   41:  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
   42:  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
   43:  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
   44:  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
   45:  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
   46:  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
   47:  * SOFTWARE.
   48:  */
   49: 
   50: /*
   51:  * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
   52:  *
   53:  * Permission to use, copy, modify, and distribute this software for any
   54:  * purpose with or without fee is hereby granted, provided that the above
   55:  * copyright notice and this permission notice appear in all copies.
   56:  *
   57:  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
   58:  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
   59:  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
   60:  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
   61:  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
   62:  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
   63:  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
   64:  * SOFTWARE.
   65:  */
   66: 
   67: #if defined(LIBC_SCCS) && !defined(lint)
   68: static const char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93";
   69: static const char rcsid[] = "$BINDId: res_mkquery.c,v 8.12 1999/10/13 16:39:40 vixie Exp $";
   70: #endif /* LIBC_SCCS and not lint */
   71: 
   72: #include <sys/types.h>
   73: #include <sys/param.h>
   74: #include <netinet/in.h>
   75: #include <arpa/nameser.h>
   76: #include <netdb.h>
   77: #include <resolv.h>
   78: #include <stdio.h>
   79: #include <string.h>
   80: 
   81: /* Options.  Leave them on. */
   82: /* #define DEBUG */
   83: 
   84: #ifdef _LIBC
   85: # include <hp-timing.h>
   86: # if HP_TIMING_AVAIL
   87: #  define RANDOM_BITS(Var) { uint64_t v64; HP_TIMING_NOW (v64); Var = v64; }
   88: # endif
   89: #endif
   90: 
   91: /*
   92:  * Form all types of queries.
   93:  * Returns the size of the result or -1.
   94:  */
   95: int
   96: res_nmkquery(res_state statp,
   97:              int op,                   /* opcode of query */
   98:              const char *dname,                /* domain name */
   99:              int class, int type,      /* class and type of query */
  100:              const u_char *data,       /* resource record data */
  101:              int datalen,              /* length of data */
  102:              const u_char *newrr_in,   /* new rr for modify or append */
  103:              u_char *buf,              /* buffer to put query */
  104:              int buflen)               /* size of buffer */
  105: {
  106:         register HEADER *hp;
  107:         register u_char *cp;
  108:         register int n;
  109:         u_char *dnptrs[20], **dpp, **lastdnptr;
  110: 
  111: #ifdef DEBUG
  112:         if (statp->options & RES_DEBUG)
  113:                 printf(";; res_nmkquery(%s, %s, %s, %s)\n",
  114:                        _res_opcodes[op], dname, p_class(class), p_type(type));
  115: #endif
  116:         /*
  117:          * Initialize header fields.
  118:          */
  119:         if ((buf == NULL) || (buflen < HFIXEDSZ))
  120:                 return (-1);
  121:         memset(buf, 0, HFIXEDSZ);
  122:         hp = (HEADER *) buf;
  123:         /* We randomize the IDs every time.  The old code just
  124:            incremented by one after the initial randomization which
  125:            still predictable if the application does multiple
  126:            requests.  */
  127:         int randombits;
  128:         do
  129:           {
  130: #ifdef RANDOM_BITS
  131:             RANDOM_BITS (randombits);
  132: #else
  133:             struct timeval tv;
  134:             __gettimeofday (&tv, NULL);
  135:             randombits = (tv.tv_sec << 8) ^ tv.tv_usec;
  136: #endif
  137:           }
  138:         while ((randombits & 0xffff) == 0);
  139:         statp->id = (statp->id + randombits) & 0xffff;
  140:         hp->id = statp->id;
  141:         hp->opcode = op;
  142:         hp->rd = (statp->options & RES_RECURSE) != 0;
  143:         hp->rcode = NOERROR;
  144:         cp = buf + HFIXEDSZ;
  145:         buflen -= HFIXEDSZ;
  146:         dpp = dnptrs;
  147:         *dpp++ = buf;
  148:         *dpp++ = NULL;
  149:         lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
  150:         /*
  151:          * perform opcode specific processing
  152:          */
  153:         switch (op) {
  154:         case NS_NOTIFY_OP:
  155:                 if ((buflen -= QFIXEDSZ + (data == NULL ? 0 : RRFIXEDSZ)) < 0)
  156:                         return (-1);
  157:                 goto compose;
  158: 
  159:         case QUERY:
  160:                 if ((buflen -= QFIXEDSZ) < 0)
  161:                         return (-1);
  162:         compose:
  163:                 if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
  164:                         return (-1);
  165:                 cp += n;
  166:                 buflen -= n;
  167:                 NS_PUT16 (type, cp);
  168:                 NS_PUT16 (class, cp);
  169:                 hp->qdcount = htons(1);
  170:                 if (op == QUERY || data == NULL)
  171:                         break;
  172:                 /*
  173:                  * Make an additional record for completion domain.
  174:                  */
  175:                 n = dn_comp((char *)data, cp, buflen, dnptrs, lastdnptr);
  176:                 if (__builtin_expect (n < 0, 0))
  177:                         return (-1);
  178:                 cp += n;
  179:                 buflen -= n;
  180:                 NS_PUT16 (T_NULL, cp);
  181:                 NS_PUT16 (class, cp);
  182:                 NS_PUT32 (0, cp);
  183:                 NS_PUT16 (0, cp);
  184:                 hp->arcount = htons(1);
  185:                 break;
  186: 
  187:         case IQUERY:
  188:                 /*
  189:                  * Initialize answer section
  190:                  */
  191:                 if (__builtin_expect (buflen < 1 + RRFIXEDSZ + datalen, 0))
  192:                         return (-1);
  193:                 *cp++ = '\0'; /* no domain name */
  194:                 NS_PUT16 (type, cp);
  195:                 NS_PUT16 (class, cp);
  196:                 NS_PUT32 (0, cp);
  197:                 NS_PUT16 (datalen, cp);
  198:                 if (datalen) {
  199:                         memcpy(cp, data, datalen);
  200:                         cp += datalen;
  201:                 }
  202:                 hp->ancount = htons(1);
  203:                 break;
  204: 
  205:         default:
  206:                 return (-1);
  207:         }
  208:         return (cp - buf);
  209: }
  210: libresolv_hidden_def (res_nmkquery)
  211: 
  212: 
  213: /* attach OPT pseudo-RR, as documented in RFC2671 (EDNS0). */
  214: #ifndef T_OPT
  215: #define T_OPT   41
  216: #endif
  217: 
  218: int
  219: __res_nopt(res_state statp,
  220:            int n0,                /* current offset in buffer */
  221:            u_char *buf,           /* buffer to put query */
  222:            int buflen,            /* size of buffer */
  223:            int anslen)            /* UDP answer buffer size */
  224: {
  225:         u_int16_t flags = 0;
  226: 
  227: #ifdef DEBUG
  228:         if ((statp->options & RES_DEBUG) != 0U)
  229:                 printf(";; res_nopt()\n");
  230: #endif
  231: 
  232:         HEADER *hp = (HEADER *) buf;
  233:         u_char *cp = buf + n0;
  234:         u_char *ep = buf + buflen;
  235: 
  236:         if ((ep - cp) < 1 + RRFIXEDSZ)
  237:                 return -1;
  238: 
  239:         *cp++ = 0;     /* "." */
  240: 
  241:         ns_put16(T_OPT, cp);   /* TYPE */
  242:         cp += INT16SZ;
  243:         ns_put16(anslen & 0xffff, cp); /* CLASS = UDP payload size */
  244:         cp += INT16SZ;
  245:         *cp++ = NOERROR;       /* extended RCODE */
  246:         *cp++ = 0;             /* EDNS version */
  247:         /* XXX Once we support DNSSEC we change the flag value here.  */
  248:         ns_put16(flags, cp);
  249:         cp += INT16SZ;
  250:         ns_put16(0, cp);       /* RDLEN */
  251:         cp += INT16SZ;
  252:         hp->arcount = htons(ntohs(hp->arcount) + 1);
  253: 
  254:         return cp - buf;
  255: }
  256: libresolv_hidden_def (__res_nopt)
Syntax (Markdown)