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
--- /dev/null
+; 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
--- /dev/null
+/*
+ * 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 <config.h>
+#include <ldns/ldns.h>
+#include <ldns/str2host.h>
+#include <ldns/host2str.h>
+#include <ldns/buffer.h>
+
+#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<len; i++) {
+ c = hexstr[i];
+
+ /* case insensitive, skip spaces */
+ if (c != ' ') {
+ if (c >= '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;
+}
+