use std::path::{Path, PathBuf};
const ALLOWED_MAC_PREFIXES: &[&str] = &[
"aabbcc", "112233", "223344", "ddeeff", "000000", "ffffff", ];
const ALLOWED_IP_PREFIXES: &[&str] = &["192.0.2.", "198.51.100.", "203.0.113."];
const ALLOWED_IPS: &[&str] = &["127.0.0.1", "0.0.0.0", "255.255.255.255"];
fn macs(text: &str) -> Vec<String> {
let bytes: Vec<char> = text.chars().collect();
let mut found = Vec::new();
let mut i = 0;
while i < bytes.len() {
if !boundary_before(&bytes, i) {
i += 1;
continue;
}
let separated: String = bytes[i..(i + 17).min(bytes.len())].iter().collect();
if separated.chars().count() == 17
&& is_separated_mac(&separated)
&& boundary_after(&bytes, i + 17)
{
found.push(separated.to_ascii_lowercase().replace([':', '-'], ""));
i += 17;
continue;
}
let bare: String = bytes[i..(i + 12).min(bytes.len())].iter().collect();
if bare.chars().count() == 12
&& bare.chars().all(|c| c.is_ascii_hexdigit())
&& boundary_after(&bytes, i + 12)
{
found.push(bare.to_ascii_lowercase());
i += 12;
continue;
}
i += 1;
}
found
}
fn boundary_before(bytes: &[char], i: usize) -> bool {
i == 0 || !matches!(bytes[i - 1], c if c.is_ascii_hexdigit() || c == ':' || c == '-')
}
fn boundary_after(bytes: &[char], end: usize) -> bool {
!bytes
.get(end)
.is_some_and(|c| c.is_ascii_hexdigit() || *c == ':' || *c == '-')
}
fn is_separated_mac(window: &str) -> bool {
let sep = window.as_bytes()[2] as char;
if sep != ':' && sep != '-' {
return false;
}
window.chars().enumerate().all(|(idx, c)| {
if idx % 3 == 2 {
c == sep
} else {
c.is_ascii_hexdigit()
}
})
}
fn ipv4s(text: &str) -> Vec<String> {
let mut found = Vec::new();
for candidate in text.split(|c: char| !(c.is_ascii_digit() || c == '.')) {
let parts: Vec<&str> = candidate.split('.').collect();
if parts.len() != 4 {
continue;
}
if parts
.iter()
.all(|p| !p.is_empty() && p.len() <= 3 && p.parse::<u8>().is_ok())
{
found.push(candidate.to_string());
}
}
found
}
fn scanned_files() -> Vec<PathBuf> {
let root = Path::new(env!("CARGO_MANIFEST_DIR"));
let mut files = vec![root.join("README.md"), root.join("CHANGELOG.md")];
for dir in ["src", "tests"] {
collect_rs(&root.join(dir), &mut files);
}
let self_path = root.join("tests").join("no_real_network_data.rs");
files.retain(|f| f != &self_path && f.exists());
files
}
fn collect_rs(dir: &Path, out: &mut Vec<PathBuf>) {
let Ok(entries) = std::fs::read_dir(dir) else {
return;
};
for entry in entries.flatten() {
let path = entry.path();
if path.is_dir() {
collect_rs(&path, out);
} else if path.extension().is_some_and(|e| e == "rs") {
out.push(path);
}
}
}
#[test]
fn no_vendor_assigned_mac_addresses_are_committed() {
let oui = "d6";
let probe = format!("mac: \"9c:05:{oui}:bc:06:43\" raw: \"9c05{oui}bc0643\"");
let probe_hits = macs(&probe);
assert_eq!(
probe_hits.len(),
2,
"the MAC scanner found {probe_hits:?} in {probe}"
);
for hit in &probe_hits {
assert_eq!(hit, "9c05d6bc0643", "both spellings normalize the same way");
assert!(!ALLOWED_MAC_PREFIXES.contains(&&hit[..6]));
}
let benign = "commit a4ea0fbdeadbe and id 550e8400-e29b-41d4-a716-446655440000";
assert!(
macs(benign).is_empty(),
"the scanner read {:?} out of {benign}",
macs(benign)
);
let mut offenders = Vec::new();
for file in scanned_files() {
let Ok(text) = std::fs::read_to_string(&file) else {
continue;
};
for mac in macs(&text) {
if !ALLOWED_MAC_PREFIXES.contains(&&mac[..6]) {
offenders.push(format!("{}: {mac}", file.display()));
}
}
}
assert!(
offenders.is_empty(),
"MAC addresses outside the fixture allowlist {ALLOWED_MAC_PREFIXES:?} \
reached the repository. If one is real, replace it; if a new synthetic \
prefix is wanted, add it to the allowlist deliberately:\n {}",
offenders.join("\n ")
);
}
#[test]
fn no_addresses_outside_the_documentation_ranges_are_committed() {
let probe = format!("ip: \"10.{}.0.5\", gateway: \"192.168.1.1\"", 0);
let probe_hits = ipv4s(&probe);
assert_eq!(
probe_hits.len(),
2,
"the address scanner found {probe_hits:?} in {probe}"
);
for hit in &probe_hits {
assert!(!is_allowed_ip(hit), "{hit} must not be allowed");
}
let mut offenders = Vec::new();
for file in scanned_files() {
let Ok(text) = std::fs::read_to_string(&file) else {
continue;
};
for ip in ipv4s(&text) {
if !is_allowed_ip(&ip) {
offenders.push(format!("{}: {ip}", file.display()));
}
}
}
assert!(
offenders.is_empty(),
"addresses outside the RFC 5737 documentation ranges reached the \
repository. Use 192.0.2.x, 198.51.100.x or 203.0.113.x:\n {}",
offenders.join("\n ")
);
}
fn is_allowed_ip(ip: &str) -> bool {
ALLOWED_IPS.contains(&ip) || ALLOWED_IP_PREFIXES.iter().any(|p| ip.starts_with(p))
}
#[test]
fn the_scanners_read_the_files_they_claim_to() {
let files = scanned_files();
assert!(
files.len() > 5,
"the scan covers only {files:?}, so a clean result would prove nothing"
);
assert!(
files.iter().any(|f| f.ends_with("mock_server.rs")),
"the largest fixture file must be scanned: {files:?}"
);
assert!(
!files.iter().any(|f| f.ends_with("no_real_network_data.rs")),
"this file names the patterns and must exclude itself"
);
}