Implement openif(), raw packet interface access

This commit is contained in:
XANTRONIX Development 2020-07-02 23:33:34 -04:00 committed by XANTRONIX Industrial
parent c853b79529
commit 73ae096b2d
3 changed files with 147 additions and 1 deletions

View file

@ -8,6 +8,7 @@ enum patty_ax25_call {
PATTY_AX25_CALL_LISTEN,
PATTY_AX25_CALL_ACCEPT,
PATTY_AX25_CALL_CONNECT,
PATTY_AX25_CALL_OPENIF,
PATTY_AX25_CALL_CLOSE,
PATTY_AX25_CALL_SENDTO,
PATTY_AX25_CALL_RECVFROM,
@ -103,6 +104,24 @@ int patty_ax25_call_connect(int server,
int fd,
patty_ax25_addr *peer);
/*
* openif()
*/
typedef struct _patty_ax25_call_openif_request {
char name[8];
} patty_ax25_call_openif_request;
typedef struct _patty_ax25_call_openif_response {
int fd;
int eno;
char path[PATTY_AX25_SOCK_PATH_SIZE];
} patty_ax25_call_openif_response;
int patty_ax25_call_openif(int server,
char *name,
char *path,
size_t len);
/*
* close()
*/

View file

@ -180,6 +180,41 @@ error_io:
return -1;
}
int patty_ax25_call_openif(int server,
char *name,
char *path,
size_t len) {
enum patty_ax25_call call = PATTY_AX25_CALL_OPENIF;
patty_ax25_call_openif_request request;
patty_ax25_call_openif_response response;
memcpy(request.name, name, sizeof(request.name));
if (write(server, &call, sizeof(call)) < 0) {
goto error_io;
}
if (write(server, &request, sizeof(request)) < 0) {
goto error_io;
}
if (read(server, &response, sizeof(response)) < 0) {
goto error_io;
}
if (path) {
strncpy(path, response.path, len);
}
errno = response.eno;
return response.fd;
error_io:
return -1;
}
int patty_ax25_call_close(int server,
int fd) {
enum patty_ax25_call call = PATTY_AX25_CALL_CLOSE;

View file

@ -722,6 +722,65 @@ error_io:
return -1;
}
static int server_openif(patty_ax25_server *server,
int client) {
patty_ax25_call_openif_request request;
patty_ax25_call_openif_response response;
patty_ax25_sock *sock;
patty_ax25_if *iface;
if (read(client, &request, sizeof(request)) < 0) {
goto error_io;
}
if ((sock = patty_ax25_sock_new(PATTY_AX25_SOCK_RAW,
PATTY_AX25_PROTO_NONE)) == NULL) {
response.fd = -1;
response.eno = errno;
goto error_sock_new;
}
if ((iface = patty_ax25_server_get_if(server, request.name)) == NULL) {
response.fd = -1;
response.eno = ENODEV;
goto error_get_if;
}
patty_ax25_sock_bind_if(sock, iface);
watch_fd(server, sock->fd);
if (sock_save_by_fd(server->socks_by_fd, sock) < 0) {
response.fd = -1;
response.eno = errno;
goto error_sock_save_by_fd;
}
if (sock_save_by_fd(server->socks_established, sock) < 0) {
response.fd = -1;
response.eno = errno;
goto error_sock_save_by_fd;
}
response.fd = sock->fd;
response.eno = 0;
strncpy(response.path, sock->path, sizeof(response.path));
error_get_if:
error_sock_new:
return write(client, &response, sizeof(response));
error_sock_save_by_fd:
error_io:
return -1;
}
static int server_close(patty_ax25_server *server,
int client) {
patty_ax25_call_close_request request;
@ -769,6 +828,7 @@ static patty_ax25_server_call server_calls[PATTY_AX25_CALL_COUNT] = {
server_listen,
server_accept,
server_connect,
server_openif,
server_close,
NULL,
NULL
@ -1225,12 +1285,38 @@ error_sock_delete:
return -1;
}
struct sock_raw_frame {
void *buf;
size_t len;
patty_ax25_if *iface;
};
static int handle_sock_raw(void *key,
size_t keysz,
void *value,
void *ctx) {
patty_ax25_sock *sock = value;
struct sock_raw_frame *raw_frame = ctx;
if (raw_frame->iface != sock->iface || !(sock->opts & PATTY_AX25_SOCK_RAW)) {
return 0;
}
return write(sock->fd, raw_frame->buf, raw_frame->len);
}
static int handle_frame(patty_ax25_server *server,
patty_ax25_if *iface,
void *buf,
size_t len) {
patty_ax25_frame frame;
struct sock_raw_frame ctx = {
.buf = buf,
.len = len,
.iface = iface
};
if (patty_ax25_frame_decode(&frame,
PATTY_AX25_FRAME_NORMAL,
buf,
@ -1240,6 +1326,12 @@ static int handle_frame(patty_ax25_server *server,
goto error_io;
}
if (patty_dict_each(server->socks_established,
handle_sock_raw,
&ctx) < 0) {
goto error_io;
}
if (PATTY_AX25_CONTROL_UNNUMBERED_SABM(frame.control)) {
return handle_sabm(server, iface, &frame);
} else if (PATTY_AX25_CONTROL_UNNUMBERED_UA(frame.control)) {
@ -1317,7 +1409,7 @@ static int handle_sock(void *key,
ssize_t len;
if (!FD_ISSET(fd, &server->fds_r)) {
if (!FD_ISSET(fd, &server->fds_r) || sock->opts & PATTY_AX25_SOCK_RAW) {
goto done;
}