diff --git a/examples/ax25dump.c b/examples/ax25dump.c index e23ff27..89395ab 100644 --- a/examples/ax25dump.c +++ b/examples/ax25dump.c @@ -61,6 +61,8 @@ int main(int argc, char **argv) { strncpy(ifreq.name, "kiss0", sizeof(ifreq.name)); + ifreq.status = PATTY_AX25_SOCK_PROMISC; + if (patty_client_setsockopt(client, fd, PATTY_AX25_SOCK_IF, &ifreq, sizeof(ifreq)) < 0) { fprintf(stderr, "%s: %s: %s\n", argv[0], "patty_client_setsockopt()", strerror(errno)); diff --git a/include/patty/ax25/sock.h b/include/patty/ax25/sock.h index 13caa79..498b93c 100644 --- a/include/patty/ax25/sock.h +++ b/include/patty/ax25/sock.h @@ -103,6 +103,8 @@ typedef struct _patty_ax25_sock { patty_ax25_if *iface; + patty_kiss_tnc *raw; + patty_ax25_addr local, remote, repeaters[PATTY_AX25_MAX_HOPS]; diff --git a/include/patty/client.h b/include/patty/client.h index 1ab270d..d5c34af 100644 --- a/include/patty/client.h +++ b/include/patty/client.h @@ -58,6 +58,7 @@ typedef struct _patty_client_setsockopt_request { typedef struct _patty_client_setsockopt_if { char name[8]; + int status; } patty_client_setsockopt_if; typedef struct _patty_client_setsockopt_response { diff --git a/src/if.c b/src/if.c index 1f9d9f9..0a3a440 100644 --- a/src/if.c +++ b/src/if.c @@ -272,21 +272,15 @@ error_ntop: int patty_ax25_if_promisc_add(patty_ax25_if *iface, int fd) { - patty_kiss_tnc *tnc; - if (patty_dict_get(iface->promisc_fds, (uint32_t)fd)) { errno = EEXIST; goto error_exists; } - if ((tnc = patty_kiss_tnc_new_fd(fd)) == NULL) { - goto error_kiss_tnc_new_fd; - } - if (patty_dict_set(iface->promisc_fds, (uint32_t)fd, - tnc) == NULL) { + NULL) == NULL) { errno = ENOMEM; goto error_dict_set; @@ -295,29 +289,13 @@ int patty_ax25_if_promisc_add(patty_ax25_if *iface, return 0; error_dict_set: - patty_kiss_tnc_destroy(tnc); - -error_kiss_tnc_new_fd: error_exists: return -1; } int patty_ax25_if_promisc_delete(patty_ax25_if *iface, int fd) { - patty_kiss_tnc *tnc; - - if ((tnc = patty_dict_get(iface->promisc_fds, (uint32_t)fd)) == NULL) { - errno = ENOENT; - - goto error_notfound; - } - - patty_kiss_tnc_destroy(tnc); - return patty_dict_delete(iface->promisc_fds, (uint32_t)fd); - -error_notfound: - return -1; } struct promisc_frame { @@ -329,10 +307,10 @@ struct promisc_frame { static int handle_promisc_frame(uint32_t key, void *value, void *ctx) { - patty_kiss_tnc *tnc = value; + int fd = (int)key; struct promisc_frame *frame = ctx; - return patty_kiss_tnc_send(tnc, frame->buf, frame->len, 0); + return patty_kiss_frame_send(fd, frame->buf, frame->len, 0); } ssize_t patty_ax25_if_pending(patty_ax25_if *iface) { diff --git a/src/server.c b/src/server.c index 1001757..d87bcbe 100644 --- a/src/server.c +++ b/src/server.c @@ -605,6 +605,10 @@ static int server_setsockopt(patty_ax25_server *server, goto error_read; } + if (data.status == PATTY_AX25_SOCK_PROMISC) { + sock->status = PATTY_AX25_SOCK_PROMISC; + } + if ((iface = patty_ax25_server_get_if(server, data.name)) == NULL) { response.ret = -1; response.eno = ENODEV; @@ -614,8 +618,6 @@ static int server_setsockopt(patty_ax25_server *server, patty_ax25_sock_bind_if(sock, iface); - sock->status = PATTY_AX25_SOCK_PROMISC; - fd_watch(server, sock->fd); break; @@ -1732,6 +1734,34 @@ error_io: return -1; } +static int handle_sock_raw(patty_ax25_server *server, + patty_ax25_sock *sock) { + ssize_t len; + int port; + + if (!FD_ISSET(sock->fd, &server->fds_r) || sock->iface == NULL) { + return 0; + } + + if ((len = patty_kiss_tnc_recv(sock->raw, + sock->iface->tx_buf, + sock->iface->mtu, + &port)) < 0) { + goto error_io; + } + + if (patty_ax25_if_send(sock->iface, + sock->iface->tx_buf, + len) < 0) { + goto error_io; + } + + return 0; + +error_io: + return -1; +} + static int handle_sock(uint32_t key, void *value, void *ctx) { @@ -1740,6 +1770,10 @@ static int handle_sock(uint32_t key, ssize_t len; + if (sock->type == PATTY_AX25_SOCK_RAW) { + return handle_sock_raw(server, sock); + } + switch (sock->status) { case PATTY_AX25_SOCK_PENDING_CONNECT: patty_timer_tick(&sock->timer_t1, &server->elapsed); @@ -1821,15 +1855,14 @@ static int handle_sock(uint32_t key, goto done; } - if (sock->type == PATTY_AX25_SOCK_STREAM) { - /* - * NOTE: See AX.25 2.2, Section 6.4.1, "Sending I Frames" - */ - if (sock->vs + sock->n_window_tx == sock->vs) { - fd_clear(server, sock->fd); + /* + * NOTE: See AX.25 2.2, Section 6.4.1, "Sending I Frames" + */ + if (sock->vs + sock->n_window_tx == sock->vs) { + fd_clear(server, sock->fd); - goto done; - } + return patty_ax25_sock_send_rnr(sock, PATTY_AX25_FRAME_COMMAND, 1); + goto done; } if ((len = read(sock->fd, sock->rx_buf, sock->n_maxlen_rx)) < 0) { @@ -1850,12 +1883,10 @@ static int handle_sock(uint32_t key, goto error_sock_write; } - if (sock->type == PATTY_AX25_SOCK_STREAM) { - /* - * AX.25 v2.2, Section 6.4.1 "Sending I Frames" - */ - patty_timer_start(&sock->timer_t1, sock->n_ack); - } + /* + * AX.25 v2.2, Section 6.4.1 "Sending I Frames" + */ + patty_timer_start(&sock->timer_t1, sock->n_ack); done: return 0; diff --git a/src/sock.c b/src/sock.c index d26aba4..94921d9 100644 --- a/src/sock.c +++ b/src/sock.c @@ -111,6 +111,29 @@ error_realloc_tx_buf: return -1; } +static patty_ax25_sock *init_raw(patty_ax25_sock *sock) { + if (bind_pty(sock) < 0) { + goto error_bind_pty; + } + + if ((sock->raw = patty_kiss_tnc_new_fd(sock->fd)) == NULL) { + goto error_kiss_tnc_new_fd; + } + + sock->proto = PATTY_AX25_PROTO_NONE; + sock->type = PATTY_AX25_SOCK_RAW; + + return sock; + +error_kiss_tnc_new_fd: + (void)close(sock->fd); + +error_bind_pty: + free(sock); + + return NULL; +} + patty_ax25_sock *patty_ax25_sock_new(enum patty_ax25_proto proto, enum patty_ax25_sock_type type) { patty_ax25_sock *sock; @@ -121,6 +144,10 @@ patty_ax25_sock *patty_ax25_sock_new(enum patty_ax25_proto proto, memset(sock, '\0', sizeof(*sock)); + if (type == PATTY_AX25_SOCK_RAW) { + return init_raw(sock); + } + patty_ax25_sock_init(sock); sock->proto = proto; @@ -160,6 +187,10 @@ void patty_ax25_sock_destroy(patty_ax25_sock *sock) { close(sock->fd); } + if (sock->raw) { + patty_kiss_tnc_destroy(sock->raw); + } + free(sock->tx_slots); free(sock->rx_buf); free(sock->tx_buf); @@ -315,15 +346,14 @@ char *patty_ax25_sock_pty(patty_ax25_sock *sock) { int patty_ax25_sock_bind_if(patty_ax25_sock *sock, patty_ax25_if *iface) { sock->iface = iface; + sock->flags_classes |= iface->flags_classes; - if (sock->type == PATTY_AX25_SOCK_RAW) { + if (sock->status == PATTY_AX25_SOCK_PROMISC) { if (patty_ax25_if_promisc_add(iface, sock->fd) < 0) { goto error_if_promisc_add; } } - sock->flags_classes |= iface->flags_classes; - return 0; error_if_promisc_add: