Move raw frame capture to patty_ax25_if
Move raw frame interface capture to patty_ax25_if, patty_ax25_sock; this resolves the issue wherein only bytes received, not sent, would be captured by a raw socket bound to a specific interface with setsockopt()
This commit is contained in:
parent
1888b70ed9
commit
84ae427037
5 changed files with 115 additions and 36 deletions
|
@ -42,6 +42,7 @@ typedef struct _patty_ax25_if {
|
|||
patty_kiss_tnc *tnc;
|
||||
patty_ax25_addr addr;
|
||||
patty_list *aliases;
|
||||
patty_dict *promisc_fds;
|
||||
} patty_ax25_if;
|
||||
|
||||
typedef struct _patty_ax25_if_info {
|
||||
|
@ -75,6 +76,12 @@ int patty_ax25_if_addr_add(patty_ax25_if *iface,
|
|||
int patty_ax25_if_addr_delete(patty_ax25_if *iface,
|
||||
const char *callsign, uint8_t ssid);
|
||||
|
||||
int patty_ax25_if_promisc_add(patty_ax25_if *iface,
|
||||
int fd);
|
||||
|
||||
int patty_ax25_if_promisc_delete(patty_ax25_if *iface,
|
||||
int fd);
|
||||
|
||||
ssize_t patty_ax25_if_recv(patty_ax25_if *iface,
|
||||
void **buf);
|
||||
|
||||
|
|
|
@ -78,8 +78,8 @@ void patty_ax25_sock_destroy(patty_ax25_sock *sock);
|
|||
|
||||
char *patty_ax25_sock_pty(patty_ax25_sock *sock);
|
||||
|
||||
void patty_ax25_sock_bind_if(patty_ax25_sock *sock,
|
||||
patty_ax25_if *iface);
|
||||
int patty_ax25_sock_bind_if(patty_ax25_sock *sock,
|
||||
patty_ax25_if *iface);
|
||||
|
||||
ssize_t patty_ax25_sock_send(patty_ax25_sock *sock,
|
||||
uint16_t control,
|
||||
|
|
89
src/if.c
89
src/if.c
|
@ -1,6 +1,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <patty/ax25.h>
|
||||
|
@ -62,6 +63,10 @@ patty_ax25_if *patty_ax25_if_new(int opts, patty_ax25_if_info *info) {
|
|||
goto error_list_new_aliases;
|
||||
}
|
||||
|
||||
if ((iface->promisc_fds = patty_dict_new()) == NULL) {
|
||||
goto error_dict_new_promisc_fds;
|
||||
}
|
||||
|
||||
switch (PATTY_AX25_IF_OPT_TYPE(opts)) {
|
||||
case PATTY_AX25_IF_KISS_TNC:
|
||||
if (init_tnc(iface, (patty_ax25_if_kiss_tnc_info *)info) < 0) {
|
||||
|
@ -82,6 +87,9 @@ patty_ax25_if *patty_ax25_if_new(int opts, patty_ax25_if_info *info) {
|
|||
|
||||
error_invalid_if_type:
|
||||
error_init:
|
||||
patty_dict_destroy(iface->promisc_fds);
|
||||
|
||||
error_dict_new_promisc_fds:
|
||||
patty_list_destroy(iface->aliases);
|
||||
|
||||
error_list_new_aliases:
|
||||
|
@ -108,6 +116,7 @@ void patty_ax25_if_destroy(patty_ax25_if *iface) {
|
|||
break;
|
||||
}
|
||||
|
||||
patty_dict_destroy(iface->promisc_fds);
|
||||
patty_list_destroy(iface->aliases);
|
||||
|
||||
free(iface->tx_buf);
|
||||
|
@ -261,10 +270,67 @@ error_ntop:
|
|||
return -1;
|
||||
}
|
||||
|
||||
int patty_ax25_if_promisc_add(patty_ax25_if *iface,
|
||||
int fd) {
|
||||
if (patty_dict_get_with_hash(iface->promisc_fds, (uint32_t)fd)) {
|
||||
errno = EEXIST;
|
||||
|
||||
goto error_exists;
|
||||
}
|
||||
|
||||
if (patty_dict_set_with_hash(iface->promisc_fds,
|
||||
NULL + fd,
|
||||
sizeof(fd),
|
||||
NULL + fd,
|
||||
(uint32_t)fd) == NULL) {
|
||||
errno = ENOMEM;
|
||||
|
||||
goto error_dict_set_with_hash;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_dict_set_with_hash:
|
||||
error_exists:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int patty_ax25_if_promisc_delete(patty_ax25_if *iface,
|
||||
int fd) {
|
||||
if (patty_dict_delete_with_hash(iface->promisc_fds,
|
||||
(uint32_t)fd) < 0) {
|
||||
errno = ENOENT;
|
||||
|
||||
goto error_notfound;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_notfound:
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct promisc_frame {
|
||||
const void *buf;
|
||||
size_t len;
|
||||
patty_ax25_if *iface;
|
||||
};
|
||||
|
||||
static int handle_promisc_frame(void *key,
|
||||
size_t keysz,
|
||||
void *value,
|
||||
void *ctx) {
|
||||
int fd = (int)(value - NULL);
|
||||
struct promisc_frame *frame = ctx;
|
||||
|
||||
return write(fd, frame->buf, frame->len);
|
||||
}
|
||||
|
||||
ssize_t patty_ax25_if_recv(patty_ax25_if *iface,
|
||||
void **buf) {
|
||||
ssize_t readlen;
|
||||
int port;
|
||||
struct promisc_frame frame;
|
||||
|
||||
if ((readlen = patty_kiss_tnc_recv(iface->tnc,
|
||||
iface->rx_buf,
|
||||
|
@ -278,8 +344,19 @@ ssize_t patty_ax25_if_recv(patty_ax25_if *iface,
|
|||
iface->stats.rx_frames++;
|
||||
iface->stats.rx_bytes += readlen;
|
||||
|
||||
frame.buf = iface->rx_buf;
|
||||
frame.len = readlen;
|
||||
frame.iface = iface;
|
||||
|
||||
if (patty_dict_each(iface->promisc_fds,
|
||||
handle_promisc_frame,
|
||||
&frame) < 0) {
|
||||
goto error_handle_promisc_frame;
|
||||
}
|
||||
|
||||
return readlen;
|
||||
|
||||
error_handle_promisc_frame:
|
||||
error_kiss_tnc_recv:
|
||||
return -1;
|
||||
}
|
||||
|
@ -288,6 +365,7 @@ ssize_t patty_ax25_if_send(patty_ax25_if *iface,
|
|||
const void *buf,
|
||||
size_t len) {
|
||||
ssize_t wrlen;
|
||||
struct promisc_frame frame;
|
||||
|
||||
if ((wrlen = patty_kiss_tnc_send(iface->tnc, buf, len, 0)) < 0) {
|
||||
goto error_kiss_tnc_send;
|
||||
|
@ -296,8 +374,19 @@ ssize_t patty_ax25_if_send(patty_ax25_if *iface,
|
|||
iface->stats.tx_frames++;
|
||||
iface->stats.tx_bytes += wrlen;
|
||||
|
||||
frame.buf = buf;
|
||||
frame.len = wrlen;
|
||||
frame.iface = iface;
|
||||
|
||||
if (patty_dict_each(iface->promisc_fds,
|
||||
handle_promisc_frame,
|
||||
&frame) < 0) {
|
||||
goto error_handle_promisc_frame;
|
||||
}
|
||||
|
||||
return wrlen;
|
||||
|
||||
error_handle_promisc_frame:
|
||||
error_kiss_tnc_send:
|
||||
return -1;
|
||||
}
|
||||
|
|
32
src/server.c
32
src/server.c
|
@ -1309,38 +1309,12 @@ 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 (sock->type != PATTY_AX25_SOCK_RAW || raw_frame->iface != sock->iface) {
|
||||
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,
|
||||
|
@ -1350,12 +1324,6 @@ 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)) {
|
||||
|
|
19
src/sock.c
19
src/sock.c
|
@ -107,6 +107,10 @@ void patty_ax25_sock_reset(patty_ax25_sock *sock) {
|
|||
|
||||
void patty_ax25_sock_destroy(patty_ax25_sock *sock) {
|
||||
if (sock->fd) {
|
||||
if (sock->iface) {
|
||||
(void)patty_ax25_if_promisc_delete(sock->iface, sock->fd);
|
||||
}
|
||||
|
||||
close(sock->fd);
|
||||
}
|
||||
|
||||
|
@ -118,9 +122,20 @@ char *patty_ax25_sock_pty(patty_ax25_sock *sock) {
|
|||
return sock->path;
|
||||
}
|
||||
|
||||
void patty_ax25_sock_bind_if(patty_ax25_sock *sock,
|
||||
patty_ax25_if *iface) {
|
||||
int patty_ax25_sock_bind_if(patty_ax25_sock *sock,
|
||||
patty_ax25_if *iface) {
|
||||
sock->iface = iface;
|
||||
|
||||
if (sock->type == PATTY_AX25_SOCK_RAW) {
|
||||
if (patty_ax25_if_promisc_add(iface, sock->fd) < 0) {
|
||||
goto error_if_promisc_add;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_if_promisc_add:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static size_t copy_addr_to_tx_buf(patty_ax25_sock *sock) {
|
||||
|
|
Loading…
Add table
Reference in a new issue