Files
rea/tests/fixtures/pcap/pcapTestTools.ts
T

127 lines
4.6 KiB
TypeScript

import { chmod, writeFile } from "node:fs/promises";
import { join } from "node:path";
export const CAPINFOS_OUTPUT = [
"File name: /work/capture.pcap",
"File type: Wireshark/tcpdump/... - pcap",
"File encapsulation: Ethernet",
"Packet size limit: file hdr: 262144 bytes",
"Number of packets: 3",
"Capture duration: 0.123 seconds",
"Earliest packet time: 1791728020.608505",
"Latest packet time: 1791728020.981978",
].join("\n");
export const TSHARK_JSON = JSON.stringify([
{
_source: {
layers: {
"frame.number": ["1"],
"frame.protocols": ["eth:ethertype:ip:udp:dns"],
"ip.src": ["192.168.1.100"],
"ip.dst": ["8.8.8.8"],
"dns.qry.name": ["api.example.com"],
"dns.flags.response": ["1"],
"dns.a": ["93.184.216.34"],
},
},
},
{
_source: {
layers: {
"frame.number": ["2"],
"frame.protocols": ["eth:ethertype:ip:tcp:tls"],
"ip.src": ["192.168.1.100"],
"ip.dst": ["93.184.216.34"],
"tls.handshake.extensions_server_name": ["api.example.com"],
},
},
},
{
_source: {
layers: {
"frame.number": ["3"],
"frame.protocols": ["eth:ethertype:ip:tcp:http"],
"ip.src": ["192.168.1.100"],
"ip.dst": ["93.184.216.34"],
"http.request.full_uri": ["http://api.example.com/v1/data"],
},
},
},
]);
export interface PcapStubToolsOptions {
readonly failCapinfos?: boolean;
readonly httpAbsoluteUriOnly?: boolean;
readonly http2Uri?: boolean;
readonly invalidTsharkStream?: "stdout" | "stderr";
readonly invalidTsharkVersionStream?: "stdout" | "stderr";
readonly invalidCapinfosStream?: "stdout" | "stderr";
readonly invalidCapinfosVersionStream?: "stdout" | "stderr";
readonly literalReplacement?: boolean;
readonly literalTsharkVersion?: boolean;
}
/** Write caller-selected POSIX tool stubs for pcap provider and adapter tests. */
export const writeStubTools = async (
root: string,
options: PcapStubToolsOptions = {},
): Promise<{ tshark: string; capinfos: string }> => {
const tshark = join(root, "tshark");
const capinfos = join(root, "capinfos");
const tsharkOutput = options.http2Uri
? TSHARK_JSON.replace(
'"http.request.full_uri":["http://api.example.com/v1/data"]',
'"http2.request.full_uri":["http://example.test/h2"],"http2.headers.path":["/h2"]',
).replace('eth:ethertype:ip:tcp:http"', 'eth:ethertype:ip:tcp:http2"')
: options.literalReplacement
? TSHARK_JSON.replace(
"http://api.example.com/v1/data",
"http://api.example.com/�",
)
: options.httpAbsoluteUriOnly
? TSHARK_JSON.replace(
'"http.request.full_uri":["http://api.example.com/v1/data"]',
'"http.request.uri":["http://proxy.example.test/path"]',
)
: TSHARK_JSON;
await writeFile(
tshark,
`#!/bin/sh
if [ "$1" = "--version" ]; then
printf 'TShark (Wireshark) 4.6.6${options.literalTsharkVersion ? "�" : ""}-stub\\n'
${options.invalidTsharkVersionStream === "stdout" ? `printf '\\377'` : options.invalidTsharkVersionStream === "stderr" ? `printf '\\377' >&2` : ""}
exit 0
fi
[ "$1" = "-n" ] && [ "$2" = "-r" ] && [ "$4" = "-T" ] && [ "$5" = "json" ] || exit 2
case " $* " in *" -e http.request.uri "*) ;; *) exit 2 ;; esac
case " $* " in *" -e http2.request.full_uri "*) ;; *) exit 2 ;; esac
case " $* " in *" -e http2.headers.path "*) ;; *) exit 2 ;; esac
${options.invalidTsharkStream === "stdout" ? `printf '%s' '[{"_source":{"layers":{"frame.number":["1"],"frame.protocols":["eth:ip:tcp:http"],"http.request.full_uri":["http://example.test/'; printf '\\377'; printf '%s' '"]}}}]'` : `printf '%s' '${tsharkOutput.replace(/'/gu, "'\\''")}'`}
${options.invalidTsharkStream === "stderr" ? `printf '\\377' >&2` : ""}
exit 0
`,
{ mode: 0o755 },
);
await writeFile(
capinfos,
`#!/bin/sh
if [ "$1" = "--version" ]; then
printf 'Capinfos (Wireshark) 4.6.6-stub\\n'
${options.invalidCapinfosVersionStream === "stdout" ? `printf '\\377'` : options.invalidCapinfosVersionStream === "stderr" ? `printf '\\377' >&2` : ""}
exit 0
fi
[ "$1" = "-M" ] && [ "$2" = "-S" ] && [ "$3" = "--" ] && [ "$#" = "4" ] || exit 2
if [ "${String(options.failCapinfos === true)}" = "true" ]; then
printf 'capinfos: The file is not a capture file' >&2; exit 1
fi
${options.invalidCapinfosStream === "stdout" ? `printf '\\377'` : options.invalidCapinfosStream === "stderr" ? `printf '\\377' >&2` : `printf '%s\\n' '${CAPINFOS_OUTPUT.replace(/'/gu, "'\\''")}'`}
exit 0
`,
{ mode: 0o755 },
);
await chmod(tshark, 0o755);
await chmod(capinfos, 0o755);
return { tshark, capinfos };
};