| 1 | /**/ |
| 2 | |
| 3 | #include "internal.h" |
| 4 | |
| 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 | |
| 14 | void adns__procdgram(adns_state ads, const byte *dgram, int len, int serv) { |
| 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 | |
| 82 | adns__diag(ads,serv,"received datagram size %d",len); |
| 83 | |
| 84 | } |