1*18528Sralph /* res_mkquery.c 4.3 85/03/27 */ 218143Sralph 318143Sralph #include <stdio.h> 418143Sralph #include <sys/types.h> 518143Sralph #include <netinet/in.h> 618143Sralph #include <nameser.h> 718143Sralph #include <resolv.h> 818143Sralph 918143Sralph /* 1018143Sralph * Form all types of queries. 1118143Sralph * Returns the size of the result or -1. 1218143Sralph */ 1318143Sralph mkquery(op, dname, class, type, data, datalen, newrr, buf, buflen) 1418143Sralph int op; /* opcode of query */ 1518143Sralph char *dname; /* domain name */ 1618143Sralph int class, type; /* class and type of query */ 1718143Sralph char *data; /* resource record data */ 1818143Sralph int datalen; /* length of data */ 1918143Sralph struct rrec *newrr; /* new rr for modify or append */ 2018143Sralph char *buf; /* buffer to put query */ 2118143Sralph int buflen; /* size of buffer */ 2218143Sralph { 2318143Sralph register HEADER *hp; 2418143Sralph register char *cp; 2518143Sralph register int n; 2618143Sralph char dnbuf[MAXDNAME]; 2718143Sralph char *dnptrs[10], **dpp, **lastdnptr; 28*18528Sralph extern char *index(); 2918143Sralph 3018143Sralph if (_res.options & RES_DEBUG) 3118143Sralph printf("mkquery(%d, %s, %d, %d)\n", op, dname, class, type); 3218143Sralph /* 3318143Sralph * Initialize header fields. 3418143Sralph */ 3518143Sralph hp = (HEADER *) buf; 3618143Sralph hp->id = htons(++_res.id); 3718143Sralph hp->opcode = op; 3818143Sralph hp->qr = hp->aa = hp->tc = hp->ra = 0; 3918143Sralph hp->pr = (_res.options & RES_PRIMARY) != 0; 4018143Sralph hp->rd = (_res.options & RES_RECURSE) != 0; 4118143Sralph hp->rcode = NOERROR; 4218143Sralph hp->qdcount = 0; 4318143Sralph hp->ancount = 0; 4418143Sralph hp->nscount = 0; 4518143Sralph hp->arcount = 0; 4618143Sralph cp = buf + sizeof(HEADER); 4718143Sralph buflen -= sizeof(HEADER); 4818143Sralph dpp = dnptrs; 4918143Sralph *dpp++ = buf; 5018143Sralph *dpp++ = NULL; 5118341Sralph lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]); 5218143Sralph /* 53*18528Sralph * If the domain name contains no dots (single label), then 5418143Sralph * append the default domain name to the one given. 5518143Sralph */ 56*18528Sralph if ((_res.options & RES_DEFNAMES) && dname[0] != '\0' && 57*18528Sralph index(dname, '.') == NULL) { 5818143Sralph if (!(_res.options & RES_INIT)) 5918143Sralph res_init(); 6018143Sralph if (_res.defdname[0] != '\0') 6118143Sralph dname = sprintf(dnbuf, "%s.%s", dname, _res.defdname); 6218143Sralph } 6318143Sralph /* 6418143Sralph * perform opcode specific processing 6518143Sralph */ 6618143Sralph switch (op) { 6718143Sralph case QUERY: 6818143Sralph case CQUERYM: 6918143Sralph case CQUERYU: 7018143Sralph buflen -= QFIXEDSZ; 7118143Sralph if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) 7218143Sralph return (-1); 7318143Sralph cp += n; 7418143Sralph buflen -= n; 75*18528Sralph putshort(type, cp); 7618143Sralph cp += sizeof(u_short); 77*18528Sralph putshort(class, cp); 7818143Sralph cp += sizeof(u_short); 7918143Sralph hp->qdcount = HTONS(1); 8018143Sralph if (op == QUERY || data == NULL) 8118143Sralph break; 8218143Sralph /* 8318143Sralph * Make an additional record for completion domain. 8418143Sralph */ 85*18528Sralph buflen -= RRFIXEDSZ; 8618143Sralph if ((n = dn_comp(data, cp, buflen, dnptrs, lastdnptr)) < 0) 8718143Sralph return (-1); 8818143Sralph cp += n; 8918143Sralph buflen -= n; 90*18528Sralph putshort(T_NULL, cp); 9118143Sralph cp += sizeof(u_short); 92*18528Sralph putshort(class, cp); 9318143Sralph cp += sizeof(u_short); 94*18528Sralph putlong(0, cp); 9518143Sralph cp += sizeof(u_long); 96*18528Sralph putshort(0, cp); 9718143Sralph cp += sizeof(u_short); 9818143Sralph hp->arcount = HTONS(1); 9918143Sralph break; 10018143Sralph 10118143Sralph case IQUERY: 10218143Sralph /* 10318143Sralph * Initialize answer section 10418143Sralph */ 10518143Sralph if (buflen < 1 + RRFIXEDSZ + datalen) 10618143Sralph return (-1); 10718143Sralph *cp++ = '\0'; /* no domain name */ 108*18528Sralph putshort(type, cp); 10918143Sralph cp += sizeof(u_short); 110*18528Sralph putshort(class, cp); 11118143Sralph cp += sizeof(u_short); 112*18528Sralph putlong(0, cp); 11318143Sralph cp += sizeof(u_long); 114*18528Sralph putshort(datalen, cp); 11518143Sralph cp += sizeof(u_short); 11618143Sralph if (datalen) { 11718143Sralph bcopy(data, cp, datalen); 11818143Sralph cp += datalen; 11918143Sralph } 12018143Sralph hp->ancount = HTONS(1); 12118143Sralph break; 12218143Sralph 12318143Sralph #ifdef notdef 12418143Sralph case UPDATED: 12518143Sralph /* 12618143Sralph * Put record to be added or deleted in additional section 12718143Sralph */ 12818143Sralph buflen -= RRFIXEDSZ + datalen; 12918143Sralph if ((n = dn_comp(dname, cp, buflen, NULL, NULL)) < 0) 13018143Sralph return (-1); 13118143Sralph cp += n; 13218143Sralph *((u_short *)cp) = htons(type); 13318143Sralph cp += sizeof(u_short); 13418143Sralph *((u_short *)cp) = htons(class); 13518143Sralph cp += sizeof(u_short); 13618143Sralph *((u_long *)cp) = 0; 13718143Sralph cp += sizeof(u_long); 13818143Sralph *((u_short *)cp) = htons(datalen); 13918143Sralph cp += sizeof(u_short); 14018143Sralph if (datalen) { 14118143Sralph bcopy(data, cp, datalen); 14218143Sralph cp += datalen; 14318143Sralph } 14418143Sralph break; 14518143Sralph 14618143Sralph case UPDATEM: 14718143Sralph /* 14818143Sralph * Record to be modified followed by its replacement 14918143Sralph */ 15018143Sralph buflen -= RRFIXEDSZ + datalen; 15118143Sralph if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) 15218143Sralph return (-1); 15318143Sralph cp += n; 15418143Sralph *((u_short *)cp) = htons(type); 15518143Sralph cp += sizeof(u_short); 15618143Sralph *((u_short *)cp) = htons(class); 15718143Sralph cp += sizeof(u_short); 15818143Sralph *((u_long *)cp) = 0; 15918143Sralph cp += sizeof(u_long); 16018143Sralph *((u_short *)cp) = htons(datalen); 16118143Sralph cp += sizeof(u_short); 16218143Sralph if (datalen) { 16318143Sralph bcopy(data, cp, datalen); 16418143Sralph cp += datalen; 16518143Sralph } 16618143Sralph 16718143Sralph case UPDATEA: 16818143Sralph buflen -= RRFIXEDSZ + newrr->r_size; 16918143Sralph if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) 17018143Sralph return (-1); 17118143Sralph cp += n; 17218143Sralph *((u_short *)cp) = htons(newrr->r_type); 17318143Sralph cp += sizeof(u_short); 17418143Sralph *((u_short *)cp) = htons(newrr->r_type); 17518143Sralph cp += sizeof(u_short); 17618143Sralph *((u_long *)cp) = htonl(newrr->r_ttl); 17718143Sralph cp += sizeof(u_long); 17818143Sralph *((u_short *)cp) = htons(newrr->r_size); 17918143Sralph cp += sizeof(u_short); 18018143Sralph if (newrr->r_size) { 18118143Sralph bcopy(newrr->r_data, cp, newrr->r_size); 18218143Sralph cp += newrr->r_size; 18318143Sralph } 18418143Sralph break; 18518143Sralph #endif 18618143Sralph } 18718143Sralph return (cp - buf); 18818143Sralph } 189