From 52165d0dd55a1071b935d002a41a95210c97f8e7 Mon Sep 17 00:00:00 2001
From: Guillaume Valadon <guillaume@valadon.net>
Date: Tue, 6 Jun 2017 13:15:13 +0200
Subject: [PATCH] filter() calls rewritten as list comprehensions

---
 scapy/arch/linux.py            |  2 +-
 scapy/arch/unix.py             |  2 +-
 scapy/arch/windows/__init__.py |  2 +-
 scapy/dadict.py                |  2 +-
 scapy/layers/dhcp6.py          | 12 ++++++------
 scapy/layers/dns.py            | 34 +++++++++++++++++-----------------
 scapy/layers/inet.py           |  7 ++++---
 scapy/layers/inet6.py          |  8 ++++----
 scapy/main.py                  |  2 +-
 scapy/modules/p0f.py           | 12 ++++++------
 scapy/packet.py                |  2 +-
 scapy/plist.py                 |  6 +++---
 scapy/route6.py                | 10 +++++-----
 scapy/utils6.py                | 14 +++++++-------
 14 files changed, 58 insertions(+), 57 deletions(-)

diff --git a/scapy/arch/linux.py b/scapy/arch/linux.py
index 3b5eb8cf..31b59873 100644
--- a/scapy/arch/linux.py
+++ b/scapy/arch/linux.py
@@ -334,7 +334,7 @@ def read_routes6():
                 continue
             cset = ['::1']
         else:
-            devaddrs = filter(lambda x: x[2] == dev, lifaddr)
+            devaddrs = (x for x in lifaddr if x[2] == dev)
             cset = scapy.utils6.construct_source_candidate_set(d, dp, devaddrs)
         
         if len(cset) != 0:
diff --git a/scapy/arch/unix.py b/scapy/arch/unix.py
index 4a65495c..abdcef90 100644
--- a/scapy/arch/unix.py
+++ b/scapy/arch/unix.py
@@ -319,7 +319,7 @@ def read_routes6():
             next_hop = "::"
         else:
             # Get possible IPv6 source addresses
-            devaddrs = filter(lambda x: x[2] == dev, lifaddr)
+            devaddrs = (x for x in lifaddr if x[2] == dev)
             cset = construct_source_candidate_set(destination, destination_plen, devaddrs)
 
         if len(cset):
diff --git a/scapy/arch/windows/__init__.py b/scapy/arch/windows/__init__.py
index 07aff9d7..295effa5 100755
--- a/scapy/arch/windows/__init__.py
+++ b/scapy/arch/windows/__init__.py
@@ -683,7 +683,7 @@ def _append_route6(routes, dpref, dp, nh, iface, lifaddr):
             return
         cset = ['::1']
     else:
-        devaddrs = filter(lambda x: x[2] == iface, lifaddr)
+        devaddrs = (x for x in lifaddr if x[2] == iface)
         cset = scapy.utils6.construct_source_candidate_set(dpref, dp, devaddrs)
     if len(cset) == 0:
         return
diff --git a/scapy/dadict.py b/scapy/dadict.py
index 67cb8515..f3605a02 100644
--- a/scapy/dadict.py
+++ b/scapy/dadict.py
@@ -41,7 +41,7 @@ class DADict:
             if k and k[0] != "_":
                 print "%10s = %r" % (k,getattr(self,k))
     def __repr__(self):
-        return "<%s/ %s>" % (self._name," ".join(filter(lambda x:x and x[0]!="_",self.__dict__.keys())))
+        return "<%s/ %s>" % (self._name," ".join(x for x in self.__dict__ if x and x[0]!="_"))
 
     def _branch(self, br, uniq=0):
         if uniq and br._name in self:
