diff --git a/include/patty/ax25/frame.h b/include/patty/ax25/frame.h index e388414..ed75534 100644 --- a/include/patty/ax25/frame.h +++ b/include/patty/ax25/frame.h @@ -13,6 +13,7 @@ enum patty_ax25_frame_format { }; enum patty_ax25_frame_cr { + PATTY_AX25_FRAME_OLD, PATTY_AX25_FRAME_COMMAND, PATTY_AX25_FRAME_RESPONSE }; @@ -72,7 +73,9 @@ typedef struct _patty_ax25_frame { uint16_t control; uint8_t nr, ns, pf; + enum patty_ax25_frame_cr cr; enum patty_ax25_frame_type type; + enum patty_ax25_version version; uint8_t proto; void *info; diff --git a/include/patty/ax25/sock.h b/include/patty/ax25/sock.h index 7ecb32e..e97c04b 100644 --- a/include/patty/ax25/sock.h +++ b/include/patty/ax25/sock.h @@ -75,17 +75,22 @@ void patty_ax25_sock_seq_send_incr(patty_ax25_sock *sock); void patty_ax25_sock_seq_recv_incr(patty_ax25_sock *sock); ssize_t patty_ax25_sock_send(patty_ax25_sock *sock, + enum patty_ax25_frame_cr cr, uint16_t control, void *info, size_t infolen); -ssize_t patty_ax25_sock_send_rr(patty_ax25_sock *sock); +ssize_t patty_ax25_sock_send_rr(patty_ax25_sock *sock, + enum patty_ax25_frame_cr cr); -ssize_t patty_ax25_sock_send_rnr(patty_ax25_sock *sock); +ssize_t patty_ax25_sock_send_rnr(patty_ax25_sock *sock, + enum patty_ax25_frame_cr cr); -ssize_t patty_ax25_sock_send_rej(patty_ax25_sock *sock); +ssize_t patty_ax25_sock_send_rej(patty_ax25_sock *sock, + enum patty_ax25_frame_cr cr); -ssize_t patty_ax25_sock_send_srej(patty_ax25_sock *sock); +ssize_t patty_ax25_sock_send_srej(patty_ax25_sock *sock, + enum patty_ax25_frame_cr cr); ssize_t patty_ax25_sock_send_sabm(patty_ax25_sock *sock, int flag); diff --git a/src/frame.c b/src/frame.c index 4491405..71c4ed3 100644 --- a/src/frame.c +++ b/src/frame.c @@ -109,6 +109,18 @@ ssize_t patty_ax25_frame_decode_address(patty_ax25_frame *frame, offset += decoded; } + if (PATTY_AX25_ADDR_SSID_C(frame->dest.ssid) != PATTY_AX25_ADDR_SSID_C(frame->src.ssid)) { + frame->cr = PATTY_AX25_ADDR_SSID_C(frame->dest.ssid)? + PATTY_AX25_FRAME_COMMAND: + PATTY_AX25_FRAME_RESPONSE; + + frame->version = PATTY_AX25_2_0; + + } else { + frame->cr = PATTY_AX25_FRAME_OLD; + frame->version = PATTY_AX25_OLD; + } + /* * If the source address is not the final address in the frame, begin * decoding repeater addresses. @@ -313,29 +325,21 @@ static ssize_t encode_reply_address(patty_ax25_frame *frame, hops = frame->hops > PATTY_AX25_MAX_HOPS? PATTY_AX25_MAX_HOPS: frame->hops; + uint8_t *buf = dest; + if ((2 + hops) * sizeof(patty_ax25_addr) > len) { goto error_toobig; } - memcpy((uint8_t *)dest + offset, &frame->src, sizeof(patty_ax25_addr)); - offset += sizeof(patty_ax25_addr); - ((uint8_t *)dest)[offset-1] &= ~1; - - memcpy((uint8_t *)dest + offset, &frame->dest, sizeof(patty_ax25_addr)); - offset += sizeof(patty_ax25_addr); - ((uint8_t *)dest)[offset-1] &= ~1; + offset += patty_ax25_addr_copy(buf + offset, &frame->src, 0x00); + offset += patty_ax25_addr_copy(buf + offset, &frame->dest, 0x80); for (i=0; irepeaters[i].callsign[0] == '\0') { break; } - memcpy((uint8_t *)dest + offset, - &frame->repeaters[hops-1-i], - sizeof(patty_ax25_addr)); - - offset += sizeof(patty_ax25_addr); - ((uint8_t *)dest)[offset-1] &= ~1; + offset += patty_ax25_addr_copy(buf + offset, &frame->repeaters[hops-1-i], 0); } ((uint8_t *)dest)[offset-1] |= 1; @@ -435,9 +439,7 @@ error_toobig: } enum patty_ax25_version patty_ax25_frame_version(patty_ax25_frame *frame) { - return PATTY_AX25_ADDR_SSID_C(frame->src.ssid) == - PATTY_AX25_ADDR_SSID_C(frame->dest.ssid)? - PATTY_AX25_2_0: PATTY_AX25_OLD; + return frame->version; } enum patty_ax25_frame_type patty_ax25_frame_type(patty_ax25_frame *frame) { @@ -445,9 +447,7 @@ enum patty_ax25_frame_type patty_ax25_frame_type(patty_ax25_frame *frame) { } enum patty_ax25_frame_cr patty_ax25_frame_cr(patty_ax25_frame *frame) { - return PATTY_AX25_ADDR_SSID_C(frame->src.ssid)? - PATTY_AX25_FRAME_RESPONSE: - PATTY_AX25_FRAME_COMMAND; + return frame->cr; } ssize_t patty_ax25_frame_info(patty_ax25_frame *frame, diff --git a/src/print.c b/src/print.c index 5c56cc8..3710b8a 100644 --- a/src/print.c +++ b/src/print.c @@ -7,7 +7,7 @@ #define printable(c) \ (c >= 0x20 && c < 0x7f) -static char *frame_type_name(enum patty_ax25_frame_type type) { +static char *frame_type(enum patty_ax25_frame_type type) { switch (type) { case PATTY_AX25_FRAME_I: return "I"; case PATTY_AX25_FRAME_RR: return "RR"; @@ -31,6 +31,26 @@ static char *frame_type_name(enum patty_ax25_frame_type type) { return "unknown"; } +static char *version(enum patty_ax25_version version) { + switch (version) { + case PATTY_AX25_2_0: return "v2.0"; + case PATTY_AX25_2_2: return "v2.2"; + case PATTY_AX25_OLD: return "old"; + } + + return "unknown"; +} + +static char *frame_cr(enum patty_ax25_frame_cr cr) { + switch (cr) { + case PATTY_AX25_FRAME_COMMAND: return "command"; + case PATTY_AX25_FRAME_RESPONSE: return "response"; + case PATTY_AX25_FRAME_OLD: return "?"; + } + + return "unknown"; +} + int patty_print_hexdump(FILE *fh, void *data, size_t len) { size_t i; @@ -128,8 +148,10 @@ int patty_print_frame(FILE *fh, } if (PATTY_AX25_FRAME_CONTROL_I(frame->control)) { - if (fprintf(fh, " type I (%s) nr %d ns %d pf %d info %zu bytes", - frame_type_name(frame->type), + 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, @@ -137,8 +159,10 @@ int patty_print_frame(FILE *fh, goto error_io; } } else if (PATTY_AX25_FRAME_CONTROL_U(frame->control)) { - if (fprintf(fh, " type U (%s) pf %d", - frame_type_name(frame->type), + 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; } @@ -149,8 +173,10 @@ int patty_print_frame(FILE *fh, } } } else if (PATTY_AX25_FRAME_CONTROL_S(frame->control)) { - if (fprintf(fh, " type S (%s) nr %d pf %d", - frame_type_name(frame->type), + 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; diff --git a/src/server.c b/src/server.c index 1b117a5..1f7b492 100644 --- a/src/server.c +++ b/src/server.c @@ -1244,7 +1244,7 @@ static int handle_i(patty_ax25_server *server, if (sock->seq_recv == frame->ns) { patty_ax25_sock_seq_recv_incr(sock); } else { - return patty_ax25_sock_send_rej(sock); + return patty_ax25_sock_send_rej(sock, PATTY_AX25_FRAME_RESPONSE); } if (write(sock->fd, frame->info, frame->infolen) < 0) { @@ -1252,7 +1252,7 @@ static int handle_i(patty_ax25_server *server, } if (frame->pf) { - return patty_ax25_sock_send_rr(sock); + return patty_ax25_sock_send_rr(sock, PATTY_AX25_FRAME_RESPONSE); } return 0; diff --git a/src/sock.c b/src/sock.c index 93b6789..f77ee57 100644 --- a/src/sock.c +++ b/src/sock.c @@ -154,29 +154,27 @@ void patty_ax25_sock_seq_recv_incr(patty_ax25_sock *sock) { } } -static size_t copy_addr_to_tx_buf(patty_ax25_sock *sock) { - void *buf = sock->iface->tx_buf; +static size_t addr_copy_to_tx_buf(patty_ax25_sock *sock, + enum patty_ax25_frame_cr cr) { + uint8_t *buf = sock->iface->tx_buf; + size_t offset = 0; + + uint8_t flags_remote = 0x00, + flags_local = 0x00; unsigned int i; - size_t offset = 0; + switch (cr) { + case PATTY_AX25_FRAME_COMMAND: flags_remote = 0x80; break; + case PATTY_AX25_FRAME_RESPONSE: flags_local = 0x80; break; + case PATTY_AX25_FRAME_OLD: break; + } - memcpy((uint8_t *)buf + offset, &sock->remote, sizeof(patty_ax25_addr)); - offset += sizeof(patty_ax25_addr); - ((uint8_t *)buf)[offset-1] &= ~1; - - memcpy((uint8_t *)buf + offset, &sock->local, sizeof(patty_ax25_addr)); - offset += sizeof(patty_ax25_addr); - ((uint8_t *)buf)[offset-1] &= ~1; + offset += patty_ax25_addr_copy(buf + offset, &sock->remote, flags_remote); + offset += patty_ax25_addr_copy(buf + offset, &sock->local, flags_local); for (i=0; ihops; i++) { - memcpy((uint8_t *)buf + offset, - &sock->repeaters[i], - sizeof(patty_ax25_addr)); - - offset += sizeof(patty_ax25_addr); - - ((uint8_t *)buf)[offset-1] &= ~1; + offset += patty_ax25_addr_copy(buf + offset, &sock->repeaters[i], 0); } ((uint8_t *)buf)[offset-1] |= 1; @@ -196,6 +194,7 @@ static inline int toobig(patty_ax25_sock *sock, } ssize_t patty_ax25_sock_send(patty_ax25_sock *sock, + enum patty_ax25_frame_cr cr, uint16_t control, void *info, size_t infolen) { @@ -206,7 +205,7 @@ ssize_t patty_ax25_sock_send(patty_ax25_sock *sock, goto error_toobig; } - offset = copy_addr_to_tx_buf(sock); + offset = addr_copy_to_tx_buf(sock, cr); if (sock->mode == PATTY_AX25_SOCK_SABME) { buf[offset++] = (control & 0xff00) >> 8; @@ -270,29 +269,37 @@ static uint16_t control_u(enum patty_ax25_frame_type type, | (flag << 4); } -ssize_t patty_ax25_sock_send_rr(patty_ax25_sock *sock) { +ssize_t patty_ax25_sock_send_rr(patty_ax25_sock *sock, + enum patty_ax25_frame_cr cr) { return patty_ax25_sock_send(sock, + cr, control_s(sock, PATTY_AX25_FRAME_RR, 1), NULL, 0); } -ssize_t patty_ax25_sock_send_rnr(patty_ax25_sock *sock) { +ssize_t patty_ax25_sock_send_rnr(patty_ax25_sock *sock, + enum patty_ax25_frame_cr cr) { return patty_ax25_sock_send(sock, + cr, control_s(sock, PATTY_AX25_FRAME_RNR, 1), NULL, 0); } -ssize_t patty_ax25_sock_send_rej(patty_ax25_sock *sock) { +ssize_t patty_ax25_sock_send_rej(patty_ax25_sock *sock, + enum patty_ax25_frame_cr cr) { return patty_ax25_sock_send(sock, + cr, control_s(sock, PATTY_AX25_FRAME_REJ, 1), NULL, 0); } -ssize_t patty_ax25_sock_send_srej(patty_ax25_sock *sock) { +ssize_t patty_ax25_sock_send_srej(patty_ax25_sock *sock, + enum patty_ax25_frame_cr cr) { return patty_ax25_sock_send(sock, + cr, control_s(sock, PATTY_AX25_FRAME_SREJ, 1), NULL, 0); @@ -300,6 +307,7 @@ ssize_t patty_ax25_sock_send_srej(patty_ax25_sock *sock) { ssize_t patty_ax25_sock_send_sabm(patty_ax25_sock *sock, int flag) { return patty_ax25_sock_send(sock, + PATTY_AX25_FRAME_COMMAND, control_u(PATTY_AX25_FRAME_SABM, flag), NULL, 0); @@ -307,6 +315,7 @@ ssize_t patty_ax25_sock_send_sabm(patty_ax25_sock *sock, int flag) { ssize_t patty_ax25_sock_send_sabme(patty_ax25_sock *sock, int flag) { return patty_ax25_sock_send(sock, + PATTY_AX25_FRAME_COMMAND, control_u(PATTY_AX25_FRAME_SABME, flag), NULL, 0); @@ -314,6 +323,7 @@ ssize_t patty_ax25_sock_send_sabme(patty_ax25_sock *sock, int flag) { ssize_t patty_ax25_sock_send_disc(patty_ax25_sock *sock, int flag) { return patty_ax25_sock_send(sock, + PATTY_AX25_FRAME_COMMAND, control_u(PATTY_AX25_FRAME_DISC, flag), NULL, 0); @@ -336,7 +346,7 @@ ssize_t patty_ax25_sock_write(patty_ax25_sock *sock, control = control_i(sock, 0); - if (patty_ax25_sock_send(sock, control, buf, len) < 0) { + if (patty_ax25_sock_send(sock, PATTY_AX25_FRAME_RESPONSE, control, buf, len) < 0) { goto error_send; }