Refactor parameter decoding/display
Changes: * Implement patty_ax25_params struct to contain all parameters supported by patty, at the interface and socket level alike * Move parameter enumerate types into include/patty/ax25.h, from include/patty/ax25/frame.h; make corrections as necessary * Reimplement patty_ax25_frame_decode_xid() to parse known XID information parameters into a patty_ax25_params object * Implement patty_print_params() in src/print.c * Refactor patty_print_frame() as patty_print_frame_header(), without a call to patty_print_hexdump(); this allows patty_print_params() to be called prior to patty_print_hexdump(), for better readability * Use patty_print_params() in examples/ax25dump.c, decode.c * Refactor usage of patty_ax25_frame_decode_xid() in src/server.c to parse XID frames into a patty_ax25_params object
This commit is contained in:
parent
a722b8f9b3
commit
1fbf09c9ba
8 changed files with 351 additions and 166 deletions
|
@ -92,28 +92,56 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((readlen = patty_kiss_tnc_recv(raw, buf, sizeof(buf), NULL)) > 0) {
|
while ((readlen = patty_kiss_tnc_recv(raw, buf, sizeof(buf), NULL)) > 0) {
|
||||||
|
ssize_t decoded,
|
||||||
|
offset = 0;
|
||||||
|
|
||||||
patty_ax25_frame frame;
|
patty_ax25_frame frame;
|
||||||
ssize_t decoded;
|
|
||||||
|
|
||||||
if ((decoded = patty_ax25_frame_decode_address(&frame, buf, readlen)) < 0) {
|
if ((decoded = patty_ax25_frame_decode_address(&frame, buf, readlen)) < 0) {
|
||||||
fprintf(stderr, "%s: %s: %s\n",
|
fprintf(stderr, "%s: %s: %s\n",
|
||||||
argv[0], "patty_ax25_frame_decode_address()", strerror(errno));
|
argv[0], "patty_ax25_frame_decode_address()", strerror(errno));
|
||||||
|
|
||||||
goto error_ax25_frame_decode_address;
|
goto error_ax25_frame_decode_address;
|
||||||
|
} else {
|
||||||
|
offset += decoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (patty_ax25_frame_decode_control(&frame, PATTY_AX25_FRAME_NORMAL, buf, decoded, readlen) < 0) {
|
if ((decoded = patty_ax25_frame_decode_control(&frame, PATTY_AX25_FRAME_NORMAL, buf, decoded, readlen)) < 0) {
|
||||||
fprintf(stderr, "%s: %s: %s\n",
|
fprintf(stderr, "%s: %s: %s\n",
|
||||||
argv[0], "patty_ax25_frame_decode_control()", strerror(errno));
|
argv[0], "patty_ax25_frame_decode_control()", strerror(errno));
|
||||||
|
|
||||||
goto error_ax25_frame_decode_control;
|
goto error_ax25_frame_decode_control;
|
||||||
|
} else {
|
||||||
|
offset += decoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (patty_print_frame(stdout, &frame, buf, readlen) < 0) {
|
if (patty_print_frame_header(stdout, &frame) < 0) {
|
||||||
fprintf(stderr, "%s: %s: %s\n",
|
fprintf(stderr, "%s: %s: %s\n",
|
||||||
argv[0], "patty_print_frame()", strerror(errno));
|
argv[0], "patty_print_frame_header()", strerror(errno));
|
||||||
|
|
||||||
goto error_print_frame;
|
goto error_print;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame.type == PATTY_AX25_FRAME_XID) {
|
||||||
|
patty_ax25_params params;
|
||||||
|
|
||||||
|
if (patty_ax25_frame_decode_xid(¶ms,
|
||||||
|
buf,
|
||||||
|
offset,
|
||||||
|
readlen) < 0) {
|
||||||
|
fprintf(stderr, "%s: %s: %s\n",
|
||||||
|
argv[0], "patty_ax25_frame_decode_xid()", strerror(errno));
|
||||||
|
|
||||||
|
goto error_ax25_frame_decode_xid;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (patty_print_params(stdout, ¶ms) < 0) {
|
||||||
|
goto error_print;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (patty_print_hexdump(stdout, buf, readlen) < 0) {
|
||||||
|
goto error_print;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,7 +153,8 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_print_frame:
|
error_print:
|
||||||
|
error_ax25_frame_decode_xid:
|
||||||
error_ax25_frame_decode_control:
|
error_ax25_frame_decode_control:
|
||||||
error_ax25_frame_decode_address:
|
error_ax25_frame_decode_address:
|
||||||
patty_kiss_tnc_destroy(raw);
|
patty_kiss_tnc_destroy(raw);
|
||||||
|
|
|
@ -50,7 +50,9 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
ssize_t len,
|
ssize_t len,
|
||||||
decoded;
|
decoded,
|
||||||
|
offset = 0;
|
||||||
|
|
||||||
patty_ax25_frame frame;
|
patty_ax25_frame frame;
|
||||||
|
|
||||||
if ((len = patty_kiss_tnc_recv(tnc, buf, PATTY_KISS_BUFSZ, &port)) < 0) {
|
if ((len = patty_kiss_tnc_recv(tnc, buf, PATTY_KISS_BUFSZ, &port)) < 0) {
|
||||||
|
@ -67,20 +69,46 @@ int main(int argc, char **argv) {
|
||||||
argv[0], "patty_ax25_frame_decode_address()", strerror(errno));
|
argv[0], "patty_ax25_frame_decode_address()", strerror(errno));
|
||||||
|
|
||||||
goto error_ax25_frame_decode_address;
|
goto error_ax25_frame_decode_address;
|
||||||
|
} else {
|
||||||
|
offset += decoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (patty_ax25_frame_decode_control(&frame, PATTY_AX25_FRAME_NORMAL, buf, decoded, len) < 0) {
|
if ((decoded = patty_ax25_frame_decode_control(&frame, PATTY_AX25_FRAME_NORMAL, buf, offset, len)) < 0) {
|
||||||
fprintf(stderr, "%s: %s: %s\n",
|
fprintf(stderr, "%s: %s: %s\n",
|
||||||
argv[0], "patty_ax25_frame_decode_control()", strerror(errno));
|
argv[0], "patty_ax25_frame_decode_control()", strerror(errno));
|
||||||
|
|
||||||
goto error_ax25_frame_decode_control;
|
goto error_ax25_frame_decode_control;
|
||||||
|
} else {
|
||||||
|
offset += decoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (patty_print_frame(stdout, &frame, buf, len) < 0) {
|
if (patty_print_frame_header(stdout, &frame) < 0) {
|
||||||
fprintf(stderr, "%s: %s: %s\n",
|
fprintf(stderr, "%s: %s: %s\n",
|
||||||
argv[0], "patty_print_frame()", strerror(errno));
|
argv[0], "patty_print_frame_header()", strerror(errno));
|
||||||
|
|
||||||
goto error_print_frame;
|
goto error_print;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame.type == PATTY_AX25_FRAME_XID) {
|
||||||
|
patty_ax25_params params;
|
||||||
|
|
||||||
|
if (patty_ax25_frame_decode_xid(¶ms,
|
||||||
|
buf,
|
||||||
|
offset,
|
||||||
|
len) < 0) {
|
||||||
|
fprintf(stderr, "%s: %s: %s\n",
|
||||||
|
argv[0], "patty_ax25_frame_decode_xid()", strerror(errno));
|
||||||
|
|
||||||
|
goto error_ax25_frame_decode_xid;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (patty_print_params(stdout, ¶ms) < 0) {
|
||||||
|
goto error_print;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (patty_print_hexdump(stdout, buf, len) < 0) {
|
||||||
|
goto error_print;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +118,8 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_print_frame:
|
error_print:
|
||||||
|
error_ax25_frame_decode_xid:
|
||||||
error_ax25_frame_decode_control:
|
error_ax25_frame_decode_control:
|
||||||
error_ax25_frame_decode_address:
|
error_ax25_frame_decode_address:
|
||||||
error_kiss_tnc_recv:
|
error_kiss_tnc_recv:
|
||||||
|
|
|
@ -48,6 +48,47 @@ typedef struct _patty_ax25_addr {
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
enum patty_ax25_param_type {
|
||||||
|
PATTY_AX25_PARAM_CLASSES = 2,
|
||||||
|
PATTY_AX25_PARAM_HDLC = 3,
|
||||||
|
PATTY_AX25_PARAM_INFO_TX = 5,
|
||||||
|
PATTY_AX25_PARAM_INFO_RX = 6,
|
||||||
|
PATTY_AX25_PARAM_WINDOW_TX = 7,
|
||||||
|
PATTY_AX25_PARAM_WINDOW_RX = 8,
|
||||||
|
PATTY_AX25_PARAM_ACK = 9,
|
||||||
|
PATTY_AX25_PARAM_RETRY = 10
|
||||||
|
};
|
||||||
|
|
||||||
|
enum patty_ax25_param_classes {
|
||||||
|
PATTY_AX25_PARAM_CLASSES_ABM = (1 << 0),
|
||||||
|
PATTY_AX25_PARAM_CLASSES_HALF_DUPLEX = (1 << 5),
|
||||||
|
PATTY_AX25_PARAM_CLASSES_FULL_DUPLEX = (1 << 6)
|
||||||
|
};
|
||||||
|
|
||||||
|
enum patty_ax25_param_hdlc {
|
||||||
|
PATTY_AX25_PARAM_HDLC_REJ = (1 << 1),
|
||||||
|
PATTY_AX25_PARAM_HDLC_SREJ = (1 << 2),
|
||||||
|
PATTY_AX25_PARAM_HDLC_XADDR = (1 << 8),
|
||||||
|
PATTY_AX25_PARAM_HDLC_MODULO_8 = (1 << 11),
|
||||||
|
PATTY_AX25_PARAM_HDLC_MODULO_128 = (1 << 12),
|
||||||
|
PATTY_AX25_PARAM_HDLC_TEST = (1 << 14),
|
||||||
|
PATTY_AX25_PARAM_HDLC_SYNC_TX = (1 << 18)
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _patty_ax25_params {
|
||||||
|
uint32_t found;
|
||||||
|
|
||||||
|
uint32_t classes,
|
||||||
|
hdlc;
|
||||||
|
|
||||||
|
size_t info_tx,
|
||||||
|
info_rx,
|
||||||
|
window_tx,
|
||||||
|
window_rx,
|
||||||
|
ack,
|
||||||
|
retry;
|
||||||
|
} patty_ax25_params;
|
||||||
|
|
||||||
typedef struct _patty_ax25_if patty_ax25_if;
|
typedef struct _patty_ax25_if patty_ax25_if;
|
||||||
|
|
||||||
#include <patty/ax25/frame.h>
|
#include <patty/ax25/frame.h>
|
||||||
|
|
|
@ -89,32 +89,6 @@ enum patty_ax25_frame_xid_group_type {
|
||||||
PATTY_AX25_FRAME_XID_GROUP_PARAMS = 0x80
|
PATTY_AX25_FRAME_XID_GROUP_PARAMS = 0x80
|
||||||
};
|
};
|
||||||
|
|
||||||
enum patty_ax25_frame_xid_param_type {
|
|
||||||
PATTY_AX25_FRAME_XID_PARAM_CLASS = 2,
|
|
||||||
PATTY_AX25_FRAME_XID_PARAM_HDLC = 3,
|
|
||||||
PATTY_AX25_FRAME_XID_PARAM_INFO_TX = 5,
|
|
||||||
PATTY_AX25_FRAME_XID_PARAM_INFO_RX = 6,
|
|
||||||
PATTY_AX25_FRAME_XID_PARAM_WINDOW_TX = 7,
|
|
||||||
PATTY_AX25_FRAME_XID_PARAM_WINDOW_RX = 8,
|
|
||||||
PATTY_AX25_FRAME_XID_PARAM_ACK = 9
|
|
||||||
};
|
|
||||||
|
|
||||||
enum patty_ax25_frame_xid_param_class_flags {
|
|
||||||
PATTY_AX25_FRAME_XID_PARAM_CLASS_ABM = (1 << 1),
|
|
||||||
PATTY_AX25_FRAME_XID_PARAM_CLASS_HALF_DUPLEX = (1 << 6),
|
|
||||||
PATTY_AX25_FRAME_XID_PARAM_CLASS_FULL_DUPLEX = (1 << 7)
|
|
||||||
};
|
|
||||||
|
|
||||||
enum patty_ax25_frame_xid_param_hdlc_flags {
|
|
||||||
PATTY_AX25_FRAME_XID_PARAM_HDLC_REJ = (1 << 1),
|
|
||||||
PATTY_AX25_FRAME_XID_PARAM_HDLC_SREJ = (1 << 2),
|
|
||||||
PATTY_AX25_FRAME_XID_PARAM_HDLC_XADDR = (1 << 8),
|
|
||||||
PATTY_AX25_FRAME_XID_PARAM_HDLC_MODULO_8 = (1 << 11),
|
|
||||||
PATTY_AX25_FRAME_XID_PARAM_HDLC_MODULO_128 = (1 << 12),
|
|
||||||
PATTY_AX25_FRAME_XID_PARAM_HDLC_TEST = (1 << 14),
|
|
||||||
PATTY_AX25_FRAME_XID_PARAM_HDLC_SYNC_TX = (1 << 18)
|
|
||||||
};
|
|
||||||
|
|
||||||
#pragma pack(push)
|
#pragma pack(push)
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
|
||||||
|
@ -131,10 +105,6 @@ typedef struct _patty_ax25_frame_xid_param {
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
typedef int (*patty_ax25_frame_xid_callback)(enum patty_ax25_frame_xid_param_type type,
|
|
||||||
uint32_t value,
|
|
||||||
void *ctx);
|
|
||||||
|
|
||||||
ssize_t patty_ax25_frame_decode_address(patty_ax25_frame *frame,
|
ssize_t patty_ax25_frame_decode_address(patty_ax25_frame *frame,
|
||||||
void *buf,
|
void *buf,
|
||||||
size_t len);
|
size_t len);
|
||||||
|
@ -145,11 +115,10 @@ ssize_t patty_ax25_frame_decode_control(patty_ax25_frame *frame,
|
||||||
size_t offset,
|
size_t offset,
|
||||||
size_t len);
|
size_t len);
|
||||||
|
|
||||||
ssize_t patty_ax25_frame_decode_xid(patty_ax25_frame_xid_callback callback,
|
ssize_t patty_ax25_frame_decode_xid(patty_ax25_params *params,
|
||||||
void *data,
|
void *data,
|
||||||
size_t offset,
|
size_t offset,
|
||||||
size_t len,
|
size_t len);
|
||||||
void *ctx);
|
|
||||||
|
|
||||||
ssize_t patty_ax25_frame_encode(patty_ax25_frame *frame,
|
ssize_t patty_ax25_frame_encode(patty_ax25_frame *frame,
|
||||||
enum patty_ax25_frame_format format,
|
enum patty_ax25_frame_format format,
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
#ifndef _PATTY_PRINT_H
|
#ifndef _PATTY_PRINT_H
|
||||||
#define _PATTY_PRINT_H
|
#define _PATTY_PRINT_H
|
||||||
|
|
||||||
|
int patty_print_frame_header(FILE *fh,
|
||||||
|
const patty_ax25_frame *frame);
|
||||||
|
|
||||||
|
int patty_print_params(FILE *fh,
|
||||||
|
const patty_ax25_params *params);
|
||||||
|
|
||||||
int patty_print_hexdump(FILE *fh, void *data, size_t len);
|
int patty_print_hexdump(FILE *fh, void *data, size_t len);
|
||||||
|
|
||||||
int patty_print_frame(FILE *fh,
|
|
||||||
const patty_ax25_frame *frame,
|
|
||||||
void *buf,
|
|
||||||
size_t len);
|
|
||||||
|
|
||||||
#endif /* _PATTY_PRINT_H */
|
#endif /* _PATTY_PRINT_H */
|
||||||
|
|
56
src/frame.c
56
src/frame.c
|
@ -271,11 +271,45 @@ error:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t decode_xid_group(patty_ax25_frame_xid_callback callback,
|
static void save_xid_param(patty_ax25_params *params,
|
||||||
|
enum patty_ax25_param_type type,
|
||||||
|
uint32_t value) {
|
||||||
|
switch (type) {
|
||||||
|
case PATTY_AX25_PARAM_CLASSES:
|
||||||
|
params->classes = value; break;
|
||||||
|
|
||||||
|
case PATTY_AX25_PARAM_HDLC:
|
||||||
|
params->hdlc = value; break;
|
||||||
|
|
||||||
|
case PATTY_AX25_PARAM_INFO_TX:
|
||||||
|
params->info_tx = (size_t)value; break;
|
||||||
|
|
||||||
|
case PATTY_AX25_PARAM_INFO_RX:
|
||||||
|
params->info_rx = (size_t)value; break;
|
||||||
|
|
||||||
|
case PATTY_AX25_PARAM_WINDOW_TX:
|
||||||
|
params->window_tx = (size_t)value; break;
|
||||||
|
|
||||||
|
case PATTY_AX25_PARAM_WINDOW_RX:
|
||||||
|
params->window_rx = (size_t)value; break;
|
||||||
|
|
||||||
|
case PATTY_AX25_PARAM_ACK:
|
||||||
|
params->ack = (size_t)value; break;
|
||||||
|
|
||||||
|
case PATTY_AX25_PARAM_RETRY:
|
||||||
|
params->retry = (size_t)value; break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
params->found |= (1 << type);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t decode_xid_group(patty_ax25_params *params,
|
||||||
void *data,
|
void *data,
|
||||||
size_t offset,
|
size_t offset,
|
||||||
size_t len,
|
size_t len) {
|
||||||
void *ctx) {
|
|
||||||
patty_ax25_frame_xid_group *group = (patty_ax25_frame_xid_group *)
|
patty_ax25_frame_xid_group *group = (patty_ax25_frame_xid_group *)
|
||||||
((uint8_t *)data + offset);
|
((uint8_t *)data + offset);
|
||||||
|
|
||||||
|
@ -297,6 +331,8 @@ ssize_t decode_xid_group(patty_ax25_frame_xid_callback callback,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(params, '\0', sizeof(*params));
|
||||||
|
|
||||||
while (offset - start < sizeof(*group) + grouplen) {
|
while (offset - start < sizeof(*group) + grouplen) {
|
||||||
patty_ax25_frame_xid_param *param = (patty_ax25_frame_xid_param *)
|
patty_ax25_frame_xid_param *param = (patty_ax25_frame_xid_param *)
|
||||||
((uint8_t *)data + offset);
|
((uint8_t *)data + offset);
|
||||||
|
@ -308,11 +344,7 @@ ssize_t decode_xid_group(patty_ax25_frame_xid_callback callback,
|
||||||
value |= ((uint8_t *)(param + 1))[param->len-1-i] << (i << 3);
|
value |= ((uint8_t *)(param + 1))[param->len-1-i] << (i << 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (callback(param->id,
|
save_xid_param(params, param->id, value);
|
||||||
value,
|
|
||||||
ctx) < 0) {
|
|
||||||
goto error_callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += sizeof(*param) + param->len;
|
offset += sizeof(*param) + param->len;
|
||||||
}
|
}
|
||||||
|
@ -327,21 +359,19 @@ done:
|
||||||
error:
|
error:
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
|
|
||||||
error_callback:
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t patty_ax25_frame_decode_xid(patty_ax25_frame_xid_callback callback,
|
ssize_t patty_ax25_frame_decode_xid(patty_ax25_params *params,
|
||||||
void *data,
|
void *data,
|
||||||
size_t offset,
|
size_t offset,
|
||||||
size_t len,
|
size_t len) {
|
||||||
void *ctx) {
|
|
||||||
size_t start = offset;
|
size_t start = offset;
|
||||||
|
|
||||||
while (offset < len) {
|
while (offset < len) {
|
||||||
ssize_t decoded;
|
ssize_t decoded;
|
||||||
|
|
||||||
if ((decoded = decode_xid_group(callback, data, offset, len, ctx)) < 0) {
|
if ((decoded = decode_xid_group(params, data, offset, len)) < 0) {
|
||||||
goto error_decode_xid_group;
|
goto error_decode_xid_group;
|
||||||
} else {
|
} else {
|
||||||
offset += decoded;
|
offset += decoded;
|
||||||
|
|
256
src/print.c
256
src/print.c
|
@ -51,6 +51,173 @@ static char *frame_cr(enum patty_ax25_frame_cr cr) {
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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_header(FILE *fh,
|
||||||
|
const patty_ax25_frame *frame) {
|
||||||
|
if (print_frame_addrs(fh, frame) < 0) {
|
||||||
|
goto error_io;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PATTY_AX25_FRAME_CONTROL_I(frame->control)) {
|
||||||
|
if (fprintf(fh, " type I (%s) %s %s nr %d ns %d pf %d info %zu bytes",
|
||||||
|
frame_type(frame->type),
|
||||||
|
version(frame->version),
|
||||||
|
frame_cr(frame->cr),
|
||||||
|
(int)frame->nr,
|
||||||
|
(int)frame->ns,
|
||||||
|
(int)frame->pf,
|
||||||
|
frame->infolen) < 0) {
|
||||||
|
goto error_io;
|
||||||
|
}
|
||||||
|
} else if (PATTY_AX25_FRAME_CONTROL_U(frame->control)) {
|
||||||
|
if (fprintf(fh, " type U (%s) %s %s pf %d",
|
||||||
|
frame_type(frame->type),
|
||||||
|
version(frame->version),
|
||||||
|
frame_cr(frame->cr),
|
||||||
|
(int)frame->pf) < 0) {
|
||||||
|
goto error_io;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PATTY_AX25_FRAME_CONTROL_UI(frame->control)) {
|
||||||
|
if (fprintf(fh, " info %zu bytes", frame->infolen) < 0) {
|
||||||
|
goto error_io;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (PATTY_AX25_FRAME_CONTROL_S(frame->control)) {
|
||||||
|
if (fprintf(fh, " type S (%s) %s %s nr %d pf %d",
|
||||||
|
frame_type(frame->type),
|
||||||
|
version(frame->version),
|
||||||
|
frame_cr(frame->cr),
|
||||||
|
(int)frame->nr,
|
||||||
|
(int)frame->pf) < 0) {
|
||||||
|
goto error_io;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fprintf(fh, "\n");
|
||||||
|
|
||||||
|
error_io:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int patty_print_params(FILE *fh,
|
||||||
|
const patty_ax25_params *params) {
|
||||||
|
static const struct {
|
||||||
|
enum patty_ax25_param_classes flag;
|
||||||
|
char *name;
|
||||||
|
} classes_flags[] = {
|
||||||
|
{ PATTY_AX25_PARAM_CLASSES_ABM, "ABM" },
|
||||||
|
{ PATTY_AX25_PARAM_CLASSES_HALF_DUPLEX, "half-duplex" },
|
||||||
|
{ PATTY_AX25_PARAM_CLASSES_FULL_DUPLEX, "full-duplex" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct {
|
||||||
|
enum patty_ax25_param_hdlc flag;
|
||||||
|
char *name;
|
||||||
|
} hdlc_flags[] = {
|
||||||
|
{ PATTY_AX25_PARAM_HDLC_REJ, "REJ" },
|
||||||
|
{ PATTY_AX25_PARAM_HDLC_SREJ, "SREJ" },
|
||||||
|
{ PATTY_AX25_PARAM_HDLC_XADDR, "extended addresses" },
|
||||||
|
{ PATTY_AX25_PARAM_HDLC_MODULO_8, "modulo 8" },
|
||||||
|
{ PATTY_AX25_PARAM_HDLC_MODULO_128, "modulo 128" },
|
||||||
|
{ PATTY_AX25_PARAM_HDLC_TEST, "TEST" },
|
||||||
|
{ PATTY_AX25_PARAM_HDLC_SYNC_TX, "synchronous TX" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct {
|
||||||
|
enum patty_ax25_param_type flag;
|
||||||
|
size_t value;
|
||||||
|
char *name;
|
||||||
|
} fields[] = {
|
||||||
|
{ PATTY_AX25_PARAM_INFO_TX, params->info_tx, "I Field Length TX" },
|
||||||
|
{ PATTY_AX25_PARAM_INFO_RX, params->info_rx, "I Field Length RX" },
|
||||||
|
{ PATTY_AX25_PARAM_WINDOW_TX, params->window_tx, "Window Size TX" },
|
||||||
|
{ PATTY_AX25_PARAM_WINDOW_RX, params->window_rx, "Window Size RX" },
|
||||||
|
{ PATTY_AX25_PARAM_ACK, params->ack, "Ack timer" },
|
||||||
|
{ PATTY_AX25_PARAM_RETRY, params->retry, "Retry" },
|
||||||
|
{ 0, 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (fprintf(fh, " XID parameters:\n") < 0) {
|
||||||
|
goto error_fprintf;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fprintf(fh, " Classes of procedures:\n") < 0) {
|
||||||
|
goto error_fprintf;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; classes_flags[i].name; i++) {
|
||||||
|
if (params->classes & classes_flags[i].flag) {
|
||||||
|
if (fprintf(fh, " > %s\n", classes_flags[i].name) < 0) {
|
||||||
|
goto error_fprintf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(fh, " HDLC optional functions:\n");
|
||||||
|
|
||||||
|
for (i=0; hdlc_flags[i].name; i++) {
|
||||||
|
if (params->hdlc & hdlc_flags[i].flag) {
|
||||||
|
if (fprintf(fh, " > %s\n", hdlc_flags[i].name) < 0) {
|
||||||
|
goto error_fprintf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; fields[i].name; i++) {
|
||||||
|
if (params->found & (1 << fields[i].flag)) {
|
||||||
|
if (fprintf(fh, " %s: %zu\n", fields[i].name, fields[i].value) < 0) {
|
||||||
|
goto error_fprintf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error_fprintf:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int patty_print_hexdump(FILE *fh, void *data, size_t len) {
|
int patty_print_hexdump(FILE *fh, void *data, size_t len) {
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
|
@ -101,92 +268,3 @@ int patty_print_hexdump(FILE *fh, void *data, size_t len) {
|
||||||
error_io:
|
error_io:
|
||||||
return -1;
|
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_FRAME_CONTROL_I(frame->control)) {
|
|
||||||
if (fprintf(fh, " type I (%s) %s %s nr %d ns %d pf %d info %zu bytes",
|
|
||||||
frame_type(frame->type),
|
|
||||||
version(frame->version),
|
|
||||||
frame_cr(frame->cr),
|
|
||||||
(int)frame->nr,
|
|
||||||
(int)frame->ns,
|
|
||||||
(int)frame->pf,
|
|
||||||
frame->infolen) < 0) {
|
|
||||||
goto error_io;
|
|
||||||
}
|
|
||||||
} else if (PATTY_AX25_FRAME_CONTROL_U(frame->control)) {
|
|
||||||
if (fprintf(fh, " type U (%s) %s %s pf %d",
|
|
||||||
frame_type(frame->type),
|
|
||||||
version(frame->version),
|
|
||||||
frame_cr(frame->cr),
|
|
||||||
(int)frame->pf) < 0) {
|
|
||||||
goto error_io;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PATTY_AX25_FRAME_CONTROL_UI(frame->control)) {
|
|
||||||
if (fprintf(fh, " info %zu bytes", frame->infolen) < 0) {
|
|
||||||
goto error_io;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (PATTY_AX25_FRAME_CONTROL_S(frame->control)) {
|
|
||||||
if (fprintf(fh, " type S (%s) %s %s nr %d pf %d",
|
|
||||||
frame_type(frame->type),
|
|
||||||
version(frame->version),
|
|
||||||
frame_cr(frame->cr),
|
|
||||||
(int)frame->nr,
|
|
||||||
(int)frame->pf) < 0) {
|
|
||||||
goto error_io;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(fh, "\n");
|
|
||||||
|
|
||||||
return patty_print_hexdump(fh, buf, len);
|
|
||||||
|
|
||||||
error_io:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
36
src/server.c
36
src/server.c
|
@ -1277,7 +1277,6 @@ error_sock_delete:
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_rej(patty_ax25_server *server,
|
static int handle_rej(patty_ax25_server *server,
|
||||||
patty_ax25_if *iface,
|
|
||||||
patty_ax25_sock *sock,
|
patty_ax25_sock *sock,
|
||||||
patty_ax25_frame *frame) {
|
patty_ax25_frame *frame) {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
@ -1295,7 +1294,6 @@ error_sock_resend:
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_srej(patty_ax25_server *server,
|
static int handle_srej(patty_ax25_server *server,
|
||||||
patty_ax25_if *iface,
|
|
||||||
patty_ax25_sock *sock,
|
patty_ax25_sock *sock,
|
||||||
patty_ax25_frame *frame) {
|
patty_ax25_frame *frame) {
|
||||||
/*
|
/*
|
||||||
|
@ -1311,10 +1309,26 @@ error_sock_resend:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_xid_param(enum patty_ax25_frame_xid_param_type type,
|
static int handle_xid(patty_ax25_server *server,
|
||||||
uint32_t value,
|
patty_ax25_sock *sock,
|
||||||
void *ctx) {
|
void *buf,
|
||||||
|
size_t offset,
|
||||||
|
size_t len) {
|
||||||
|
patty_ax25_params params;
|
||||||
|
|
||||||
|
if (patty_ax25_frame_decode_xid(¶ms, buf, offset, len) < 0) {
|
||||||
|
goto error_io;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: Actually do something with the parameters received; also perhaps
|
||||||
|
* consider replying to this XID frame with another XID frame
|
||||||
|
*/
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
error_io:
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_frame(patty_ax25_server *server,
|
static int handle_frame(patty_ax25_server *server,
|
||||||
|
@ -1356,17 +1370,11 @@ static int handle_frame(patty_ax25_server *server,
|
||||||
case PATTY_AX25_FRAME_SABME: return handle_sabm(server, iface, &frame);
|
case PATTY_AX25_FRAME_SABME: return handle_sabm(server, iface, &frame);
|
||||||
case PATTY_AX25_FRAME_DISC: return handle_disc(server, iface, &frame);
|
case PATTY_AX25_FRAME_DISC: return handle_disc(server, iface, &frame);
|
||||||
case PATTY_AX25_FRAME_I: return handle_i(server, iface, sock, &frame);
|
case PATTY_AX25_FRAME_I: return handle_i(server, iface, sock, &frame);
|
||||||
case PATTY_AX25_FRAME_REJ: return handle_rej(server, iface, sock, &frame);
|
case PATTY_AX25_FRAME_REJ: return handle_rej(server, sock, &frame);
|
||||||
case PATTY_AX25_FRAME_SREJ: return handle_srej(server, iface, sock, &frame);
|
case PATTY_AX25_FRAME_SREJ: return handle_srej(server, sock, &frame);
|
||||||
|
case PATTY_AX25_FRAME_XID: return handle_xid(server, sock, buf, offset, len);
|
||||||
case PATTY_AX25_FRAME_FRMR: return 0;
|
case PATTY_AX25_FRAME_FRMR: return 0;
|
||||||
|
|
||||||
case PATTY_AX25_FRAME_XID:
|
|
||||||
if (patty_ax25_frame_decode_xid(handle_xid_param, buf, offset, len, sock) < 0) {
|
|
||||||
goto error_io;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue