home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / ixemul-45.0-src.tgz / tar.out / contrib / ixemul / net / res_mkquery.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  8KB  |  238 lines

  1. /*    $NetBSD: res_mkquery.c,v 1.5 1995/02/25 06:20:58 cgd Exp $    */
  2.  
  3. /*-
  4.  * Copyright (c) 1985, 1993
  5.  *    The Regents of the University of California.  All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 2. Redistributions in binary form must reproduce the above copyright
  13.  *    notice, this list of conditions and the following disclaimer in the
  14.  *    documentation and/or other materials provided with the distribution.
  15.  * 3. All advertising materials mentioning features or use of this software
  16.  *    must display the following acknowledgement:
  17.  *    This product includes software developed by the University of
  18.  *    California, Berkeley and its contributors.
  19.  * 4. Neither the name of the University nor the names of its contributors
  20.  *    may be used to endorse or promote products derived from this software
  21.  *    without specific prior written permission.
  22.  *
  23.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  24.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  27.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  28.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  29.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  30.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  31.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  32.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  33.  * SUCH DAMAGE.
  34.  * -
  35.  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
  36.  * 
  37.  * Permission to use, copy, modify, and distribute this software for any
  38.  * purpose with or without fee is hereby granted, provided that the above
  39.  * copyright notice and this permission notice appear in all copies, and that
  40.  * the name of Digital Equipment Corporation not be used in advertising or
  41.  * publicity pertaining to distribution of the document or software without
  42.  * specific, written prior permission.
  43.  * 
  44.  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  45.  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  46.  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
  47.  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  48.  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  49.  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  50.  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  51.  * SOFTWARE.
  52.  * -
  53.  * --Copyright--
  54.  */
  55.  
  56. #if defined(LIBC_SCCS) && !defined(lint)
  57. #if 0
  58. static char sccsid[] = "@(#)res_mkquery.c    8.1 (Berkeley) 6/4/93";
  59. static char rcsid[] = "$Id: res_mkquery.c,v 4.9.1.2 1993/05/17 10:00:01 vixie Exp ";
  60. #else
  61. static char rcsid[] = "$NetBSD: res_mkquery.c,v 1.5 1995/02/25 06:20:58 cgd Exp $";
  62. #endif
  63. #endif /* LIBC_SCCS and not lint */
  64.  
  65. #include <sys/param.h>
  66. #include <netinet/in.h>
  67. #include <arpa/nameser.h>
  68. #include <resolv.h>
  69. #include <stdio.h>
  70. #include <string.h>
  71.  
  72. /*
  73.  * Form all types of queries.
  74.  * Returns the size of the result or -1.
  75.  */
  76. int
  77. res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
  78.     int op;            /* opcode of query */
  79.     const char *dname;        /* domain name */
  80.     int class, type;    /* class and type of query */
  81.     const char *data;        /* resource record data */
  82.     int datalen;        /* length of data */
  83.     const char *newrr_in;    /* new rr for modify or append */
  84.     char *buf;        /* buffer to put query */
  85.     int buflen;        /* size of buffer */
  86. {
  87.     register HEADER *hp;
  88.     register char *cp;
  89.     register int n;
  90.     struct rrec *newrr = (struct rrec *) newrr_in;
  91.     char *dnptrs[10], **dpp, **lastdnptr;
  92.  
  93. #ifdef DEBUG
  94.     if (_res.options & RES_DEBUG)
  95.         printf(";; res_mkquery(%d, %s, %d, %d)\n",
  96.                op, dname, class, type);
  97. #endif
  98.     /*
  99.      * Initialize header fields.
  100.      */
  101.     if ((buf == NULL) || (buflen < sizeof(HEADER)))
  102.         return(-1);
  103.     bzero(buf, sizeof(HEADER));
  104.     hp = (HEADER *) buf;
  105.     hp->id = htons(++_res.id);
  106.     hp->opcode = op;
  107.     hp->pr = (_res.options & RES_PRIMARY) != 0;
  108.     hp->rd = (_res.options & RES_RECURSE) != 0;
  109.     hp->rcode = NOERROR;
  110.     cp = buf + sizeof(HEADER);
  111.     buflen -= sizeof(HEADER);
  112.     dpp = dnptrs;
  113.     *dpp++ = buf;
  114.     *dpp++ = NULL;
  115.     lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]);
  116.     /*
  117.      * perform opcode specific processing
  118.      */
  119.     switch (op) {
  120.     case QUERY:
  121.         if ((buflen -= QFIXEDSZ) < 0)
  122.             return(-1);
  123.         if ((n = dn_comp((u_char *)dname, (u_char *)cp, buflen,
  124.             (u_char **)dnptrs, (u_char **)lastdnptr)) < 0)
  125.             return (-1);
  126.         cp += n;
  127.         buflen -= n;
  128.         __putshort(type, (u_char *)cp);
  129.         cp += sizeof(u_int16_t);
  130.         __putshort(class, (u_char *)cp);
  131.         cp += sizeof(u_int16_t);
  132.         hp->qdcount = htons(1);
  133.         if (op == QUERY || data == NULL)
  134.             break;
  135.         /*
  136.          * Make an additional record for completion domain.
  137.          */
  138.         buflen -= RRFIXEDSZ;
  139.         if ((n = dn_comp((u_char *)data, (u_char *)cp, buflen,
  140.             (u_char **)dnptrs, (u_char **)lastdnptr)) < 0)
  141.             return (-1);
  142.         cp += n;
  143.         buflen -= n;
  144.         __putshort(T_NULL, (u_char *)cp);
  145.         cp += sizeof(u_int16_t);
  146.         __putshort(class, (u_char *)cp);
  147.         cp += sizeof(u_int16_t);
  148.         __putlong(0, (u_char *)cp);
  149.         cp += sizeof(u_int32_t);
  150.         __putshort(0, (u_char *)cp);
  151.         cp += sizeof(u_int16_t);
  152.         hp->arcount = htons(1);
  153.         break;
  154.  
  155.     case IQUERY:
  156.         /*
  157.          * Initialize answer section
  158.          */
  159.         if (buflen < 1 + RRFIXEDSZ + datalen)
  160.             return (-1);
  161.         *cp++ = '\0';    /* no domain name */
  162.         __putshort(type, (u_char *)cp);
  163.         cp += sizeof(u_int16_t);
  164.         __putshort(class, (u_char *)cp);
  165.         cp += sizeof(u_int16_t);
  166.         __putlong(0, (u_char *)cp);
  167.         cp += sizeof(u_int32_t);
  168.         __putshort(datalen, (u_char *)cp);
  169.         cp += sizeof(u_int16_t);
  170.         if (datalen) {
  171.             bcopy(data, cp, datalen);
  172.             cp += datalen;
  173.         }
  174.         hp->ancount = htons(1);
  175.         break;
  176.  
  177. #ifdef ALLOW_UPDATES
  178.     /*
  179.      * For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA
  180.      * (Record to be modified is followed by its replacement in msg.)
  181.      */
  182.     case UPDATEM:
  183.     case UPDATEMA:
  184.  
  185.     case UPDATED:
  186.         /*
  187.          * The res code for UPDATED and UPDATEDA is the same; user
  188.          * calls them differently: specifies data for UPDATED; server
  189.          * ignores data if specified for UPDATEDA.
  190.          */
  191.     case UPDATEDA:
  192.         buflen -= RRFIXEDSZ + datalen;
  193.         if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
  194.             return (-1);
  195.         cp += n;
  196.         __putshort(type, cp);
  197.                 cp += sizeof(u_int16_t);
  198.                 __putshort(class, cp);
  199.                 cp += sizeof(u_int16_t);
  200.         __putlong(0, cp);
  201.         cp += sizeof(u_int32_t);
  202.         __putshort(datalen, cp);
  203.                 cp += sizeof(u_int16_t);
  204.         if (datalen) {
  205.             bcopy(data, cp, datalen);
  206.             cp += datalen;
  207.         }
  208.         if ( (op == UPDATED) || (op == UPDATEDA) ) {
  209.             hp->ancount = htons(0);
  210.             break;
  211.         }
  212.         /* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */
  213.  
  214.     case UPDATEA:    /* Add new resource record */
  215.         buflen -= RRFIXEDSZ + datalen;
  216.         if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
  217.             return (-1);
  218.         cp += n;
  219.         __putshort(newrr->r_type, cp);
  220.                 cp += sizeof(u_int16_t);
  221.                 __putshort(newrr->r_class, cp);
  222.                 cp += sizeof(u_int16_t);
  223.         __putlong(0, cp);
  224.         cp += sizeof(u_int32_t);
  225.         __putshort(newrr->r_size, cp);
  226.                 cp += sizeof(u_int16_t);
  227.         if (newrr->r_size) {
  228.             bcopy(newrr->r_data, cp, newrr->r_size);
  229.             cp += newrr->r_size;
  230.         }
  231.         hp->ancount = htons(0);
  232.         break;
  233.  
  234. #endif /* ALLOW_UPDATES */
  235.     }
  236.     return (cp - buf);
  237. }
  238.