summaryrefslogtreecommitdiff
path: root/src/ipcpd
diff options
context:
space:
mode:
authorDimitri Staessens <dimitri@ouroboros.rocks>2026-05-03 17:00:15 +0200
committerSander Vrijders <sander@ouroboros.rocks>2026-05-20 08:17:05 +0200
commit875df4e784530430b13e77f4c37e37466db4ef3c (patch)
tree99bc2b5c8dd7eae690d9d1f39750f0b468d9c5c0 /src/ipcpd
parentee329b9047532c7e9199bba2246992ea1a619df8 (diff)
downloadouroboros-875df4e784530430b13e77f4c37e37466db4ef3c.tar.gz
ouroboros-875df4e784530430b13e77f4c37e37466db4ef3c.zip
ipcpd: Reject outbound packets on eth
AF_PACKET under `tc netem duplicate`, produces an extra PACKET_OUTGOING frame at the source that receive path didn't reject. Read with recvfrom(2) and discard frames whose sll_pkttype is PACKET_OUTGOING. Restores the dst-MAC check body (defense in depth, also bumps n_bad_id) so any frame addressed neither to us nor the broadcast MAC is dropped before flow lookup. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
Diffstat (limited to 'src/ipcpd')
-rw-r--r--src/ipcpd/eth/eth.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/src/ipcpd/eth/eth.c b/src/ipcpd/eth/eth.c
index 7981ade5..10a8b338 100644
--- a/src/ipcpd/eth/eth.c
+++ b/src/ipcpd/eth/eth.c
@@ -1118,6 +1118,10 @@ static void * eth_ipcp_packet_reader(void * o)
fd_set fds;
int frame_len;
#endif
+#if defined(HAVE_RAW_SOCKETS)
+ struct sockaddr_ll src;
+ socklen_t slen;
+#endif
size_t eth_len;
uint8_t hcs;
struct eth_frame * e_frame;
@@ -1168,8 +1172,10 @@ static void * eth_ipcp_packet_reader(void * o)
FETCH_ADD_RELAXED(&eth_data.stat.n_buf_f, 1);
continue;
}
- frame_len = recv(eth_data.s_fd, buf,
- ETH_MTU + ETH_HEADER_TOT_SIZE, 0);
+ slen = sizeof(src);
+ frame_len = recvfrom(eth_data.s_fd, buf,
+ ETH_MTU + ETH_HEADER_TOT_SIZE, 0,
+ (struct sockaddr *) &src, &slen);
#endif
if (frame_len <= 0) {
log_dbg("Failed to receive frame.");
@@ -1179,6 +1185,12 @@ static void * eth_ipcp_packet_reader(void * o)
}
#endif
+#if defined(HAVE_RAW_SOCKETS)
+ /* Drop our own egress. */
+ if (src.sll_pkttype == PACKET_OUTGOING)
+ goto fail_frame;
+#endif
+
#if defined(HAVE_BPF) && !defined(HAVE_NETMAP)
e_frame = (struct eth_frame *)
(buf + ((struct bpf_hdr *) buf)->bh_hdrlen);
@@ -1196,6 +1208,8 @@ static void * eth_ipcp_packet_reader(void * o)
e_frame->dst_hwaddr,
MAC_SIZE) &&
memcmp(br_addr, e_frame->dst_hwaddr, MAC_SIZE)) {
+ FETCH_ADD_RELAXED(&eth_data.stat.n_bad_id, 1);
+ goto fail_frame;
}
#endif
length = ntohs(e_frame->length);