stamparm/maltrail · error
src ipv6
Error message
src ipv6
What it means
This is a test-kit invariant panic, not a catchable error: the ipv6() packet builder in sensor/src/testkit.rs converts its src address string via addr_to_int() and unwraps with expect("src ipv6"), which fires when the caller passes a src string that is not a valid IPv6 address.ipv6() is a test fixture used by ipv6_detections, ipv6_addr_port_trail, seeds, and valid_seeds to synthesize IPv6 packet bytes, so a malformed src means a broken test seed/address literal, never production input. Fix by correcting the src literal in the calling test to a parseable IPv6 address (e.g. '2001:db8::1').
Solutions
- Validate the src string with parse_ipv6 or std's Ipv6Addr::from_str before building the packet
- Use canonical literals such as "2001:db8::1"
- Match on parse_ipv6 to include the offending string in the panic message
- Ensure the IPv6 builder is not accidentally given IPv4 literals
Example fix
// before ipv6(proto, "2001:db8:::1", dst, payload) // malformed compression // after ipv6(proto, "2001:db8::1", dst, payload)
Defensive patterns
Strategy: validation
Validate before calling
fn is_ipv6(s: &str) -> bool { s.parse::<std::net::Ipv6Addr>().is_ok() }
assert!(is_ipv6(src), "src must be valid IPv6: {src}"); Type guard
fn is_ipv6(s: &str) -> bool { s.parse::<std::net::Ipv6Addr>().is_ok() } Try / catch
let v = crate::addr::parse_ipv6(src).unwrap_or_else(|e| panic!("src ipv6 '{src}': {e:?}")); Prevention
- Use canonical IPv6 literals in tests
- Guard against passing IPv4 addresses to IPv6 helpers
- Add a round-trip test for the ipv6 packet builder
When it happens
Trigger: `ipv6()` called with a src string that is not a valid IPv6 literal (empty, IPv4-only, bad group count, invalid hex, misuse of :: compression).
Common situations: Typo in hardcoded test IPv6 like "2001:db8::1"; passing an IPv4 address to the IPv6 builder; string interpolation producing unbalanced colons.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- dst ipv6
- src ipv4
- dst ipv4
- invalid USERS entry ' ' [?] (hint: add whitespace at start…
- invalid configuration
AI-assisted analysis of stamparm/maltrail@77cfb06d76 (2026-09-13).
Data as JSON: /api/errors/e0fd6d15a93218ad.
Report an issue: GitHub.
Appendix: source
Thrown at sensor/src/testkit.rs:462
out.extend_from_slice(&total.to_be_bytes());
out.extend_from_slice(&0x1234u16.to_be_bytes());
out.extend_from_slice(&frag.to_be_bytes());
out.push(64);
out.push(proto);
out.extend_from_slice(&[0, 0]);
out.extend_from_slice(&crate::addr::addr_to_int(src).expect("src ipv4").to_be_bytes());
out.extend_from_slice(&crate::addr::addr_to_int(dst).expect("dst ipv4").to_be_bytes());
out.extend_from_slice(&options);
out.extend_from_slice(payload);
out
}
pub fn ipv6(proto: u8, src: &str, dst: &str, payload: &[u8]) -> Vec<u8> {
let mut out = vec![0x60, 0, 0, 0];
out.extend_from_slice(&(payload.len() as u16).to_be_bytes());
out.push(proto);
out.push(64);
out.extend_from_slice(&crate::addr::parse_ipv6(src).expect("src ipv6").to_be_bytes());
out.extend_from_slice(&crate::addr::parse_ipv6(dst).expect("dst ipv6").to_be_bytes());
out.extend_from_slice(payload);
out
}
/// IPv6 carrying a chain of extension headers before `proto`.
///
/// Each `exts` entry is (header type, body length in bytes NOT counting the 2-byte
/// Next-Header/Hdr-Ext-Len prefix). Type 44 (Fragment) is fixed at 8 bytes total and ignores the
/// requested length, which is what makes it usable for the non-first-fragment case.
pub fn ipv6_ext(proto: u8, src: &str, dst: &str, exts: &[(u8, usize)], payload: &[u8]) -> Vec<u8> {
let mut chain: Vec<u8> = Vec::new();
for (i, &(kind, body)) in exts.iter().enumerate() {
// each header names the NEXT one, and the last names the transport protocol
let next = exts.get(i + 1).map(|&(k, _)| k).unwrap_or(proto);
if kind == 44 {
chain.extend_from_slice(&[next, 0, 0, 0, 0, 0, 0, 0]);
continue;View on GitHub (pinned to 77cfb06d76)