1 package edu.uci.iotproject.evaluation;
3 import edu.uci.iotproject.Conversation;
4 import edu.uci.iotproject.TcpReassembler;
5 import edu.uci.iotproject.io.PcapHandleReader;
6 import edu.uci.iotproject.util.PrintUtils;
7 import org.pcap4j.core.*;
9 import java.util.ArrayList;
10 import java.util.List;
11 import java.util.Optional;
14 * Hacky utility for producing a sanity signature for negative test sets.
16 * More precisely, given information about packet lengths and packet directions known to be present in an input trace,
17 * this class locates the first occurrence of a matching sequence in the input trace and outputs it to a file in the
18 * signature format (i.e., a {@code List<List<List<PcapPacket>>>}.
21 * Note: can only produce simplistic signatures, i.e., a signature that is a <em>single</em> packet sequence that
22 * occurs on a single TCP connection.
26 * @author Janus Varmarken {@literal <jvarmark@uci.edu>}
27 * @author Rahmadi Trimananda {@literal <rtrimana@uci.edu>}
29 public class SanitySignatureGenerator {
31 public static void main(String[] args) throws PcapNativeException, NotOpenException {
33 final String pcapPath = "/Users/varmarken/temp/UCI IoT Project/experiments/evaluation/negative-datasets/UNB/Monday-WorkingHours_one-local-endpoint.pcap";
34 final String sigOutputPath = "/Users/varmarken/temp/UCI IoT Project/experiments/evaluation/negative-datasets/UNB/Monday-WorkingHours_one-local-endpoint_sanity.sig";
35 // The sequence of packet lengths known to be present in the trace
36 final List<Integer> pktLengths = new ArrayList<>();
39 // ...and their corresponding directions
40 final List<Conversation.Direction> pktDirections = new ArrayList<>();
41 pktDirections.add(Conversation.Direction.CLIENT_TO_SERVER);
42 pktDirections.add(Conversation.Direction.SERVER_TO_CLIENT);
43 // Is the signature a TLS sequence?
44 final boolean tlsSequence = false;
49 handle = Pcaps.openOffline(pcapPath, PcapHandle.TimestampPrecision.NANO);
50 } catch (PcapNativeException pne) {
51 handle = Pcaps.openOffline(pcapPath);
53 SequenceFinder seqFinder = new SequenceFinder(pktLengths, pktDirections, tlsSequence, sigOutputPath);
54 final PcapHandleReader reader = new PcapHandleReader(handle, p -> true, seqFinder);
55 seqFinder.setPcapHandleReader(reader);
56 reader.readFromHandle();
60 private static class SequenceFinder implements PacketListener {
61 private final TcpReassembler mTcpReassembler = new TcpReassembler();
62 private final List<Integer> mPktLengths;
63 private final List<Conversation.Direction> mPktDirections;
64 private final boolean mTlsSequence;
65 private PcapHandleReader mReader;
66 private final String mSignatureOutputPath;
68 private SequenceFinder(List<Integer> pktLengths,
69 List<Conversation.Direction> pktDirections,
71 String sigOutputPath) {
72 mPktLengths = pktLengths;
73 mPktDirections = pktDirections;
74 mTlsSequence = tlsSequence;
75 mSignatureOutputPath = sigOutputPath;
79 public void gotPacket(PcapPacket packet) {
80 // Skip packets not matching expected length
81 if (!mPktLengths.contains(packet.getOriginalLength())) {
84 // Otherwise forward to TCP reassembler.
85 mTcpReassembler.gotPacket(packet);
86 // We are done as soon as we have one conversation that has the expected number of packets with the expected
88 Optional<Conversation> match = mTcpReassembler.getTcpConversations().stream().filter(c -> {
89 List<PcapPacket> cPkts = mTlsSequence ? c.getTlsApplicationDataPackets() : c.getPackets();
90 if (cPkts.size() != mPktLengths.size()) {
93 for (int i = 0; i < cPkts.size(); i++) {
94 if (c.getDirection(cPkts.get(i)) != mPktDirections.get(i) ||
95 cPkts.get(i).getOriginalLength() != mPktLengths.get(i)) {
101 if (match.isPresent()) {
102 System.out.println("match found");
103 // Terminate reader; no need to process the full file as we already have the data to produce the signature.
104 mReader.stopReading();
105 // Convert sequence to signature format.
106 List<List<List<PcapPacket>>> signature = new ArrayList<>();
107 List<List<PcapPacket>> cluster = new ArrayList<>();
108 List<PcapPacket> sequence = mTlsSequence ? match.get().getTlsApplicationDataPackets() : match.get().getPackets();
109 cluster.add(sequence);
110 signature.add(cluster);
111 // Output the signature to a file.
112 PrintUtils.serializeSignatureIntoFile(mSignatureOutputPath, signature);
116 private void setPcapHandleReader(PcapHandleReader reader) {