tshark protocol restriction lifted, frontedn details for packet
All checks were successful
Build and Deploy MITM Webserver / build (push) Successful in 11s
All checks were successful
Build and Deploy MITM Webserver / build (push) Successful in 11s
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// src/components/PacketViewer.tsx
|
||||
import { DeleteOutlined, DownloadOutlined, SyncOutlined } from '@ant-design/icons';
|
||||
import { DeleteOutlined, DownloadOutlined, EyeOutlined, SyncOutlined } from '@ant-design/icons';
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
@@ -47,6 +47,15 @@ function base64ToBlob(b64: string) {
|
||||
return new Blob([arr.buffer], { type: 'application/octet-stream' });
|
||||
}
|
||||
|
||||
function formatJson(value: unknown) {
|
||||
if (value == null) return '(no tshark data)';
|
||||
try {
|
||||
return JSON.stringify(value, null, 2);
|
||||
} catch {
|
||||
return '(failed to format tshark data)';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Improved deterministic color generation
|
||||
*
|
||||
@@ -133,6 +142,7 @@ export default function PacketViewer(): ReactElement {
|
||||
const wsRef = useRef<WebSocket | null>(null);
|
||||
const [hexModalOpen, setHexModalOpen] = useState(false);
|
||||
const [rawHex, setRawHex] = useState<string | null>(null);
|
||||
const [rawTshark, setRawTshark] = useState<string | null>(null);
|
||||
const [rawB64ForDownload, setRawB64ForDownload] = useState<string | null>(null);
|
||||
const [selectedPacket, setSelectedPacket] = useState<PacketRow | null>(null);
|
||||
const queuedDuringPause = useRef<PacketRow[]>([]);
|
||||
@@ -277,6 +287,7 @@ export default function PacketViewer(): ReactElement {
|
||||
return;
|
||||
}
|
||||
setRawHex(base64ToHex(row.raw_b64));
|
||||
setRawTshark(formatJson(row.dpi_metadata ?? null));
|
||||
setRawB64ForDownload(row.raw_b64 ?? null);
|
||||
setSelectedPacket(row);
|
||||
setHexModalOpen(true);
|
||||
@@ -457,28 +468,34 @@ export default function PacketViewer(): ReactElement {
|
||||
{
|
||||
title: 'Actions',
|
||||
key: 'actions',
|
||||
width: 180,
|
||||
width: 96,
|
||||
render: (_: any, rec: PacketRow) => (
|
||||
<Space>
|
||||
<Button size="small" onClick={() => openRawModal(rec)}>
|
||||
View raw
|
||||
</Button>
|
||||
{rec.raw_b64 && (
|
||||
<Tooltip title="View raw + tshark">
|
||||
<Button
|
||||
size="small"
|
||||
icon={<DownloadOutlined />}
|
||||
onClick={() => {
|
||||
const blob = base64ToBlob(rec.raw_b64!);
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = `packet_${rec.id ?? 'pkt'}.bin`;
|
||||
a.click();
|
||||
URL.revokeObjectURL(url);
|
||||
}}
|
||||
>
|
||||
Download
|
||||
</Button>
|
||||
icon={<EyeOutlined />}
|
||||
onClick={() => openRawModal(rec)}
|
||||
aria-label="View raw and tshark data"
|
||||
/>
|
||||
</Tooltip>
|
||||
{rec.raw_b64 && (
|
||||
<Tooltip title="Download raw">
|
||||
<Button
|
||||
size="small"
|
||||
icon={<DownloadOutlined />}
|
||||
onClick={() => {
|
||||
const blob = base64ToBlob(rec.raw_b64!);
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = `packet_${rec.id ?? 'pkt'}.bin`;
|
||||
a.click();
|
||||
URL.revokeObjectURL(url);
|
||||
}}
|
||||
aria-label="Download raw packet"
|
||||
/>
|
||||
</Tooltip>
|
||||
)}
|
||||
</Space>
|
||||
),
|
||||
@@ -545,12 +562,22 @@ export default function PacketViewer(): ReactElement {
|
||||
</Card>
|
||||
|
||||
<Modal
|
||||
title={`Raw packet ${selectedPacket?.id ?? ''}`}
|
||||
title={`Raw + tshark ${selectedPacket?.id ?? ''}`}
|
||||
open={hexModalOpen}
|
||||
onCancel={() => setHexModalOpen(false)}
|
||||
onCancel={() => {
|
||||
setHexModalOpen(false);
|
||||
setRawTshark(null);
|
||||
}}
|
||||
footer={
|
||||
<Space>
|
||||
<Button onClick={() => setHexModalOpen(false)}>Close</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setHexModalOpen(false);
|
||||
setRawTshark(null);
|
||||
}}
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
<Button icon={<DownloadOutlined />} onClick={downloadRaw} type="primary">
|
||||
Download raw
|
||||
</Button>
|
||||
@@ -558,7 +585,16 @@ export default function PacketViewer(): ReactElement {
|
||||
}
|
||||
width={900}
|
||||
>
|
||||
<pre style={{ whiteSpace: 'pre-wrap', wordBreak: 'break-word', fontSize: 12 }}>{rawHex}</pre>
|
||||
<Space direction="vertical" size="middle" style={{ width: '100%' }}>
|
||||
<div>
|
||||
<Text strong>Raw bytes</Text>
|
||||
<pre style={{ whiteSpace: 'pre-wrap', wordBreak: 'break-word', fontSize: 12, marginTop: 8 }}>{rawHex}</pre>
|
||||
</div>
|
||||
<div>
|
||||
<Text strong>TShark data</Text>
|
||||
<pre style={{ whiteSpace: 'pre-wrap', wordBreak: 'break-word', fontSize: 12, marginTop: 8 }}>{rawTshark}</pre>
|
||||
</div>
|
||||
</Space>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user