chiark / gitweb /
WIP DNS bugfixes and debugging
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 1 Aug 2011 13:37:27 +0000 (14:37 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 27 Aug 2011 15:44:05 +0000 (16:44 +0100)
dns-bitenc-test.c
dns-transp-common.c
dns-transp-common.h

index 19536ac1aab55676b3fa6fdf0e3e6750a55ea5a1..972542c73883e756e2a5f9d1220ea484529abc59 100644 (file)
@@ -4,22 +4,20 @@
 
 #include "dns-transp-common.h"
 
-#include <stdio.h>
-#include <inttypes.h>
 
 #define NMYLABELS 3
 static const char *const mylabels[NMYLABELS]={"z","example","com"};
-static const char prefix[]="PREFIX ";
-static const char suffix[]=" SUFFIX";
+static const char prefix[6]="PREFIX";
+static const char suffix[6]="SUFFIX";
 static uint8_t packet[100];
 
 static struct dnsdomainenc enc;
 static struct dnsdomaindec dec;
 
 int main(int argc, const char **argv) {
+    const char **argv_save=argv;
     dnsdomaindec_globalinit();
 
-    const char **argv_save=argv;
     memcpy(packet+sizeof(packet)-sizeof(suffix), suffix, sizeof(suffix));
     dnsdomainenc_start(&enc, packet+sizeof(prefix),
                       sizeof(packet)-sizeof(prefix)-sizeof(suffix),
@@ -47,15 +45,14 @@ int main(int argc, const char **argv) {
     uint8_t *pktbegin=encoded-sizeof(prefix);
     memcpy(pktbegin,prefix,sizeof(prefix));
 
-    const uint8_t *pr;
-    for (pr=pktbegin; pr<packet+sizeof(packet); pr++)
-       printf(" %02x",*pr);
-    printf("\n");
+    FILE *hexdump=popen("hexdump -C","w");  assert(hexdump);
+    fwrite(pktbegin,1,packet+sizeof(packet)-pktbegin,hexdump);
+    int r=pclose(hexdump);  assert(!r);
 
     const uint8_t *domainend;
-    int r=dnsdomaindec_start(&dec, pktbegin, packet+sizeof(packet),
-                            pktbegin+sizeof(prefix), NMYLABELS,mylabels,
-                            &domainend);
+    r=dnsdomaindec_start(&dec, pktbegin, packet+sizeof(packet),
+                        pktbegin+sizeof(prefix), NMYLABELS,mylabels,
+                        &domainend);
     if (r) {
        printf("DEC ERROR %d\n",r);
        return 0;
@@ -72,11 +69,14 @@ int main(int argc, const char **argv) {
            uint32_t val=dnsdomaindec_getu32(&dec);
            printf("w 0x%"PRIx32, val);
        } else if (!strcmp(arg,"r")) {
+           ++argv;
            uint8_t rbuf[MAX_DOMAIN_BYTES];
            int l=dnsdomaindec_restbytes(&dec,rbuf);
-           printf("r %.*s",l,rbuf);
+           printf("r \"%.*s\"\n",l,rbuf);
+           break;
        } else {
            abort();
        }
     }
+    return 0;
 }
index 55b14c8ec904b9c1c193009a51066350199ed9f4..eb7d7cbc4c8a636f0f807e416b327407b9d77ced 100644 (file)
@@ -6,6 +6,13 @@
 
 static const char out_table[32]="0123456789abcdefghijklmnopqrstuv";
 
+static void dump_enc(struct dnsdomainenc *be, const char *what) {
+    printf("ENC p=%08"PRIx32"/%-2d o=[%d]|%02x %s\n",
+          be->pending, be->npending,
+          (int)(be->out - be->bufstop), *be->out,
+          what);
+}
+
 static inline int enoughinput(struct dnsdomainenc *be) {
     return be->npending >= 5;
 }
@@ -17,10 +24,13 @@ static inline void outputchar(struct dnsdomainenc *be) {
     if (!be->labremain) {
        *--(be->out) = 63;
        startlabel(be);
+       dump_enc(be,"outputchar labelfull");
     }
     *--(be->out) = out_table[be->pending & 0x1f];
+    be->labremain--;
     be->pending >>= 5;
     be->npending -= 5;
+    dump_enc(be,"outputchar");
 }
 
 int dnsdomainenc_start(struct dnsdomainenc *be, uint8_t *buf, int buflen,
@@ -31,6 +41,7 @@ int dnsdomainenc_start(struct dnsdomainenc *be, uint8_t *buf, int buflen,
     be->npending=0;
     be->bufstop=buf+1;
     be->out=buf+buflen;
+    *--be->out=0;
     for (i=mydompathlen-1; i>=0; i--) {
        const char *lab=mydompath[i];
        int ll=strlen(lab);
@@ -38,9 +49,11 @@ int dnsdomainenc_start(struct dnsdomainenc *be, uint8_t *buf, int buflen,
        if (be->out <= be->bufstop+ll+1) return FAKERCODE_MYDOMAINTOOLONG;
        be->out -= ll;
        memcpy(be->out, lab, ll);
-       *be->out -= ll;
+       *--be->out = ll;
+       dump_enc(be,"start mydompath");
     }
     startlabel(be);
+    dump_enc(be,"start");
     return 0;
 }
 
@@ -49,10 +62,12 @@ void dnsdomainenc_addbits(struct dnsdomainenc *be, uint32_t val, int nbits) {
     assert(!(val & ~(((uint32_t)1 << nbits)-1)));
     be->pending |= val << be->npending;
     be->npending += nbits;
+    dump_enc(be,"addbits 1");
     while (enoughinput(be)) {
        assert(be->out > be->bufstop);
        outputchar(be);
     }
+    dump_enc(be,"addbits 2");
 }
 
 void dnsdomainenc_addu32(struct dnsdomainenc *be, uint32_t val) {
@@ -64,22 +79,29 @@ int dnsdomainenc_restbytes(struct dnsdomainenc *be,
                           const uint8_t *bytes, int avail) {
     for (;;) {
        if (be->out == be->bufstop) {
+           dump_enc(be,"restbytes bufstop");
            return avail + ((be->npending + 7) / 8);
        }
        if (be->npending<5) {
            if (avail) {
                be->pending |= (*bytes++) << be->npending;
                be->npending += 8;
+               avail--;
+               dump_enc(be,"restbytes moreavail");
            } else if (be->npending <= 0) {
+               dump_enc(be,"restbytes nopending");
                return 0;
            }
-       }       
+       }
        outputchar(be);
+       dump_enc(be,"restbytes outputchar");
     }
 }
 
 uint8_t *dnsdomainenc_getresult(struct dnsdomainenc *be) {
-    *--(be->out) = 63 - be->labremain; /* finish the last label */
+    if (be->labremain != 63)
+       *--(be->out) = 63 - be->labremain; /* finish the last label */
+    dump_enc(be,"getresult");
     return be->out;
 }
 
@@ -97,6 +119,14 @@ void dnsdomaindec_globalinit(void) {
 }
 
 
+static void dump_dec(struct dnsdomaindec *bd, const char *what) {
+    int remain=bd->in - bd->databuf;
+    printf("DEC4 i=[%d]|%02x p=%08"PRIx32"/%-2d %s\n",
+          remain, remain ? *(bd->in-1) : 0,
+          bd->pending, bd->npending,
+          what);
+}
+
 struct labelinpacket {
     const uint8_t *bytes;
     int len;
@@ -122,6 +152,8 @@ int dnsdomaindec_start(struct dnsdomaindec *bd, const uint8_t *packet,
     for (;;) {
        if (domain==endpacket)
            return RCODE_FORMERR;
+       printf("DEC1 dom=|%d|%02x[%d]\n", domain-packet,
+              *domain, endpacket-domain);
        unsigned b=*domain++;
        if (!b) {
            totallen++;
@@ -150,6 +182,8 @@ int dnsdomaindec_start(struct dnsdomaindec *bd, const uint8_t *packet,
            return RCODE_FORMERR;
        labels[nlabels].bytes=domain;
        labels[nlabels].len=b;
+       printf("DEC1 labels[%d]=%.*s\n", nlabels,
+              labels[nlabels].len, labels[nlabels].bytes);
        nlabels++;
        domain += b;
     }
@@ -157,22 +191,28 @@ int dnsdomaindec_start(struct dnsdomaindec *bd, const uint8_t *packet,
        return FAKERCODE_NOTAUTH;
     for (i=0; i<mydompathlen; i++) {
        int l=strlen(mydompath[i]);
-       const struct labelinpacket *got=&labels[nlabels-mydompathlen];
+       const struct labelinpacket *got=&labels[nlabels-mydompathlen+i];
+       printf("DEC2 [%d] %s ?= %.*s\n", i, mydompath[i],
+              got->len, got->bytes);
        if (got->len != l || memcmp(got->bytes, mydompath[i], l))
            return FAKERCODE_NOTAUTH;
     }
     /* OK, it's our domain and it has some data and a good
      * number of labels.  Wow. */
     uint8_t *copyto=bd->databuf;
-    for (i=0; i<nlabels-mydompathlen; i++) {
+    printf("DEC3");
+    for (i=nlabels-mydompathlen-1; i>=0; i--) {
        const uint8_t *p=labels[i].bytes;
        for (j=0; j<labels[i].len; j++) {
            int val=in_table[*p++];
            if (val & 0x80)
                return RCODE_NXDOMAIN;
+           printf(" %02x",val);
            *copyto++=val;
        }
+       printf(" .");
     }
+    printf("\n");
     assert(copyto <= bd->databuf+sizeof(bd->databuf));
     bd->in=copyto;
     return 0;
@@ -180,10 +220,12 @@ int dnsdomaindec_start(struct dnsdomaindec *bd, const uint8_t *packet,
 
 static void inputchar(struct dnsdomaindec *bd) {
     /* must be enough input and enough space in pending */
+    dump_dec(bd,"inputchar 1");
     int ch=*--(bd->in);
     bd->pending <<= 8;
     bd->pending |= ch; /* already decoded */
     bd->npending += 5;
+    dump_dec(bd,"inputchar 2");
 }
 uint32_t dnsdomaindec_getbits(struct dnsdomaindec *bd, int nbits)
 {
index b4b718aeb623f681ca040ce673c4d37533fe0552..53f6a73f0849c0f7e691640f00b5b0dce544fa0a 100644 (file)
@@ -21,6 +21,8 @@
 #include <string.h>
 #include <assert.h>
 #include <ctype.h>
+#include <stdio.h>
+#include <inttypes.h>
 
 
 void dnsdomaindec_globalinit(void);