1*18341Sralph /* res_mkquery.c 4.2 85/03/15 */ 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; 2818143Sralph 2918143Sralph if (_res.options & RES_DEBUG) 3018143Sralph printf("mkquery(%d, %s, %d, %d)\n", op, dname, class, type); 3118143Sralph /* 3218143Sralph * Initialize header fields. 3318143Sralph */ 3418143Sralph hp = (HEADER *) buf; 3518143Sralph hp->id = htons(++_res.id); 3618143Sralph hp->opcode = op; 3718143Sralph hp->qr = hp->aa = hp->tc = hp->ra = 0; 3818143Sralph hp->pr = (_res.options & RES_PRIMARY) != 0; 3918143Sralph hp->rd = (_res.options & RES_RECURSE) != 0; 4018143Sralph hp->rcode = NOERROR; 4118143Sralph hp->qdcount = 0; 4218143Sralph hp->ancount = 0; 4318143Sralph hp->nscount = 0; 4418143Sralph hp->arcount = 0; 4518143Sralph cp = buf + sizeof(HEADER); 4618143Sralph buflen -= sizeof(HEADER); 4718143Sralph dpp = dnptrs; 4818143Sralph *dpp++ = buf; 4918143Sralph *dpp++ = NULL; 50*18341Sralph lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]); 5118143Sralph /* 52*18341Sralph * If the domain name does not end in '.', then 5318143Sralph * append the default domain name to the one given. 5418143Sralph */ 55*18341Sralph if ((_res.options & RES_DEFNAMES) && (n = strlen(dname)) > 0 && 56*18341Sralph dname[n - 1] != '.') { 5718143Sralph if (!(_res.options & RES_INIT)) 5818143Sralph res_init(); 5918143Sralph if (_res.defdname[0] != '\0') 6018143Sralph dname = sprintf(dnbuf, "%s.%s", dname, _res.defdname); 6118143Sralph } 6218143Sralph /* 6318143Sralph * perform opcode specific processing 6418143Sralph */ 6518143Sralph switch (op) { 6618143Sralph case QUERY: 6718143Sralph case CQUERYM: 6818143Sralph case CQUERYU: 6918143Sralph buflen -= QFIXEDSZ; 7018143Sralph if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) 7118143Sralph return (-1); 7218143Sralph cp += n; 7318143Sralph buflen -= n; 7418143Sralph *((u_short *)cp) = htons(type); 7518143Sralph cp += sizeof(u_short); 7618143Sralph *((u_short *)cp) = htons(class); 7718143Sralph cp += sizeof(u_short); 7818143Sralph hp->qdcount = HTONS(1); 7918143Sralph if (op == QUERY || data == NULL) 8018143Sralph break; 8118143Sralph /* 8218143Sralph * Make an additional record for completion domain. 8318143Sralph */ 8418143Sralph if ((n = dn_comp(data, cp, buflen, dnptrs, lastdnptr)) < 0) 8518143Sralph return (-1); 8618143Sralph cp += n; 8718143Sralph buflen -= n; 8818143Sralph *((u_short *)cp) = htons(T_NULL); 8918143Sralph cp += sizeof(u_short); 9018143Sralph *((u_short *)cp) = htons(class); 9118143Sralph cp += sizeof(u_short); 9218143Sralph *((u_long *)cp) = 0; 9318143Sralph cp += sizeof(u_long); 9418143Sralph *((u_short *)cp) = 0; 9518143Sralph cp += sizeof(u_short); 9618143Sralph hp->arcount = HTONS(1); 9718143Sralph break; 9818143Sralph 9918143Sralph case IQUERY: 10018143Sralph /* 10118143Sralph * Initialize answer section 10218143Sralph */ 10318143Sralph if (buflen < 1 + RRFIXEDSZ + datalen) 10418143Sralph return (-1); 10518143Sralph *cp++ = '\0'; /* no domain name */ 10618143Sralph *((u_short *)cp) = htons(type); 10718143Sralph cp += sizeof(u_short); 10818143Sralph *((u_short *)cp) = htons(class); 10918143Sralph cp += sizeof(u_short); 11018143Sralph *((u_long *)cp) = 0; 11118143Sralph cp += sizeof(u_long); 11218143Sralph *((u_short *)cp) = htons(datalen); 11318143Sralph cp += sizeof(u_short); 11418143Sralph if (datalen) { 11518143Sralph bcopy(data, cp, datalen); 11618143Sralph cp += datalen; 11718143Sralph } 11818143Sralph hp->ancount = HTONS(1); 11918143Sralph break; 12018143Sralph 12118143Sralph #ifdef notdef 12218143Sralph case UPDATED: 12318143Sralph /* 12418143Sralph * Put record to be added or deleted in additional section 12518143Sralph */ 12618143Sralph buflen -= RRFIXEDSZ + datalen; 12718143Sralph if ((n = dn_comp(dname, cp, buflen, NULL, NULL)) < 0) 12818143Sralph return (-1); 12918143Sralph cp += n; 13018143Sralph *((u_short *)cp) = htons(type); 13118143Sralph cp += sizeof(u_short); 13218143Sralph *((u_short *)cp) = htons(class); 13318143Sralph cp += sizeof(u_short); 13418143Sralph *((u_long *)cp) = 0; 13518143Sralph cp += sizeof(u_long); 13618143Sralph *((u_short *)cp) = htons(datalen); 13718143Sralph cp += sizeof(u_short); 13818143Sralph if (datalen) { 13918143Sralph bcopy(data, cp, datalen); 14018143Sralph cp += datalen; 14118143Sralph } 14218143Sralph break; 14318143Sralph 14418143Sralph case UPDATEM: 14518143Sralph /* 14618143Sralph * Record to be modified followed by its replacement 14718143Sralph */ 14818143Sralph buflen -= RRFIXEDSZ + datalen; 14918143Sralph if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) 15018143Sralph return (-1); 15118143Sralph cp += n; 15218143Sralph *((u_short *)cp) = htons(type); 15318143Sralph cp += sizeof(u_short); 15418143Sralph *((u_short *)cp) = htons(class); 15518143Sralph cp += sizeof(u_short); 15618143Sralph *((u_long *)cp) = 0; 15718143Sralph cp += sizeof(u_long); 15818143Sralph *((u_short *)cp) = htons(datalen); 15918143Sralph cp += sizeof(u_short); 16018143Sralph if (datalen) { 16118143Sralph bcopy(data, cp, datalen); 16218143Sralph cp += datalen; 16318143Sralph } 16418143Sralph 16518143Sralph case UPDATEA: 16618143Sralph buflen -= RRFIXEDSZ + newrr->r_size; 16718143Sralph if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) 16818143Sralph return (-1); 16918143Sralph cp += n; 17018143Sralph *((u_short *)cp) = htons(newrr->r_type); 17118143Sralph cp += sizeof(u_short); 17218143Sralph *((u_short *)cp) = htons(newrr->r_type); 17318143Sralph cp += sizeof(u_short); 17418143Sralph *((u_long *)cp) = htonl(newrr->r_ttl); 17518143Sralph cp += sizeof(u_long); 17618143Sralph *((u_short *)cp) = htons(newrr->r_size); 17718143Sralph cp += sizeof(u_short); 17818143Sralph if (newrr->r_size) { 17918143Sralph bcopy(newrr->r_data, cp, newrr->r_size); 18018143Sralph cp += newrr->r_size; 18118143Sralph } 18218143Sralph break; 18318143Sralph #endif 18418143Sralph } 18518143Sralph return (cp - buf); 18618143Sralph } 187