diff --git a/scapy/layers/dhcp6.py b/scapy/layers/dhcp6.py
index 2c97471f..a404c594 100644
--- a/scapy/layers/dhcp6.py
+++ b/scapy/layers/dhcp6.py
@@ -1346,13 +1346,13 @@ DHCPv6_am.parse_options( dns="2001:500::1035", domain="localdomain, local",
 
         ####
         # Find the source address we will use
-        l = filter(lambda x: x[2] == iface and in6_islladdr(x[0]), 
-                   in6_getifaddr())
-        if not l:
+        try:
+            addr = next(x for x in in6_getifaddr() if x[2] == iface and in6_islladdr(x[0]))
+        except StopIteration:
             warning("Unable to get a Link-Local address")
-            return 
-        
-        self.src_addr = l[0][0]
+            return
+        else:
+            self.src_addr = addr[0]
 
         ####
         # Our leases
diff --git a/scapy/layers/dns.py b/scapy/layers/dns.py
index 2080e4ad..fa4fa13e 100644
--- a/scapy/layers/dns.py
+++ b/scapy/layers/dns.py
@@ -442,34 +442,34 @@ def RRlist2bitmap(lst):
     for wb in xrange(min_window_blocks, max_window_blocks+1):
         # First, filter out RR not encoded in the current window block
         # i.e. keep everything between 256*wb <= 256*(wb+1)
-        rrlist = sorted(filter(lambda x: 256 * wb <= x < 256 * (wb + 1), lst))
+        rrlist = sorted(x for x in lst if 256 * wb <= x < 256 * (wb + 1))
         if rrlist == []:
             continue
 
         # Compute the number of bytes used to store the bitmap
         if rrlist[-1] == 0: # only one element in the list
-            bytes = 1
+            bytes_count = 1
         else:
             max = rrlist[-1] - 256*wb
-            bytes = int(math.ceil(max / 8)) + 1  # use at least 1 byte
-        if bytes > 32: # Don't encode more than 256 bits / values
-            bytes = 32
+            bytes_count = int(math.ceil(max / 8)) + 1  # use at least 1 byte
+        if bytes_count > 32: # Don't encode more than 256 bits / values
+            bytes_count = 32
 
         bitmap += struct.pack("B", wb)
-        bitmap += struct.pack("B", bytes)
+        bitmap += struct.pack("B", bytes_count)
 
         # Generate the bitmap
-        for tmp in xrange(bytes):
-            v = 0
-            # Remove out of range Resource Records
-            tmp_rrlist = filter(lambda x: 256 * wb + 8 * tmp <= x < 256 * wb + 8 * tmp + 8, rrlist)
-            if tmp_rrlist:
-                # 1. rescale to fit into 8 bits
-                # 2. x gives the bit position ; compute the corresponding value
-                tmp_rrlist = [2 ** (7 - (x - 256 * wb) + (tmp * 8)) for x in tmp_rrlist]
-                # 3. sum everything
-                v = reduce(lambda x,y: x+y, tmp_rrlist)
-            bitmap += struct.pack("B", v)
+	# The idea is to remove out of range Resource Records with these steps
+	# 1. rescale to fit into 8 bits
+	# 2. x gives the bit position ; compute the corresponding value
+	# 3. sum everything
+        bitmap += b"".join(
+	    struct.pack(
+		b"B",
+		sum(2 ** (7 - (x - 256 * wb) + (tmp * 8)) for x in rrlist
+		if 256 * wb + 8 * tmp <= x < 256 * wb + 8 * tmp + 8),
+	    ) for tmp in xrange(bytes_count)
+	)
 
     return bitmap
 
diff --git a/scapy/layers/inet.py b/scapy/layers/inet.py
index f969dc5e..81383c31 100644
--- a/scapy/layers/inet.py
+++ b/scapy/layers/inet.py
@@ -1003,8 +1003,8 @@ def _packetlist_timeskew_graph(self, ip, **kargs):
     """Tries to graph the timeskew between the timestamps and real time for a given ip"""
 
     # Filter TCP segments which source address is 'ip'
-    res = [self._elt2pkt(x) for x in self.res]
-    b = filter(lambda x:x.haslayer(IP) and x.getlayer(IP).src == ip and x.haslayer(TCP), res)
+    tmp = (self._elt2pkt(x) for x in self.res)
+    b = (x for x in tmp if IP in x and x[IP].src == ip and TCP in x)
 
     # Build a list of tuples (creation_time, replied_timestamp)
     c = []
@@ -1643,7 +1643,8 @@ funcID:   a function that returns IP id values
 funcpres: a function used to summarize packets"""
     idlst = [funcID(e) for e in lst]
     idlst.sort()
-    classes = [idlst[0]] + [x[1] for x in zip(idlst[:-1], idlst[1:]) if abs(x[0] - x[1]) > 50]
+    classes = [idlst[0]]
+    classes += [t[1] for t in zip(idlst[:-1], idlst[1:]) if abs(t[0]-t[1]) > 50]
     lst = [(funcID(x), funcpres(x)) for x in lst]
     lst.sort()
     print "Probably %i classes:" % len(classes), classes
diff --git a/scapy/layers/inet6.py b/scapy/layers/inet6.py
index c35468f5..98ddd9d6 100644
--- a/scapy/layers/inet6.py
+++ b/scapy/layers/inet6.py
@@ -163,7 +163,7 @@ class Net6(Gen): # syntax ex. fec0::/126
         def m8(i):
             if i % 8 == 0:
                 return i
-        tuple = filter(lambda x: m8(x), xrange(8, 129))
+        tuple = [x for x in xrange(8, 129) if m8(x)]
 
         a = in6_and(self.net, self.mask)
         tmp = [x for x in struct.unpack("16B", a)]
@@ -1078,20 +1078,20 @@ class IPv6ExtHdrFragment(_IPv6ExtHdr):
     overload_fields = {IPv6: { "nh": 44 }}
 
 
-def defragment6(pktlist):
+def defragment6(packets):
     """
     Performs defragmentation of a list of IPv6 packets. Packets are reordered.
     Crap is dropped. What lacks is completed by 'X' characters.
     """
 
-    l = filter(lambda x: IPv6ExtHdrFragment in x, pktlist) # remove non fragments
+    l = [x for x in packets if IPv6ExtHdrFragment in x] # remove non fragments
     if not l:
         return []
 
     id = l[0][IPv6ExtHdrFragment].id
 
     llen = len(l)
-    l = filter(lambda x: x[IPv6ExtHdrFragment].id == id, l)
+    l = [x for x in l if x[IPv6ExtHdrFragment].id == id]
     if len(l) != llen:
         warning("defragment6: some fragmented packets have been removed from list")
     llen = len(l)
diff --git a/scapy/main.py b/scapy/main.py
index ea0d441b..82ad6da9 100644
--- a/scapy/main.py
+++ b/scapy/main.py
@@ -308,7 +308,7 @@ def interact(mydict=None,argv=None,mybanner=None,loglevel=20):
                         return []
                 from scapy.packet import Packet, Packet_metaclass
                 if isinstance(object, Packet) or isinstance(object, Packet_metaclass):
-                    words = filter(lambda x: x[0]!="_",dir(object))
+                    words = [x for x in dir(object) if x[0] != "_"]
                     words += [x.name for x in object.fields_desc]
                 else:
                     words = dir(object)
diff --git a/scapy/modules/p0f.py b/scapy/modules/p0f.py
index 39ce6190..2076d640 100644
--- a/scapy/modules/p0f.py
+++ b/scapy/modules/p0f.py
@@ -365,9 +365,9 @@ Some specifications of the p0f.fp file are not (yet) implemented."""
         pb = db.get_base()
         if pb is None:
             pb = []
-        pb = filter(lambda x: x[6] == osgenre, pb)
+        pb = [x for x in pb if x[6] == osgenre]
         if osdetails:
-            pb = filter(lambda x: x[7] == osdetails, pb)
+            pb = [x for x in pb if x[7] == osdetails]
     elif signature:
         pb = [signature]
     else:
@@ -375,9 +375,9 @@ Some specifications of the p0f.fp file are not (yet) implemented."""
     if db == p0fr_kdb:
         # 'K' quirk <=> RST+ACK
         if pkt.payload.flags & 0x4 == 0x4:
-            pb = filter(lambda x: 'K' in x[5], pb)
+            pb = [x for x in pb if 'K' in x[5]]
         else:
-            pb = filter(lambda x: 'K' not in x[5], pb)
+            pb = [x for x in pb if 'K' not in x[5]]
     if not pb:
         raise Scapy_Exception("No match in the p0f database")
     pers = pb[random.randint(0, len(pb) - 1)]
@@ -459,8 +459,8 @@ Some specifications of the p0f.fp file are not (yet) implemented."""
         pkt.payload.window = mtu * int(pers[0][1:])
     elif pers[0][0] == 'S':
         ## needs MSS set
-        MSS = filter(lambda x: x[0] == 'MSS', options)
-        if not filter(lambda x: x[0] == 'MSS', options):
+        mss = [x for x in options if x[0] == 'MSS']
+        if not mss:
             raise Scapy_Exception("TCP window value requires MSS, and MSS option not set")
         pkt.payload.window = filter(lambda x: x[0] == 'MSS', options)[0][1] * int(pers[0][1:])
     else:
diff --git a/scapy/packet.py b/scapy/packet.py
index 588d9fbf..7fe4261c 100644
--- a/scapy/packet.py
+++ b/scapy/packet.py
@@ -1345,7 +1345,7 @@ def split_bottom_up(lower, upper, __fval=None, **fval):
             if k not in f or f[k] != fval[k]:
                 return True
         return False
-    lower.payload_guess = filter(do_filter, lower.payload_guess)
+    lower.payload_guess = [x for x in lower.payload_guess if do_filter(x)]
         
 def split_top_down(lower, upper, __fval=None, **fval):
     if __fval is not None:
diff --git a/scapy/plist.py b/scapy/plist.py
index a5643492..72745e7f 100644
--- a/scapy/plist.py
+++ b/scapy/plist.py
@@ -76,7 +76,7 @@ class PacketList(BasePacketList):
         return getattr(self.res, attr)
     def __getitem__(self, item):
         if isinstance(item,type) and issubclass(item,BasePacket):
-            return self.__class__(filter(lambda x: item in self._elt2pkt(x),self.res),
+            return self.__class__([x for x in self.res if item in self._elt2pkt(x)],
                                   name="%s from %s"%(item.__name__,self.listname))
         if isinstance(item, slice):
             return self.__class__(self.res.__getitem__(item),
@@ -122,7 +122,7 @@ lfilter: truth function to apply to each packet to decide whether it will be dis
     
     def filter(self, func):
         """Returns a packet list filtered by a truth function"""
-        return self.__class__(filter(func,self.res),
+        return self.__class__([x for x in self.res if func(x)],
                               name="filtered %s"%self.listname)
     def make_table(self, *args, **kargs):
         """Prints a table using a function that returns for each packet its head column value, head row value and displayed value
@@ -470,7 +470,7 @@ lfilter: truth function to apply to each packet to decide whether it will be dis
                     break
             i += 1
         if multi:
-            remain = filter(lambda x:not hasattr(x,"_answered"), remain)
+            remain = [x for x in remain if not hasattr(x, "_answered")]
         return SndRcvList(sr),PacketList(remain)
 
     def sessions(self, session_extractor=None):
diff --git a/scapy/route6.py b/scapy/route6.py
index 3eed0c53..80009b32 100644
--- a/scapy/route6.py
+++ b/scapy/route6.py
@@ -74,7 +74,7 @@ class Route6:
             # TODO: do better than that
             # replace that unique address by the list of all addresses
             lifaddr = in6_getifaddr()
-            devaddrs = filter(lambda x: x[2] == dev, lifaddr)
+            devaddrs = [x for x in lifaddr if x[2] == dev]
             ifaddr = construct_source_candidate_set(prefix, plen, devaddrs)
 
         return (prefix, plen, gw, dev, ifaddr)
@@ -100,7 +100,7 @@ class Route6:
         dst, plen = tmp.split('/')[:2]
         dst = in6_ptop(dst)
         plen = int(plen)
-        l = filter(lambda x: in6_ptop(x[0]) == dst and x[1] == plen, self.routes)
+        l = [x for x in self.routes if in6_ptop(x[0]) == dst and x[1] == plen]
         if gw:
             gw = in6_ptop(gw)
             l = [x for x in self.routes if in6_ptop(x[2]) == gw]
@@ -224,7 +224,7 @@ class Route6:
         pathes.sort(reverse=True)
 
         best_plen = pathes[0][0]
-        pathes = filter(lambda x: x[0] == best_plen, pathes)
+        pathes = [x for x in pathes if x[0] == best_plen]
 
         res = []
         for p in pathes: # Here we select best source address for every route
@@ -252,10 +252,10 @@ class Route6:
             if in6_isgladdr(dst) and in6_isaddr6to4(dst):
                 # TODO : see if taking the longest match between dst and
                 #        every source addresses would provide better results
-                tmp = filter(lambda x: in6_isaddr6to4(x[1][1]), res)
+                tmp = [x for x in res if in6_isaddr6to4(x[1][1])]
             elif in6_ismaddr(dst) or in6_islladdr(dst):
                 # TODO : I'm sure we are not covering all addresses. Check that
-                tmp = filter(lambda x: x[1][0] == conf.iface6, res)
+                tmp = [x for x in res if x[1][0] == conf.iface6]
 
             if tmp:
                 res = tmp
diff --git a/scapy/utils6.py b/scapy/utils6.py
index 7d1c62e4..92cfe523 100644
--- a/scapy/utils6.py
+++ b/scapy/utils6.py
@@ -51,22 +51,22 @@ def construct_source_candidate_set(addr, plen, laddr):
 
     cset = []
     if in6_isgladdr(addr) or in6_isuladdr(addr):
-        cset = filter(lambda x: x[1] == IPV6_ADDR_GLOBAL, laddr)
+        cset = (x for x in laddr if x[1] == IPV6_ADDR_GLOBAL)
     elif in6_islladdr(addr):
-        cset = filter(lambda x: x[1] == IPV6_ADDR_LINKLOCAL, laddr)
+        cset = (x for x in laddr if x[1] == IPV6_ADDR_LINKLOCAL)
     elif in6_issladdr(addr):
-        cset = filter(lambda x: x[1] == IPV6_ADDR_SITELOCAL, laddr)
+        cset = (x for x in laddr if x[1] == IPV6_ADDR_SITELOCAL)
     elif in6_ismaddr(addr):
         if in6_ismnladdr(addr):
             cset = [('::1', 16, scapy.consts.LOOPBACK_INTERFACE)]
         elif in6_ismgladdr(addr):
-            cset = filter(lambda x: x[1] == IPV6_ADDR_GLOBAL, laddr)
+            cset = (x for x in laddr if x[1] == IPV6_ADDR_GLOBAL)
         elif in6_ismlladdr(addr):
-            cset = filter(lambda x: x[1] == IPV6_ADDR_LINKLOCAL, laddr)
+            cset = (x for x in laddr if x[1] == IPV6_ADDR_LINKLOCAL)
         elif in6_ismsladdr(addr):
-            cset = filter(lambda x: x[1] == IPV6_ADDR_SITELOCAL, laddr)
+            cset = (x for x in laddr if x[1] == IPV6_ADDR_SITELOCAL)
     elif addr == '::' and plen == 0:
-        cset = filter(lambda x: x[1] == IPV6_ADDR_GLOBAL, laddr)
+        cset = (x for x in laddr if x[1] == IPV6_ADDR_GLOBAL)
     cset = [x[0] for x in cset]
     cset.sort(cmp=cset_sort) # Sort with global addresses first
     return cset            
-- 
GitLab