#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),
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;
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;
}
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;
}
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,
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);
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;
}
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) {
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;
}
}
+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;
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++;
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;
}
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;
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)
{