+
{this.generateRows(["service_port", "client_address", "min_duration",
- "min_bytes", "started_after", "closed_after", "marked"])}
+ "min_bytes"])}
@@ -95,14 +95,11 @@ class Filters extends Component {
{this.generateRows(["matched_rules", "client_port", "max_duration",
- "max_bytes", "started_before", "closed_before", "hidden"])}
+ "max_bytes", "marked"])}
-
-
-
diff --git a/frontend/src/components/fields/ButtonField.js b/frontend/src/components/fields/ButtonField.js
index ffcceae..193339c 100644
--- a/frontend/src/components/fields/ButtonField.js
+++ b/frontend/src/components/fields/ButtonField.js
@@ -55,8 +55,8 @@ class ButtonField extends Component {
}
return (
-
-
);
diff --git a/frontend/src/components/fields/TextField.scss b/frontend/src/components/fields/TextField.scss
index c2d6ef5..5fde9e6 100644
--- a/frontend/src/components/fields/TextField.scss
+++ b/frontend/src/components/fields/TextField.scss
@@ -51,4 +51,8 @@
padding: 5px 10px;
color: $color-secondary-0;
}
+
+ &:hover::-webkit-scrollbar-thumb {
+ background: $color-secondary-2 !important;
+ }
}
diff --git a/frontend/src/components/filters/FiltersDefinitions.js b/frontend/src/components/filters/FiltersDefinitions.js
index cde3cfb..9fb3b18 100644
--- a/frontend/src/components/filters/FiltersDefinitions.js
+++ b/frontend/src/components/filters/FiltersDefinitions.js
@@ -22,8 +22,7 @@ import RulesConnectionsFilter from "./RulesConnectionsFilter";
import BooleanConnectionsFilter from "./BooleanConnectionsFilter";
export const filtersNames = ["service_port", "matched_rules", "client_address", "client_port",
- "min_duration", "max_duration", "min_bytes", "max_bytes", "started_after",
- "started_before", "closed_after", "closed_before", "marked", "hidden"];
+ "min_duration", "max_duration", "min_bytes", "max_bytes", "marked"];
export const filtersDefinitions = {
service_port: ,
- // started_after: ,
- // started_before: ,
- // closed_after: ,
- // closed_before: ,
- marked: ,
- // hidden:
+ contains_string: ,
+ marked:
};
diff --git a/frontend/src/components/objects/Connection.js b/frontend/src/components/objects/Connection.js
index 5e2beba..e0e942a 100644
--- a/frontend/src/components/objects/Connection.js
+++ b/frontend/src/components/objects/Connection.js
@@ -17,11 +17,12 @@
import React, {Component} from 'react';
import './Connection.scss';
-import {Form, OverlayTrigger, Popover} from "react-bootstrap";
+import {Form} from "react-bootstrap";
import backend from "../../backend";
import {dateTimeToTime, durationBetween, formatSize} from "../../utils";
import ButtonField from "../fields/ButtonField";
import LinkPopover from "./LinkPopover";
+import TextField from "../fields/TextField";
const classNames = require('classnames');
@@ -81,14 +82,6 @@ class Connection extends Component {
Closed at {closedAt.toLocaleDateString() + " " + closedAt.toLocaleTimeString()}
;
- const popoverFor = function (name, content) {
- return
-
- {content}
-
- ;
- };
-
const commentPopoverContent =
Click to {conn.comment.length > 0 ? "edit" : "add"} comment
{conn.comment &&
}
@@ -97,7 +90,7 @@ class Connection extends Component {
const copyPopoverContent =
{this.state.copiedMessage ? Copied! :
Click to copy the connection id}
-
+
;
return (
@@ -119,22 +112,16 @@ class Connection extends Component {
{durationBetween(startedAt, closedAt)} |
{formatSize(conn["client_bytes"])} |
{formatSize(conn["server_bytes"])} |
-
- Mark this connection)}>
- this.handleAction("mark")}>!!
-
-
- this.handleAction("comment")}>@
-
-
- this.handleAction("copy")}>#
-
+ |
+ this.handleAction("mark")}>!!}
+ content={Mark this connection} placement="right"/>
+ this.handleAction("comment")}>@}
+ content={commentPopoverContent} placement="right"/>
+ this.handleAction("copy")}>#}
+ content={copyPopoverContent} placement="right"/>
|
);
diff --git a/frontend/src/components/objects/Connection.scss b/frontend/src/components/objects/Connection.scss
index 3b9f479..bf66272 100644
--- a/frontend/src/components/objects/Connection.scss
+++ b/frontend/src/components/objects/Connection.scss
@@ -46,6 +46,10 @@
.link-popover {
font-weight: 400;
}
+
+ .connection-actions .link-popover {
+ text-decoration: none;
+ }
}
.connection-popover {
diff --git a/frontend/src/components/objects/LinkPopover.scss b/frontend/src/components/objects/LinkPopover.scss
index 725224c..c81f8bb 100644
--- a/frontend/src/components/objects/LinkPopover.scss
+++ b/frontend/src/components/objects/LinkPopover.scss
@@ -5,3 +5,8 @@
cursor: pointer;
text-decoration: underline;
}
+
+.popover {
+ font-family: "Fira Code", monospace;
+ font-size: 0.75em;
+}
diff --git a/frontend/src/components/pages/MainPage.js b/frontend/src/components/pages/MainPage.js
index 7376091..4632bbd 100644
--- a/frontend/src/components/pages/MainPage.js
+++ b/frontend/src/components/pages/MainPage.js
@@ -57,7 +57,7 @@ class MainPage extends Component {
}/>
}/>
- }/>
+ }/>
diff --git a/frontend/src/components/pages/MainPage.scss b/frontend/src/components/pages/MainPage.scss
index 3b1a689..4ca54c0 100644
--- a/frontend/src/components/pages/MainPage.scss
+++ b/frontend/src/components/pages/MainPage.scss
@@ -13,6 +13,7 @@
}
.details-pane {
+ position: relative;
flex: 1 1;
margin-left: 7.5px;
}
diff --git a/frontend/src/components/panels/ConnectionsPane.js b/frontend/src/components/panels/ConnectionsPane.js
index 038ef8f..1f79ab8 100644
--- a/frontend/src/components/panels/ConnectionsPane.js
+++ b/frontend/src/components/panels/ConnectionsPane.js
@@ -27,6 +27,8 @@ import log from "../../log";
import ButtonField from "../fields/ButtonField";
import dispatcher from "../../dispatcher";
+const classNames = require('classnames');
+
class ConnectionsPane extends Component {
state = {
@@ -81,6 +83,11 @@ class ConnectionsPane extends Component {
this.loadServices().then(() => log.debug("Services reloaded after notification update"));
}
});
+
+ dispatcher.register("pulse_connections_view", payload => {
+ this.setState({pulseConnectionsView: true});
+ setTimeout(() => this.setState({pulseConnectionsView: false}), payload.duration);
+ });
}
connectionSelected = (c, doRedirect = true) => {
@@ -246,7 +253,7 @@ class ConnectionsPane extends Component {
return (
{this.state.showMoreRecentButton &&
- {
+ {
this.disableScrollHandler = true;
this.connectionsListRef.current.scrollTop = 0;
this.loadConnections({limit: this.queryLimit})
@@ -257,7 +264,8 @@ class ConnectionsPane extends Component {
}}/>
}
-
+
diff --git a/frontend/src/components/panels/ConnectionsPane.scss b/frontend/src/components/panels/ConnectionsPane.scss
index 06f5827..59fe372 100644
--- a/frontend/src/components/panels/ConnectionsPane.scss
+++ b/frontend/src/components/panels/ConnectionsPane.scss
@@ -33,6 +33,9 @@
z-index: 20;
top: 45px;
left: calc(50% - 50px);
- background-color: red;
+ }
+
+ .connections-pulse {
+ animation: pulse 2s infinite;
}
}
diff --git a/frontend/src/components/panels/MainPane.js b/frontend/src/components/panels/MainPane.js
index 74c859c..8aa8ad8 100644
--- a/frontend/src/components/panels/MainPane.js
+++ b/frontend/src/components/panels/MainPane.js
@@ -17,17 +17,91 @@
import React, {Component} from 'react';
import './common.scss';
-import './ServicesPane.scss';
+import './MainPane.scss';
+import Typed from "typed.js";
+import dispatcher from "../../dispatcher";
+import RulesPane from "./RulesPane";
+import StreamsPane from "./StreamsPane";
+import PcapsPane from "./PcapsPane";
+import ServicesPane from "./ServicesPane";
class MainPane extends Component {
state = {};
+ componentDidMount() {
+ const nl = "^600\n^400";
+ const options = {
+ strings: [
+ `welcome to caronte!^1000 the current version is ${this.props.version}` + nl +
+ "caronte is a network analyzer,^300 it is able to read pcaps and extract connections", // 0
+ "the left panel lists all connections that have already been closed" + nl +
+ "scrolling up the list will load the most recent connections,^300 downward the oldest ones", // 1
+ "by selecting a connection you can view its content,^300 which will be shown in the right panel" + nl +
+ "you can choose the display format,^300 or decide to download the connection content", // 2
+ "below there is the timeline,^300 which shows the number of connections per minute per service" + nl +
+ "you can use the sliding window to move the time range of the connections to be displayed", // 3
+ "there are also additional metrics,^300 selectable from the drop-down menu", // 4
+ "at the top are the filters,^300 which can be used to select only certain types of connections" + nl +
+ "you can choose which filters to display in the top bar from the filters window", // 5
+ "in the pcaps panel it is possible to analyze new pcaps,^300 or to see the pcaps already analyzed" + nl +
+ "you can load pcaps from your browser,^300 or process pcaps already present on the filesystem", // 6
+ "in the rules panel you can see the rules already created,^300 or create new ones" + nl +
+ "the rules inserted will be used only to label new connections, not those already analyzed" + nl +
+ "a connection is tagged if it meets all the requirements specified by the rule", // 7
+ "in the services panel you can assign new services or edit existing ones" + nl +
+ "each service is associated with a port number,^300 and will be shown in the connection list", // 8
+ "from the configuration panel you can change the settings of the frontend application", // 9
+ "that's all! and have fun!" + nl + "created by @eciavatta" // 10
+ ],
+ typeSpeed: 40,
+ cursorChar: "_",
+ backSpeed: 5,
+ smartBackspace: false,
+ backDelay: 1500,
+ preStringTyped: (arrayPos) => {
+ switch (arrayPos) {
+ case 1:
+ return dispatcher.dispatch("pulse_connections_view", {duration: 12000});
+ case 2:
+ return this.setState({backgroundPane: });
+ case 3:
+ this.setState({backgroundPane: null});
+ return dispatcher.dispatch("pulse_timeline", {duration: 12000});
+ case 6:
+ return this.setState({backgroundPane: });
+ case 7:
+ return this.setState({backgroundPane: });
+ case 8:
+ return this.setState({backgroundPane: });
+ case 10:
+ return this.setState({backgroundPane: null});
+ default:
+ return;
+ }
+ },
+ };
+ this.typed = new Typed(this.el, options);
+ }
+
+ componentWillUnmount() {
+ this.typed.destroy();
+ }
+
render() {
return (
-
-
- MainPane
+
+
+
+
+ {
+ this.el = el;
+ }}/>
+
+
+
+
+ {this.state.backgroundPane}
);
diff --git a/frontend/src/components/panels/MainPane.scss b/frontend/src/components/panels/MainPane.scss
index c8460f2..8f99b3c 100644
--- a/frontend/src/components/panels/MainPane.scss
+++ b/frontend/src/components/panels/MainPane.scss
@@ -1,5 +1,30 @@
@import "../../colors";
-.main-pane {
+.pane-container {
+ background-color: $color-primary-0;
+ .main-pane {
+ position: absolute;
+ z-index: 50;
+ top: 0;
+ left: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 100%;
+ height: 100%;
+ background-color: transparent;
+
+ .tutorial {
+ flex-basis: 100%;
+ padding: 5px 10px;
+ text-align: center;
+ background-color: $color-primary-2;
+ }
+ }
+
+ .background-pane {
+ height: 100%;
+ opacity: 0.4;
+ }
}
diff --git a/frontend/src/components/panels/StreamsPane.js b/frontend/src/components/panels/StreamsPane.js
index c8bd121..bd1964e 100644
--- a/frontend/src/components/panels/StreamsPane.js
+++ b/frontend/src/components/panels/StreamsPane.js
@@ -208,8 +208,8 @@ class StreamsPane extends Component {
);
return (
-
-
+
+
flow: {conn["ip_src"]}:{conn["port_src"]} -> {conn["ip_dst"]}:{conn["port_dst"]}
@@ -235,7 +235,6 @@ class StreamsPane extends Component {
);
}
-
}
diff --git a/frontend/src/components/panels/StreamsPane.scss b/frontend/src/components/panels/StreamsPane.scss
index d5510cf..1f641f3 100644
--- a/frontend/src/components/panels/StreamsPane.scss
+++ b/frontend/src/components/panels/StreamsPane.scss
@@ -1,7 +1,6 @@
@import "../../colors";
-.connection-content {
- height: 100%;
+.stream-pane {
background-color: $color-primary-0;
pre {
@@ -15,6 +14,10 @@
margin: 0;
padding: 0;
}
+
+ &:hover::-webkit-scrollbar-thumb {
+ background: $color-secondary-2;
+ }
}
.connection-message {
@@ -87,7 +90,7 @@
}
}
- .connection-content-header {
+ .stream-pane-header {
height: 33px;
padding: 0;
background-color: $color-primary-3;
diff --git a/frontend/src/components/panels/common.scss b/frontend/src/components/panels/common.scss
index 1468f35..335e65b 100644
--- a/frontend/src/components/panels/common.scss
+++ b/frontend/src/components/panels/common.scss
@@ -32,6 +32,10 @@
margin-left: 10px;
color: $color-secondary-0;
}
+
+ &:hover::-webkit-scrollbar-thumb {
+ background: $color-secondary-2;
+ }
}
table {
@@ -96,4 +100,8 @@
margin-left: 5px;
}
}
+
+ &:hover::-webkit-scrollbar-thumb {
+ background: $color-secondary-2;
+ }
}
diff --git a/frontend/src/index.scss b/frontend/src/index.scss
index 9d6afc4..ea360be 100644
--- a/frontend/src/index.scss
+++ b/frontend/src/index.scss
@@ -77,3 +77,15 @@ a {
.popover-header {
color: $color-primary-1;
}
+
+@keyframes pulse {
+ 0% {
+ opacity: 1;
+ }
+ 50% {
+ opacity: 0.3;
+ }
+ 100% {
+ opacity: 1;
+ }
+}
diff --git a/frontend/src/logo.svg b/frontend/src/logo.svg
index 6b60c10..cb825f3 100644
--- a/frontend/src/logo.svg
+++ b/frontend/src/logo.svg
@@ -1,7 +1 @@
-
+
\ No newline at end of file
diff --git a/notification_controller.go b/notification_controller.go
index 3fa3c5b..b9b3b1c 100644
--- a/notification_controller.go
+++ b/notification_controller.go
@@ -27,10 +27,6 @@ import (
)
const (
- InsertNotification = "insert"
- UpdateNotification = "update"
- DeleteNotification = "delete"
-
writeWait = 10 * time.Second
pongWait = 60 * time.Second
pingPeriod = (pongWait * 9) / 10
@@ -122,8 +118,8 @@ func (wc *NotificationController) Run() {
}
}
-func (wc *NotificationController) Notify(event string, eventType string, message interface{}) {
- wc.broadcast <- gin.H{"event": event, "event_type": eventType, "message": message}
+func (wc *NotificationController) Notify(event string, message interface{}) {
+ wc.broadcast <- gin.H{"event": event, "message": message}
}
func (c *client) readPump() {
diff --git a/resources_controller.go b/resources_controller.go
index 10b31e3..0576e0f 100644
--- a/resources_controller.go
+++ b/resources_controller.go
@@ -98,7 +98,7 @@ func (csc *ResourcesController) Run() {
avg := Average(cpuPercent)
if avg > averageCPUPercentAlertThreshold && time.Now().Sub(lastAlertTime).Seconds() > averageCPUPercentAlertMinInterval {
- csc.notificationController.Notify("resources.cpu_alert", "alert", gin.H{
+ csc.notificationController.Notify("resources.cpu_alert", gin.H{
"cpu_percent": cpuPercent,
})
log.WithField("cpu_percent", cpuPercent).Warn("cpu percent usage has exceeded the limit threshold")
--
cgit v1.2.3-70-g09d2