Added processing of connections.

This commit is contained in:
WickedJack99
2023-12-28 21:53:25 +01:00
parent 5ec27cc673
commit 9db12a6da4
7 changed files with 337 additions and 68 deletions

View File

@@ -0,0 +1,24 @@
/**
* @author Aaron Moser
* @date 28.12.2023
*/
package controller.src.DataProcessing.ConnectionsProcessing;
/**
* Record displays packed information about one connection at the agent side.
*/
public final record ConnectionInformation(
int fileDescriptor,
String addressFamily,
String socketKind,
String localAddress,
int localPort,
String remoteAddress,
int remotePort,
String status,
int pid) {
public boolean equals(ConnectionInformation other) {
return this.fileDescriptor == other.fileDescriptor && this.pid == other.pid;
}
}

View File

@@ -0,0 +1,191 @@
/**
* @author Aaron Moser
* @date 28.12.2023
*/
package controller.src.DataProcessing.ConnectionsProcessing;
/**
* Provides a function to retrieve information from a connection string.
* sconn(fd=9, family=<AddressFamily.AF_UNIX: 1>, type=<SocketKind.SOCK_STREAM: 1>, laddr='', raddr='', status='NONE', pid=1789)
* fd stands for file descriptor
* laddr: local address
* raddr: remote address
* pid stands for process id
*/
public final class ConnectionsProcessor {
private static final int HEAD_LENGTH = 6;
private static final int TAIL_LENGTH = 1;
private static final String[] ADDRESS_FAMILIES = {
"AF_UNIX", // Unix domain sockets
"AF_LOCAL", // Unix domain sockets
"AF_INET", // IPv4 communication
"AF_INET6", // IPv6 communication
"AF_NETLINK", // Used for communication with the Linux kernel using the Netlink protocol
"AF_PACKET", // Low-level packet manipulation
"AF_BLUETOOTH", // Bluetooth communication
"AF_CAN", // Controller Area Network (CAN) communication
"AF_RDS", // Reliable Datagram Sockets (RDS) communication
"AF_ALG", // Cryptographic socket support
"AF_VSOCK", // Virtual Socket (vsock) communication for hypervisor-based applications
"AF_XDP" // eXpress Data Path (XDP) socket family for high-performance packet processing
};
private static final String[] SOCKET_KINDS = {
"SOCK_STREAM", // provides a reliable, stream-oriented connection, typically used for TCP sockets
"SOCK_DGRAM", // provides a connectionless, unreliable communication method, typically used for UDP sockets
"SOCK_RAW", // allows low-level access to network protocols, often used for custom packet manipulation
"SOCK_SEQPACKET", // similar to SOCK_STREAM but provides a record-oriented, connection-based socket
"SOCK_RDM", // reliable datagram sockets
"SOCK_PACKET" // used for low-level packet capture and injection
};
private static final String[] CONNECTION_STATUSES = {
"NONE",
"ESTABLISHED", // socket connection is established and data can be exchanged
"LISTEN", // socket is listening for incoming connections
"CLOSE_WAIT", // socket is waiting for the remote end to close the connection
"TIME_WAIT", // socket is waiting for any remaining packets to arrive after the connection is closed
"CLOSED", // socket is closed and no longer in use
"SYN_SENT", // socket has sent a SYN packet to initiate a connection
"SYN_RECEIVED", // socket has received a SYN packet and is waiting for an ACK to complete the connection establishment
"FIN_WAIT1", // socket is in the process of closing the connection
"FIN_WAIT2" // socket is in the process of closing the connection
};
/**
* Processes a data string which contains the information about one connection at the agents side.
* @param dataString the string which contains the information.
* @return an object of type ConnectionInformation.
*/
public static ConnectionInformation processDataString(String dataString) {
String[] dataStringParts = removeHeadAndTail(dataString).split(" ");
int fileDescriptor = -1;
String addressFamily = "";
String socketKind = "";
String localAddress = "";
int localPort = -1;
String remoteAddress = "";
int remotePort = -1;
String status = "";
int pid = -1;
for (int i = 0; i < dataStringParts.length; i++) {
String part = dataStringParts[i];
if (part.startsWith("fd")) {
fileDescriptor = processFileDescriptor(part);
} else if (part.startsWith("family")) {
addressFamily = processAddressFamily(part);
} else if (part.startsWith("type")) {
socketKind = processSocketKind(part);
} else if (part.startsWith("laddr")) {
localAddress = processAddress(part);
// Check if entry after is of type port
if (dataStringParts[i+1].startsWith("port")) {
localPort = processPort(dataStringParts[i+1]);
i++;
}
} else if (part.startsWith("raddr")) {
remoteAddress = processAddress(part);
// CHeck if entry after is of type port
if (dataStringParts[i+1].startsWith("port")) {
remotePort = processPort(dataStringParts[i+1]);
i++;
}
} else if (part.startsWith("status")) {
status = processStatus(part);
} else if (part.startsWith("pid")) {
pid = processPID(part);
} else {
// Do nothing
}
}
return new ConnectionInformation(fileDescriptor, addressFamily, socketKind, localAddress, localPort, remoteAddress, remotePort, status, pid);
}
private static String removeHeadAndTail(String input) {
return input.substring(HEAD_LENGTH, input.length()-TAIL_LENGTH);
}
private static int processFileDescriptor(String fileDescriptorString) {
int fileDescriptor = 0;
try {
fileDescriptor = Integer.valueOf(fileDescriptorString.substring(3, fileDescriptorString.length()-1));
} catch (Exception e) {
System.out.println(e);
}
return fileDescriptor;
}
private static String processAddressFamily(String addressFamilyString) {
for (String addressFamily : ADDRESS_FAMILIES) {
if (addressFamilyString.contains(addressFamily)) {
return addressFamily;
}
}
return "";
}
private static String processSocketKind(String socketKindString) {
for (String socketKind : SOCKET_KINDS) {
if (socketKindString.contains(socketKind)) {
return socketKind;
}
}
return "";
}
private static String processAddress(String addressString) {
if (addressString.contains("''")) {
// If it's an empty address, it contains ''
return "";
} else if (addressString.contains("ip") && addressString.contains("[")) {
String ipv6Head = "xaddr=addr(ip='[";
// If it's an ipv6 address, since format is xaddr=addr(ip='[ipv6 address]',
return addressString.substring(ipv6Head.length(), addressString.length()-3);
} else if (addressString.contains("ip")) {
String ipv4Head = "xaddr=addr(ip='";
// If it's an ipv4 address, since format is xaddr=addr(ip='ipv4 address',
return addressString.substring(ipv4Head.length(), addressString.length()-2);
} else {
String head = "xaddr='";
// If it's not an empty or ip address, it is xaddr='path'
return addressString.substring(head.length(), addressString.length()-1);
}
}
private static int processPort(String portString) {
int port = 0;
try {
port = Integer.valueOf(portString.substring(5, portString.length()-2));
} catch (Exception e) {
System.out.println(e);
}
return port;
}
private static String processStatus(String statusString) {
return statusString.substring(8, statusString.length()-2);
}
private static int processPID(String pidString) {
int processID = -1;
try {
processID = Integer.valueOf(pidString.substring(4));
} catch (Exception e) {
System.out.println(e);
}
return processID;
}
}

