/* * 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
{sessions}
id started_at duration size processed_packets invalid_packets packets_per_service actions
POST /api/pcap/upload
options: this.setState({uploadFlushAll: v})}/>
POST /api/pcap/file
this.setState({processFlushAll: v})}/> this.setState({deleteOriginalFile: v})}/>
); } } export default PcapsPane;