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_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()
|
||||
*/
|
||||
|
|
35
src/call.c
35
src/call.c
|
@ -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;
|
||||
|
|
94
src/server.c
94
src/server.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue