From: Ian Jackson Date: Mon, 1 Aug 2011 13:37:27 +0000 (+0100) Subject: WIP DNS bugfixes and debugging X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?a=commitdiff_plain;h=66c640de61960b073eac43639365c2924852f091;p=secnet.git WIP DNS bugfixes and debugging --- diff --git a/dns-bitenc-test.c b/dns-bitenc-test.c index 19536ac..972542c 100644 --- a/dns-bitenc-test.c +++ b/dns-bitenc-test.c @@ -4,22 +4,20 @@ #include "dns-transp-common.h" -#include -#include #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; prpending, 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; ilen, 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=0; i--) { const uint8_t *p=labels[i].bytes; for (j=0; jdatabuf+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) { diff --git a/dns-transp-common.h b/dns-transp-common.h index b4b718a..53f6a73 100644 --- a/dns-transp-common.h +++ b/dns-transp-common.h @@ -21,6 +21,8 @@ #include #include #include +#include +#include void dnsdomaindec_globalinit(void);