void log_memdump_ex(logger_handle* hndl, u32 level, const void* data_pointer_, size_t size_, size_t line_size, bool hex, bool text, bool address) { if((hndl == NULL) || (level >= MSG_LEVEL_COUNT) || (hndl->channels[level].offset < 0)) { return; } output_stream os; char buffer[4096]; bytearray_output_stream_init((u8*)buffer, sizeof (buffer), &os); u8* data_pointer = (u8*)data_pointer_; s32 size = size_; int dump_size; int i; do { dump_size = MIN(line_size, size); u8* data; if(address) { osformat(&os, "%p ", data_pointer); } if(hex) { data = data_pointer; for(i = 0; i < dump_size; i++) { osformat(&os, "%02x", *data++); if((i & 3) == 3) { output_stream_write_u8(&os, (u8)' '); } } for(; i < line_size; i++) { osprint(&os, " "); if((i & 3) == 0) { osprint(&os, " "); } } } if(hex & text) { output_stream_write(&os, (u8*)" | ", 3); } if(text) { data = data_pointer; for(i = 0; i < dump_size; i++) { char c = *data++; if(c < ' ') { c = '.'; } else if(c == '%') { output_stream_write_u8(&os, '%'); } output_stream_write_u8(&os, (u8)c); } } data_pointer += dump_size; size -= dump_size; if(size != 0) { output_stream_write_u8(&os, 0); logger_handle_msg(hndl, level, "%s", bytearray_output_stream_buffer(&os)); bytearray_output_stream_reset(&os); } } while(size > 0); //if(size_ > line_size) if(bytearray_output_stream_size(&os) > 0) { output_stream_write_u8(&os, 0); logger_handle_msg(hndl, level, "%s", bytearray_output_stream_buffer(&os)); } output_stream_close(&os); }
static void message_viewer_wire_header(message_viewer *mv, const u8 *buffer) { /* 1. get the output stream */ output_stream *os = mv->os; /* 2. get values of the different sections: QUESTION, ANSWER, AUTHORITY and ADDITIONAL */ u16 count[4]; count[0] = ntohs(MESSAGE_QD(buffer)); count[1] = ntohs(MESSAGE_AN(buffer)); count[2] = ntohs(MESSAGE_NS(buffer)); count[3] = ntohs(MESSAGE_AR(buffer)); /* 3. add the amount of section resource records into a total */ message_viewer_resource_record_total_update(mv, count); /* 4. get message id */ u16 id = MESSAGE_ID(buffer); /* 5. get opcode and rcode. * opcode is needed for for knowing the difference between a regular message and a update message */ u8 opcode = MESSAGE_OP(buffer); opcode >>= OPCODE_SHIFT; u8 rcode = MESSAGE_RCODE(buffer); const char *opcode_txt = get_opcode(opcode); const char *status_txt = get_rcode(rcode); mv->section_name = (opcode != OPCODE_UPDATE)? message_section_names : message_section_update_names; /* if no view with header then inmediately return, * wire axfr has no header information so --> return */ if(mv->view_mode_with & VM_WITH_XFR) { return; } /* 6. we have all the information, fill the stream */ osformat(os, ";; Got answer:\n"); osformat(os, ";; ->>HEADER<<- opcode: %s, status: %s, id: %hd\n", opcode_txt, status_txt, id); osformat(os, ";; flags: "); if(MESSAGE_QR(buffer) != 0) osprint(os, "qr "); if(MESSAGE_AA(buffer) != 0) osprint(os, "aa "); if(MESSAGE_TC(buffer) != 0) osprint(os, "tc "); if(MESSAGE_RD(buffer) != 0) osprint(os, "rd "); if(MESSAGE_RA(buffer) != 0) osprint(os, "ra "); if(MESSAGE_ZF(buffer) != 0) osprint(os, "zf "); if(MESSAGE_AD(buffer) != 0) osprint(os, "ad "); if(MESSAGE_CD(buffer) != 0) osprint(os, "cd "); /* 3. get the names for the presentation */ char **count_name; count_name = (opcode != OPCODE_UPDATE)? message_count_names : message_count_update_names; osformat(os, "%s: %hd, %s: %hd, %s: %hd, %s: %hd\n", count_name[0], count[0], count_name[1], count[1], count_name[2], count[2], count_name[3], count[3] ); }