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
;