View File

@@ -0,0 +1,77 @@
/**
* @author Aaron Moser
* @date 28.12.2023
*/
package controller.src.DataProcessing;
import controller.src.DataProcessing.ConnectionsProcessing.ConnectionsProcessor;
import queues.src.ReceivingQueue;
public final class DataProcessorThread extends Thread {
private static DataProcessorThread instance = null;
private DataProcessorThread() {}
private enum DataKind {
Connection,
NFTablesConfiguration,
Undefined
}
private boolean dataProcessorRunning = false;
public static DataProcessorThread getInstance() {
if (instance == null) {
instance = new DataProcessorThread();
}
return instance;
}
@Override
public void run() {
dataProcessorRunning = true;
while (getDataProcessorRunning()) {
try {
String data = ReceivingQueue.getInstance().take();
//System.out.println("Took " + data + " from receiving queue.");
DataKind dataKind = getKindOfData(data.substring(0, 10));
processDependingOnDataKind(dataKind, data);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void stopThread() {
this.dataProcessorRunning = false;
}
public synchronized boolean getDataProcessorRunning() {
return this.dataProcessorRunning;
}
private DataKind getKindOfData(String headOfData) {
if (headOfData.startsWith("sconn")) {
return DataKind.Connection;
}
if (headOfData.startsWith("{\"nft")) {
return DataKind.NFTablesConfiguration;
}
return DataKind.Undefined;
}
private void processDependingOnDataKind(DataKind dataKind, String data) {
switch (dataKind) {
case Connection: {
System.out.println(ConnectionsProcessor.processDataString(data));
}break;
case NFTablesConfiguration: {
}break;
case Undefined: // intended fall through
default: {
System.out.println("Unknown data kind.");
}break;
}
}
}

View File

@@ -5,5 +5,5 @@
package model.src;
public interface Model {
public void addNetworkConnection(String networkConnection);
}

View File

@@ -0,0 +1,10 @@
package model.src;
public class ModelConstants {
public enum AccessModifier {
ReadAllEntries,
WriteEntry,
DeleteEntry,
DeleteAllEntries
}
}

View File

@@ -15,19 +15,15 @@ public class ModelRepresentation implements Model {
this.connectionModel = new ConnectionModel();
}
public NetworkModel getNetworkModel() {
public synchronized NetworkModel getNetworkModel() {
return this.networkModel;
}
public NFTablesModel getNFTablesModel() {
public synchronized NFTablesModel getNFTablesModel() {
return this.nfTablesModel;
}
public ConnectionModel getConnectionModel() {
public synchronized ConnectionModel getConnectionModel() {
return this.connectionModel;
}
public void addNetworkConnection(String networkConnection) {
networkModel.addNetworkConnection(networkConnection);
}
}

View File

@@ -4,76 +4,47 @@
*/
package model.src;
import java.util.LinkedList;
import java.util.HashSet;
import java.util.Set;
import controller.src.DataProcessing.ConnectionsProcessing.ConnectionInformation;
import model.src.ModelConstants.AccessModifier;
public class NetworkModel {
private LinkedList<String> ipv4NetworkConnections;
private LinkedList<String> ipv6NetworkConnections;
private LinkedList<String> tcpOverIPv4NetworkConnections;
private LinkedList<String> tcpOverIPv6NetworkConnections;
private LinkedList<String> udpOverIPv4NetworkConnections;
private LinkedList<String> udpOverIPv6NetworkConnections;
private LinkedList<String> unixNetworkConnections;
private Set<ConnectionInformation> connections;
public NetworkModel() {
ipv4NetworkConnections = new LinkedList<String>();
ipv6NetworkConnections = new LinkedList<String>();
tcpOverIPv4NetworkConnections = new LinkedList<String>();
tcpOverIPv6NetworkConnections = new LinkedList<String>();
udpOverIPv6NetworkConnections = new LinkedList<String>();
udpOverIPv6NetworkConnections = new LinkedList<String>();
unixNetworkConnections = new LinkedList<String>();
connections = new HashSet<ConnectionInformation>();
}
public void addNetworkConnection(String networkConnection) {
public synchronized Set<ConnectionInformation> getConnections() {
return new HashSet<ConnectionInformation>(connections);
}
private void addIPv4NetworkConnection(String networkConnection) {
if (null != networkConnection && null != ipv4NetworkConnections) {
ipv4NetworkConnections.add(networkConnection);
public synchronized Set<ConnectionInformation> accessConnections(AccessModifier accessModifier, ConnectionInformation connection) {
switch (accessModifier) {
case ReadAllEntries: {
return new HashSet<ConnectionInformation>(connections);
}//break;
case WriteEntry: {
connections.add(connection);
return null;
}//break;
case DeleteEntry: {
connections.remove(connection);
return new HashSet<ConnectionInformation>(connections);
}//break;
case DeleteAllEntries: {
connections = new HashSet<ConnectionInformation>();
return null;
}//break;
default: {
return null;
}//break;
}
}
private void addIPv6NetworkConnection(String networkConnection) {
if (null != networkConnection && null != ipv6NetworkConnections) {
ipv6NetworkConnections.add(networkConnection);
}
}
public void clearConnections() {
private void addTCPOverIPv4NetworkConnection(String networkConnection) {
if (null != networkConnection && null != tcpOverIPv4NetworkConnections) {
tcpOverIPv4NetworkConnections.add(networkConnection);
}
}
private void addTCPOverIPv6NetworkConnection(String networkConnection) {
if (null != networkConnection && null != tcpOverIPv6NetworkConnections) {
tcpOverIPv6NetworkConnections.add(networkConnection);
}
}
private void addUDPOverIPv4NetworkConnection(String networkConnection) {
if (null != networkConnection && null != udpOverIPv4NetworkConnections) {
udpOverIPv4NetworkConnections.add(networkConnection);
}
}
private void addUDPOverIPv6NetworkConnection(String networkConnection) {
if (null != networkConnection && null != udpOverIPv6NetworkConnections) {
udpOverIPv6NetworkConnections.add(networkConnection);
}
}
private void addUnixNetworkConnection(String networkConnection) {
if (null != networkConnection && null != unixNetworkConnections) {
unixNetworkConnections.add(networkConnection);
}
}
}