diff --git a/scapy/ansmachine.py b/scapy/ansmachine.py
index ddc3a93557206f2a0e3269dc79b56f2a0c55ac72..09c7d44c157a43117b450e26f77e324b641befae 100644
--- a/scapy/ansmachine.py
+++ b/scapy/ansmachine.py
@@ -70,7 +70,7 @@ class AnsweringMachine(six.with_metaclass(ReferenceAM, object)):
     def parse_all_options(self, mode, kargs):
         sniffopt = {}
         sendopt = {}
-        for k in kargs.keys():  # use .keys(): kargs is modified in the loop
+        for k in list(kargs):  # use list(): kargs is modified in the loop
             if k in self.sniff_options_list:
                 sniffopt[k] = kargs[k]
             if k in self.send_options_list:
diff --git a/scapy/asn1/mib.py b/scapy/asn1/mib.py
index 6a5d37e0cc7b850abe5d35a755ae0980499a2918..697887bbd3240f35c028dccd579b037cf9793ce2 100644
--- a/scapy/asn1/mib.py
+++ b/scapy/asn1/mib.py
@@ -73,8 +73,6 @@ class MIBDict(DADict):
             s += '\t"%s" -> "%s" [label="%s"];\n' % (parent, o,remainder)
         s += "}\n"
         do_graph(s, **kargs)
-    def __len__(self):
-        return len(self.keys())
 
 
 def mib_register(ident, value, the_mib, unresolved):
@@ -102,7 +100,7 @@ def mib_register(ident, value, the_mib, unresolved):
         return False
     else:
         the_mib[ident] = resval
-        keys = list(unresolved.keys())
+        keys = list(unresolved)
         i = 0
         while i < len(keys):
             k = keys[i]
diff --git a/scapy/asn1fields.py b/scapy/asn1fields.py
index 5f1caf40de6c9ad1b1fa2dfa60c29c5620c08faf..3a9ed21f8fb30f47aa02390ebd553ecbe82e5e39 100644
--- a/scapy/asn1fields.py
+++ b/scapy/asn1fields.py
@@ -178,7 +178,7 @@ class ASN1F_enum_INTEGER(ASN1F_INTEGER):
         if isinstance(enum, list):
             keys = range(len(enum))
         else:
-            keys = enum.keys()
+            keys = list(enum)
         if any(isinstance(x, six.string_types) for x in keys):
             i2s, s2i = s2i, i2s
         for k in keys:
diff --git a/scapy/contrib/http2.py b/scapy/contrib/http2.py
index 8cfe66dd77809dd76f99899dda65e96d6e3357a1..32b2293b28f74757edbf8b823df957a3d40e4425 100644
--- a/scapy/contrib/http2.py
+++ b/scapy/contrib/http2.py
@@ -2230,7 +2230,7 @@ class HPackHdrTable(Sized):
     @classmethod
     def init_static_table(cls):
         # type: () -> None
-        cls._static_entries_last_idx = max(cls._static_entries.keys())
+        cls._static_entries_last_idx = max(cls._static_entries)
 
     def __init__(self, dynamic_table_max_size=4096, dynamic_table_cap_size=4096):
         # type: (int, int) -> None
@@ -2379,12 +2379,12 @@ class HPackHdrTable(Sized):
         If no matching header is found, this method returns None.
         """
         name = name.lower()
-        for k in type(self)._static_entries.keys():
-            if type(self)._static_entries[k].name() == name:
-                return k
-        for k in range(0, len(self._dynamic_table)):
-            if self._dynamic_table[k].name() == name:
-                return type(self)._static_entries_last_idx + k + 1
+        for key, val in six.iteritems(type(self)._static_entries):
+            if val.name() == name:
+                return key
+        for idx, val in enumerate(self._dynamic_table):
+            if val.name() == name:
+                return type(self)._static_entries_last_idx + idx + 1
         return None
 
     def get_idx_by_name_and_value(self, name, value):
@@ -2398,14 +2398,12 @@ class HPackHdrTable(Sized):
         If no matching header is found, this method returns None.
         """
         name = name.lower()
-        for k in type(self)._static_entries.keys():
-            elmt = type(self)._static_entries[k]
-            if elmt.name() == name and elmt.value() == value:
-                return k
-        for k in range(0, len(self._dynamic_table)):
-            elmt = self._dynamic_table[k]
-            if elmt.name() == name and elmt.value() == value:
-                return type(self)._static_entries_last_idx + k + 1
+        for key, val in six.iteritems(type(self)._static_entries):
+            if val.name() == name and val.value() == value:
+                return key
+        for idx, val in enumerate(self._dynamic_table):
+            if val.name() == name and val.value() == value:
+                return type(self)._static_entries_last_idx + idx + 1
         return None
 
     def __len__(self):
