-adns_status adns__mkquery(adns_state ads, vbuf *vb,
- const char *owner, int ol, int *id_r,
- const typeinfo *typei, adns_queryflags flags) {
- int ll, c, nlabs, id;
- byte label[255], *rqp;
- const char *p, *pe;
-
-#define MKQUERY_ADDB(b) *rqp++= (b)
-#define MKQUERY_ADDW(w) (MKQUERY_ADDB(((w)>>8)&0x0ff), MKQUERY_ADDB((w)&0x0ff))
-
- vb->used= 0;
- if (!adns__vbuf_ensure(vb,DNS_HDRSIZE+strlen(owner)+1+5))
- return adns_s_nolocalmem;
- rqp= vb->buf;
-
- *id_r= id= (ads->nextid++) & 0x0ffff;
-
- MKQUERY_ADDW(id);
- MKQUERY_ADDB(0x01); /* QR=Q(0), OPCODE=QUERY(0000), !AA, !TC, RD */
- MKQUERY_ADDB(0x00); /* !RA, Z=000, RCODE=NOERROR(0000) */
- MKQUERY_ADDW(1); /* QDCOUNT=1 */
- MKQUERY_ADDW(0); /* ANCOUNT=0 */
- MKQUERY_ADDW(0); /* NSCOUNT=0 */
- MKQUERY_ADDW(0); /* ARCOUNT=0 */
- p= owner; pe= owner+ol;
- nlabs= 0;
- if (!*p) return adns_s_invaliddomain;
- do {
- ll= 0;
- while (p!=pe && (c= *p++)!='.') {
- if (c=='\\') {
- if (!(flags & adns_qf_anyquote)) return adns_s_invaliddomain;
- if (ctype_digit(p[0])) {
- if (ctype_digit(p[1]) && ctype_digit(p[2])) {
- c= (*p++ - '0')*100 + (*p++ - '0')*10 + (*p++ - '0');
- if (c >= 256) return adns_s_invaliddomain;
- } else {
- return adns_s_invaliddomain;
- }
- } else if (!(c= *p++)) {
- return adns_s_invaliddomain;
- }
- }
- if (!(flags & adns_qf_anyquote)) {
- if (ctype_digit(c) || c == '-') {
- if (!ll) return adns_s_invaliddomain;
- } else if (!ctype_alpha(c)) {
- return adns_s_invaliddomain;
- }
- }
- if (ll == sizeof(label)) return adns_s_invaliddomain;
- label[ll++]= c;
- }
- if (!ll) return adns_s_invaliddomain;
- if (nlabs++ > 63) return adns_s_invaliddomain;
- MKQUERY_ADDB(ll);
- memcpy(rqp,label,ll); rqp+= ll;
- } while (p!=pe);
-
- MKQUERY_ADDB(0);
- MKQUERY_ADDW(typei->type & adns__rrt_typemask); /* QTYPE */
- MKQUERY_ADDW(DNS_CLASS_IN); /* QCLASS=IN */
-
- vb->used= rqp - vb->buf;
- assert(vb->used <= vb->avail);