{"record":{"id":"e0fd6d15a93218ad","repo":"stamparm/maltrail","slug":"src-ipv6","errorCode":null,"errorMessage":"src ipv6","messagePattern":"src ipv6","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sensor/src/testkit.rs","lineNumber":462,"sourceCode":"    out.extend_from_slice(&total.to_be_bytes());\n    out.extend_from_slice(&0x1234u16.to_be_bytes());\n    out.extend_from_slice(&frag.to_be_bytes());\n    out.push(64);\n    out.push(proto);\n    out.extend_from_slice(&[0, 0]);\n    out.extend_from_slice(&crate::addr::addr_to_int(src).expect(\"src ipv4\").to_be_bytes());\n    out.extend_from_slice(&crate::addr::addr_to_int(dst).expect(\"dst ipv4\").to_be_bytes());\n    out.extend_from_slice(&options);\n    out.extend_from_slice(payload);\n    out\n}\n\npub fn ipv6(proto: u8, src: &str, dst: &str, payload: &[u8]) -> Vec<u8> {\n    let mut out = vec![0x60, 0, 0, 0];\n    out.extend_from_slice(&(payload.len() as u16).to_be_bytes());\n    out.push(proto);\n    out.push(64);\n    out.extend_from_slice(&crate::addr::parse_ipv6(src).expect(\"src ipv6\").to_be_bytes());\n    out.extend_from_slice(&crate::addr::parse_ipv6(dst).expect(\"dst ipv6\").to_be_bytes());\n    out.extend_from_slice(payload);\n    out\n}\n\n/// IPv6 carrying a chain of extension headers before `proto`.\n///\n/// Each `exts` entry is (header type, body length in bytes NOT counting the 2-byte\n/// Next-Header/Hdr-Ext-Len prefix). Type 44 (Fragment) is fixed at 8 bytes total and ignores the\n/// requested length, which is what makes it usable for the non-first-fragment case.\npub fn ipv6_ext(proto: u8, src: &str, dst: &str, exts: &[(u8, usize)], payload: &[u8]) -> Vec<u8> {\n    let mut chain: Vec<u8> = Vec::new();\n    for (i, &(kind, body)) in exts.iter().enumerate() {\n        // each header names the NEXT one, and the last names the transport protocol\n        let next = exts.get(i + 1).map(|&(k, _)| k).unwrap_or(proto);\n        if kind == 44 {\n            chain.extend_from_slice(&[next, 0, 0, 0, 0, 0, 0, 0]);\n            continue;","sourceCodeStart":444,"sourceCodeEnd":480,"githubUrl":"https://github.com/stamparm/maltrail/blob/77cfb06d7606506d101bbcec0786c77166c4255e/sensor/src/testkit.rs#L444-L480","documentation":"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').","triggerScenarios":"`ipv6()` called with a src string that is not a valid IPv6 literal (empty, IPv4-only, bad group count, invalid hex, misuse of :: compression).","commonSituations":"Typo in hardcoded test IPv6 like \"2001:db8::1\"; passing an IPv4 address to the IPv6 builder; string interpolation producing unbalanced colons.","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"],"exampleFix":"// before\nipv6(proto, \"2001:db8:::1\", dst, payload) // malformed compression\n// after\nipv6(proto, \"2001:db8::1\", dst, payload)","handlingStrategy":"validation","validationCode":"fn is_ipv6(s: &str) -> bool { s.parse::<std::net::Ipv6Addr>().is_ok() }\nassert!(is_ipv6(src), \"src must be valid IPv6: {src}\");","typeGuard":"fn is_ipv6(s: &str) -> bool { s.parse::<std::net::Ipv6Addr>().is_ok() }","tryCatchPattern":"let v = crate::addr::parse_ipv6(src).unwrap_or_else(|e| panic!(\"src ipv6 '{src}': {e:?}\"));","preventionTips":["Use canonical IPv6 literals in tests","Guard against passing IPv4 addresses to IPv6 helpers","Add a round-trip test for the ipv6 packet builder"],"tags":["rust","ipv6","test-harness","parsing"],"backgroundTag":"invalid-argument-format","analyzedSha":"77cfb06d7606506d101bbcec0786c77166c4255e","analyzedAt":"2026-09-13T03:50:16.010Z","contentChangedAt":"2026-09-13T03:50:16.010Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}