home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / NETWORK / ISP / bind.4.8.3.lzh / BIND483 / RES / res_mkquery.c < prev    next >
Text File  |  1994-09-23  |  5KB  |  198 lines

  1. /*
  2.  * Copyright (c) 1985 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that: (1) source distributions retain this entire copyright
  7.  * notice and comment, and (2) distributions including binaries display
  8.  * the following acknowledgement:  ``This product includes software
  9.  * developed by the University of California, Berkeley and its contributors''
  10.  * in the documentation or other materials provided with the distribution
  11.  * and in all advertising materials mentioning features or use of this
  12.  * software. Neither the name of the University nor the names of its
  13.  * contributors may be used to endorse or promote products derived
  14.  * from this software without specific prior written permission.
  15.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  16.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  17.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  18.  */
  19.  
  20. #if defined(LIBC_SCCS) && !defined(lint)
  21. static char sccsid[] = "@(#)res_mkquery.c    6.12 (Berkeley) 6/1/90";
  22. #endif /* LIBC_SCCS and not lint */
  23.  
  24. #include <stdio.h>
  25. #ifdef OSK
  26. #include <types.h>
  27. #include <in.h>
  28. #include <nameser.h>
  29. #else
  30. #include <sys/types.h>
  31. #include <netinet/in.h>
  32. #include <arpa/nameser.h>
  33. #endif
  34. #include <resolv.h>
  35.  
  36. /*
  37.  * Form all types of queries.
  38.  * Returns the size of the result or -1.
  39.  */
  40. res_mkquery(op, dname, class, type, data, datalen, newrr, buf, buflen)
  41.     int op;            /* opcode of query */
  42.     char *dname;        /* domain name */
  43.     int class, type;    /* class and type of query */
  44.     char *data;        /* resource record data */
  45.     int datalen;        /* length of data */
  46.     struct rrec *newrr;    /* new rr for modify or append */
  47.     char *buf;        /* buffer to put query */
  48.     int buflen;        /* size of buffer */
  49. {
  50.     register HEADER *hp;
  51.     register char *cp;
  52.     register int n;
  53.     char *dnptrs[10], **dpp, **lastdnptr;
  54.     extern char *index();
  55.  
  56. #ifdef DEBUG
  57.     if (_res.options & RES_DEBUG)
  58.         printf("res_mkquery(%d, %s, %d, %d)\n", op, dname, class, type);
  59. #endif DEBUG
  60.     /*
  61.      * Initialize header fields.
  62.      */
  63.     if ((buf == NULL) || (buflen < sizeof(HEADER)))
  64.         return(-1);
  65.     bzero(buf, sizeof(HEADER));
  66.     hp = (HEADER *) buf;
  67.     hp->id = htons(++_res.id);
  68.     hp->opcode = op;
  69.     hp->pr = (_res.options & RES_PRIMARY) != 0;
  70.     hp->rd = (_res.options & RES_RECURSE) != 0;
  71.     hp->rcode = NOERROR;
  72.     cp = buf + sizeof(HEADER);
  73.     buflen -= sizeof(HEADER);
  74.     dpp = dnptrs;
  75.     *dpp++ = buf;
  76.     *dpp++ = NULL;
  77.     lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]);
  78.     /*
  79.      * perform opcode specific processing
  80.      */
  81.     switch (op) {
  82.     case QUERY:
  83.         if ((buflen -= QFIXEDSZ) < 0)
  84.             return(-1);
  85.         if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
  86.             return (-1);
  87.         cp += n;
  88.         buflen -= n;
  89.         putshort(type, cp);
  90.         cp += sizeof(u_short);
  91.         putshort(class, cp);
  92.         cp += sizeof(u_short);
  93.         hp->qdcount = htons(1);
  94.         if (op == QUERY || data == NULL)
  95.             break;
  96.         /*
  97.          * Make an additional record for completion domain.
  98.          */
  99.         buflen -= RRFIXEDSZ;
  100.         if ((n = dn_comp(data, cp, buflen, dnptrs, lastdnptr)) < 0)
  101.             return (-1);
  102.         cp += n;
  103.         buflen -= n;
  104.         putshort(T_NULL, cp);
  105.         cp += sizeof(u_short);
  106.         putshort(class, cp);
  107.         cp += sizeof(u_short);
  108.         putlong(0, cp);
  109.         cp += sizeof(u_long);
  110.         putshort(0, cp);
  111.         cp += sizeof(u_short);
  112.         hp->arcount = htons(1);
  113.         break;
  114.  
  115.     case IQUERY:
  116.         /*
  117.          * Initialize answer section
  118.          */
  119.         if (buflen < 1 + RRFIXEDSZ + datalen)
  120.             return (-1);
  121.         *cp++ = '\0';    /* no domain name */
  122.         putshort(type, cp);
  123.         cp += sizeof(u_short);
  124.         putshort(class, cp);
  125.         cp += sizeof(u_short);
  126.         putlong(0, cp);
  127.         cp += sizeof(u_long);
  128.         putshort(datalen, cp);
  129.         cp += sizeof(u_short);
  130.         if (datalen) {
  131.             bcopy(data, cp, datalen);
  132.             cp += datalen;
  133.         }
  134.         hp->ancount = htons(1);
  135.         break;
  136.  
  137. #ifdef ALLOW_UPDATES
  138.     /*
  139.      * For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA
  140.      * (Record to be modified is followed by its replacement in msg.)
  141.      */
  142.     case UPDATEM:
  143.     case UPDATEMA:
  144.  
  145.     case UPDATED:
  146.         /*
  147.          * The res code for UPDATED and UPDATEDA is the same; user
  148.          * calls them differently: specifies data for UPDATED; server
  149.          * ignores data if specified for UPDATEDA.
  150.          */
  151.     case UPDATEDA:
  152.         buflen -= RRFIXEDSZ + datalen;
  153.         if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
  154.             return (-1);
  155.         cp += n;
  156.         putshort(type, cp);
  157.                 cp += sizeof(u_short);
  158.                 putshort(class, cp);
  159.                 cp += sizeof(u_short);
  160.         putlong(0, cp);
  161.         cp += sizeof(u_long);
  162.         putshort(datalen, cp);
  163.                 cp += sizeof(u_short);
  164.         if (datalen) {
  165.             bcopy(data, cp, datalen);
  166.             cp += datalen;
  167.         }
  168.         if ( (op == UPDATED) || (op == UPDATEDA) ) {
  169.             hp->ancount = htons(0);
  170.             break;
  171.         }
  172.         /* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */
  173.  
  174.     case UPDATEA:    /* Add new resource record */
  175.         buflen -= RRFIXEDSZ + datalen;
  176.         if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
  177.             return (-1);
  178.         cp += n;
  179.         putshort(newrr->r_type, cp);
  180.                 cp += sizeof(u_short);
  181.                 putshort(newrr->r_class, cp);
  182.                 cp += sizeof(u_short);
  183.         putlong(0, cp);
  184.         cp += sizeof(u_long);
  185.         putshort(newrr->r_size, cp);
  186.                 cp += sizeof(u_short);
  187.         if (newrr->r_size) {
  188.             bcopy(newrr->r_data, cp, newrr->r_size);
  189.             cp += newrr->r_size;
  190.         }
  191.         hp->ancount = htons(0);
  192.         break;
  193.  
  194. #endif ALLOW_UPDATES
  195.     }
  196.     return (cp - buf);
  197. }
  198.