1*18548Sralph /* res_mkquery.c 4.5 85/04/01 */ 218143Sralph 3*18548Sralph /* 4*18548Sralph * Copyright (c) 1985 Regents of the University of California 5*18548Sralph * All Rights Reserved 6*18548Sralph */ 7*18548Sralph 818143Sralph #include <stdio.h> 918143Sralph #include <sys/types.h> 1018143Sralph #include <netinet/in.h> 1118143Sralph #include <nameser.h> 1218143Sralph #include <resolv.h> 1318143Sralph 1418143Sralph /* 1518143Sralph * Form all types of queries. 1618143Sralph * Returns the size of the result or -1. 1718143Sralph */ 1818531Sralph res_mkquery(op, dname, class, type, data, datalen, newrr, buf, buflen) 1918143Sralph int op; /* opcode of query */ 2018143Sralph char *dname; /* domain name */ 2118143Sralph int class, type; /* class and type of query */ 2218143Sralph char *data; /* resource record data */ 2318143Sralph int datalen; /* length of data */ 2418143Sralph struct rrec *newrr; /* new rr for modify or append */ 2518143Sralph char *buf; /* buffer to put query */ 2618143Sralph int buflen; /* size of buffer */ 2718143Sralph { 2818143Sralph register HEADER *hp; 2918143Sralph register char *cp; 3018143Sralph register int n; 3118143Sralph char dnbuf[MAXDNAME]; 3218143Sralph char *dnptrs[10], **dpp, **lastdnptr; 3318528Sralph extern char *index(); 3418143Sralph 3518143Sralph if (_res.options & RES_DEBUG) 3618531Sralph printf("res_mkquery(%d, %s, %d, %d)\n", op, dname, class, type); 3718143Sralph /* 3818143Sralph * Initialize header fields. 3918143Sralph */ 4018143Sralph hp = (HEADER *) buf; 4118143Sralph hp->id = htons(++_res.id); 4218143Sralph hp->opcode = op; 4318143Sralph hp->qr = hp->aa = hp->tc = hp->ra = 0; 4418143Sralph hp->pr = (_res.options & RES_PRIMARY) != 0; 4518143Sralph hp->rd = (_res.options & RES_RECURSE) != 0; 4618143Sralph hp->rcode = NOERROR; 4718143Sralph hp->qdcount = 0; 4818143Sralph hp->ancount = 0; 4918143Sralph hp->nscount = 0; 5018143Sralph hp->arcount = 0; 5118143Sralph cp = buf + sizeof(HEADER); 5218143Sralph buflen -= sizeof(HEADER); 5318143Sralph dpp = dnptrs; 5418143Sralph *dpp++ = buf; 5518143Sralph *dpp++ = NULL; 5618341Sralph lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]); 5718143Sralph /* 5818528Sralph * If the domain name contains no dots (single label), then 5918143Sralph * append the default domain name to the one given. 6018143Sralph */ 6118528Sralph if ((_res.options & RES_DEFNAMES) && dname[0] != '\0' && 6218528Sralph index(dname, '.') == NULL) { 6318143Sralph if (!(_res.options & RES_INIT)) 6418143Sralph res_init(); 6518143Sralph if (_res.defdname[0] != '\0') 6618143Sralph dname = sprintf(dnbuf, "%s.%s", dname, _res.defdname); 6718143Sralph } 6818143Sralph /* 6918143Sralph * perform opcode specific processing 7018143Sralph */ 7118143Sralph switch (op) { 7218143Sralph case QUERY: 7318143Sralph case CQUERYM: 7418143Sralph case CQUERYU: 7518143Sralph buflen -= QFIXEDSZ; 7618143Sralph if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) 7718143Sralph return (-1); 7818143Sralph cp += n; 7918143Sralph buflen -= n; 8018528Sralph putshort(type, cp); 8118143Sralph cp += sizeof(u_short); 8218528Sralph putshort(class, cp); 8318143Sralph cp += sizeof(u_short); 8418143Sralph hp->qdcount = HTONS(1); 8518143Sralph if (op == QUERY || data == NULL) 8618143Sralph break; 8718143Sralph /* 8818143Sralph * Make an additional record for completion domain. 8918143Sralph */ 9018528Sralph buflen -= RRFIXEDSZ; 9118143Sralph if ((n = dn_comp(data, cp, buflen, dnptrs, lastdnptr)) < 0) 9218143Sralph return (-1); 9318143Sralph cp += n; 9418143Sralph buflen -= n; 9518528Sralph putshort(T_NULL, cp); 9618143Sralph cp += sizeof(u_short); 9718528Sralph putshort(class, cp); 9818143Sralph cp += sizeof(u_short); 9918528Sralph putlong(0, cp); 10018143Sralph cp += sizeof(u_long); 10118528Sralph putshort(0, cp); 10218143Sralph cp += sizeof(u_short); 10318143Sralph hp->arcount = HTONS(1); 10418143Sralph break; 10518143Sralph 10618143Sralph case IQUERY: 10718143Sralph /* 10818143Sralph * Initialize answer section 10918143Sralph */ 11018143Sralph if (buflen < 1 + RRFIXEDSZ + datalen) 11118143Sralph return (-1); 11218143Sralph *cp++ = '\0'; /* no domain name */ 11318528Sralph putshort(type, cp); 11418143Sralph cp += sizeof(u_short); 11518528Sralph putshort(class, cp); 11618143Sralph cp += sizeof(u_short); 11718528Sralph putlong(0, cp); 11818143Sralph cp += sizeof(u_long); 11918528Sralph putshort(datalen, cp); 12018143Sralph cp += sizeof(u_short); 12118143Sralph if (datalen) { 12218143Sralph bcopy(data, cp, datalen); 12318143Sralph cp += datalen; 12418143Sralph } 12518143Sralph hp->ancount = HTONS(1); 12618143Sralph break; 12718143Sralph 12818143Sralph #ifdef notdef 12918143Sralph case UPDATED: 13018143Sralph /* 13118143Sralph * Put record to be added or deleted in additional section 13218143Sralph */ 13318143Sralph buflen -= RRFIXEDSZ + datalen; 13418143Sralph if ((n = dn_comp(dname, cp, buflen, NULL, NULL)) < 0) 13518143Sralph return (-1); 13618143Sralph cp += n; 13718143Sralph *((u_short *)cp) = htons(type); 13818143Sralph cp += sizeof(u_short); 13918143Sralph *((u_short *)cp) = htons(class); 14018143Sralph cp += sizeof(u_short); 14118143Sralph *((u_long *)cp) = 0; 14218143Sralph cp += sizeof(u_long); 14318143Sralph *((u_short *)cp) = htons(datalen); 14418143Sralph cp += sizeof(u_short); 14518143Sralph if (datalen) { 14618143Sralph bcopy(data, cp, datalen); 14718143Sralph cp += datalen; 14818143Sralph } 14918143Sralph break; 15018143Sralph 15118143Sralph case UPDATEM: 15218143Sralph /* 15318143Sralph * Record to be modified followed by its replacement 15418143Sralph */ 15518143Sralph buflen -= RRFIXEDSZ + datalen; 15618143Sralph if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) 15718143Sralph return (-1); 15818143Sralph cp += n; 15918143Sralph *((u_short *)cp) = htons(type); 16018143Sralph cp += sizeof(u_short); 16118143Sralph *((u_short *)cp) = htons(class); 16218143Sralph cp += sizeof(u_short); 16318143Sralph *((u_long *)cp) = 0; 16418143Sralph cp += sizeof(u_long); 16518143Sralph *((u_short *)cp) = htons(datalen); 16618143Sralph cp += sizeof(u_short); 16718143Sralph if (datalen) { 16818143Sralph bcopy(data, cp, datalen); 16918143Sralph cp += datalen; 17018143Sralph } 17118143Sralph 17218143Sralph case UPDATEA: 17318143Sralph buflen -= RRFIXEDSZ + newrr->r_size; 17418143Sralph if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) 17518143Sralph return (-1); 17618143Sralph cp += n; 17718143Sralph *((u_short *)cp) = htons(newrr->r_type); 17818143Sralph cp += sizeof(u_short); 17918143Sralph *((u_short *)cp) = htons(newrr->r_type); 18018143Sralph cp += sizeof(u_short); 18118143Sralph *((u_long *)cp) = htonl(newrr->r_ttl); 18218143Sralph cp += sizeof(u_long); 18318143Sralph *((u_short *)cp) = htons(newrr->r_size); 18418143Sralph cp += sizeof(u_short); 18518143Sralph if (newrr->r_size) { 18618143Sralph bcopy(newrr->r_data, cp, newrr->r_size); 18718143Sralph cp += newrr->r_size; 18818143Sralph } 18918143Sralph break; 19018143Sralph #endif 19118143Sralph } 19218143Sralph return (cp - buf); 19318143Sralph } 194