1 package edu.uci.iotproject.trafficreassembly.layer2;
3 import org.pcap4j.core.PcapPacket;
4 import org.pcap4j.packet.EthernetPacket;
5 import org.pcap4j.util.MacAddress;
7 import java.util.ArrayList;
8 import java.util.Collections;
12 * Models a layer 2 flow: groups packets exchanged between two specific endpoints (MAC addresses).
14 * @author Janus Varmarken {@literal <jvarmark@uci.edu>}
15 * @author Rahmadi Trimananda {@literal <rtrimana@uci.edu>}
17 public class Layer2Flow {
20 * The first endpoint of this layer 2 flow.
22 private final MacAddress mEndpoint1;
25 * The second endpoint of this layer 2 flow.
27 private final MacAddress mEndpoint2;
30 * Clients observing for changes to this layer 2 flow.
32 private final List<Layer2FlowObserver> mFlowObservers = new ArrayList<>();
34 public Layer2Flow(MacAddress endpoint1, MacAddress endpoint2) {
35 mEndpoint1 = endpoint1;
36 mEndpoint2 = endpoint2;
40 * Register as an observer of this flow.
41 * @param observer The client that is to be notified whenever this flow changes (has new packets added).
43 public void addFlowObserver(Layer2FlowObserver observer) {
44 mFlowObservers.add(observer);
48 * Deregister as an observer of this flow.
49 * @param observer The client that no longer wishes to be notified whenever this flow changes.
51 public void removeFlowObserver(Layer2FlowObserver observer) {
52 mFlowObservers.remove(observer);
56 * The packets in the flow.
58 private final List<PcapPacket> mPackets = new ArrayList<>();
61 * Add a packet to this flow.
62 * @param packet The packet that is to be added to the flow.
64 public void addPacket(PcapPacket packet) {
65 verifyAddresses(packet);
67 // Notify flow observers of the new packet
68 mFlowObservers.forEach(o -> o.onNewPacket(this, packet));
72 * Get the packets pertaining to this flow.
73 * @return The packets pertaining to this flow.
75 public List<PcapPacket> getPackets() {
76 return Collections.unmodifiableList(mPackets);
80 * Verify that a packet pertains to this flow.
81 * @param packet The packet that is to be verified.
83 private void verifyAddresses(PcapPacket packet) {
84 EthernetPacket ethPkt = packet.get(EthernetPacket.class);
85 MacAddress srcAddr = ethPkt.getHeader().getSrcAddr();
86 MacAddress dstAddr = ethPkt.getHeader().getDstAddr();
87 if ((mEndpoint1.equals(srcAddr) && mEndpoint2.equals(dstAddr)) ||
88 (mEndpoint1.equals(dstAddr) && mEndpoint2.equals(srcAddr))) {
92 throw new IllegalArgumentException("Mismatch in MACs: packet does not pertain to this flow");