package edu.uci.iotproject.analysis;
+import org.apache.commons.math3.ml.clustering.Clusterable;
import org.pcap4j.core.PcapPacket;
+import java.util.Optional;
+
/**
* A simple wrapper for holding a pair of packets (e.g., a request and associated reply packet).
*
* @author Janus Varmarken {@literal <jvarmark@uci.edu>}
* @author Rahmadi Trimananda {@literal <rtrimana@uci.edu>}
*/
-public class PcapPacketPair {
+public class PcapPacketPair implements Clusterable {
private final PcapPacket mFirst;
- private final PcapPacket mSecond;
+ private final Optional<PcapPacket> mSecond;
public PcapPacketPair(PcapPacket first, PcapPacket second) {
mFirst = first;
- mSecond = second;
+ mSecond = Optional.ofNullable(second);
}
public PcapPacket getFirst() { return mFirst; }
- public PcapPacket getSecond() { return mSecond; }
+ public Optional<PcapPacket> getSecond() { return mSecond; }
@Override
public String toString() {
- return getFirst().getOriginalLength() + ", " + (getSecond() == null ? "null" : getSecond().getOriginalLength());
+ return String.format("%d, %s",
+ getFirst().getOriginalLength(),
+ getSecond().map(pkt -> Integer.toString(pkt.getOriginalLength())).orElse("null"));
}
+ @Override
+ public double[] getPoint() {
+ return new double[0];
+ }
}
import edu.uci.iotproject.DnsMap;
import edu.uci.iotproject.analysis.PcapPacketPair;
+import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
* For example, the resulting string will be "123, 456" if the first packet of the pair has a length of 123 and the
* second packet of the pair has a length of 456.
*
+ * <b>Note:</b> if the {@link PcapPacketPair} has no second element, 0 is printed as the length of the second packet
+ * in the pair.
+ *
* @return a CSV string containing the packet lengths of the two packets of the given {@code PcapPacketPair}.
*/
public static String toCsv(PcapPacketPair packetPair) {
return String.format("%d, %d", packetPair.getFirst().getOriginalLength(),
- packetPair.getSecond().getOriginalLength());
+ packetPair.getSecond().map(pp -> pp.getOriginalLength()).orElse(0));
}
/**
* a source IP of '192.168.1.42' that cannot be resolved to a hostname, and the second packet of the pair has an IP
* that resolves to 'domain.com'.
*
+ * <b>Note:</b> if the {@link PcapPacketPair} has no second element, 0 is printed as the length of the second packet
+ * in the pair, and null is printed for its source.
+ *
* @return a CSV string containing the packet lengths of the two packets of the given {@code PcapPacketPair} as well
* as their respective sources.
*/
public static String toCsv(PcapPacketPair packetPair, DnsMap ipHostnameMappings) {
- // First optain source IPs
+ // First obtain source IPs
String firstSrc = PcapPacketUtils.getSourceIp(packetPair.getFirst());
- String secondSrc = PcapPacketUtils.getSourceIp(packetPair.getSecond());
+ // Note: use optional for second item in pair as there might not be one.
+ Optional<String> secondSrc = packetPair.getSecond().map(pkt -> PcapPacketUtils.getSourceIp(pkt));
// If possible, map source IPs to hostnames.
Set<String> firstHostnames = ipHostnameMappings.getHostnamesForIp(firstSrc);
- Set<String> secondHostnames = ipHostnameMappings.getHostnamesForIp(secondSrc);
+ Optional<Set<String>> secondHostnames = secondSrc.map(src -> ipHostnameMappings.getHostnamesForIp(src));
final String delimiter = " ";
if (firstHostnames != null) {
// If one IP maps to multiple hostnames, we concatenate the hostnames (separated by a delimiter)
firstSrc = firstHostnames.stream().collect(Collectors.joining(delimiter));
}
- if (secondHostnames != null) {
- // If one IP maps to multiple hostnames, we concatenate the hostnames (separated by a delimiter)
- secondSrc = secondHostnames.stream().collect(Collectors.joining(delimiter));
- }
+ // If one IP maps to multiple hostnames, we concatenate the hostnames (separated by a delimiter)
+ Optional<String> hostnames = secondHostnames.map(hostnameSet -> hostnameSet.stream().collect(Collectors.joining(delimiter)));
+ // Fall back to IP if we couldn't second pair is present, but we couldn't map to (a) hostname(s).
+ secondSrc = hostnames.isPresent() ? hostnames : secondSrc;
return String.format("%d, %d, %s, %s", packetPair.getFirst().getOriginalLength(),
- packetPair.getSecond().getOriginalLength(), firstSrc, secondSrc);
+ packetPair.getSecond().map(pp -> pp.getOriginalLength()).orElse(0),
+ firstSrc,
+ secondSrc.orElse("null"));
}
}