4353a5c4 |
1 | /**/ |
2 | |
3 | #include "internal.h" |
4 | |
ec477b9e |
5 | typedef enum { |
6 | rcode_noerror, |
7 | rcode_formaterror, |
8 | rcode_serverfail, |
9 | rcode_nxdomain, |
10 | rcode_notimp, |
11 | rcode_refused |
12 | } dns_rcode; |
13 | |
4353a5c4 |
14 | void adns__procdgram(adns_state ads, const byte *dgram, int len, int serv) { |
ec477b9e |
15 | unsigned char *rpp; |
16 | |
17 | if (len<12) { |
18 | adns__diag(ads,serv,"received datagram too short for message header (%d)",len); |
19 | return; |
20 | } |
21 | id= GFREPLYW; |
22 | f1= GFREPLYB; |
23 | f2= GFREPLYB; |
24 | qdcount= GFREPLYW; |
25 | ancount= GFREPLYW; |
26 | nscount= GFREPLYW; |
27 | arcount= GFREPLYW; |
28 | |
29 | if (f1&0x80) { |
30 | adns__diag(ads,serv,"server sent us a query, not a response"); |
31 | return; |
32 | } |
33 | if (f1&0x70) { |
34 | adns__diag(ads,serv,"server sent us unknown opcode %d (wanted 0=QUERY)", |
35 | (f1>>4)&0x70); |
36 | return; |
37 | } |
38 | if (!qdcount) { |
39 | adns__diag(ads,serv,"server sent reply without quoting our question"); |
40 | return; |
41 | } else if (qdcount>1) { |
42 | adns__diag(ads,serv,"server claimed to answer %d questions with one message", |
43 | qdcount); |
44 | return; |
45 | } |
46 | for (qu= ads->timew; qu= nqu; qu++) { |
47 | nqu= qu->next; |
48 | if (qu->id != id) continue; |
49 | if (len < qu->querylen) continue; |
50 | if (memcmp(qu->querymsg+12,rpp,qu->querylen-12)) continue; |
51 | break; |
52 | } |
53 | if (!qu) { |
54 | adns__debug(ads,serv,"reply not found (id=%02x)",id); |
55 | return; |
56 | } |
57 | if (!(f2&0x80)) { |
58 | adns__diag(ads,serv,"server is not willing to do recursive lookups for us"); |
59 | adns__query_fail(ads,qu,adns_s_norecurse); |
60 | return; |
61 | } |
62 | if (!(f1&0x01)) { |
63 | adns__diag(ads,serv,"server thinks we didn't ask for recursive lookup"); |
64 | adns__query_fail(ads,qu,adns_s_serverfaulty); |
65 | return; |
66 | } |
67 | switch (f1&0x0f) { |
68 | case 0: /* NOERROR */ |
69 | break; |
70 | case 1: /* Format error */ |
71 | adns__diag(ads,serv,"server cannot understand our query (Format Error)"); |
72 | adns__query_fail(ads,qu,adns_s_serverfaulty); |
73 | return; |
74 | case 2: /* Server failure */ |
75 | adns__query_fail(ads,qu,adns_s_serverfailure); |
76 | return; |
77 | case 3: /* Name Error */ |
78 | |
79 | qr= f1&0x80; |
80 | |
81 | |
4353a5c4 |
82 | adns__diag(ads,serv,"received datagram size %d",len); |
ec477b9e |
83 | |
4353a5c4 |
84 | } |