X-Git-Url: https://gerrit.fd.io/r/gitweb?p=csit.git;a=blobdiff_plain;f=resources%2Flibraries%2Fpython%2FPacketVerifier.py;h=45009611511c166fb391a18101a649952e521e68;hp=bbfdfe86888476e50be73d818d29eec1bbed79c1;hb=66919d66b8ab63369266eaab8db1628501e884aa;hpb=a912d105f3a1d8fed0b4cf6b18e0ef7789be81bf diff --git a/resources/libraries/python/PacketVerifier.py b/resources/libraries/python/PacketVerifier.py index bbfdfe8688..4500961151 100644 --- a/resources/libraries/python/PacketVerifier.py +++ b/resources/libraries/python/PacketVerifier.py @@ -51,7 +51,7 @@ chksum = 0xa607 src = 11.11.11.11 dst = 11.11.11.10 - \options \ + options ###[ ICMP ]### type = echo-reply code = 0 @@ -62,19 +62,24 @@ load = 'RT\x00\xca]\x0b\xaa\xbb\xcc\xdd\xee\xff\x08\x06\x00\x01\x08\x00' """ - import os -import socket import select +import interruptingcow +from scapy.config import conf from scapy.all import ETH_P_IP, ETH_P_IPV6, ETH_P_ALL, ETH_P_ARP -from scapy.all import Ether, ARP from scapy.layers.inet6 import IPv6 +from scapy.layers.l2 import Ether, ARP + +# Enable libpcap's L2listen +conf.use_pcap = True +import scapy.arch.pcapdnet # pylint: disable=C0413, unused-import __all__ = ['RxQueue', 'TxQueue', 'Interface', 'create_gratuitous_arp_request', 'auto_pad', 'checksum_equal'] -# TODO: http://stackoverflow.com/questions/320232/ensuring-subprocesses-are-dead-on-exiting-python-program +# TODO: http://stackoverflow.com/questions/320232/ +# ensuring-subprocesses-are-dead-on-exiting-python-program class PacketVerifier(object): @@ -83,9 +88,6 @@ class PacketVerifier(object): os.system('sudo echo 1 > /proc/sys/net/ipv6/conf/{0}/disable_ipv6' .format(interface_name)) os.system('sudo ip link set {0} up promisc on'.format(interface_name)) - self._sock = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, - ETH_P_ALL) - self._sock.bind((interface_name, ETH_P_ALL)) self._ifname = interface_name @@ -97,7 +99,7 @@ def extract_one_packet(buf): :param buf: String representation of incoming packet buffer. :type buf: str - :return: String representation of first packet in buf. + :returns: String representation of first packet in buf. :rtype: str """ pkt_len = 0 @@ -105,11 +107,6 @@ def extract_one_packet(buf): if len(buf) < 60: return None - # print - # print buf.__repr__() - # print Ether(buf).__repr__() - # print len(Ether(buf)) - # print try: ether_type = Ether(buf[0:14]).type except AttributeError: @@ -182,10 +179,9 @@ def packet_reader(interface_name, queue): :param queue: Queue in which this function will push incoming packets. :type interface_name: str :type queue: multiprocessing.Queue - :return: None + :returns: None """ - sock = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, ETH_P_ALL) - sock.bind((interface_name, ETH_P_ALL)) + sock = conf.L2listen(iface=interface_name, type=ETH_P_ALL) while True: pkt = sock.recv(0x7fff) @@ -203,6 +199,7 @@ class RxQueue(PacketVerifier): """ def __init__(self, interface_name): PacketVerifier.__init__(self, interface_name) + self._sock = conf.L2listen(iface=interface_name, type=ETH_P_ALL) def recv(self, timeout=3, ignore=None, verbose=True): """Read next received packet. @@ -218,32 +215,36 @@ class RxQueue(PacketVerifier): :type ignore: list :type verbose: bool - :return: Ether() initialized object from packet data. + :returns: Ether() initialized object from packet data. :rtype: scapy.Ether """ (rlist, _, _) = select.select([self._sock], [], [], timeout) if self._sock not in rlist: return None - - pkt = self._sock.recv(0x7fff) - pkt_pad = auto_pad(pkt) - print 'Received packet on {0} of len {1}'.format(self._ifname, len(pkt)) - if verbose: - Ether(pkt).show2() - print - - if ignore is not None: - for i, ig_pkt in enumerate(ignore): - # Auto pad all packets in ignore list - ignore[i] = auto_pad(ig_pkt) - for ig_pkt in ignore: - if ig_pkt == pkt_pad: - # Found the packet in ignore list, get another one - # TODO: subtract timeout - time_spent in here - ignore.remove(ig_pkt) - return self.recv(timeout, ignore, verbose) - - return Ether(pkt) + try: + with interruptingcow.timeout(timeout, + exception=RuntimeError('Timeout')): + ignore_list = list() + if ignore is not None: + for ig_pkt in ignore: + # Auto pad all packets in ignore list + ignore_list.append(auto_pad(ig_pkt)) + while True: + pkt = self._sock.recv(0x7fff) + pkt_pad = auto_pad(pkt) + print 'Received packet on {0} of len {1}'\ + .format(self._ifname, len(pkt)) + if verbose: + pkt.show2() # pylint: disable=no-member + print + if pkt_pad in ignore_list: + ignore_list.remove(pkt_pad) + print 'Received packet ignored.' + continue + else: + return pkt + except RuntimeError: + return None class TxQueue(PacketVerifier): @@ -256,6 +257,7 @@ class TxQueue(PacketVerifier): """ def __init__(self, interface_name): PacketVerifier.__init__(self, interface_name) + self._sock = conf.L2socket(iface=interface_name, type=ETH_P_ALL) def send(self, pkt, verbose=True): """Send packet out of the bound interface. @@ -299,7 +301,7 @@ class Interface(object): :param timeout: Timeout value in seconds. :type timeout: int - :return: Ether() initialized object from packet data. + :returns: Ether() initialized object from packet data. :rtype: scapy.Ether """ return self.rxq.recv(timeout, self.sent_packets) @@ -332,7 +334,7 @@ def checksum_equal(chksum1, chksum2): :type chksum1: uint16 :type chksum2: uint16 - :return: True if checksums are equivalent, False otherwise. + :returns: True if checksums are equivalent, False otherwise. :rtype: boolean """ if chksum1 == 0xFFFF: