Implement openif(), raw packet interface access
This commit is contained in:
parent
c853b79529
commit
73ae096b2d
3 changed files with 147 additions and 1 deletions
|
@ -8,6 +8,7 @@ enum patty_ax25_call {
|
||||||
PATTY_AX25_CALL_LISTEN,
|
PATTY_AX25_CALL_LISTEN,
|
||||||
PATTY_AX25_CALL_ACCEPT,
|
PATTY_AX25_CALL_ACCEPT,
|
||||||
PATTY_AX25_CALL_CONNECT,
|
PATTY_AX25_CALL_CONNECT,
|
||||||
|
PATTY_AX25_CALL_OPENIF,
|
||||||
PATTY_AX25_CALL_CLOSE,
|
PATTY_AX25_CALL_CLOSE,
|
||||||
PATTY_AX25_CALL_SENDTO,
|
PATTY_AX25_CALL_SENDTO,
|
||||||
PATTY_AX25_CALL_RECVFROM,
|
PATTY_AX25_CALL_RECVFROM,
|
||||||
|
@ -103,6 +104,24 @@ int patty_ax25_call_connect(int server,
|
||||||
int fd,
|
int fd,
|
||||||
patty_ax25_addr *peer);
|
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()
|
* close()
|
||||||
*/
|
*/
|
||||||
|
|
35
src/call.c
35
src/call.c
|
@ -180,6 +180,41 @@ error_io:
|
||||||
return -1;
|
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 patty_ax25_call_close(int server,
|
||||||
int fd) {
|
int fd) {
|
||||||
enum patty_ax25_call call = PATTY_AX25_CALL_CLOSE;
|
enum patty_ax25_call call = PATTY_AX25_CALL_CLOSE;
|
||||||
|
|
94
src/server.c
94
src/server.c
|
@ -722,6 +722,65 @@ error_io:
|
||||||
return -1;
|
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,
|
static int server_close(patty_ax25_server *server,
|
||||||
int client) {
|
int client) {
|
||||||
patty_ax25_call_close_request request;
|
patty_ax25_call_close_request request;
|
||||||
|
@ -769,6 +828,7 @@ static patty_ax25_server_call server_calls[PATTY_AX25_CALL_COUNT] = {
|
||||||
server_listen,
|
server_listen,
|
||||||
server_accept,
|
server_accept,
|
||||||
server_connect,
|
server_connect,
|
||||||
|
server_openif,
|
||||||
server_close,
|
server_close,
|
||||||
NULL,
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
|
@ -1225,12 +1285,38 @@ error_sock_delete:
|
||||||
return -1;
|
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,
|
static int handle_frame(patty_ax25_server *server,
|
||||||
patty_ax25_if *iface,
|
patty_ax25_if *iface,
|
||||||
void *buf,
|
void *buf,
|
||||||
size_t len) {
|
size_t len) {
|
||||||
patty_ax25_frame frame;
|
patty_ax25_frame frame;
|
||||||
|
|
||||||
|
struct sock_raw_frame ctx = {
|
||||||
|
.buf = buf,
|
||||||
|
.len = len,
|
||||||
|
.iface = iface
|
||||||
|
};
|
||||||
|
|
||||||
if (patty_ax25_frame_decode(&frame,
|
if (patty_ax25_frame_decode(&frame,
|
||||||
PATTY_AX25_FRAME_NORMAL,
|
PATTY_AX25_FRAME_NORMAL,
|
||||||
buf,
|
buf,
|
||||||
|
@ -1240,6 +1326,12 @@ static int handle_frame(patty_ax25_server *server,
|
||||||
goto error_io;
|
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)) {
|
if (PATTY_AX25_CONTROL_UNNUMBERED_SABM(frame.control)) {
|
||||||
return handle_sabm(server, iface, &frame);
|
return handle_sabm(server, iface, &frame);
|
||||||
} else if (PATTY_AX25_CONTROL_UNNUMBERED_UA(frame.control)) {
|
} else if (PATTY_AX25_CONTROL_UNNUMBERED_UA(frame.control)) {
|
||||||
|
@ -1317,7 +1409,7 @@ static int handle_sock(void *key,
|
||||||
|
|
||||||
ssize_t len;
|
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;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue