restore: networking stack files from reflog (Phases 1-6)

Recovered from reflog commits 1c80937e and d0ecc067 after force-push data loss.
Includes: filter/, icmp_error.rs, slaac.rs, bond.rs, bridge.rs, gre.rs, ipip.rs,
qdisc.rs, tun.rs, vlan.rs, vxlan.rs, netfilter.rs, tun.rs, conntrack.rs, nat.rs,
rule.rs, table.rs, redbear-ufw/, dhcpv6d/, netdiag/ — 39 files total.
This commit is contained in:
Red Bear OS
2026-07-08 13:27:49 +03:00
parent 4506bfe02a
commit bb3e36e4e0
40 changed files with 6042 additions and 467 deletions
+116
View File
@@ -0,0 +1,116 @@
//! ICMP error message generation — mirrors Linux 7.1's `icmp_send`.
//!
//! Reference files:
//! - `net/ipv4/icmp.c:802` — `__icmp_send()` — builds ICMPv4 error messages
//! - `net/ipv6/icmp.c:icmpv6_send()` — ICMPv6 error messages
//! - `include/uapi/linux/icmp.h` — ICMP type/code constants
//!
//! ICMP error messages contain: ICMP header + original IP header + 8 bytes
//! of original transport payload (RFC 792 §3.1, RFC 4443 §2.4).
use smoltcp::wire::{
Icmpv4Packet, Icmpv4Repr, Icmpv6Packet, Icmpv6Repr, IpAddress, Ipv4Address, Ipv4Packet,
Ipv4Repr, Ipv6Address, Ipv6Packet, Ipv6Repr,
};
/// Builds an ICMPv4 Destination Unreachable error message (Type 3).
/// Code 3 = Port Unreachable (mirrors `ICMP_PORT_UNREACH` in icmp.c).
pub fn build_icmpv4_port_unreachable(
original_packet: &[u8],
) -> Option<Vec<u8>> {
let ipv4 = Ipv4Packet::new_checked(original_packet).ok()?;
let src = ipv4.src_addr();
let dst = ipv4.dst_addr();
let ip_header_len = (ipv4.version() & 0x0f) as usize * 4;
let total_len = original_packet.len().min(ip_header_len + 8);
let mut payload = alloc::vec![0u8; 4 + total_len];
payload[0] = 0;
payload[1] = 0;
payload[2] = 0;
payload[3] = 0;
payload[4..4 + total_len].copy_from_slice(&original_packet[..total_len]);
let icmp_repr = Icmpv4Repr::DstUnreachable {
reason: smoltcp::wire::Icmpv4DstUnreachable::PortUnreachable,
header: Ipv4Repr {
src_addr: dst,
dst_addr: src,
next_header: smoltcp::wire::IpProtocol::Icmp,
hop_limit: 64,
payload_len: 4 + total_len,
},
data: &payload,
};
let mut buf = alloc::vec![0u8; icmp_repr.buffer_len()];
let mut pkt = Icmpv4Packet::new_unchecked(&mut buf);
icmp_repr.emit(&mut pkt, &smoltcp::phy::ChecksumCapabilities::ignored());
Some(buf)
}
/// Builds an ICMPv4 Time Exceeded error message (Type 11, Code 0).
/// Mirrors `ICMP_TIME_EXCEEDED` / `ICMP_EXC_TTL` in `icmp.c:1168`.
pub fn build_icmpv4_time_exceeded(
original_packet: &[u8],
) -> Option<Vec<u8>> {
let ipv4 = Ipv4Packet::new_checked(original_packet).ok()?;
let src = ipv4.src_addr();
let dst = ipv4.dst_addr();
let ip_header_len = (ipv4.version() & 0x0f) as usize * 4;
let total_len = original_packet.len().min(ip_header_len + 8);
let mut payload = alloc::vec![0u8; 4 + total_len];
payload[4..4 + total_len].copy_from_slice(&original_packet[..total_len]);
let icmp_repr = Icmpv4Repr::TimeExceeded {
reason: smoltcp::wire::Icmpv4TimeExceeded::TtlExpired,
header: Ipv4Repr {
src_addr: dst,
dst_addr: src,
next_header: smoltcp::wire::IpProtocol::Icmp,
hop_limit: 64,
payload_len: 4 + total_len,
},
data: &payload,
};
let mut buf = alloc::vec![0u8; icmp_repr.buffer_len()];
let mut pkt = Icmpv4Packet::new_unchecked(&mut buf);
icmp_repr.emit(&mut pkt, &smoltcp::phy::ChecksumCapabilities::ignored());
Some(buf)
}
/// Builds an ICMPv6 Destination Unreachable error (Type 1, Code 4).
pub fn build_icmpv6_port_unreachable(
original_packet: &[u8],
) -> Option<Vec<u8>> {
let ipv6 = Ipv6Packet::new_checked(original_packet).ok()?;
let src = ipv6.src_addr();
let _dst = ipv6.dst_addr();
let total_len = original_packet.len().min(48);
let mut data = alloc::vec![0u8; 4 + total_len];
data[4..4 + total_len].copy_from_slice(&original_packet[..total_len]);
let icmp_repr = Icmpv6Repr::DstUnreachable {
reason: smoltcp::wire::Icmpv6DstUnreachable::PortUnreachable,
header: Ipv6Repr {
src_addr: _dst,
dst_addr: src,
next_header: smoltcp::wire::IpProtocol::Icmpv6,
hop_limit: 64,
payload_len: 4 + total_len,
},
data: &data,
};
let mut buf = alloc::vec![0u8; icmp_repr.buffer_len()];
let mut pkt = Icmpv6Packet::new_unchecked(&mut buf);
icmp_repr.emit(&_dst, &src, &mut pkt, &smoltcp::phy::ChecksumCapabilities::ignored());
Some(buf)
}
extern crate alloc;