{"record":{"id":"531354c9e1b4d4eb","repo":"stamparm/maltrail","slug":"dst-ipv4","errorCode":null,"errorMessage":"dst ipv4","messagePattern":"dst ipv4","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sensor/src/testkit.rs","lineNumber":451,"sourceCode":"    out\n}\n\npub fn ipv4(proto: u8, src: &str, dst: &str, payload: &[u8]) -> Vec<u8> {\n    ipv4_opts(proto, src, dst, payload, 5, 0)\n}\n\npub fn ipv4_opts(proto: u8, src: &str, dst: &str, payload: &[u8], ihl: u8, frag: u16) -> Vec<u8> {\n    let options = vec![0u8; ((ihl as usize).saturating_sub(5)) * 4];\n    let total = (ihl as usize * 4 + payload.len()) as u16;\n    let mut out = vec![0x40 | (ihl & 0x0f), 0];\n    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///","sourceCodeStart":433,"sourceCodeEnd":469,"githubUrl":"https://github.com/stamparm/maltrail/blob/77cfb06d7606506d101bbcec0786c77166c4255e/sensor/src/testkit.rs#L433-L469","documentation":"Panic from `.expect(\"dst ipv4\")` when `crate::addr::addr_to_int(dst)` fails to parse the destination IPv4 address in `ipv4_opts`. Same strictness as the source address check, applied to the destination.","triggerScenarios":"`ipv4_opts()`/`ipv4` called with a dst string that is not a valid dotted-quad IPv4 address (empty, hostname, out-of-range octet, IPv6 literal).","commonSituations":"Copy-paste of an IPv6 destination into the IPv4 builder; dynamically generated dst with a formatting bug; placeholder string left unedited.","solutions":["Validate the dst string parses as IPv4 before calling the builder","Replace the malformed literal with a valid dotted-quad address","Panic with the address value via match for faster diagnosis","Add a small helper test asserting the helper builders round-trip valid addresses"],"exampleFix":"// before\nipv4_opts(proto, src, \"192.168.1\", &[], payload) // missing octet\n// after\nipv4_opts(proto, src, \"192.168.1.1\", &[], payload)","handlingStrategy":"validation","validationCode":"fn is_ipv4(s: &str) -> bool { s.parse::<std::net::Ipv4Addr>().is_ok() }\nassert!(is_ipv4(dst), \"dst must be valid IPv4: {dst}\");","typeGuard":"fn is_ipv4(s: &str) -> bool { s.parse::<std::net::Ipv4Addr>().is_ok() }","tryCatchPattern":"let v = crate::addr::addr_to_int(dst).unwrap_or_else(|e| panic!(\"dst ipv4 '{dst}': {e:?}\"));","preventionTips":["Check dotted-quad completeness (four octets) in generated addresses","Validate literals before building packets","Keep src/dst argument order fixed to avoid swapped types"],"tags":["rust","ipv4","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"}