From: Jelte Jansen Date: Fri, 24 Dec 2004 11:34:38 +0000 (+0000) Subject: added new test that reads packet from drill-formatted hexdump X-Git-Tag: release-0.50~588 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=71dbbb8a0ede33878dadcab5fb6bce0d9fe85783;p=thirdparty%2Fldns.git added new test that reads packet from drill-formatted hexdump (which can be created with drill -w ), for wire2host and host2str testing) added example hexdump packet (which is read if no filename is given) fixed bug when reading bad rcode --- diff --git a/Makefile.in b/Makefile.in index 41fa9c67..0e279619 100644 --- a/Makefile.in +++ b/Makefile.in @@ -34,7 +34,7 @@ LIBDNS_HEADERS = ldns/error.h \ util.h LIBDNS_OBJECTS = $(LIBDNS_SOURCES:.c=.o) -ALL_SOURCES = run-test0.c run-test1.c $(LIBDNS_SOURCES) +ALL_SOURCES = run-test0.c run-test1.c run-test2.c $(LIBDNS_SOURCES) COMPILE = $(CC) $(CPPFLAGS) $(CFLAGS) LINK = $(CC) $(CFLAGS) $(LDFLAGS) @@ -44,7 +44,7 @@ LINK = $(CC) $(CFLAGS) $(LDFLAGS) .PHONY: clean realclean docclean doc lint -all: run-test0 run-test1 +all: run-test0 run-test1 run-test2 run-test0: run-test0.o $(LIBDNS_OBJECTS) $(LIBOBJS) $(LINK) -o $@ $+ @@ -52,12 +52,17 @@ run-test0: run-test0.o $(LIBDNS_OBJECTS) $(LIBOBJS) run-test1: run-test1.o $(LIBDNS_OBJECTS) $(LIBOBJS) $(LINK) -o $@ $+ +run-test2: run-test2.o $(LIBDNS_OBJECTS) $(LIBOBJS) + $(LINK) -o $@ $+ + doc: doxygen libdns.doxygen clean: rm -f *.o *.d rm -f run-test0 + rm -f run-test1 + rm -f run-test2 rm -rf autom4te.cache/ rm -f aclocal.m4 @@ -78,7 +83,10 @@ test0: run-test0 test1: run-test1 ./run-test1 -test: test0 test1 +test2: run-test2 + ./run-test2 + +test: test0 test1 test2 lint: for i in $(ALL_SOURCES); do \ diff --git a/host2str.c b/host2str.c index 9163d2ca..8c207d5e 100644 --- a/host2str.c +++ b/host2str.c @@ -326,15 +326,28 @@ ldns_status ldns_pktheader2buffer(ldns_buffer *output, ldns_pkt *pkt) { /* TODO: strings for known names instead of numbers, flags etc */ + const char *opcode_str, *rcode_str; + ldns_lookup_table *opcode = ldns_lookup_by_id(ldns_opcodes, + (int) ldns_pkt_opcode(pkt)); + ldns_lookup_table *rcode = ldns_lookup_by_id(ldns_rcodes, + (int) ldns_pkt_rcode(pkt)); + + if (opcode) { + opcode_str = opcode->name; + } else { + opcode_str = "??"; + } + if (rcode) { + rcode_str = rcode->name; + } else { + rcode_str = "??"; + } + if ( ldns_buffer_printf(output, ";; ->>HEADER<<- ") < 0 || - ldns_buffer_printf(output, "opcode: %s, ", - ldns_lookup_by_id(ldns_opcodes, - (int) ldns_pkt_opcode(pkt))->name + ldns_buffer_printf(output, "opcode: %s, ", opcode_str ) < 0 || - ldns_buffer_printf(output, "status: %s, ", - ldns_lookup_by_id(ldns_rcodes, - (int) ldns_pkt_rcode(pkt))->name + ldns_buffer_printf(output, "rcode: %s, ", rcode_str ) < 0 || ldns_buffer_printf(output, "id %lu\n", ldns_pkt_id(pkt)) < 0 || ldns_buffer_printf(output, ";; flags: ") < 0 diff --git a/packetdump.txt b/packetdump.txt new file mode 100644 index 00000000..75278c31 --- /dev/null +++ b/packetdump.txt @@ -0,0 +1,14 @@ +; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 +;-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + 18 c4 81 80 00 01 00 01 00 02 00 02 03 77 77 77 0b 6b 61 6e ; 0- 19 + 61 72 69 65 70 69 65 74 03 63 6f 6d 00 00 01 00 01 03 77 77 ; 20- 39 + 77 0b 6b 61 6e 61 72 69 65 70 69 65 74 03 63 6f 6d 00 00 01 ; 40- 59 + 00 01 00 01 44 0a 00 04 d5 85 27 cf 0b 6b 61 6e 61 72 69 65 ; 60- 79 + 70 69 65 74 03 63 6f 6d 00 00 02 00 01 00 01 44 0a 00 11 03 ; 80- 99 + 6e 73 32 08 68 65 78 6f 6e 2d 69 73 02 6e 6c 00 0b 6b 61 6e ; 100-119 + 61 72 69 65 70 69 65 74 03 63 6f 6d 00 00 02 00 01 00 01 44 ; 120-139 + 0a 00 11 03 6e 73 31 08 68 65 78 6f 6e 2d 69 73 02 6e 6c 00 ; 140-159 + 03 6e 73 31 08 68 65 78 6f 6e 2d 69 73 02 6e 6c 00 00 01 00 ; 160-179 + 01 00 00 5d 8c 00 04 d5 85 27 cb 03 6e 73 32 08 68 65 78 6f ; 180-199 + 6e 2d 69 73 02 6e 6c 00 00 01 00 01 00 00 5d 8c 00 04 d4 cc ; 200-219 + db 5b ; 220-221 diff --git a/run-test2.c b/run-test2.c new file mode 100644 index 00000000..683a5c97 --- /dev/null +++ b/run-test2.c @@ -0,0 +1,196 @@ +/* + * test2, read hexdump of file and print query + * + * reading code taken from drill, maybe put it in the library? + * (rewritten cleanly of course, and with error checking) + */ + +#include +#include +#include +#include +#include + +#include "util.h" + +#define MAX_PACKET 1000 + +/** + * Converts a hex string to binary data + * len is the length of the string + * buf is the buffer to store the result in + * offset is the starting position in the result buffer + * + * This function returns the length of the result + */ +size_t +hexstr2bin(char *hexstr, int len, uint8_t *buf, size_t offset) +{ + char c; + int i; + uint8_t int8 = 0; + int sec = 0; + size_t bufpos = 0; + + if (len % 2 != 0) { + return 0; + } + + for (i=0; i= '0' && c <= '9') { + int8 += c & 0x0f; + } else if (c >= 'a' && c <= 'z') { + int8 += (c & 0x0f) + 9; + } else if (c >= 'A' && c <= 'Z') { + int8 += (c & 0x0f) + 9; + } else { + printf("Error in reading hex data: \n"); + printf("%s ('%c' at %d, should read %d bytes)\n", hexstr, c, i, len); + return 0; + } + + if (sec == 0) { + int8 = int8 << 4; + sec = 1; + } else { + + buf[bufpos+offset] = int8; + int8 = 0; + sec = 0; + bufpos++; + } + } + + } + return bufpos; +} + + +ldns_pkt * +file2pkt(const char *filename) +{ + ldns_pkt *pkt; + FILE *fp = NULL; + char c; + ldns_status status; + + /* stat hack + * 0 = normal + * 1 = comment (skip to end of line) + * 2 = unprintable character found, read binary data directly + */ + int state = 0; + uint8_t *hexbuf = XMALLOC(uint8_t, MAX_PACKET); + int hexbufpos = 0; + size_t wirelen; + uint8_t *wire = XMALLOC(uint8_t, MAX_PACKET); + + if (strncmp(filename, "-", 2) == 0) { + fp = stdin; + } else { + fp = fopen(filename, "r"); + } + if (fp == NULL) { + printf("Unable to open file for reading: %s\n", filename); + return NULL; + } + + printf("Opened %s\n", filename); + + c = fgetc(fp); + while (c != EOF && hexbufpos < MAX_PACKET) { + if (state < 2 && !isascii(c)) { + printf("non ascii character found in file: (%d) switching to raw mode\n", c); + state = 2; + } + switch (state) { + case 0: + if ( (c >= '0' && c <= '9') || + (c >= 'a' && c <= 'f') || + (c >= 'A' && c <= 'F') ) + { + hexbuf[hexbufpos] = (uint8_t) c; + hexbufpos++; + } else if (c == ';') { + state = 1; + } else if (c == ' ' || c == '\t' || c == '\n') { + /* skip whitespace */ + } + break; + case 1: + if (c == '\n' || c == EOF) { + state = 0; + } + break; + case 2: + hexbuf[hexbufpos] = (uint8_t) c; + hexbufpos++; + break; + default: + printf("unknown state while reading file\n"); + return NULL; + break; + } + c = fgetc(fp); + } + if (c == EOF) { + if (state < 2) { + printf("read:\n"); + printf("%s\n", (char *)hexbuf); + } else { + printf("Not printing wire because it contains non ascii data\n"); + } + } + if (hexbufpos >= MAX_PACKET) { + printf("packet size reached\n"); + } + + /* lenient mode: length must be multiple of 2 */ + if (hexbufpos % 2 != 0) { + hexbuf[hexbufpos] = (uint8_t) '0'; + hexbufpos++; + } + + if (state < 2) { + wirelen = hexstr2bin((char *) hexbuf, hexbufpos, wire, 0); + } else { + memcpy(wire, hexbuf, (size_t) hexbufpos); + wirelen = (size_t) hexbufpos; + } + + status = ldns_wire2pkt(&pkt, wire, wirelen); + + if (status == LDNS_STATUS_OK) { + return pkt; + } else { + printf("error in wire2pkt: %d\n", status); + return NULL; + } +} + + +int +main(int argc, char **argv) +{ + const char *file; + ldns_pkt *pkt; + if (argc == 2) { + file = argv[1]; + } else { + file = "packetdump.txt"; + } + + pkt = file2pkt(file); + if (pkt) { + printf("packet:\n"); + printf("%s", ldns_pkt2str(pkt)); + } else { + printf("\n"); + } + return 0; +} +