/* Read RR's in getdns wire format and print them in presentation format on stdout. */ #include #include #include #include #include #include #undef DEBUG #if defined(DEBUG) static void hd(const char *buf, size_t buf_len) { for (size_t n = 0; n < buf_len; n++) { if (n % 16 == 0) { if (n != 0) fprintf(stderr, "\n"); fprintf(stderr, "%08x ", n); } else if (n % 8 == 0) fprintf(stderr, " "); fprintf(stderr, "%02hhx ", buf[n]); } fprintf(stderr, "\n"); } #else /* !DEBUG */ #define hd(a,b) #endif /* Return value: <0 -- error, the return value being -errorcode 0 -- done >0 -- not done yet, call me again */ static int read_rr(const uint8_t **buf, size_t *buf_len, getdns_dict **rr_dict) { getdns_return_t r = getdns_wire2rr_dict_scan(buf, buf_len, rr_dict); if (r) return -r; return *buf_len; } #define INBUFLEN 4096 static size_t read_inbuf(FILE *infp, uint8_t **bufp_out) { size_t nread = 0; uint8_t *wirebuf = malloc(INBUFLEN); int chunks = 1; if (wirebuf == NULL) goto out; while (1) { size_t n = fread(wirebuf + nread, 1, INBUFLEN, infp); nread += n; if (n < INBUFLEN) break; /* Done. */ wirebuf = realloc(wirebuf, ++chunks * INBUFLEN); if (wirebuf == NULL) break; } out: if (bufp_out != NULL) *bufp_out = wirebuf; return nread; } int main(int argc, char *argv[]) { int rrv = 0; uint8_t *inbuf = NULL; const uint8_t *bufp = NULL; size_t inbuf_len = 0; getdns_dict *rr_dict = NULL; getdns_return_t r = 0; FILE *infp = stdin; if (argc > 1) { infp = fopen(argv[1], "r"); if (infp == NULL) { perror("fopen(argv[1])"); return -errno; } } inbuf_len = read_inbuf(infp, &inbuf); if (inbuf == NULL) { perror("read_inbuf"); return -errno; } if (infp != stdin) if (fclose(infp)) perror("fclose"); hd((const char *) wirebuf, n); bufp = inbuf; while (1) { char *stringbuf = NULL; rrv = read_rr(&bufp, &inbuf_len, &rr_dict); if (rrv < 0) break; r = getdns_rr_dict2str(rr_dict, &stringbuf); if (r) break; getdns_dict_destroy(rr_dict); printf("%s", stringbuf); free(stringbuf); if (rrv == 0) break; /* Done. */ } free(inbuf); if (rrv < 0) { fprintf(stderr, "parsing input failed: %s\n", getdns_get_errorstr_by_id(-rrv)); return rrv; } if (r) { fprintf(stderr, "converting dict to string failed: %s\n", getdns_get_errorstr_by_id(r)); return -r; } return 0; }