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 this notice is preserved and that due credit is given
   7:  * to the University of California at Berkeley. The name of the University
   8:  * may not be used to endorse or promote products derived from this
   9:  * software without specific prior written permission. This software
  10:  * is provided ``as is'' without express or implied warranty.
  11:  */
  12: 
  13: #if defined(LIBC_SCCS) && !defined(lint)
  14: static char sccsid[] = "@(#)res_mkquery.c	6.7 (Berkeley) 3/7/88";
  15: #endif /* LIBC_SCCS and not lint */
  16: 
  17: #include <stdio.h>
  18: #include <sys/types.h>
  19: #include <netinet/in.h>
  20: #include <arpa/nameser.h>
  21: #include <resolv.h>
  22: 
  23: /*
  24:  * Form all types of queries.
  25:  * Returns the size of the result or -1.
  26:  */
  27: res_mkquery(op, dname, class, type, data, datalen, newrr, buf, buflen)
  28:     int op;         /* opcode of query */
  29:     char *dname;        /* domain name */
  30:     int class, type;    /* class and type of query */
  31:     char *data;     /* resource record data */
  32:     int datalen;        /* length of data */
  33:     struct rrec *newrr; /* new rr for modify or append */
  34:     char *buf;      /* buffer to put query */
  35:     int buflen;     /* size of buffer */
  36: {
  37:     register HEADER *hp;
  38:     register char *cp;
  39:     register int n;
  40:     char dnbuf[MAXDNAME];
  41:     char *dnptrs[10], **dpp, **lastdnptr;
  42:     extern char *index();
  43: 
  44: #ifdef DEBUG
  45:     if (_res.options & RES_DEBUG)
  46:         printf("res_mkquery(%d, %s, %d, %d)\n", op, dname, class, type);
  47: #endif DEBUG
  48:     /*
  49: 	 * Initialize header fields.
  50: 	 */
  51:     hp = (HEADER *) buf;
  52:     hp->id = htons(++_res.id);
  53:     hp->opcode = op;
  54:     hp->qr = hp->aa = hp->tc = hp->ra = 0;
  55:     hp->pr = (_res.options & RES_PRIMARY) != 0;
  56:     hp->rd = (_res.options & RES_RECURSE) != 0;
  57:     hp->rcode = NOERROR;
  58:     hp->qdcount = 0;
  59:     hp->ancount = 0;
  60:     hp->nscount = 0;
  61:     hp->arcount = 0;
  62:     cp = buf + sizeof(HEADER);
  63:     buflen -= sizeof(HEADER);
  64:     dpp = dnptrs;
  65:     *dpp++ = buf;
  66:     *dpp++ = NULL;
  67:     lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]);
  68:     /*
  69: 	 * If the domain name contains no dots (single label), then
  70: 	 * append the default domain name to the one given.
  71: 	 */
  72:     if ((_res.options & RES_DEFNAMES) && dname != 0 && dname[0] != '\0' &&
  73:         index(dname, '.') == NULL) {
  74:         if (!(_res.options & RES_INIT))
  75:             if (res_init() == -1)
  76:                 return(-1);
  77:         if (_res.defdname[0] != '\0') {
  78:             (void)sprintf(dnbuf, "%s.%s", dname, _res.defdname);
  79:             dname = dnbuf;
  80:         }
  81:     }
  82:     /*
  83: 	 * perform opcode specific processing
  84: 	 */
  85:     switch (op) {
  86:     case QUERY:
  87:         buflen -= QFIXEDSZ;
  88:         if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
  89:             return (-1);
  90:         cp += n;
  91:         buflen -= n;
  92:         putshort(type, cp);
  93:         cp += sizeof(u_short);
  94:         putshort(class, cp);
  95:         cp += sizeof(u_short);
  96:         hp->qdcount = htons(1);
  97:         if (op == QUERY || data == NULL)
  98:             break;
  99:         /*
 100: 		 * Make an additional record for completion domain.
 101: 		 */
 102:         buflen -= RRFIXEDSZ;
 103:         if ((n = dn_comp(data, cp, buflen, dnptrs, lastdnptr)) < 0)
 104:             return (-1);
 105:         cp += n;
 106:         buflen -= n;
 107:         putshort(T_NULL, cp);
 108:         cp += sizeof(u_short);
 109:         putshort(class, cp);
 110:         cp += sizeof(u_short);
 111:         putlong((long)0, cp);
 112:         cp += sizeof(u_long);
 113:         putshort(0, cp);
 114:         cp += sizeof(u_short);
 115:         hp->arcount = htons(1);
 116:         break;
 117: 
 118:     case IQUERY:
 119:         /*
 120: 		 * Initialize answer section
 121: 		 */
 122:         if (buflen < 1 + RRFIXEDSZ + datalen)
 123:             return (-1);
 124:         *cp++ = '\0';   /* no domain name */
 125:         putshort(type, cp);
 126:         cp += sizeof(u_short);
 127:         putshort(class, cp);
 128:         cp += sizeof(u_short);
 129:         putlong((long)0, cp);
 130:         cp += sizeof(u_long);
 131:         putshort(datalen, cp);
 132:         cp += sizeof(u_short);
 133:         if (datalen) {
 134:             bcopy(data, cp, datalen);
 135:             cp += datalen;
 136:         }
 137:         hp->ancount = htons(1);
 138:         break;
 139: 
 140: #ifdef ALLOW_UPDATES
 141:     /*
 142: 	 * For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA
 143: 	 * (Record to be modified is followed by its replacement in msg.)
 144: 	 */
 145:     case UPDATEM:
 146:     case UPDATEMA:
 147: 
 148:     case UPDATED:
 149:         /*
 150: 		 * The res code for UPDATED and UPDATEDA is the same; user
 151: 		 * calls them differently: specifies data for UPDATED; server
 152: 		 * ignores data if specified for UPDATEDA.
 153: 		 */
 154:     case UPDATEDA:
 155:         buflen -= RRFIXEDSZ + datalen;
 156:         if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
 157:             return (-1);
 158:         cp += n;
 159:         putshort(type, cp);
 160:                 cp += sizeof(u_short);
 161:                 putshort(class, cp);
 162:                 cp += sizeof(u_short);
 163:         putlong((long)0, cp);
 164:         cp += sizeof(u_long);
 165:         putshort(datalen, cp);
 166:                 cp += sizeof(u_short);
 167:         if (datalen) {
 168:             bcopy(data, cp, datalen);
 169:             cp += datalen;
 170:         }
 171:         if ( (op == UPDATED) || (op == UPDATEDA) ) {
 172:             hp->ancount = htons(0);
 173:             break;
 174:         }
 175:         /* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */
 176: 
 177:     case UPDATEA:   /* Add new resource record */
 178:         buflen -= RRFIXEDSZ + datalen;
 179:         if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
 180:             return (-1);
 181:         cp += n;
 182:         putshort(newrr->r_type, cp);
 183:                 cp += sizeof(u_short);
 184:                 putshort(newrr->r_class, cp);
 185:                 cp += sizeof(u_short);
 186:         putlong((long)0, cp);
 187:         cp += sizeof(u_long);
 188:         putshort(newrr->r_size, cp);
 189:                 cp += sizeof(u_short);
 190:         if (newrr->r_size) {
 191:             bcopy(newrr->r_data, cp, newrr->r_size);
 192:             cp += newrr->r_size;
 193:         }
 194:         hp->ancount = htons(0);
 195:         break;
 196: 
 197: #endif ALLOW_UPDATES
 198:     }
 199:     return (cp - buf);
 200: }
Last modified: 1988-09-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2695
Valid CSS Valid XHTML 1.0 Strict