diff --git a/scapy/contrib/modbus.py b/scapy/contrib/modbus.py
index 25bcc82f470c65d7f92de84a3a57463bab4ed630..ee1bdaa407ff52835f4caea5323d2629df8516e0 100644
--- a/scapy/contrib/modbus.py
+++ b/scapy/contrib/modbus.py
@@ -785,7 +785,7 @@ class ModbusADURequest(Packet):
             return _modbus_request_classes[function_code]
         except KeyError:
             pass
-        if function_code in _reserved_funccode_request.keys():
+        if function_code in _reserved_funccode_request:
             return ModbusPDUReservedFunctionCodeRequest
         return ModbusPDUUserDefinedFunctionCodeRequest
 
@@ -820,9 +820,9 @@ class ModbusADUResponse(Packet):
             return _modbus_error_classes[function_code]
         except KeyError:
             pass
-        if function_code in _reserved_funccode_response.keys():
+        if function_code in _reserved_funccode_response:
             return ModbusPDUReservedFunctionCodeResponse
-        elif function_code in _reserved_funccode_error.keys():
+        elif function_code in _reserved_funccode_error:
             return ModbusPDUReservedFunctionCodeError
         if function_code < 0x80:
             return ModbusPDUUserDefinedFunctionCodeResponse
diff --git a/scapy/dadict.py b/scapy/dadict.py
index f45e6e37f11a1bf77392db6f8b25b7cec8ca1333..8fca8e49c1176cb6c1b5dc32b96e0820bf44c272 100644
--- a/scapy/dadict.py
+++ b/scapy/dadict.py
@@ -39,9 +39,10 @@ class DADict:
     def __setitem__(self, attr, val):        
         return setattr(self, self.fixname(attr), val)
     def __iter__(self):
-        return iter(map(lambda x_y1: x_y1[1],filter(lambda x_y: x_y[0] and x_y[0][0]!="_", self.__dict__.items())))
+        return (value for key, value in six.iteritems(self.__dict__)
+                if key and key[0] != '_')
     def _show(self):
-        for k in self.__dict__.keys():
+        for k in self.__dict__:
             if k and k[0] != "_":
                 print("%10s = %r" % (k,getattr(self,k)))
     def __repr__(self):
diff --git a/scapy/fields.py b/scapy/fields.py
index b478779edf3de7646fea4803aedad41d4599cb07..e548200d99a49669c50999728579d94dc8964536 100644
--- a/scapy/fields.py
+++ b/scapy/fields.py
@@ -10,6 +10,7 @@ Fields: basic data structures that make up parts of packets.
 from __future__ import absolute_import
 import struct,copy,socket,collections
 from scapy.config import conf
+from scapy.dadict import DADict
 from scapy.volatile import *
 from scapy.data import *
 from scapy.compat import *
@@ -917,8 +918,10 @@ class _EnumField(Field):
             self.s2i_cb = None
             if isinstance(enum, list):
                 keys = range(len(enum))
-            else:
+            elif isinstance(enum, DADict):
                 keys = enum.keys()
+            else:
+                keys = list(enum)
             if any(isinstance(x, str) for x in keys):
                 i2s, s2i = s2i, i2s
             for k in keys:
@@ -965,7 +968,7 @@ class CharEnumField(EnumField):
     def __init__(self, name, default, enum, fmt = "1s"):
         EnumField.__init__(self, name, default, enum, fmt)
         if self.i2s is not None:
-            k = list(self.i2s.keys())
+            k = list(self.i2s)
             if k and len(k[0]) != 1:
                 self.i2s,self.s2i = self.s2i,self.i2s
     def any2i_one(self, pkt, x):
@@ -1270,8 +1273,8 @@ class MultiFlagsField(BitField):
                     these_names = self.names[v]
                     s = set()
                     for i in x:
-                        for j in these_names.keys():
-                            if these_names[j].short == i:
+                        for val in six.itervalues(these_names):
+                            if val.short == i:
                                 s.add(i)
                                 break
                         else:
@@ -1289,8 +1292,8 @@ class MultiFlagsField(BitField):
 
         r = 0
         for flag_set in x:
