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