test ebpf
All checks were successful
Build and Deploy MITM Webserver / build (push) Successful in 1m40s
All checks were successful
Build and Deploy MITM Webserver / build (push) Successful in 1m40s
This commit is contained in:
@@ -84,8 +84,12 @@ function colorForName(name: string) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Parse iface field into an array of strings */
|
||||
function parseIfaces(ifaceField?: string | string[]) {
|
||||
function packetKey(packet: PacketRow) {
|
||||
return String(packet.packet_uid ?? packet.id ?? `${packet.iface ?? 'if'}:${packet.timestamp ?? ''}`);
|
||||
}
|
||||
|
||||
function parseIfaces(ifaceField?: string | string[] | null, observedIfaces?: string[] | null) {
|
||||
if (Array.isArray(observedIfaces) && observedIfaces.length > 0) return observedIfaces;
|
||||
if (!ifaceField) return [];
|
||||
if (Array.isArray(ifaceField)) return ifaceField;
|
||||
return String(ifaceField)
|
||||
@@ -131,14 +135,32 @@ export default function PacketViewer(): ReactElement {
|
||||
const [selectedPacket, setSelectedPacket] = useState<PacketRow | null>(null);
|
||||
const queuedDuringPause = useRef<PacketRow[]>([]);
|
||||
|
||||
// helper: prepend new packets (newest first). Keep list capped.
|
||||
const pushNew = useCallback((newPkts: PacketRow[] | PacketRow) => {
|
||||
setPackets((prev) => {
|
||||
const arr = Array.isArray(newPkts) ? newPkts : [newPkts];
|
||||
const normalized = arr.map((p) => p);
|
||||
const merged = [...normalized, ...prev];
|
||||
if (merged.length > MAX_PACKETS) return merged.slice(0, MAX_PACKETS);
|
||||
return merged;
|
||||
const next = [...prev];
|
||||
|
||||
for (const packet of arr) {
|
||||
const key = packetKey(packet);
|
||||
const index = next.findIndex((item) => packetKey(item) === key);
|
||||
if (index >= 0) {
|
||||
next[index] = { ...next[index], ...packet };
|
||||
} else {
|
||||
next.unshift(packet);
|
||||
}
|
||||
}
|
||||
|
||||
next.sort((left, right) => {
|
||||
const leftId = Number(left.id ?? 0);
|
||||
const rightId = Number(right.id ?? 0);
|
||||
if (!Number.isNaN(leftId) && !Number.isNaN(rightId) && leftId !== rightId) {
|
||||
return rightId - leftId;
|
||||
}
|
||||
return String(right.timestamp ?? '').localeCompare(String(left.timestamp ?? ''));
|
||||
});
|
||||
|
||||
if (next.length > MAX_PACKETS) return next.slice(0, MAX_PACKETS);
|
||||
return next;
|
||||
});
|
||||
}, []);
|
||||
|
||||
@@ -284,7 +306,7 @@ export default function PacketViewer(): ReactElement {
|
||||
key: 'iface',
|
||||
width: 100,
|
||||
render: (_: any, rec: PacketRow) => {
|
||||
const ifaces = parseIfaces(rec.iface);
|
||||
const ifaces = parseIfaces(rec.iface, rec.observed_ifaces);
|
||||
if (ifaces.length === 0) return <Text type="secondary">-</Text>;
|
||||
return (
|
||||
<Space wrap size={[6, 6]}>
|
||||
@@ -301,10 +323,38 @@ export default function PacketViewer(): ReactElement {
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Path',
|
||||
key: 'path',
|
||||
width: 150,
|
||||
render: (_: any, rec: PacketRow) => (
|
||||
<Space direction="vertical" size={0}>
|
||||
<Text>{rec.ingress_if ?? '-'}</Text>
|
||||
<Text type="secondary">{rec.egress_if ?? '-'}</Text>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Verdict',
|
||||
key: 'verdict',
|
||||
width: 120,
|
||||
render: (_: any, rec: PacketRow) => {
|
||||
const verdict = rec.verdict ?? '-';
|
||||
const confidence = rec.verdict_confidence ? ` (${rec.verdict_confidence})` : '';
|
||||
return (
|
||||
<Space direction="vertical" size={0}>
|
||||
<Text>{verdict}</Text>
|
||||
<Text type="secondary" style={{ fontSize: 12 }}>
|
||||
{(rec.verdict_reason ?? '') + confidence}
|
||||
</Text>
|
||||
</Space>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'MAC (src → dst)',
|
||||
key: 'macs',
|
||||
width: 100,
|
||||
width: 180,
|
||||
render: (_: any, rec: PacketRow) => (
|
||||
<div>
|
||||
<div>
|
||||
@@ -445,7 +495,14 @@ export default function PacketViewer(): ReactElement {
|
||||
<Switch checked={!paused} onChange={(checked) => handlePauseToggle(!checked ? true : false)} />
|
||||
|
||||
<Button icon={<SyncOutlined />} onClick={handleRefresh} loading={statusLoading} />
|
||||
<Button onClick={() => clearPackets()} danger icon={<DeleteOutlined />} />
|
||||
<Button
|
||||
onClick={async () => {
|
||||
await clearPackets();
|
||||
setPackets([]);
|
||||
}}
|
||||
danger
|
||||
icon={<DeleteOutlined />}
|
||||
/>
|
||||
</Space>
|
||||
</Col>
|
||||
</Row>
|
||||
@@ -461,9 +518,7 @@ export default function PacketViewer(): ReactElement {
|
||||
</div>
|
||||
) : (
|
||||
<Table
|
||||
rowKey={(rec: PacketRow) =>
|
||||
String(rec.id ?? `${rec.iface ?? 'if'}:${rec.timestamp ?? ''}:${Math.random()}`)
|
||||
}
|
||||
rowKey={(rec: PacketRow) => packetKey(rec)}
|
||||
dataSource={packets}
|
||||
columns={columns as any}
|
||||
pagination={{ pageSize: 25 }}
|
||||
|
||||
Reference in New Issue
Block a user