Работа над чтением pcap файлов
This commit is contained in:
@@ -1,20 +1,33 @@
|
|||||||
package ru.serega6531.packmate;
|
package ru.serega6531.packmate;
|
||||||
|
|
||||||
|
import org.pcap4j.core.PcapNativeException;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.web.socket.config.annotation.EnableWebSocket;
|
||||||
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
|
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
|
||||||
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
|
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
|
||||||
|
import ru.serega6531.packmate.model.enums.CaptureMode;
|
||||||
|
import ru.serega6531.packmate.pcap.FilePcapWorker;
|
||||||
|
import ru.serega6531.packmate.pcap.LivePcapWorker;
|
||||||
|
import ru.serega6531.packmate.pcap.PcapWorker;
|
||||||
|
import ru.serega6531.packmate.service.ServicesService;
|
||||||
|
import ru.serega6531.packmate.service.StreamService;
|
||||||
|
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
|
@EnableScheduling
|
||||||
|
@EnableWebSocket
|
||||||
public class ApplicationConfiguration extends WebSecurityConfigurerAdapter implements WebSocketConfigurer {
|
public class ApplicationConfiguration extends WebSecurityConfigurerAdapter implements WebSocketConfigurer {
|
||||||
|
|
||||||
@Value("${account-login}")
|
@Value("${account-login}")
|
||||||
@@ -30,6 +43,21 @@ public class ApplicationConfiguration extends WebSecurityConfigurerAdapter imple
|
|||||||
this.webSocketHandler = webSocketHandler;
|
this.webSocketHandler = webSocketHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean(destroyMethod = "stop")
|
||||||
|
@Autowired
|
||||||
|
public PcapWorker pcapWorker(ServicesService servicesService,
|
||||||
|
StreamService streamService,
|
||||||
|
@Value("${local-ip}") String localIpString,
|
||||||
|
@Value("${interface-name}") String interfaceName,
|
||||||
|
@Value("${pcap-file}") String filename,
|
||||||
|
@Value("${capture-mode}") CaptureMode captureMode) throws PcapNativeException, UnknownHostException {
|
||||||
|
if(captureMode == CaptureMode.LIVE) {
|
||||||
|
return new LivePcapWorker(servicesService, streamService, localIpString, interfaceName);
|
||||||
|
} else {
|
||||||
|
return new FilePcapWorker(servicesService, streamService, localIpString, filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
||||||
auth.inMemoryAuthentication()
|
auth.inMemoryAuthentication()
|
||||||
|
|||||||
@@ -6,12 +6,9 @@ import org.springframework.boot.SpringApplication;
|
|||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||||
import org.springframework.context.event.EventListener;
|
import org.springframework.context.event.EventListener;
|
||||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
import ru.serega6531.packmate.pcap.PcapWorker;
|
||||||
import org.springframework.web.socket.config.annotation.EnableWebSocket;
|
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@EnableScheduling
|
|
||||||
@EnableWebSocket
|
|
||||||
public class PackmateApplication {
|
public class PackmateApplication {
|
||||||
|
|
||||||
@Value("${enable-capture}")
|
@Value("${enable-capture}")
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import org.springframework.beans.factory.annotation.Value;
|
|||||||
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import ru.serega6531.packmate.model.enums.Protocol;
|
import ru.serega6531.packmate.model.enums.Protocol;
|
||||||
|
import ru.serega6531.packmate.pcap.PcapWorker;
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package ru.serega6531.packmate.model.enums;
|
||||||
|
|
||||||
|
public enum CaptureMode {
|
||||||
|
|
||||||
|
LIVE, FILE
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,25 +1,22 @@
|
|||||||
package ru.serega6531.packmate;
|
package ru.serega6531.packmate.pcap;
|
||||||
|
|
||||||
import com.google.common.collect.*;
|
import com.google.common.collect.*;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
|
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
|
||||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||||
import org.pcap4j.core.*;
|
import org.pcap4j.core.PacketListener;
|
||||||
|
import org.pcap4j.core.PcapHandle;
|
||||||
import org.pcap4j.packet.IpV4Packet;
|
import org.pcap4j.packet.IpV4Packet;
|
||||||
import org.pcap4j.packet.Packet;
|
import org.pcap4j.packet.Packet;
|
||||||
import org.pcap4j.packet.TcpPacket;
|
import org.pcap4j.packet.TcpPacket;
|
||||||
import org.pcap4j.packet.UdpPacket;
|
import org.pcap4j.packet.UdpPacket;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import ru.serega6531.packmate.model.CtfService;
|
import ru.serega6531.packmate.model.CtfService;
|
||||||
import ru.serega6531.packmate.model.enums.Protocol;
|
import ru.serega6531.packmate.model.enums.Protocol;
|
||||||
import ru.serega6531.packmate.model.pojo.UnfinishedStream;
|
import ru.serega6531.packmate.model.pojo.UnfinishedStream;
|
||||||
import ru.serega6531.packmate.service.ServicesService;
|
import ru.serega6531.packmate.service.ServicesService;
|
||||||
import ru.serega6531.packmate.service.StreamService;
|
import ru.serega6531.packmate.service.StreamService;
|
||||||
|
|
||||||
import javax.annotation.PreDestroy;
|
|
||||||
import java.net.Inet4Address;
|
import java.net.Inet4Address;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
@@ -29,16 +26,14 @@ import java.util.concurrent.ExecutorService;
|
|||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Component
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class PcapWorker implements PacketListener {
|
public abstract class AbstractPcapWorker implements PcapWorker, PacketListener {
|
||||||
|
|
||||||
private final ServicesService servicesService;
|
private final ServicesService servicesService;
|
||||||
private final StreamService streamService;
|
private final StreamService streamService;
|
||||||
|
|
||||||
private final PcapNetworkInterface device;
|
protected PcapHandle pcap = null;
|
||||||
private PcapHandle pcap = null;
|
protected final ExecutorService listenerExecutorService;
|
||||||
private final ExecutorService listenerExecutorService;
|
|
||||||
|
|
||||||
private final InetAddress localIp;
|
private final InetAddress localIp;
|
||||||
|
|
||||||
@@ -51,11 +46,9 @@ public class PcapWorker implements PacketListener {
|
|||||||
private final SetMultimap<UnfinishedStream, ImmutablePair<Inet4Address, Integer>> fins = HashMultimap.create();
|
private final SetMultimap<UnfinishedStream, ImmutablePair<Inet4Address, Integer>> fins = HashMultimap.create();
|
||||||
private final SetMultimap<UnfinishedStream, ImmutablePair<Inet4Address, Integer>> acks = HashMultimap.create();
|
private final SetMultimap<UnfinishedStream, ImmutablePair<Inet4Address, Integer>> acks = HashMultimap.create();
|
||||||
|
|
||||||
@Autowired
|
public AbstractPcapWorker(ServicesService servicesService,
|
||||||
public PcapWorker(ServicesService servicesService,
|
|
||||||
StreamService streamService,
|
StreamService streamService,
|
||||||
@Value("${interface-name}") String interfaceName,
|
String localIpString) throws UnknownHostException {
|
||||||
@Value("${local-ip}") String localIpString) throws PcapNativeException, UnknownHostException {
|
|
||||||
this.servicesService = servicesService;
|
this.servicesService = servicesService;
|
||||||
this.streamService = streamService;
|
this.streamService = streamService;
|
||||||
|
|
||||||
@@ -67,37 +60,6 @@ public class PcapWorker implements PacketListener {
|
|||||||
BasicThreadFactory factory = new BasicThreadFactory.Builder()
|
BasicThreadFactory factory = new BasicThreadFactory.Builder()
|
||||||
.namingPattern("pcap-worker-listener").build();
|
.namingPattern("pcap-worker-listener").build();
|
||||||
listenerExecutorService = Executors.newSingleThreadExecutor(factory);
|
listenerExecutorService = Executors.newSingleThreadExecutor(factory);
|
||||||
device = Pcaps.getDevByName(interfaceName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void start() throws PcapNativeException {
|
|
||||||
log.info("Using interface " + device.getName());
|
|
||||||
pcap = device.openLive(65536, PcapNetworkInterface.PromiscuousMode.PROMISCUOUS, 100);
|
|
||||||
|
|
||||||
BasicThreadFactory factory = new BasicThreadFactory.Builder()
|
|
||||||
.namingPattern("pcap-worker-loop").build();
|
|
||||||
ExecutorService loopExecutorService = Executors.newSingleThreadExecutor(factory);
|
|
||||||
try {
|
|
||||||
log.info("Intercept started");
|
|
||||||
pcap.loop(-1, this, loopExecutorService);
|
|
||||||
} catch (InterruptedException ignored) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
// выходим
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Error while capturing packet", e);
|
|
||||||
stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@PreDestroy
|
|
||||||
@SneakyThrows
|
|
||||||
private void stop() {
|
|
||||||
if (pcap != null && pcap.isOpen()) {
|
|
||||||
pcap.breakLoop();
|
|
||||||
pcap.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info("Intercept stopped");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void gotPacket(Packet rawPacket) {
|
public void gotPacket(Packet rawPacket) {
|
||||||
@@ -241,7 +203,7 @@ public class PcapWorker implements PacketListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
int closeTimeoutStreams(Protocol protocol, long timeoutMillis) {
|
public int closeTimeoutStreams(Protocol protocol, long timeoutMillis) {
|
||||||
return listenerExecutorService.submit(() -> {
|
return listenerExecutorService.submit(() -> {
|
||||||
int streamsClosed = 0;
|
int streamsClosed = 0;
|
||||||
|
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package ru.serega6531.packmate.pcap;
|
||||||
|
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.pcap4j.core.PcapNativeException;
|
||||||
|
import org.pcap4j.core.Pcaps;
|
||||||
|
import org.pcap4j.packet.Packet;
|
||||||
|
import ru.serega6531.packmate.service.ServicesService;
|
||||||
|
import ru.serega6531.packmate.service.StreamService;
|
||||||
|
|
||||||
|
import java.io.EOFException;
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class FilePcapWorker extends AbstractPcapWorker {
|
||||||
|
|
||||||
|
private final File file;
|
||||||
|
|
||||||
|
public FilePcapWorker(ServicesService servicesService,
|
||||||
|
StreamService streamService,
|
||||||
|
String localIpString,
|
||||||
|
String filename) throws UnknownHostException {
|
||||||
|
super(servicesService, streamService, localIpString);
|
||||||
|
|
||||||
|
file = new File(filename);
|
||||||
|
if(!file.exists()) {
|
||||||
|
throw new IllegalArgumentException("File " + file.getAbsolutePath() + " does not exist");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
pcap = Pcaps.openOffline(file.getAbsolutePath());
|
||||||
|
|
||||||
|
while (pcap.isOpen()) {
|
||||||
|
try {
|
||||||
|
final Packet packet = pcap.getNextPacketEx();
|
||||||
|
gotPacket(packet);
|
||||||
|
} catch (PcapNativeException e) {
|
||||||
|
log.error("Pcap read", e);
|
||||||
|
Thread.sleep(100);
|
||||||
|
} catch (EOFException e) {
|
||||||
|
stop();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
public void stop() {
|
||||||
|
if (pcap != null && pcap.isOpen()) {
|
||||||
|
pcap.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("Intercept stopped");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
package ru.serega6531.packmate.pcap;
|
||||||
|
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
|
||||||
|
import org.pcap4j.core.PcapNativeException;
|
||||||
|
import org.pcap4j.core.PcapNetworkInterface;
|
||||||
|
import org.pcap4j.core.Pcaps;
|
||||||
|
import ru.serega6531.packmate.service.ServicesService;
|
||||||
|
import ru.serega6531.packmate.service.StreamService;
|
||||||
|
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class LivePcapWorker extends AbstractPcapWorker {
|
||||||
|
|
||||||
|
private final PcapNetworkInterface device;
|
||||||
|
|
||||||
|
public LivePcapWorker(ServicesService servicesService,
|
||||||
|
StreamService streamService,
|
||||||
|
String localIpString,
|
||||||
|
String interfaceName) throws PcapNativeException, UnknownHostException {
|
||||||
|
super(servicesService, streamService, localIpString);
|
||||||
|
device = Pcaps.getDevByName(interfaceName);
|
||||||
|
|
||||||
|
if(device == null) {
|
||||||
|
throw new IllegalArgumentException("Device " + interfaceName + " does not exist");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() throws PcapNativeException {
|
||||||
|
log.info("Using interface " + device.getName());
|
||||||
|
pcap = device.openLive(65536, PcapNetworkInterface.PromiscuousMode.PROMISCUOUS, 100);
|
||||||
|
|
||||||
|
BasicThreadFactory factory = new BasicThreadFactory.Builder()
|
||||||
|
.namingPattern("pcap-worker-loop").build();
|
||||||
|
ExecutorService loopExecutorService = Executors.newSingleThreadExecutor(factory);
|
||||||
|
try {
|
||||||
|
log.info("Intercept started");
|
||||||
|
pcap.loop(-1, this, loopExecutorService);
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
// выходим
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error while capturing packet", e);
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
public void stop() {
|
||||||
|
if (pcap != null && pcap.isOpen()) {
|
||||||
|
pcap.breakLoop();
|
||||||
|
pcap.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("Intercept stopped");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
12
src/main/java/ru/serega6531/packmate/pcap/PcapWorker.java
Normal file
12
src/main/java/ru/serega6531/packmate/pcap/PcapWorker.java
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package ru.serega6531.packmate.pcap;
|
||||||
|
|
||||||
|
import org.pcap4j.core.PcapNativeException;
|
||||||
|
import ru.serega6531.packmate.model.enums.Protocol;
|
||||||
|
|
||||||
|
public interface PcapWorker {
|
||||||
|
|
||||||
|
void start() throws PcapNativeException;
|
||||||
|
void stop();
|
||||||
|
int closeTimeoutStreams(Protocol protocol, long timeoutMillis);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -15,6 +15,7 @@ spring:
|
|||||||
|
|
||||||
|
|
||||||
enable-capture: true
|
enable-capture: true
|
||||||
|
capture-mode: LIVE # LIVE, FILE
|
||||||
interface-name: enp0s31f6
|
interface-name: enp0s31f6
|
||||||
local-ip: "192.168.0.125"
|
local-ip: "192.168.0.125"
|
||||||
account-login: BinaryBears
|
account-login: BinaryBears
|
||||||
|
|||||||
Reference in New Issue
Block a user