def pcap(self): combined_pcap = PacketList() for pcap in self.__pcap: for packet in pcap: combined_pcap.append(packet) return combined_pcap
def send_batch(self, batches): packets_len = len(batches) if packets_len == 0: return packet_list = PacketList() for pkt in batches: packet_raw = Packet(pkt) packet_list.append(packet_raw) sendp(packet_list, iface=self._options.iface, verbose=0)
def received(self, src=None, dst=None, lbda=None, seq=None, type=None, raw=False): packet_list = PacketList(raw and self.__raw_buffer[:] or self.__receive_buffer[:]) def packet_dst_in(dsts, p): dsts = isinstance(dsts, list) and dsts or [dsts] for d in dsts: d = IPAddress.identify(d) if d.version() == 4 and p.haslayer(IP) and IPAddress.identify( p.getlayer(IP).dst) == d: return True elif d.version() == 6 and p.haslayer( IPv6) and IPAddress.identify( p.getlayer(IPv6).dst) == d: return True return False def packet_src_in(srcs, p): srcs = isinstance(srcs, list) and srcs or [srcs] for s in srcs: s = IPAddress.identify(s) if s.version() == 4 and p.haslayer(IP) and IPAddress.identify( p.getlayer(IP).src) == s: return True elif s.version() == 6 and p.haslayer( IPv6) and IPAddress.identify( p.getlayer(IPv6).src) == s: return True return False if not (src == None and dst == None and lbda == None and seq == None and type == None): packet_list = packet_list.filter(lambda p: (src == None or hasattr(p, 'haslayer') and packet_src_in(src, p)) and \ (dst == None or hasattr(p, 'haslayer') and packet_dst_in(dst, p)) and \ (seq == None or hasattr(p, 'haslayer') and (p.haslayer(ICMPv6EchoRequest) and p.getlayer(ICMPv6EchoRequest).seq == seq or p.haslayer(ICMPv6EchoReply) and p.getlayer(ICMPv6EchoReply).seq == seq)) and \ (type == None or hasattr(p, 'haslayer') and p.getlayer(type)) and \ (lbda == None or lbda(p))) return packet_list
def test_only_duplicate_ack_removed(self): """Given a PacketList with three packets, only the duplicate should be removed. The other two should remain. Duplicates: a pair of ACK packets (ACK flag set, same SEQ and ACK numbers) Other: SYN packet (SYN flag set) """ non_dup = Ether() / IP() / TCP(flags='S', seq=0, ack=0) ack1 = Ether() / IP() / TCP(flags='A', seq=1, ack=1) ack2 = Ether() / IP() / TCP(flags='A', seq=1, ack=1) pkts = PacketList([non_dup, ack1, ack2]) sr = Session_Reassembler() deduped_pkts = sr._remove_duplicate_packets(pkts) self.assertTrue(deduped_pkts[0][TCP].flags == 'S') self.assertTrue(len(deduped_pkts) == 2)
def test_only_duplicate_synack_removed(self): """Given a PacketList with three packets, only the duplicate should be removed. The other two should remain. Duplicates: a pair of SYN/ACK packets (SYN and ACK flag set, same SEQ and ACK numbers) Other: ACK packet (ACK flag set) """ synack1 = Ether() / IP() / TCP(flags='SA', seq=0, ack=1) synack2 = Ether() / IP() / TCP(flags='SA', seq=0, ack=1) non_dup = Ether() / IP() / TCP(flags='A', seq=10, ack=11) pkts = PacketList([synack1, synack2, non_dup]) sr = Session_Reassembler() deduped_pkts = sr._remove_duplicate_packets(pkts) self.assertTrue(deduped_pkts[-1][TCP].flags == 'A') self.assertTrue(len(deduped_pkts) == 2)
def test_only_duplicate_data_removed(self): """Given a PacketList with three packets, only the duplicate should be removed. The other two should remain. Duplicates: a pair of data packets (PUSH and ACK flags set, same SEQ and ACK numbers) Other: SYN packet (SYN flag set) """ non_dup = Ether() / IP() / TCP(flags='S', seq=0, ack=0) data1 = Ether() \ /IP() \ /TCP(flags='PA', seq=10, ack=11, chksum=0xccfe ) \ /Raw(load='abc') data2 = Ether() \ /IP() \ /TCP(flags='PA', seq=10, ack=11, chksum=0xccfe ) \ /Raw(load='abc') pkts = PacketList([non_dup, data1, data2]) sr = Session_Reassembler() deduped_pkts = sr._remove_duplicate_packets(pkts) self.assertTrue(deduped_pkts[0][TCP].flags == 'S') self.assertTrue(len(deduped_pkts) == 2)
def fake_sr_return(): """Fake srl response.""" # fake unans pkt_fail = IP(dst="127.0.0.1") / TCP( flags="S", seq=0, dport=80, sport=65000) fake_unans = PacketList(pkt_fail) # fake ans pkt_ok_sent = IP(dst="127.0.0.1") / TCP( flags="S", seq=1, dport=80, sport=65001) pkt_ok_response = IP(dst="127.0.0.1") / TCP( flags="S", seq=1, ack=2, dport=65001, sport=80) pkt_ok_sent.sent_time = 0 pkt_ok_response.time = 0.1 fake_ans = [[pkt_ok_sent, pkt_ok_response]] return (fake_ans, fake_unans)
from struct import pack from packages.common.utils import gps_week_seconds_to_utc from scapy.all import (Packet, PacketList, sendp, resolve_iface) from packages.common import utils from packages.common import uart_helper # utc_time = gps_week_seconds_to_utc(2166, 463261.918) # print(utc_time) if __name__ == '__main__': config = utils.get_config() iface = resolve_iface(config['local']['name']) # 'eth0' src_mac = config['local']['mac'] # 'b8:27:eb:04:e0:73' dst_mac_addresses = config['devices_mac'] raw_bytes = uart_helper.build_eth_command() packet_list = PacketList() for i in range(5): packet_list.append( Packet(raw_bytes) ) sendp(packet_list, iface=iface, verbose=0)
def _remove_duplicate_packets(self, session): """Carries out partial de-duplication of Scapy.PacketList. Packets are considered duplicate if they fall under one of these cases: both directions: * duplicate ack: no payload, flags=A, same seq and ack numbers. * duplicate data: flags=PA or A, same seq/ack/TCP chksum, same non-zero payload cli_to_svr: * duplicate syn: flags=S, same seq numbers svr_to_cli: * duplicate synack: flags=SA, same seq/ack We hash the packets (credit: https://stackoverflow.com/a/3350656) depending on context. We'll need to make separate hash tables for each case to check. To make it easier to read, make a few reusable, function-like methods first and use them to build up to the bigger algorithm. Args: session (Scapy.PacketList) Returns: Scapy.PacketList """ def payload_len(pkt): return len(pkt[TCP].payload) def flags(pkt): return str(pkt[TCP].flags) def seq(pkt): return pkt[TCP].seq def ack(pkt): return pkt[TCP].ack def chksum(pkt): return pkt[TCP].chksum def md5(*args): str_args = map(str, args) return hashlib.md5("".join(str_args)).hexdigest() def is_ack(pkt): return flags(pkt) == 'A' and payload_len(pkt) == 0 def hash_ack(pkt): return md5(seq(pkt)), ack(pkt) def is_data(pkt): return payload_len(pkt) != 0 and (flags(pkt) == 'A' or flags(pkt) == 'PA') def hash_data(pkt): return md5(seq(pkt), ack(pkt), chksum(pkt), flags(pkt)) def is_syn(pkt): return flags(pkt) == 'S' and ack(pkt) == 0 def hash_syn(pkt): return md5(seq(pkt)) def is_synack(pkt): return flags(pkt) == 'SA' def hash_synack(pkt): return md5(seq(pkt), ack(pkt)) ack_pkts = {} data_pkts = {} syn_pkts = {} synack_pkts = {} deduped = [] # if it's one of our cases and we haven't seen it then add to appropriate hash table and deduped. # if not one of our cases, just add it to deduped. # Can we safely assume no packet can fall under two cases? for pkt in session: if is_ack(pkt): if (hash_ack(pkt) not in ack_pkts.keys()): deduped.append(pkt) ack_pkts[hash_ack(pkt)] = pkt elif is_data(pkt): if (hash_data(pkt) not in data_pkts.keys()): deduped.append(pkt) data_pkts[hash_data(pkt)] = pkt elif is_syn(pkt): if (hash_syn(pkt) not in syn_pkts.keys()): deduped.append(pkt) syn_pkts[hash_syn(pkt)] = pkt elif is_synack(pkt): if (hash_synack(pkt) not in synack_pkts.keys()): deduped.append(pkt) synack_pkts[hash_synack(pkt)] = pkt else: deduped.append(pkt) return PacketList(deduped)
def link_traffic(pcap_data): pcaps = pcap_data.pcaps total_hosts = len(USER_PORTS) + len(SERVER_PORTS) eth_no = total_hosts + 1 for i in range(1, NUM_SWITCHES + 1): # Traffic over links with users and servers for j in (USER_PORTS + SERVER_PORTS): all_packets = PacketList() try: # Packets outgoing to host or server outgoing_packets = pcaps[(i, j, "in")] all_packets += outgoing_packets except: pass try: # Packets incoming from host or server incoming_packets = pcaps[(i, j, "out")] all_packets += incoming_packets except: if not all_packets: continue else: pass # Number of packets num_pkts = sum([1 for pkt in all_packets]) # Total size of all packets total_pkt_size = sum([len(pkt) for pkt in all_packets]) host_number = (i - 1) * (total_hosts) + j print("Number of packets over link s%d-h%d: %d" % (i, host_number, num_pkts)) print("Data through the link s%d-h%d: %d bytes\n" % (i, host_number, total_pkt_size)) # Traffic over links with other switches eth_copy = eth_no for j in range(i + 1, NUM_SWITCHES + 1): all_packets = PacketList() try: # Packets exchanged between a pair of switches incoming1 = pcaps[(i, eth_copy, "out")] all_packets += incoming1 except: pass try: incoming2 = pcaps[(j, total_hosts + i, "out")] all_packets += incoming2 except: if not all_packets: continue else: pass all_packets = incoming1 + incoming2 # Number of packets num_pkts = sum([1 for pkt in all_packets]) # Total size of all packets total_pkt_size = sum([len(pkt) for pkt in all_packets]) print("Number of packets over link s%d-s%d: %d" % (i, j, num_pkts)) print("Data through the link s%d-s%d: %d bytes\n" % (i, j, total_pkt_size)) eth_copy += 1 eth_no += 1