5 int vbuf__append_quoted1035(vbuf *vb, const byte *buf, int len) {
11 for (i=0; i<len; i++) {
13 if (ch == '.' || ch == '"' || ch == '(' || ch == ')' ||
14 ch == '@' || ch == ';' || ch == '$') {
15 sprintf(qbuf,"\\%c",ch);
17 } else if (ch <= ' ' || ch >= 127) {
18 sprintf(qbuf,"\\%03o",ch);
22 if (!adns__vbuf_append(vb,buf,i) || !adns__vbuf_append(vb,qbuf,strlen(qbuf)))
29 adns_status adns__get_label(const byte *dgram, int dglen, int *max_io,
30 int *cbyte_io, int *lablen_r, int *labstart_r,
32 /* If succeeds, *lablen_r may be set to -1 to indicate truncation/overrun */
33 int max, cbyte, lablen, namelen;
39 if (cbyte+2 > max) goto x_truncated;
41 if (!(lablen & 0x0c000)) break;
42 if ((lablen & 0x0c000) != 0x0c000) return adns_s_unknownreply;
43 if (cbyte_io) { *cbyte_io= cbyte; cbyte_io= 0; }
44 cbyte= DNS_HDRSIZE+(lablen&0x3fff);
47 if (labstart_r) *labstart_r= cbyte;
50 if (namelen) namelen++;
52 if (namelen > DNS_MAXDOMAIN) return adns_s_domaintoolong;
55 if (cbyte > max) goto x_truncated;
57 if (cbyte_io) *cbyte_io= cbyte;
66 adns_status adns__get_domain_perm(adns_state ads, adns_query qu, int serv,
67 const byte *dgram, int dglen,
68 int *cbyte_io, int max, int *domainstart_r) {
69 /* Returns 0 for OK (*domainstart_r >=0) or truncated (*domainstart_r == -1)
70 * or any other adns_s_* value.
72 int cbyte, sused, lablen, labstart, namelen, i, ch;
75 /* If we follow a pointer we set cbyte_io to 0 to indicate that
76 * we've lost our original starting and ending points; we don't
77 * put the end of the pointed-to thing into the original *cbyte_io.
83 st= adns__get_label(dgram,dglen,&max, &cbyte,&lablen,&labstart,&namelen);
85 if (lablen<0) goto x_truncated;
87 if (qu->ans.used != sused)
88 if (!adns__vbuf_append(&qu->ans,".",1)) return adns_s_nolocalmem;
89 if (qu->flags & adns_qf_anyquote) {
90 if (!vbuf__append_quoted1035(&qu->ans,dgram+labstart,lablen))
91 return adns_s_nolocalmem;
93 if (!ctype_alpha(dgram[labstart])) return adns_s_invaliddomain;
94 for (i= cbyte+1; i<cbyte+lablen; i++) {
96 if (ch != '-' && !ctype_alpha(ch) && !ctype_digit(ch))
97 return adns_s_invaliddomain;
99 if (!adns__vbuf_append(&qu->ans,dgram+labstart,lablen))
100 return adns_s_nolocalmem;
103 if (cbyte_io) *cbyte_io= cbyte;
104 if (!adns__vbuf_append(&qu->ans,"",1)) return adns_s_nolocalmem;
105 *domainstart_r= sused;
110 return cbyte_io ? -1 : adns_s_serverfaulty;
113 adns_status adns__get_domain_temp(adns_state ads, adns_query qu, int serv,
114 const byte *dgram, int dglen,
115 int *cbyte_io, int max, int *domainstart_r) {
120 st= adns__get_domain_perm(ads,qu,serv,dgram,dglen,cbyte_io,max,domainstart_r);
125 adns_status adns__get_rr_temp(adns_state ads, adns_query qu, int serv,
126 const byte *dgram, int dglen, int *cbyte_io,
127 int *type_r, int *class_r, int *rdlen_r, int *rdstart_r,
128 const byte *eo_dgram, int eo_dglen, int eo_cbyte,
130 /* _s_ok can have *type_r == -1 and other output invalid, for truncation
131 * type_r and class_r must be !0, other _r may be 0.
132 * eo_dgram==0 for no comparison, otherwise all eo_ must be valid.
134 int cbyte, tmp, rdlen, mismatch;
135 int max, lablen, labstart, namelen, ch;
136 int eo_max, eo_lablen, eo_labstart, eo_namelen, eo_ch;
140 mismatch= eo_dgram ? 1 : 0;
142 namelen= 0; eo_namelen= 0;
143 max= dglen; eo_max= eo_dglen;
145 st= adns__get_label(dgram,dglen,&max,
146 &cbyte,&lablen,&labstart,&namelen);
148 if (lablen<0) goto x_truncated;
151 st= adns__get_label(eo_dgram,eo_dglen,&eo_max,
152 &eo_cbyte,&eo_lablen,&eo_labstart,&eo_namelen);
154 assert(eo_lablen>=0);
155 if (lablen != eo_lablen) mismatch= 1;
156 while (!mismatch && lablen-- > 0) {
157 ch= dgram[labstart++]; if (ctype_alpha(ch)) ch &= ~32;
158 eo_ch= eo_dgram[eo_labstart++]; if (ctype_alpha(eo_ch)) eo_ch &= ~32;
159 if (ch != eo_ch) mismatch= 1;
163 if (eo_matched_r) *eo_matched_r= !mismatch;
165 if (cbyte+10>dglen) goto x_truncated;
166 GET_W(cbyte,tmp); *type_r= tmp;
167 GET_W(cbyte,tmp); *class_r= tmp;
168 cbyte+= 4; /* we skip the TTL */
169 GET_W(cbyte,rdlen); if (rdlen_r) *rdlen_r= tmp;
170 if (rdstart_r) *rdstart_r= cbyte;
172 if (cbyte>dglen) goto x_truncated;