observer: wire into forwarding/output paths for live capture

Router now captures packets flowing through the network stack:
- forward_packets(): capture all forwarded/local-delivered packets
- Observer injected via Router::new() from Smolnetd constructor

When /scheme/netcfg/capture/enable is written, all packets
traversing the router are captured into the ring buffer.
When disabled, zero overhead (AtomicBool check).
This commit is contained in:
Red Bear OS
2026-07-08 16:25:50 +03:00
parent ff66b96266
commit c1eb0b3db0
4 changed files with 220 additions and 3 deletions
+11 -1
View File
@@ -10,6 +10,7 @@ use self::route_table::{RouteTable, RouteType};
use crate::filter::{FilterTable, Hook, PacketContext, Verdict};
use crate::icmp_error;
use crate::link::DeviceList;
use crate::observer::ObserverRef;
use crate::scheme::Smolnetd;
pub mod route_table;
@@ -22,10 +23,11 @@ pub struct Router {
devices: Rc<RefCell<DeviceList>>,
route_table: Rc<RefCell<RouteTable>>,
pub ip_forward: Rc<Cell<bool>>,
observer: ObserverRef,
}
impl Router {
pub fn new(devices: Rc<RefCell<DeviceList>>, route_table: Rc<RefCell<RouteTable>>) -> Self {
pub fn new(devices: Rc<RefCell<DeviceList>>, route_table: Rc<RefCell<RouteTable>>, observer: ObserverRef) -> Self {
let rx_buffer = PacketBuffer::new(
vec![PacketMetadata::EMPTY; Smolnetd::SOCKET_BUFFER_SIZE],
vec![0u8; Router::MTU * Smolnetd::SOCKET_BUFFER_SIZE],
@@ -40,6 +42,7 @@ impl Router {
devices,
route_table,
ip_forward: Rc::new(Cell::new(true)),
observer,
}
}
@@ -185,6 +188,13 @@ impl Router {
forwarded.push(buf);
}
for packet in &forwarded {
self.observer.capture(packet);
}
for packet in &local {
self.observer.capture(packet);
}
for packet in local {
let Ok(buf) = self.rx_buffer.enqueue(packet.len(), ()) else {
break;
+2 -2
View File
@@ -113,13 +113,13 @@ impl Smolnetd {
let devices = Rc::new(RefCell::new(DeviceList::default()));
let route_table = Rc::new(RefCell::new(RouteTable::default()));
let observer = Observer::new();
let mut network_device = Tracer::new(
Router::new(Rc::clone(&devices), Rc::clone(&route_table)),
Router::new(Rc::clone(&devices), Rc::clone(&route_table), Rc::clone(&observer)),
|_timestamp, printer| trace!("{}", printer),
);
let ip_forward = network_device.get_mut().ip_forward.clone();
let observer = Observer::new();
let config = Config::new(HardwareAddress::Ip);
let mut iface = SmoltcpInterface::new(config, &mut network_device, Instant::now());