-            for i in these_names.keys():
-                if these_names[i].short == flag_set:
+            for i, val in six.iteritems(these_names):
+                if val.short == flag_set:
                     r |= 1 << i
                     break
             else:
diff --git a/scapy/layers/all.py b/scapy/layers/all.py
index 1373bc9916aea5cbd39cddb985e63fda494e3c9d..8743276dfa527206826853d4ada90c8ecf7f1806 100644
--- a/scapy/layers/all.py
+++ b/scapy/layers/all.py
@@ -13,7 +13,7 @@ from scapy.error import log_loading
 from scapy.main import load_layer
 import logging, importlib
 import scapy.modules.six as six
-ignored = list(six.moves.builtins.__dict__.keys()) + ["sys"]
+ignored = list(six.moves.builtins.__dict__) + ["sys"]
 log = logging.getLogger("scapy.loading")
 
 __all__ = []
diff --git a/scapy/layers/dhcp6.py b/scapy/layers/dhcp6.py
index e109c116ad9b060e76b74a8b872cf15d9967d1b5..bb6856cf712fc7d3db014380ec7c9eb87085db01 100644
--- a/scapy/layers/dhcp6.py
+++ b/scapy/layers/dhcp6.py
@@ -1315,7 +1315,7 @@ DHCPv6_am.parse_options( dns="2001:500::1035", domain="localdomain, local",
 
         if self.debug:
             print("\n[+] List of active DHCPv6 options:")
-            opts = sorted(self.dhcpv6_options.keys())
+            opts = sorted(self.dhcpv6_options)
             for i in opts:
                 print("    %d: %s" % (i, repr(self.dhcpv6_options[i])))
 
@@ -1343,7 +1343,7 @@ DHCPv6_am.parse_options( dns="2001:500::1035", domain="localdomain, local",
 
             # Mac Address
             rawmac = get_if_raw_hwaddr(iface)[1]
-            mac = ":".join("%.02x" % ord(x) for x in rawmac)
+            mac = ":".join("%.02x" % orb(x) for x in rawmac)
 
             self.duid = DUID_LLT(timeval = timeval, lladdr = mac)
             
@@ -1574,12 +1574,12 @@ DHCPv6_am.parse_options( dns="2001:500::1035", domain="localdomain, local",
                     reqopts = []
                     if p.haslayer(DHCP6OptOptReq): # add only asked ones
                         reqopts = p[DHCP6OptOptReq].reqopts
-                        for o in self.dhcpv6_options.keys():
+                        for o, opt in six.iteritems(self.dhcpv6_options):
                             if o in reqopts:
-                                resp /= self.dhcpv6_options[o]
+                                resp /= opt
                     else: # advertise everything we have available
-                        for o in self.dhcpv6_options.keys():
-                            resp /= self.dhcpv6_options[o]                    
+                        for o, opt in six.iteritems(self.dhcpv6_options):
+                            resp /= opt
 
             return resp
 
@@ -1595,15 +1595,15 @@ DHCPv6_am.parse_options( dns="2001:500::1035", domain="localdomain, local",
             reqopts = []
             if p.haslayer(DHCP6OptOptReq): # add only asked ones
                 reqopts = p[DHCP6OptOptReq].reqopts
-                for o in self.dhcpv6_options.keys():
+                for o, opt in six.iteritems(self.dhcpv6_options):
                     if o in reqopts:
-                        resp /= self.dhcpv6_options[o]
+                        resp /= opt
             else: 
                 # advertise everything we have available.
                 # Should not happen has clients MUST include 
                 # and ORO in requests (sec 18.1.1)   -- arno
-                for o in self.dhcpv6_options.keys():
-                    resp /= self.dhcpv6_options[o]          
+                for o, opt in six.iteritems(self.dhcpv6_options):
+                    resp /= opt
 
             return resp            
         
@@ -1693,8 +1693,8 @@ DHCPv6_am.parse_options( dns="2001:500::1035", domain="localdomain, local",
             reqopts = []
             if p.haslayer(DHCP6OptOptReq):
                 reqopts = p[DHCP6OptOptReq].reqopts
-            for o in self.dhcpv6_options.keys():
-                resp /= self.dhcpv6_options[o]
+            for o, opt in six.iteritems(self.dhcpv6_options):
+                resp /= opt
 
             return resp
 
diff --git a/scapy/layers/inet.py b/scapy/layers/inet.py
index 4154d86ae85cdf5226c24ffade66953d2a06e890..5ce30aa876b01c24f6b480a15dd7a1a87c537a22 100644
--- a/scapy/layers/inet.py
+++ b/scapy/layers/inet.py
@@ -1089,7 +1089,7 @@ class TracerouteResult(SndRcvList):
                 m = min(x for x, y in six.itervalues(k) if y)
             except ValueError:
                 continue
-            for l in k.keys():  # use .keys(): k is modified in the loop
+            for l in list(k):  # use list(): k is modified in the loop
                 if l > m:
                     del k[l]
         return trace
diff --git a/scapy/layers/inet6.py b/scapy/layers/inet6.py
index f7dad10c185b829c96a4950ede432e38e4843a6d..d626a4cd5e2e7b236ac976291148e667d7385a9e 100644
--- a/scapy/layers/inet6.py
+++ b/scapy/layers/inet6.py
@@ -3179,7 +3179,7 @@ class TracerouteResult6(TracerouteResult):
                 m = min(x for x, y in six.itervalues(k) if y)
             except ValueError:
                 continue
-            for l in k.keys():  # use .keys(): k is modified in the loop
+            for l in list(k):  # use list(): k is modified in the loop
                 if l > m:
                     del k[l]
 
diff --git a/scapy/layers/ipsec.py b/scapy/layers/ipsec.py
index 91cd98ecbb7a3df2ef5b1fdd46e52c5808008110..0301351acb248cd3bf79cffcb48bd378e5a48e94 100644
--- a/scapy/layers/ipsec.py
+++ b/scapy/layers/ipsec.py
@@ -786,7 +786,7 @@ class SecurityAssociation(object):
         if crypt_algo:
             if crypt_algo not in CRYPT_ALGOS:
                 raise TypeError('unsupported encryption algo %r, try %r' %
-                                (crypt_algo, list(CRYPT_ALGOS.keys())))
+                                (crypt_algo, list(CRYPT_ALGOS)))
             self.crypt_algo = CRYPT_ALGOS[crypt_algo]
 
             if crypt_key:
@@ -804,7 +804,7 @@ class SecurityAssociation(object):
         if auth_algo:
             if auth_algo not in AUTH_ALGOS:
                 raise TypeError('unsupported integrity algo %r, try %r' %
-                                (auth_algo, list(AUTH_ALGOS.keys())))
+                                (auth_algo, list(AUTH_ALGOS)))
             self.auth_algo = AUTH_ALGOS[auth_algo]
             self.auth_key = auth_key
         else:
diff --git a/scapy/main.py b/scapy/main.py
index d4b30c39e4520980f9fbceb2fe10d8260fa2fe56..48680b0293ea61a65e11aaadbfa95446075e196a 100644
--- a/scapy/main.py
+++ b/scapy/main.py
@@ -231,7 +231,7 @@ def save_session(fname=None, session=None, pickleProto=-1):
     if "__builtins__" in to_be_saved:
         del(to_be_saved["__builtins__"])
 
-    for k in list(to_be_saved.keys()):
+    for k in list(to_be_saved):
         i = to_be_saved[k]
         if hasattr(i, "__module__") and (k[0] == "_" or i.__module__.startswith("IPython")):
             del(to_be_saved[k])
diff --git a/scapy/packet.py b/scapy/packet.py
index 89184d1724565d819f243f21a0b67b8a89e2f585..eed3f64d42a3b394ef33fd5ccd880c1b2e2439d5 100644
--- a/scapy/packet.py
+++ b/scapy/packet.py
@@ -772,7 +772,7 @@ class Packet(six.with_metaclass(Packet_metaclass, BasePacket)):
 
     def hide_defaults(self):
         """Removes fields' values that are the same as default values."""
-        for k in list(self.fields.keys()):  # use .items(): self.fields is modified in the loop
+        for k, v in list(self.fields.items()):  # use list(): self.fields is modified in the loop
             v = self.fields[k]
             if k in self.default_fields:
                 if self.default_fields[k] == v:
@@ -907,7 +907,7 @@ values.
             ccls,fld = cls,None
         if cls is None or match(self.__class__, cls) or self.__class__.__name__ == ccls:
             if all(self.getfieldval(fldname) == fldvalue
-                   for fldname, fldvalue in flt.iteritems()):
+                   for fldname, fldvalue in six.iteritems(flt)):
                 if nb == 1:
                     if fld is None:
                         return self