chiark / gitweb /
Middle of parsing incoming datagrams.
[adns.git] / src / reply.c
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 }