Merge branch 'libpcap-filters' into 'master'
Libpcap filters Closes #18 See merge request packmate/Packmate!7
This commit is contained in:
@@ -5,6 +5,7 @@ import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
import org.pcap4j.core.BpfProgram;
|
||||
import org.pcap4j.core.PacketListener;
|
||||
import org.pcap4j.core.PcapHandle;
|
||||
import org.pcap4j.packet.IpV4Packet;
|
||||
@@ -36,6 +37,8 @@ public abstract class AbstractPcapWorker implements PcapWorker, PacketListener {
|
||||
protected PcapHandle pcap = null;
|
||||
protected final ExecutorService loopExecutorService;
|
||||
|
||||
protected String filter = "tcp or udp";
|
||||
|
||||
// во время работы должен быть != null
|
||||
protected ExecutorService processorExecutorService;
|
||||
|
||||
@@ -255,4 +258,17 @@ public abstract class AbstractPcapWorker implements PcapWorker, PacketListener {
|
||||
}).get();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void setFilter(String filter) {
|
||||
this.filter = filter;
|
||||
applyFilter();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
protected void applyFilter() {
|
||||
if(filter != null && pcap != null && pcap.isOpen()) {
|
||||
pcap.setFilter(filter, BpfProgram.BpfCompileMode.OPTIMIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,9 @@ public class FilePcapWorker extends AbstractPcapWorker {
|
||||
public void start() {
|
||||
log.info("Using file " + file.getAbsolutePath());
|
||||
pcap = Pcaps.openOffline(file.getAbsolutePath());
|
||||
|
||||
applyFilter();
|
||||
|
||||
loopExecutorService.execute(this::runScan);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@ public class LivePcapWorker extends AbstractPcapWorker {
|
||||
log.info("Using interface " + device.getName());
|
||||
pcap = device.openLive(65536, PcapNetworkInterface.PromiscuousMode.PROMISCUOUS, 100);
|
||||
|
||||
applyFilter();
|
||||
|
||||
try {
|
||||
log.info("Intercept started");
|
||||
pcap.loop(-1, this, loopExecutorService);
|
||||
|
||||
@@ -18,4 +18,6 @@ public interface PcapWorker {
|
||||
*/
|
||||
int closeTimeoutStreams(Protocol protocol, long timeoutMillis);
|
||||
|
||||
void setFilter(String filter);
|
||||
|
||||
}
|
||||
|
||||
@@ -59,10 +59,10 @@ public class PatternService {
|
||||
patterns.put(id, saved);
|
||||
|
||||
if (enabled) {
|
||||
log.info("Включен паттерн {} со значением {}", pattern.getName(), pattern.getValue());
|
||||
log.info("Enabled pattern '{}' with value '{}'", pattern.getName(), pattern.getValue());
|
||||
subscriptionService.broadcast(new SubscriptionMessage(SubscriptionMessageType.ENABLE_PATTERN, id));
|
||||
} else {
|
||||
log.info("Выключен паттерн {} со значением {}", pattern.getName(), pattern.getValue());
|
||||
log.info("Disabled pattern '{}' with value '{}'", pattern.getName(), pattern.getValue());
|
||||
subscriptionService.broadcast(new SubscriptionMessage(SubscriptionMessageType.DISABLE_PATTERN, id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
package ru.serega6531.packmate.service;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.pcap4j.core.PcapNativeException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.serega6531.packmate.model.CtfService;
|
||||
import ru.serega6531.packmate.model.enums.SubscriptionMessageType;
|
||||
import ru.serega6531.packmate.model.pojo.SubscriptionMessage;
|
||||
import ru.serega6531.packmate.pcap.PcapWorker;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class PcapService {
|
||||
|
||||
@Getter
|
||||
@@ -31,4 +37,18 @@ public class PcapService {
|
||||
}
|
||||
}
|
||||
|
||||
public void updateFilter(Collection<CtfService> services) {
|
||||
final String ports = services.stream()
|
||||
.map(CtfService::getPort)
|
||||
.map(p -> "port " + p)
|
||||
.collect(Collectors.joining(" or "));
|
||||
|
||||
final String format = "(tcp or udp) and (%s)";
|
||||
String filter = String.format(format, ports);
|
||||
|
||||
log.info("New filter: " + filter);
|
||||
|
||||
worker.setFilter(filter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package ru.serega6531.packmate.service;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.serega6531.packmate.model.CtfService;
|
||||
import ru.serega6531.packmate.model.enums.SubscriptionMessageType;
|
||||
@@ -23,6 +24,7 @@ public class ServicesService {
|
||||
|
||||
private final ServiceRepository repository;
|
||||
private final SubscriptionService subscriptionService;
|
||||
private final PcapService pcapService;
|
||||
|
||||
private final InetAddress localIp;
|
||||
|
||||
@@ -31,9 +33,11 @@ public class ServicesService {
|
||||
@Autowired
|
||||
public ServicesService(ServiceRepository repository,
|
||||
SubscriptionService subscriptionService,
|
||||
@Lazy PcapService pcapService,
|
||||
@Value("${local-ip}") String localIpString) throws UnknownHostException {
|
||||
this.repository = repository;
|
||||
this.subscriptionService = subscriptionService;
|
||||
this.pcapService = pcapService;
|
||||
this.localIp = InetAddress.getByName(localIpString);
|
||||
|
||||
repository.findAll().forEach(s -> services.put(s.getPort(), s));
|
||||
@@ -60,16 +64,25 @@ public class ServicesService {
|
||||
|
||||
public void deleteByPort(int port) {
|
||||
log.info("Removed service at port {}", port);
|
||||
|
||||
services.remove(port);
|
||||
repository.deleteById(port);
|
||||
|
||||
subscriptionService.broadcast(new SubscriptionMessage(SubscriptionMessageType.DELETE_SERVICE, port));
|
||||
|
||||
pcapService.updateFilter(findAll());
|
||||
}
|
||||
|
||||
public CtfService save(CtfService service) {
|
||||
log.info("Added or edited service '{}' at port {}", service.getName(), service.getPort());
|
||||
|
||||
final CtfService saved = repository.save(service);
|
||||
services.put(saved.getPort(), saved);
|
||||
|
||||
subscriptionService.broadcast(new SubscriptionMessage(SubscriptionMessageType.SAVE_SERVICE, saved));
|
||||
|
||||
pcapService.updateFilter(findAll());
|
||||
|
||||
return saved;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user