{"record":{"id":"5ff99b4470ffea25","repo":"stamparm/maltrail","slug":"dst-ipv6","errorCode":null,"errorMessage":"dst ipv6","messagePattern":"dst ipv6","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sensor/src/testkit.rs","lineNumber":463,"sourceCode":"    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;\n        }","sourceCodeStart":445,"sourceCodeEnd":481,"githubUrl":"https://github.com/stamparm/maltrail/blob/77cfb06d7606506d101bbcec0786c77166c4255e/sensor/src/testkit.rs#L445-L481","documentation":"Same test-kit invariant as its src counterpart: in the ipv6() builder the destination address is converted with addr_to_int(dst).expect(\"dst ipv6\"), which panics when dst is not a valid IPv6 address string. Since ipv6() is only a fixture synthesizing packet bytes for tests (ipv6_detections, ipv6_addr_port_trail, seeds, valid_seeds), the panic indicates an invalid IPv6 literal passed as dst by a test, not a runtime condition. Fix by supplying a well-formed IPv6 destination address in the calling test code.","triggerScenarios":"`ipv6()` called with a dst string that is not a valid IPv6 literal — empty string, IPv4 literal, wrong group count, invalid hex digits, or malformed :: usage.","commonSituations":"Hardcoded test destination with a typo; format!-generated addresses with missing groups; swapping src/dst arguments where one holds an IPv4.","solutions":["Validate dst parses as IPv6 before calling the builder","Correct the literal to a canonical IPv6 form","Match on parse_ipv6 to surface the invalid value in the panic","Keep src/dst argument order consistent to avoid passing an IPv4 where IPv6 is expected"],"exampleFix":"// before\nipv6(proto, src, \"fe80::1::2\", payload) // double compression\n// after\nipv6(proto, src, \"fe80::2\", payload)","handlingStrategy":"validation","validationCode":"fn is_ipv6(s: &str) -> bool { s.parse::<std::net::Ipv6Addr>().is_ok() }\nassert!(is_ipv6(dst), \"dst must be valid IPv6: {dst}\");","typeGuard":"fn is_ipv6(s: &str) -> bool { s.parse::<std::net::Ipv6Addr>().is_ok() }","tryCatchPattern":"let v = crate::addr::parse_ipv6(dst).unwrap_or_else(|e| panic!(\"dst ipv6 '{dst}': {e:?}\"));","preventionTips":["Validate IPv6 literals before calling the builder","Watch for double :: compression when generating addresses programmatically","Include the offending string in panics for quick diagnosis"],"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"}