diff --git a/include/patty/ax25/frame.h b/include/patty/ax25/frame.h index 913af67..0311a19 100644 --- a/include/patty/ax25/frame.h +++ b/include/patty/ax25/frame.h @@ -24,6 +24,23 @@ enum patty_ax25_frame_type { PATTY_AX25_FRAME_UNKNOWN = 0xff }; +enum patty_ax25_frame_flags { + PATTY_AX25_FRAME_POLL = (1 << 4), + PATTY_AX25_FRAME_FINAL = (1 << 4) +}; + +enum patty_ax25_frame_cr { + PATTY_AX25_FRAME_COMMAND, + PATTY_AX25_FRAME_RESPONSE +}; + +enum patty_ax25_frame_s_type { + PATTY_AX25_FRAME_S_RR = 0x01, + PATTY_AX25_FRAME_S_RNR = 0x05, + PATTY_AX25_FRAME_S_REJ = 0x09, + PATTY_AX25_FRAME_S_SREJ = 0x0d +}; + enum patty_ax25_frame_u_type { PATTY_AX25_FRAME_U_SABME = 0x6f, PATTY_AX25_FRAME_U_SABM = 0x2f, @@ -36,16 +53,6 @@ enum patty_ax25_frame_u_type { PATTY_AX25_FRAME_U_TEST = 0xe3 }; -enum patty_ax25_frame_u_flags { - PATTY_AX25_FRAME_U_POLL = (1 << 4), - PATTY_AX25_FRAME_U_FINAL = (1 << 4) -}; - -enum patty_ax25_frame_cr { - PATTY_AX25_FRAME_COMMAND, - PATTY_AX25_FRAME_RESPONSE -}; - typedef struct _patty_ax25_frame { patty_ax25_addr dest, src, diff --git a/src/server.c b/src/server.c index 1e2459d..602e500 100644 --- a/src/server.c +++ b/src/server.c @@ -1026,7 +1026,7 @@ error_toobig: static int reply_dm(patty_ax25_if *iface, patty_ax25_frame *frame, - enum patty_ax25_frame_u_flags flags) { + enum patty_ax25_frame_flags flags) { patty_ax25_frame reply = { .control = PATTY_AX25_FRAME_U_DM | flags, .proto = PATTY_AX25_PROTO_NONE, @@ -1039,7 +1039,7 @@ static int reply_dm(patty_ax25_if *iface, static int reply_ua(patty_ax25_if *iface, patty_ax25_frame *frame, - enum patty_ax25_frame_u_flags flags) { + enum patty_ax25_frame_flags flags) { patty_ax25_frame reply = { .control = PATTY_AX25_FRAME_U_UA | flags, .proto = PATTY_AX25_PROTO_NONE, @@ -1057,7 +1057,20 @@ static int reply_ua(patty_ax25_if *iface, static int reply_frmr(patty_ax25_if *iface, patty_ax25_frame *frame, - enum patty_ax25_frame_u_flags flags) { + enum patty_ax25_frame_flags flags) { + patty_ax25_frame reply = { + .control = PATTY_AX25_FRAME_U_FRMR | flags, + .proto = PATTY_AX25_PROTO_NONE, + .info = NULL, + .infolen = 0 + }; + + return reply_to(iface, frame, &reply, PATTY_AX25_FRAME_NORMAL); +} + +static int reply_rej(patty_ax25_if *iface, + patty_ax25_frame *frame, + enum patty_ax25_frame_flags flags) { patty_ax25_frame reply = { .control = PATTY_AX25_FRAME_U_FRMR | flags, .proto = PATTY_AX25_PROTO_NONE, @@ -1077,7 +1090,7 @@ static int handle_sabm(patty_ax25_server *server, if ((local = sock_by_addr(server->socks_pending_accept, &frame->dest)) == NULL) { - return reply_dm(iface, frame, PATTY_AX25_FRAME_U_FINAL); + return reply_dm(iface, frame, PATTY_AX25_FRAME_FINAL); } if ((client = client_by_sock(server, local)) < 0) { @@ -1110,7 +1123,7 @@ static int handle_sabm(patty_ax25_server *server, goto error_sock_delete_by_addr; } - if (reply_ua(iface, frame, PATTY_AX25_FRAME_U_FINAL) < 0) { + if (reply_ua(iface, frame, PATTY_AX25_FRAME_FINAL) < 0) { goto error_reply_ua; } @@ -1152,7 +1165,7 @@ static int handle_ua(patty_ax25_server *server, if ((sock = sock_by_addrpair(server->socks_pending_connect, &frame->dest, &frame->src)) == NULL) { - return reply_frmr(iface, frame, PATTY_AX25_FRAME_U_FINAL); + return reply_frmr(iface, frame, PATTY_AX25_FRAME_FINAL); } if ((client = client_by_sock(server, sock)) < 0) { @@ -1253,7 +1266,7 @@ static int handle_info(patty_ax25_server *server, * TODO: Figure out how to respond to a packet sent outside of an * active session */ - goto done; + return 0; } if (sock->status != PATTY_AX25_SOCK_ESTABLISHED) { @@ -1261,17 +1274,19 @@ static int handle_info(patty_ax25_server *server, * TODO: Figure out how to respond to a packet sent to a socket not * in an established state */ - goto done; + return 0; } /* * TODO: Validate RX and TX sequence numbers */ + if (sock->seq_recv == PATTY_AX25_CONTROL_SEQ_SEND(frame->control)) { + sock->seq_recv++; + } else { + return reply_rej(iface, frame, PATTY_AX25_FRAME_FINAL); + } return write(sock->fd, frame->info, frame->infolen); - -done: - return 0; } static int handle_disc(patty_ax25_server *server, @@ -1282,14 +1297,14 @@ static int handle_disc(patty_ax25_server *server, if ((sock = sock_by_addrpair(server->socks_established, &frame->dest, &frame->src)) == NULL) { - return reply_frmr(iface, frame, PATTY_AX25_FRAME_U_FINAL); + return reply_frmr(iface, frame, PATTY_AX25_FRAME_FINAL); } if (sock_close(server, sock) < 0) { goto error_sock_delete; } - return reply_dm(iface, frame, PATTY_AX25_FRAME_U_FINAL); + return reply_dm(iface, frame, PATTY_AX25_FRAME_FINAL); error_sock_delete: return -1; diff --git a/src/sock.c b/src/sock.c index 9bc562d..3f16f05 100644 --- a/src/sock.c +++ b/src/sock.c @@ -204,7 +204,7 @@ error_toobig: ssize_t patty_ax25_sock_send_sabm(patty_ax25_sock *sock, int poll) { return patty_ax25_sock_send(sock, PATTY_AX25_FRAME_U_SABM - | PATTY_AX25_FRAME_U_POLL, + | PATTY_AX25_FRAME_POLL, NULL, 0); } @@ -212,7 +212,7 @@ ssize_t patty_ax25_sock_send_sabm(patty_ax25_sock *sock, int poll) { ssize_t patty_ax25_sock_send_sabme(patty_ax25_sock *sock, int poll) { return patty_ax25_sock_send(sock, PATTY_AX25_FRAME_U_SABME - | PATTY_AX25_FRAME_U_POLL, + | PATTY_AX25_FRAME_POLL, NULL, 0); } @@ -220,7 +220,7 @@ ssize_t patty_ax25_sock_send_sabme(patty_ax25_sock *sock, int poll) { ssize_t patty_ax25_sock_send_disc(patty_ax25_sock *sock, int poll) { return patty_ax25_sock_send(sock, PATTY_AX25_FRAME_U_DISC - | PATTY_AX25_FRAME_U_POLL, + | PATTY_AX25_FRAME_POLL, NULL, 0); }