/* Read RR's in getdns wire format and print them in presentation format. */ #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 #define CHUNKSIZE 4096 static size_t read_inbuf(FILE *infp, uint8_t **bufp_out) { size_t nread = 0; uint8_t *wirebuf = malloc(CHUNKSIZE); int chunks = 1; if (wirebuf == NULL) goto out; while (1) { size_t n = fread(wirebuf + nread, 1, CHUNKSIZE, infp); nread += n; if (n < CHUNKSIZE) break; /* Done. */ wirebuf = realloc(wirebuf, ++chunks * CHUNKSIZE); if (wirebuf == NULL) break; } out: if (bufp_out != NULL) *bufp_out = wirebuf; return nread; } static getdns_return_t wire_rrs2list(const uint8_t *buf, size_t buf_len, getdns_list **list_out) { getdns_return_t r = GETDNS_RETURN_GOOD; getdns_list *list = getdns_list_create(); getdns_dict *dict = NULL; size_t rr_count = 0; if (list == NULL) return GETDNS_RETURN_MEMORY_ERROR; while (buf_len > 0) { r = getdns_wire2rr_dict_scan(&buf, &buf_len, &dict); if (r) break; r = getdns_list_set_dict(list, rr_count, dict); getdns_dict_destroy(dict); /* The list has a copy. */ if (r) break; rr_count++; } if (list_out) *list_out = list; return r; } int main(int argc, char *argv[]) { /* Read from file in argv[1] or from stdin. */ FILE *infp = stdin; if (argc > 1) { infp = fopen(argv[1], "r"); if (infp == NULL) { perror("fopen(argv[1])"); return errno; } } /* Read RRs in wire format. */ uint8_t *inbuf = NULL; size_t 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); /* DEBUG */ /* Convert to getdns dicts in a getdns list. */ getdns_return_t r = 0; getdns_list *rrs_list = NULL; r = wire_rrs2list(inbuf, inbuf_len, &rrs_list); free(inbuf); if (r) { fprintf(stderr, "error converting input: %s\n", getdns_get_errorstr_by_id(r)); getdns_list_destroy(rrs_list); return r; } /* Print dicts in list. */ size_t rrs_list_len; r = getdns_list_get_length(rrs_list, &rrs_list_len); if (r) { fprintf(stderr, "error getting list length: %s\n", getdns_get_errorstr_by_id(r)); return r; } for (size_t i = 0; i < rrs_list_len; i++) { char *stringbuf = NULL; getdns_dict *rr_dict = NULL; r = getdns_list_get_dict(rrs_list, i, &rr_dict); if (r) { fprintf(stderr, "error getting dict from list: %s\n", getdns_get_errorstr_by_id(r)); break; } r = getdns_rr_dict2str(rr_dict, &stringbuf); if (r) { fprintf(stderr, "error converting dict to string: %s\n", getdns_get_errorstr_by_id(r)); break; } printf("%s", stringbuf); free(stringbuf); } getdns_list_destroy(rrs_list); return r; }