From: Janus Varmarken Date: Tue, 11 Sep 2018 23:02:09 +0000 (-0700) Subject: Bugfix: fix null-pointer when formatting PcapPacketPairs as CSV X-Git-Url: http://plrg.eecs.uci.edu/git/?p=pingpong.git;a=commitdiff_plain;h=abd2cef4e5adee1cf499b239f5fb1a379200ca15 Bugfix: fix null-pointer when formatting PcapPacketPairs as CSV --- diff --git a/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/analysis/PcapPacketPair.java b/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/analysis/PcapPacketPair.java index db5c839..f77531f 100644 --- a/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/analysis/PcapPacketPair.java +++ b/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/analysis/PcapPacketPair.java @@ -1,31 +1,40 @@ 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 } * @author Rahmadi Trimananda {@literal } */ -public class PcapPacketPair { +public class PcapPacketPair implements Clusterable { private final PcapPacket mFirst; - private final PcapPacket mSecond; + private final Optional 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 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]; + } } diff --git a/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/util/PrintUtils.java b/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/util/PrintUtils.java index 75a0035..0183922 100644 --- a/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/util/PrintUtils.java +++ b/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/util/PrintUtils.java @@ -3,6 +3,7 @@ package edu.uci.iotproject.util; import edu.uci.iotproject.DnsMap; import edu.uci.iotproject.analysis.PcapPacketPair; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -23,11 +24,14 @@ public class PrintUtils { * 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. * + * Note: 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)); } /** @@ -40,29 +44,35 @@ public class PrintUtils { * 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'. * + * Note: 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 secondSrc = packetPair.getSecond().map(pkt -> PcapPacketUtils.getSourceIp(pkt)); // If possible, map source IPs to hostnames. Set firstHostnames = ipHostnameMappings.getHostnamesForIp(firstSrc); - Set secondHostnames = ipHostnameMappings.getHostnamesForIp(secondSrc); + Optional> 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 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")); } }