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