2 * (c) Oleg Puchinin 2006
3 * graycardinalster@gmail.com
11 extern int dns_last_id
;
13 char * __name2dns (char *name
, int *len
)
18 __dlist_entry_t
* one
;
21 Dsplit (name
, ".", list
);
22 d_buf
= CNEW (char, 70);
25 one
= list
->get_head ();
27 buf_W8 (&ptr
, strlen (one
->data
));
28 buf_WS (&ptr
, one
->data
);
39 inline char * __ddup (char * ptr
, unsigned char ch
)
41 char *S
= CNEW (char, ch
+2);
48 char * __dns_rd_chunk (DPBuf
* p
, char ** ptr
, char * done
)
53 if (! p
->check (*ptr
, 1))
66 if (! p
->check (*ptr
, ch
))
68 ret
= __ddup (*ptr
, ch
);
75 char * __dns_resp_domain (DPBuf
* p
, char * domain
, char **domain_end
)
95 S
= __dns_rd_chunk (p
, &ptr
, &done
);
103 if ((domain_end
!= NULL
) & d_try
)
107 if (! p
->check (ptr
, 2))
114 offset
= (ch
&= ~0xc0) << 8;
115 offset
+= buf_R8 (&ptr
);
117 ptr
= &p
->begin
[offset
];
121 if (domain_end
&& ! d_try
)
125 if (strlen (buf
) > 0)
131 char * make_dns_pkt (uint16_t id
, uint16_t flags
, uint16_t d_type
,
132 uint16_t d_class
, char * domain
, int *len
)
138 struct dns_header hdr
;
140 pkt
= CNEW (char, 512);
142 memset (&hdr
, 0, sizeof (struct dns_header
));
144 hdr
.flags
= htons (flags
);
146 buf_Wstruct (&ptr
, &hdr
);
148 dns_name
= __name2dns (domain
, &dns_len
);
149 memcpy (ptr
, dns_name
, dns_len
);
153 buf_W16 (&ptr
, htons (d_type
)); // "A"
154 buf_W16 (&ptr
, htons (d_class
)); // Internet
162 DList
* dns_resp_split (dns_header
*hdr
, char *pkt
, int len
)
164 dns_header
*query_hdr
;
165 dns_rheader
*res_hdr
= NULL
;
166 dns_reply
*reply
= NULL
;
175 p
= new DPBuf (pkt
, len
);
176 query_hdr
= (dns_header
*) p
->rd (pkt
, sizeof (dns_header
));
180 if (query_hdr
->id
!= hdr
->id
)
183 ptr
= &p
->begin
[sizeof (dns_header
)];
184 d_name
= __dns_resp_domain (p
, ptr
, &d_end
);
191 if (! p
->check (ptr
, 4))
194 dr_type
= htons (buf_R16 (&ptr
));
195 dr_class
= htons (buf_R16 (&ptr
));
201 reply
= CNEW (dns_reply
, 1);
202 memset (reply
, 0, sizeof (dns_reply
));
204 reply
->domain
= __dns_resp_domain (p
, ptr
, &d_end
);
211 if (! p
->check (ptr
, sizeof (struct dns_rheader
)))
214 res_hdr
= buf_Rstruct (&ptr
, dns_rheader
);
215 reply
->TTL
= htonl (res_hdr
->TTL
);
216 reply
->data_len
= htons (res_hdr
->len
);
217 reply
->dr_type
= htons (res_hdr
->dr_type
);
218 reply
->dr_class
= htons (res_hdr
->dr_class
);
219 if (! p
->check (ptr
, reply
->data_len
))
222 reply
->pkt_data_ptr
= ptr
;
223 reply
->data
= buf_RD (&ptr
, reply
->data_len
);
224 ret
->add_tail (LPCHAR (reply
));
232 DROP (reply
->domain
);
243 void dns_resp_clean (DList
* list
)
245 __dlist_entry_t
*one
;
251 while ((one
= list
->get_head ()) && one
) {
252 reply
= (dns_reply
*) one
->data
;
253 DROP (reply
->domain
);
261 dns_reply
* dns_scan (DList
*list
, uint16_t dr_type
, uint16_t dr_class
)
263 __dlist_entry_t
* one
;
264 dns_reply
*Ret
= NULL
;
265 dns_reply
*reply
= NULL
;
270 one
= list
->get_head ();
275 reply
= (dns_reply
*) one
->data
;
276 if (reply
->dr_type
== dr_type
&& reply
->dr_class
== dr_class
) {