Implement src/print.c to provide facilities for pretty printing packets to any FILE handle
127 lines
2.7 KiB
C
127 lines
2.7 KiB
C
#include <stdio.h>
|
|
#include <inttypes.h>
|
|
|
|
#include <patty/ax25.h>
|
|
#include <patty/print.h>
|
|
|
|
#define printable(c) \
|
|
(c >= 0x20 && c < 0x7f)
|
|
|
|
int patty_print_hexdump(FILE *fh, void *data, size_t len) {
|
|
size_t i;
|
|
|
|
for (i=0; i<len; i+=16) {
|
|
size_t x;
|
|
|
|
if (fprintf(fh, "%08lx:", i) < 0) {
|
|
goto error_io;
|
|
}
|
|
|
|
for (x=0; x<16; x++) {
|
|
if (!(x & 1)) {
|
|
if (fprintf(fh, " ") < 0) {
|
|
goto error_io;
|
|
}
|
|
}
|
|
|
|
if (i+x < len) {
|
|
if (fprintf(fh, "%02x", ((uint8_t *)data)[i+x]) < 0) {
|
|
goto error_io;
|
|
}
|
|
} else {
|
|
if (fprintf(fh, " ") < 0) {
|
|
goto error_io;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (fprintf(fh, " ") < 0) {
|
|
goto error_io;
|
|
}
|
|
|
|
for (x=0; x<16 && i+x<len; x++) {
|
|
uint8_t c = ((uint8_t *)data)[i+x];
|
|
|
|
if (fputc(printable(c)? c: '.', fh) < 0) {
|
|
goto error_io;
|
|
}
|
|
}
|
|
|
|
if (fprintf(fh, "\n") < 0) {
|
|
goto error_io;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
|
|
error_io:
|
|
return -1;
|
|
}
|
|
|
|
static int print_addr(FILE *fh, const patty_ax25_addr *addr) {
|
|
char buf[7];
|
|
uint8_t ssid;
|
|
|
|
if (patty_ax25_ntop(addr, buf, &ssid, sizeof(buf)) < 0) {
|
|
goto error_ntop;
|
|
}
|
|
|
|
fprintf(fh, "%s", buf);
|
|
|
|
if (ssid) {
|
|
fprintf(fh, "/%d", ssid);
|
|
}
|
|
|
|
return 0;
|
|
|
|
error_ntop:
|
|
return -1;
|
|
}
|
|
|
|
static int print_frame_addrs(FILE *fh, const patty_ax25_frame *frame) {
|
|
int i;
|
|
|
|
print_addr(fh, &frame->src);
|
|
|
|
fprintf(fh, " > ");
|
|
|
|
for (i=0; i<frame->hops; i++) {
|
|
print_addr(fh, &frame->repeaters[i]);
|
|
fprintf(fh, " > ");
|
|
}
|
|
|
|
print_addr(fh, &frame->dest);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int patty_print_frame(FILE *fh,
|
|
const patty_ax25_frame *frame,
|
|
void *buf,
|
|
size_t len) {
|
|
if (print_frame_addrs(fh, frame) < 0) {
|
|
goto error_io;
|
|
}
|
|
|
|
if (PATTY_AX25_CONTROL_INFO(frame->control)) {
|
|
if (fprintf(fh, " type I poll %d ns %d nr %d info %zu bytes",
|
|
PATTY_AX25_CONTROL_POLL(frame->control),
|
|
PATTY_AX25_CONTROL_SEQ_SEND(frame->control),
|
|
PATTY_AX25_CONTROL_SEQ_RECV(frame->control),
|
|
frame->infolen) < 0) {
|
|
goto error_io;
|
|
}
|
|
} else if (PATTY_AX25_CONTROL_UNNUMBERED(frame->control)) {
|
|
if (fprintf(fh, " type U info %zu bytes",
|
|
frame->infolen) < 0) {
|
|
goto error_io;
|
|
}
|
|
}
|
|
|
|
fprintf(fh, "\n");
|
|
|
|
return patty_print_hexdump(fh, buf, len);
|
|
|
|
error_io:
|
|
return -1;
|
|
}
|