promiscuous: per-interface toggle via netcfg (ip link set promisc)
LinkDevice trait gains is_promiscuous() and set_promiscuous(). EthernetLink stores promiscuous flag (default: false). Receive path bypasses MAC check when promiscuous enabled — captures all frames regardless of destination MAC. netcfg/ifaces/eth0/promiscuous rw: cat /scheme/netcfg/ifaces/eth0/promiscuous → 'off' or 'on' echo on > .../promiscuous → enable promiscuous mode echo off > .../promiscuous → disable Accepts: on/off/1/0/yes/no/true/false. Mirrors Linux 'ip link set dev promisc on/off'. Required for packet capture tools that need to see all traffic.
This commit is contained in:
@@ -88,6 +88,7 @@ pub struct EthernetLink {
|
||||
qdisc_config: QdiscConfig,
|
||||
mtu: usize,
|
||||
enabled: bool,
|
||||
promiscuous: bool,
|
||||
stats: Stats,
|
||||
arp_requests: u64,
|
||||
arp_replies: u64,
|
||||
@@ -125,6 +126,7 @@ impl EthernetLink {
|
||||
qdisc_config: QdiscConfig::default(),
|
||||
mtu: Self::MTU,
|
||||
enabled: true,
|
||||
promiscuous: false,
|
||||
stats: Stats::default(),
|
||||
neighbor_cache: Default::default(),
|
||||
arp_requests: 0,
|
||||
@@ -799,7 +801,7 @@ impl LinkDevice for EthernetLink {
|
||||
(is_for_us, repr.ethertype)
|
||||
};
|
||||
|
||||
if !is_for_us {
|
||||
if !is_for_us && !self.promiscuous {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -970,5 +972,13 @@ impl LinkDevice for EthernetLink {
|
||||
fn remove_neighbor(&mut self, ip: IpAddress) -> bool {
|
||||
self.neighbor_cache.remove(&ip).is_some()
|
||||
}
|
||||
|
||||
fn is_promiscuous(&self) -> bool {
|
||||
self.promiscuous
|
||||
}
|
||||
|
||||
fn set_promiscuous(&mut self, enabled: bool) {
|
||||
self.promiscuous = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,12 @@ pub trait LinkDevice {
|
||||
false
|
||||
}
|
||||
|
||||
fn is_promiscuous(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn set_promiscuous(&mut self, _enabled: bool) {}
|
||||
|
||||
fn mtu(&self) -> usize {
|
||||
1500
|
||||
}
|
||||
|
||||
@@ -632,6 +632,31 @@ fn mk_root_node(
|
||||
}
|
||||
}
|
||||
|_cur_value| { Ok(()) }
|
||||
},
|
||||
"promiscuous" => {
|
||||
rw [devices] (Option<bool>, None)
|
||||
|| {
|
||||
match devices.borrow().get("eth0") {
|
||||
Some(dev) => if dev.is_promiscuous() { "on\n".to_string() } else { "off\n".to_string() },
|
||||
None => "Device not found\n".into(),
|
||||
}
|
||||
}
|
||||
|cur_value, line| {
|
||||
let s = line.trim();
|
||||
let enabled = match s {
|
||||
"on" | "1" | "true" | "yes" => true,
|
||||
"off" | "0" | "false" | "no" => false,
|
||||
_ => return Err(SyscallError::new(syscall::EINVAL)),
|
||||
};
|
||||
if let Some(dev) = devices.borrow_mut().get_mut("eth0") {
|
||||
dev.set_promiscuous(enabled);
|
||||
*cur_value = Some(enabled);
|
||||
Ok(())
|
||||
} else {
|
||||
Err(SyscallError::new(syscall::ENODEV))
|
||||
}
|
||||
}
|
||||
|_cur_value| { Ok(()) }
|
||||
}
|
||||
},
|
||||
"lo" => {
|
||||
|
||||
Reference in New Issue
Block a user