X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=GPL%2Ftraffic_scripts%2FPacketVerifier.py;h=e05084d66c4109bd911e0c9c0906dc5156337b03;hb=caedfd9b1eda24472fe1fcd7b49cfa1c5b71fd4f;hp=20e9af603bcd433bb3e3d0ce2ba4781868deb01f;hpb=79f5ba9bf7656972dd988508eff9465562dde42c;p=csit.git diff --git a/GPL/traffic_scripts/PacketVerifier.py b/GPL/traffic_scripts/PacketVerifier.py index 20e9af603b..e05084d66c 100644 --- a/GPL/traffic_scripts/PacketVerifier.py +++ b/GPL/traffic_scripts/PacketVerifier.py @@ -71,7 +71,7 @@ from scapy.all import ETH_P_IP, ETH_P_IPV6, ETH_P_ALL, ETH_P_ARP from scapy.config import conf from scapy.layers.inet6 import IPv6 from scapy.layers.l2 import Ether, ARP -from scapy.packet import Raw +from scapy.packet import Raw, Padding # Enable libpcap's L2listen conf.use_pcap = True @@ -208,7 +208,11 @@ class RxQueue(PacketVerifier): Returns scapy's Ether() object created from next packet in the queue. Queue is being filled in parallel in subprocess. If no packet - arrives in given timeout queue.Empty exception will be risen. + arrives in given timeout None is returned. + + If the list of packets to ignore is given, they are logged + but otherwise ignored upon arrival, not adding to the timeout. + Each time a packet is ignored, it is removed from the ignored list. :param timeout: How many seconds to wait for next packet. :param ignore: List of packets that should be ignored. @@ -220,16 +224,19 @@ class RxQueue(PacketVerifier): :returns: Ether() initialized object from packet data. :rtype: scapy.Ether """ - ignore_list = list() - if ignore is not None: - for ig_pkt in ignore: - # Auto pad all packets in ignore list - ignore_list.append(str(auto_pad(ig_pkt))) - while True: - rlist, _, _ = select.select([self._sock], [], [], timeout) - if self._sock not in rlist: + time_end = time.monotonic() + timeout + ignore = ignore if ignore else list() + # Auto pad all packets in ignore list + ignore = [str(auto_pad(ig_pkt)) for ig_pkt in ignore] + while 1: + time_now = time.monotonic() + if time_now >= time_end: return None - + timedelta = time_end - time_now + rlist, _, _ = select.select([self._sock], [], [], timedelta) + if self._sock not in rlist: + # Might have been an interrupt. + continue pkt = self._sock.recv(0x7fff) pkt_pad = str(auto_pad(pkt)) print(f"Received packet on {self._ifname} of len {len(pkt)}") @@ -240,8 +247,8 @@ class RxQueue(PacketVerifier): # Never happens in practice, but Pylint does not know that. print(f"Unexpected instance: {pkt!r}") print() - if pkt_pad in ignore_list: - ignore_list.remove(pkt_pad) + if pkt_pad in ignore: + ignore.remove(pkt_pad) print(u"Received packet ignored.") continue return pkt @@ -314,10 +321,14 @@ def create_gratuitous_arp_request(src_mac, src_ip): def auto_pad(packet): - """Pads zeroes at the end of the packet if the total len < 60 bytes.""" - # padded = str(packet) - if len(packet) < 60: - packet[Raw].load += (b"\0" * (60 - len(packet))) + """Pads zeroes at the end of the packet if the total packet length is less + then 64 bytes in case of IPv4 or 78 bytes in case of IPv6. + """ + min_len = 78 if packet.haslayer(IPv6) else 64 + pad_layer = Raw if packet.haslayer(Raw) \ + else Padding if packet.haslayer(Padding) else None + if pad_layer: + packet[pad_layer].load += (b"\0" * (min_len - len(packet))) return packet