/*
* This file is part of caronte (https://github.com/eciavatta/caronte).
* Copyright (c) 2020 Emiliano Ciavatta.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
import React, {Component} from "react";
import Table from "react-bootstrap/Table";
import backend from "../../backend";
import dispatcher from "../../dispatcher";
import {createCurlCommand, dateTimeToTime, durationBetween, formatSize} from "../../utils";
import ButtonField from "../fields/ButtonField";
import CheckField from "../fields/CheckField";
import InputField from "../fields/InputField";
import TextField from "../fields/TextField";
import CopyLinkPopover from "../objects/CopyLinkPopover";
import LinkPopover from "../objects/LinkPopover";
import "./common.scss";
import "./PcapsPane.scss";
class PcapsPane extends Component {
state = {
sessions: [],
isUploadFileValid: true,
isUploadFileFocused: false,
uploadFlushAll: false,
isFileValid: true,
isFileFocused: false,
fileValue: "",
processFlushAll: false,
deleteOriginalFile: false
};
componentDidMount() {
this.loadSessions();
dispatcher.register("notifications", this.handleNotifications);
document.title = "caronte:~/pcaps$";
}
componentWillUnmount() {
dispatcher.unregister(this.handleNotifications);
}
handleNotifications = (payload) => {
if (payload.event.startsWith("pcap")) {
this.loadSessions();
}
};
loadSessions = () => {
backend.get("/api/pcap/sessions")
.then((res) => this.setState({sessions: res.json, sessionsStatusCode: res.status}))
.catch((res) => this.setState({
sessions: res.json, sessionsStatusCode: res.status,
sessionsResponse: JSON.stringify(res.json)
}));
};
uploadPcap = () => {
if (this.state.uploadSelectedFile == null || !this.state.isUploadFileValid) {
this.setState({isUploadFileFocused: true});
return;
}
const formData = new FormData();
formData.append("file", this.state.uploadSelectedFile);
formData.append("flush_all", this.state.uploadFlushAll);
backend.postFile("/api/pcap/upload", formData).then((res) => {
this.setState({
uploadStatusCode: res.status,
uploadResponse: JSON.stringify(res.json)
});
this.resetUpload();
this.loadSessions();
}).catch((res) => this.setState({
uploadStatusCode: res.status,
uploadResponse: JSON.stringify(res.json)
})
);
};
processPcap = () => {
if (this.state.fileValue === "" || !this.state.isFileValid) {
this.setState({isFileFocused: true});
return;
}
backend.post("/api/pcap/file", {
"file": this.state.fileValue,
"flush_all": this.state.processFlushAll,
"delete_original_file": this.state.deleteOriginalFile
}).then((res) => {
this.setState({
processStatusCode: res.status,
processResponse: JSON.stringify(res.json)
});
this.resetProcess();
this.loadSessions();
}).catch((res) => this.setState({
processStatusCode: res.status,
processResponse: JSON.stringify(res.json)
})
);
};
resetUpload = () => {
this.setState({
isUploadFileValid: true,
isUploadFileFocused: false,
uploadFlushAll: false,
uploadSelectedFile: null
});
};
resetProcess = () => {
this.setState({
isFileValid: true,
isFileFocused: false,
fileValue: "",
processFlushAll: false,
deleteOriginalFile: false,
});
};
render() {
let sessions = this.state.sessions.map((s) => {
const startedAt = new Date(s["started_at"]);
const completedAt = new Date(s["completed_at"]);
let timeInfo =
Started at {startedAt.toLocaleDateString() + " " + startedAt.toLocaleTimeString()}
Completed at {completedAt.toLocaleDateString() + " " + completedAt.toLocaleTimeString()}
;
return
|
|
{durationBetween(s["started_at"], s["completed_at"])} |
{formatSize(s["size"])} |
{s["processed_packets"]} |
{s["invalid_packets"]} |
|
download
|
;
});
const handleUploadFileChange = (file) => {
this.setState({
isUploadFileValid: file == null || (file.type.endsWith("pcap") || file.type.endsWith("pcapng")),
isUploadFileFocused: false,
uploadSelectedFile: file,
uploadStatusCode: null,
uploadResponse: null
});
};
const handleFileChange = (file) => {
this.setState({
isFileValid: (file.endsWith("pcap") || file.endsWith("pcapng")),
isFileFocused: false,
fileValue: file,
processStatusCode: null,
processResponse: null
});
};
const uploadCurlCommand = createCurlCommand("/pcap/upload", "POST", null, {
"file": "@" + ((this.state.uploadSelectedFile != null && this.state.isUploadFileValid) ?
this.state.uploadSelectedFile.name : "invalid.pcap"),
"flush_all": this.state.uploadFlushAll
});
const fileCurlCommand = createCurlCommand("/pcap/file", "POST", {
"file": this.state.fileValue,
"flush_all": this.state.processFlushAll,
"delete_original_file": this.state.deleteOriginalFile
});
return (
GET /api/pcap/sessions
id |
started_at |
duration |
size |
processed_packets |
invalid_packets |
packets_per_service |
actions |
{sessions}
POST /api/pcap/upload
options:
this.setState({uploadFlushAll: v})}/>
POST /api/pcap/file
this.setState({processFlushAll: v})}/>
this.setState({deleteOriginalFile: v})}/>
);
}
}
export default PcapsPane;