diff --git a/scapy/arch/linux.py b/scapy/arch/linux.py
index 9ad10235e1c9d7c6754c27a2a0ffb830f343fffc..fed35df3867086d3d0915403a3ea1bf175218673 100644
--- a/scapy/arch/linux.py
+++ b/scapy/arch/linux.py
@@ -105,7 +105,7 @@ def get_if_raw_addr(iff):
 
 def get_if_list():
     try:
-        f=open("/proc/net/dev","r")
+        f=open("/proc/net/dev","rb")
     except IOError:
         warning("Can't open /proc/net/dev !")
         return []
@@ -182,14 +182,14 @@ def get_alias_address(iface_name, ip_mask):
 
     # Retrieve interfaces structures
     sck = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
-    names = array.array('B', '\0' * 4096)
+    names = array.array('B', b'\0' * 4096)
     ifreq = ioctl(sck.fileno(), SIOCGIFCONF,
                   struct.pack("iL", len(names), names.buffer_info()[0]))
 
     # Extract interfaces names
     out = struct.unpack("iL", ifreq)[0]
     names = names.tostring()
-    names = [names[i:i+offset].split('\0', 1)[0] for i in range(0, out, name_len)]
+    names = [names[i:i+offset].split(b'\0', 1)[0] for i in range(0, out, name_len)]
 
     # Look for the IP address
     for ifname in names:
@@ -204,8 +204,8 @@ def get_alias_address(iface_name, ip_mask):
         msk = struct.unpack(">I", ifreq[20:24])[0]
        
         # Get the full interface name
-        if ':' in ifname:
-            ifname = ifname[:ifname.index(':')]
+        if b':' in ifname:
+            ifname = ifname[:ifname.index(b':')]
         else:
             continue
 
@@ -221,7 +221,7 @@ def get_alias_address(iface_name, ip_mask):
 
 def read_routes():
     try:
-        f=open("/proc/net/route","r")
+        f=open("/proc/net/route","rb")
     except IOError:
         warning("Can't open /proc/net/route !")
         return []
@@ -288,7 +288,7 @@ def in6_getifaddr():
     """
     ret = []
     try:
-        f = open("/proc/net/if_inet6","r")
+        f = open("/proc/net/if_inet6","rb")
     except IOError as err:    
         return ret
     l = f.readlines()
@@ -302,7 +302,7 @@ def in6_getifaddr():
 
 def read_routes6():
     try:
-        f = open("/proc/net/ipv6_route","r")
+        f = open("/proc/net/ipv6_route","rb")
     except IOError as err:
         return []
     # 1. destination network
diff --git a/scapy/arch/pcapdnet.py b/scapy/arch/pcapdnet.py
index aa8db5494f3c29d207996521c019a00ce458a63b..5087264377c64a9553414bc4e9227fd83bdbcc01 100644
--- a/scapy/arch/pcapdnet.py
+++ b/scapy/arch/pcapdnet.py
@@ -42,12 +42,12 @@ if conf.use_winpcapy:
               pcap_freealldevs(devs)
       # Detect Pcap version
       version = pcap_lib_version()
-      if "winpcap" in version.lower():
+      if b"winpcap" in version.lower():
           if os.path.exists(os.environ["WINDIR"] + "\\System32\\Npcap\\wpcap.dll"):
               warning("Winpcap is installed over Npcap. Will use Winpcap (see 'Winpcap/Npcap conflicts' in scapy's docs)", True)
           elif platform.release() != "XP":
               warning("WinPcap is now deprecated (not maintened). Please use Npcap instead", True)
-      elif "npcap" in version.lower():
+      elif b"npcap" in version.lower():
           conf.use_npcap = True
           LOOPBACK_NAME = scapy.consts.LOOPBACK_NAME = "Npcap Loopback Adapter"
   except OSError as e:
diff --git a/scapy/arch/windows/__init__.py b/scapy/arch/windows/__init__.py
index 5f7fc1916b0c104cc493b84afc540ebc54dee40e..43614e409b75b26d86ba03147dd9add7255efe04 100755
--- a/scapy/arch/windows/__init__.py
+++ b/scapy/arch/windows/__init__.py
@@ -109,8 +109,8 @@ def _vbs_get_hardware_iface_guid(devid):
         devid = str(int(devid) + 1)
         guid = iter(_vbs_exec_code("""WScript.Echo CreateObject("WScript.Shell").RegRead("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards\\%s\\ServiceName")
 """ % devid)).next()
-        guid = guid[:-1] if guid.endswith('}\n') else guid
-        if guid.startswith('{') and guid.endswith('}'):
+        guid = guid[:-1] if guid.endswith(b'}\n') else guid
+        if guid.startswith(b'{') and guid.endswith(b'}'):
             return guid
     except StopIteration:
         return None
@@ -261,7 +261,7 @@ if conf.prog.tcpdump and conf.use_npcap and conf.prog.os_access:
         try:
             p_test_windump = sp.Popen([conf.prog.tcpdump, "-help"], stdout=sp.PIPE, stderr=sp.STDOUT)
             stdout, err = p_test_windump.communicate()
-            return "npcap" in stdout.lower()
+            return b"npcap" in stdout.lower()
         except:
             return False
     windump_ok = test_windump_npcap()
diff --git a/scapy/arch/windows/compatibility.py b/scapy/arch/windows/compatibility.py
index 9213c5e05c997b5cc78b1a1dd56517565503b867..0b4700c026323341001fcbd38ecd3874e91e7b4c 100644
--- a/scapy/arch/windows/compatibility.py
+++ b/scapy/arch/windows/compatibility.py
@@ -116,7 +116,7 @@ def sndrcv(pks, pkt, timeout = 2, inter = 0, verbose=None, chainCC=0, retry=0, m
                                     if r.answers(sentpkt):
                                         ans.append((sentpkt, r))
                                         if verbose > 1:
-                                            os.write(1, "*")
+                                            os.write(1, b"*")
                                         ok = 1
                                         if not multi:
                                             del hlst[i]
@@ -130,7 +130,7 @@ def sndrcv(pks, pkt, timeout = 2, inter = 0, verbose=None, chainCC=0, retry=0, m
                                 break
                             if not ok:
                                 if verbose > 1:
-                                    os.write(1, ".")
+                                    os.write(1, b".")
                                 nbrecv += 1
                                 if conf.debug_match:
                                     debug.recv.append(r)
diff --git a/scapy/as_resolvers.py b/scapy/as_resolvers.py
index e1c672bbea197b86bb53f8e9a5336bca27353c02..e92b3a36be65e5adcb4e0ff33837b78b8bd115a6 100644
--- a/scapy/as_resolvers.py
+++ b/scapy/as_resolvers.py
@@ -32,11 +32,11 @@ class AS_resolver:
         self.s.close()
         
     def _parse_whois(self, txt):
-        asn,desc = None,""
+        asn,desc = None,b""
         for l in txt.splitlines():
-            if not asn and l.startswith("origin:"):
+            if not asn and l.startswith(b"origin:"):
                 asn = l[7:].strip()
-            if l.startswith("descr:"):
+            if l.startswith(b"descr:"):
                 if desc:
                     desc += r"\n"
                 desc += l[6:].strip()
@@ -46,8 +46,8 @@ class AS_resolver:
 
     def _resolve_one(self, ip):
         self.s.send("%s\n" % ip)
-        x = ""
-        while not ("%" in x  or "source" in x):
+        x = b""
+        while not (b"%" in x  or b"source" in x):
             x += self.s.recv(8192)
         asn, desc = self._parse_whois(x)
         return ip,asn,desc
@@ -78,21 +78,21 @@ class AS_resolver_cymru(AS_resolver):
         ASNlist = []
         s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
         s.connect((self.server,self.port))
-        s.send("begin\r\n"+"\r\n".join(ips)+"\r\nend\r\n")
-        r = ""
+        s.send(b"begin\r\n"+b"\r\n".join(ips)+b"\r\nend\r\n")
+        r = b""
         while True:
             l = s.recv(8192)
-            if l == "":
+            if l == b"":
                 break
             r += l
         s.close()
         for l in r.splitlines()[1:]:
-            if "|" not in l:
+            if b"|" not in l:
                 continue
             asn, ip, desc = [elt.strip() for elt in l.split('|')]
-            if asn == "NA":
+            if asn == b"NA":
                 continue
-            asn = "AS" + str(int(asn))
+            asn = b"AS" + str(int(asn))
             ASNlist.append((ip, asn, desc))
         return ASNlist
 
diff --git a/scapy/asn1/ber.py b/scapy/asn1/ber.py
index 16f8381bb3608f12cc33c04579b6acf95c1d676a..176a85709ac1ff67396b87cd0205864040d46da2 100644
--- a/scapy/asn1/ber.py
+++ b/scapy/asn1/ber.py
@@ -61,7 +61,7 @@ class BER_BadTag_Decoding_Error(BER_Decoding_Error, ASN1_BadTag_Decoding_Error):
 def BER_len_enc(l, size=0):
         if l <= 127 and size==0:
             return chr(l)
-        s = ""
+        s = b""
         while l or size>0:
             s = chr(l&0xff)+s
             l >>= 8
@@ -90,7 +90,7 @@ def BER_num_enc(l, size=1):
                 x[0] |= 0x80
             l >>= 7
             size -= 1
-        return "".join(chr(k) for k in x)
+        return b"".join(chr(k) for k in x)
 def BER_num_dec(s, cls_id=0):
         if len(s) == 0:
             raise BER_Decoding_Error("BER_num_dec: got empty string", remaining=s)
@@ -287,7 +287,7 @@ class BERcodec_INTEGER(BERcodec_Object):
         s.append(BER_len_enc(len(s)))
         s.append(chr(cls.tag))
         s.reverse()
-        return "".join(s)
+        return b"".join(s)
     @classmethod
     def do_dec(cls, s, context=None, safe=False):
         l,s,t = cls.check_type_check_len(s)
@@ -326,8 +326,8 @@ class BERcodec_BIT_STRING(BERcodec_Object):
             unused_bits = 0
         else:
             unused_bits = 8 - len(s)%8
-            s += "0"*unused_bits
-        s = "".join(chr(int("".join(x),2)) for x in zip(*[iter(s)]*8))
+            s += b"0"*unused_bits
+        s = b"".join(chr(int(b"".join(x),2)) for x in zip(*[iter(s)]*8))
         s = chr(unused_bits) + s
         return chr(cls.tag)+BER_len_enc(len(s))+s
 
@@ -358,7 +358,7 @@ class BERcodec_OID(BERcodec_Object):
         if len(lst) >= 2:
             lst[1] += 40*lst[0]
             del(lst[0])
-        s = "".join(BER_num_enc(k) for k in lst)
+        s = b"".join(BER_num_enc(k) for k in lst)
         return chr(cls.tag)+BER_len_enc(len(s))+s
     @classmethod
     def do_dec(cls, s, context=None, safe=False):
diff --git a/scapy/asn1fields.py b/scapy/asn1fields.py
index d3454ac840e9803b2c4f8c5afe64c48ab7cda9d0..1b16f05ee6720d536ad806c6742015067745d7bb 100644
--- a/scapy/asn1fields.py
+++ b/scapy/asn1fields.py
@@ -93,7 +93,7 @@ class ASN1F_field(ASN1F_element):
             return codec.dec(s, context=self.context)
     def i2m(self, pkt, x):
         if x is None:
-            return ""
+            return b""
         if isinstance(x, ASN1_Object):
             if ( self.ASN1_tag == ASN1_Class_UNIVERSAL.ANY
                  or x.tag == ASN1_Class_UNIVERSAL.RAW
@@ -113,7 +113,7 @@ class ASN1F_field(ASN1F_element):
             except ASN1F_badsequence:
                 c = packet.Raw(s)
             cpad = c.getlayer(packet.Raw)
-            s = ""
+            s = b""
             if cpad is not None:
                 s = cpad.load
                 del(cpad.underlayer.payload)
@@ -199,7 +199,7 @@ class ASN1F_BIT_STRING(ASN1F_field):
     def __init__(self, name, default, default_readable=True, context=None,
                  implicit_tag=None, explicit_tag=None):
         if default is not None and default_readable:
-            default = "".join(binrepr(ord(x)).zfill(8) for x in default)
+            default = b"".join(binrepr(ord(x)).zfill(8) for x in default)
         ASN1F_field.__init__(self, name, default, context=context,
                              implicit_tag=implicit_tag,
                              explicit_tag=explicit_tag)
@@ -323,7 +323,7 @@ class ASN1F_SEQUENCE(ASN1F_field):
         _,x = self.m2i(pkt, s)
         return x
     def build(self, pkt):
-        s = reduce(lambda x,y: x+y.build(pkt), self.seq, "")
+        s = reduce(lambda x,y: x+y.build(pkt), self.seq, b"")
         return self.i2m(pkt, s)
 
 class ASN1F_SET(ASN1F_SEQUENCE):
@@ -365,9 +365,9 @@ class ASN1F_SEQUENCE_OF(ASN1F_field):
         if isinstance(val, ASN1_Object) and val.tag==ASN1_Class_UNIVERSAL.RAW:
             s = val
         elif val is None:
-            s = ""
+            s = b""
         else:
-            s = "".join(map(str, val))
+            s = b"".join(map(str, val))
         return self.i2m(pkt, s)
 
     def randval(self):
@@ -409,7 +409,7 @@ class ASN1F_optional(ASN1F_element):
             return s
     def build(self, pkt):
         if self._field.is_empty(pkt):
-            return ""
+            return b""
         return self._field.build(pkt)
     def any2i(self, pkt, x):
         return self._field.any2i(pkt, x)
@@ -477,7 +477,7 @@ class ASN1F_CHOICE(ASN1F_field):
             return self.extract_packet(choice, s)
         elif isinstance(choice, type):
             #XXX find a way not to instantiate the ASN1F_field
-            return choice(self.name, "").m2i(pkt, s)
+            return choice(self.name, b"").m2i(pkt, s)
         else:
             #XXX check properly if this is an ASN1F_PACKET
             return choice.m2i(pkt, s)
@@ -528,7 +528,7 @@ class ASN1F_PACKET(ASN1F_field):
         return p,s
     def i2m(self, pkt, x):
         if x is None:
-            s = ""
+            s = b""
         else:
             s = str(x)
         return BER_tagging_enc(s, implicit_tag=self.implicit_tag,
@@ -559,10 +559,10 @@ class ASN1F_BIT_STRING_ENCAPS(ASN1F_BIT_STRING):
         return p, remain
     def i2m(self, pkt, x):
         if x is None:
-            s = ""
+            s = b""
         else:
             s = str(x)
-        s = "".join(binrepr(ord(x)).zfill(8) for x in s)
+        s = b"".join(binrepr(ord(x)).zfill(8) for x in s)
         return ASN1F_BIT_STRING.i2m(self, pkt, s)
 
 class ASN1F_FLAGS(ASN1F_BIT_STRING):
diff --git a/scapy/automaton.py b/scapy/automaton.py
index 7419aa9151287fc9dd0cb1529cef6917bf976aac..9c525e6fcd0786e904ace762fb2fb08bd07425f4 100644
--- a/scapy/automaton.py
+++ b/scapy/automaton.py
@@ -175,7 +175,7 @@ class ObjectPipe(SelectableObject):
         return len(self.queue) > 0
     def send(self, obj):
         self.queue.append(obj)
-        os.write(self.wr,"X")
+        os.write(self.wr,b"X")
         self.call_release()
     def write(self, obj):
         self.send(obj)
diff --git a/scapy/data.py b/scapy/data.py
index a3a9b588f0fb280f6c8637648707c1add0b27b4f..e0b2a6e5f480e5a94de89411ae25cdfda95e3f69 100644
--- a/scapy/data.py
+++ b/scapy/data.py
@@ -65,12 +65,12 @@ WINDOWS=sys.platform.startswith("win")
 # file parsing to get some values :
 
 def load_protocols(filename):
-    spaces = re.compile("[ \t]+|\n")
+    spaces = re.compile(b"[ \t]+|\n")
     dct = DADict(_name=filename)
     try:
-        for l in open(filename):
+        for l in open(filename, "rb"):
             try:
-                shrp = l.find("#")
+                shrp = l.find(b"#")
                 if  shrp >= 0:
                     l = l[:shrp]
                 l = l.strip()
@@ -87,13 +87,13 @@ def load_protocols(filename):
     return dct
 
 def load_ethertypes(filename):
-    spaces = re.compile("[ \t]+|\n")
+    spaces = re.compile(b"[ \t]+|\n")
     dct = DADict(_name=filename)
     try:
-        f=open(filename)
+        f=open(filename, "rb")
         for l in f:
             try:
-                shrp = l.find("#")
+                shrp = l.find(b"#")
                 if  shrp >= 0:
                     l = l[:shrp]
                 l = l.strip()
@@ -111,14 +111,14 @@ def load_ethertypes(filename):
     return dct
 
 def load_services(filename):
-    spaces = re.compile("[ \t]+|\n")
+    spaces = re.compile(b"[ \t]+|\n")
     tdct=DADict(_name="%s-tcp"%filename)
     udct=DADict(_name="%s-udp"%filename)
     try:
-        f=open(filename)
+        f=open(filename, "rb")
         for l in f:
             try:
-                shrp = l.find("#")
+                shrp = l.find(b"#")
                 if  shrp >= 0:
                     l = l[:shrp]
                 l = l.strip()
@@ -127,10 +127,10 @@ def load_services(filename):
                 lt = tuple(re.split(spaces, l))
                 if len(lt) < 2 or not lt[0]:
                     continue
-                if lt[1].endswith("/tcp"):
-                    tdct[lt[0]] = int(lt[1].split('/')[0])
-                elif lt[1].endswith("/udp"):
-                    udct[lt[0]] = int(lt[1].split('/')[0])
+                if lt[1].endswith(b"/tcp"):
+                    tdct[lt[0]] = int(lt[1].split(b'/')[0])
+                elif lt[1].endswith(b"/udp"):
+                    udct[lt[0]] = int(lt[1].split(b'/')[0])
             except Exception as e:
                 log_loading.warning("Couldn't file [%s]: line [%r] (%s)" % (filename,l,e))
         f.close()
@@ -162,13 +162,13 @@ class ManufDA(DADict):
 def load_manuf(filename):
     try:
         manufdb=ManufDA(_name=filename)
-        for l in open(filename):
+        for l in open(filename, "rb"):
             try:
                 l = l.strip()
-                if not l or l.startswith("#"):
+                if not l or l.startswith(b"#"):
                     continue
                 oui,shrt=l.split()[:2]
-                i = l.find("#")
+                i = l.find(b"#")
                 if i < 0:
                     lng=shrt
                 else:
diff --git a/scapy/fields.py b/scapy/fields.py
index 937b101d949744e87ae1e98cdf8e53d639de5f39..8c5e571a72e2067becafbd2afad2d632d0662236 100644
--- a/scapy/fields.py
+++ b/scapy/fields.py
@@ -161,7 +161,7 @@ class PadField(object):
     def __init__(self, fld, align, padwith=None):
         self._fld = fld
         self._align = align
-        self._padwith = padwith or ""
+        self._padwith = padwith or b""
 
     def padlen(self, flen):
         return -flen%self._align
@@ -172,7 +172,7 @@ class PadField(object):
         return remain[padlen:], val
 
     def addfield(self, pkt, s, val):
-        sval = self._fld.addfield(pkt, "", val)
+        sval = self._fld.addfield(pkt, b"", val)
         return s+sval+struct.pack("%is" % (self.padlen(len(sval))), self._padwith)
 
     def __getattr__(self, attr):
@@ -380,7 +380,7 @@ class StrField(Field):
         return len(i)
     def i2m(self, pkt, x):
         if x is None:
-            x = ""
+            x = b""
         elif not isinstance(x, str):
             x=str(x)
         return x
@@ -388,7 +388,7 @@ class StrField(Field):
         return s+self.i2m(pkt, val)
     def getfield(self, pkt, s):
         if self.remain == 0:
-            return "",self.m2i(pkt, s)
+            return b"",self.m2i(pkt, s)
         else:
             return s[-self.remain:],self.m2i(pkt, s[:-self.remain])
     def randval(self):
@@ -406,7 +406,7 @@ class PacketField(StrField):
         return self.cls(m)
     def getfield(self, pkt, s):
         i = self.m2i(pkt, s)
-        remain = ""
+        remain = b""
         if conf.padding_layer in i:
             r = i[conf.padding_layer]
             del(r.underlayer.payload)
@@ -464,7 +464,7 @@ class PacketListField(PacketField):
             c = self.count_from(pkt)
 
         lst = []
-        ret = ""
+        ret = b""
         remain = s
         if l is not None:
             remain,ret = s[:l],s[l:]
@@ -479,18 +479,18 @@ class PacketListField(PacketField):
                 if conf.debug_dissector:
                     raise
                 p = conf.raw_layer(load=remain)
-                remain = ""
+                remain = b""
             else:
                 if conf.padding_layer in p:
                     pad = p[conf.padding_layer]
                     remain = pad.load
                     del(pad.underlayer.payload)
                 else:
-                    remain = ""
+                    remain = b""
             lst.append(p)
         return remain+ret,lst
     def addfield(self, pkt, s, val):
-        return s + "".join(str(v) for v in val)
+        return s + b"".join(str(v) for v in val)
 
 
 class StrFixedLenField(StrField):
@@ -502,7 +502,7 @@ class StrFixedLenField(StrField):
             self.length_from = lambda pkt,length=length: length
     def i2repr(self, pkt, v):
         if isinstance(v, str):
-            v = v.rstrip(b"\0")
+            v = v.rstrip("\0")
         return repr(v)
     def getfield(self, pkt, s):
         l = self.length_from(pkt)
@@ -523,7 +523,7 @@ class StrFixedLenEnumField(StrFixedLenField):
         StrFixedLenField.__init__(self, name, default, length=length, length_from=length_from)
         self.enum = enum
     def i2repr(self, pkt, v):
-        r = v.rstrip(b"\0")
+        r = v.rstrip("\0")
         rr = repr(r)
         if v in self.enum:
             rr = "%s (%s)" % (rr, self.enum[v])
@@ -537,15 +537,15 @@ class NetBIOSNameField(StrFixedLenField):
     def i2m(self, pkt, x):
         l = self.length_from(pkt)/2
         if x is None:
-            x = ""
-        x += " "*(l)
+            x = b""
+        x += b" "*(l)
         x = x[:l]
-        x = "".join(chr(0x41 + ord(b)>>4) + chr(0x41 + ord(b)&0xf) for b in x)
-        x = " "+x
+        x = b"".join(chr(0x41 + ord(b)>>4) + chr(0x41 + ord(b)&0xf) for b in x)
+        x = b" "+x
         return x
     def m2i(self, pkt, x):
         x = x.strip(b"\x00").strip(" ")
-        return "".join(map(lambda x,y: chr((((ord(x)-1)&0xf)<<4)+((ord(y)-1)&0xf)), x[::2],x[1::2]))
+        return b"".join(map(lambda x,y: chr((((ord(x)-1)&0xf)<<4)+((ord(y)-1)&0xf)), x[::2],x[1::2]))
 
 class StrLenField(StrField):
     __slots__ = ["length_from"]
@@ -648,7 +648,7 @@ class FieldListField(Field):
             c = self.count_from(pkt)
 
         val = []
-        ret=""
+        ret = b""
         if l is not None:
             s,ret = s[:l],s[l:]
 
@@ -689,7 +689,7 @@ class StrNullField(StrField):
         l = s.find(b"\x00")
         if l < 0:
             #XXX \x00 not found
-            return "",s
+            return b"",s
         return s[l+1:],self.m2i(pkt, s[:l])
     def randval(self):
         return RandTermString(RandNum(0,1200),b"\x00")
@@ -703,7 +703,7 @@ class StrStopField(StrField):
     def getfield(self, pkt, s):
         l = s.find(self.stop)
         if l < 0:
-            return "",s
+            return b"",s
 #            raise Scapy_Exception,"StrStopField: stop value [%s] not found" %stop
         l += len(self.stop)+self.additionnal
         return s[l:],s[:l]
diff --git a/scapy/layers/dhcp.py b/scapy/layers/dhcp.py
index 41ee24f520a97159831bf1d8827bcd068a3cb64a..ab1daad34a343bbd2af536c3411e82408f4ac9b0 100644
--- a/scapy/layers/dhcp.py
+++ b/scapy/layers/dhcp.py
@@ -43,10 +43,10 @@ class BOOTP(Packet):
                     IPField("yiaddr","0.0.0.0"),
                     IPField("siaddr","0.0.0.0"),
                     IPField("giaddr","0.0.0.0"),
-                    Field("chaddr","", "16s"),
-                    Field("sname","","64s"),
-                    Field("file","","128s"),
-                    StrField("options","") ]
+                    Field("chaddr",b"", "16s"),
+                    Field("sname",b"","64s"),
+                    Field("file",b"","128s"),
+                    StrField("options",b"") ]
     def guess_payload_class(self, payload):
         if self.options[:len(dhcpmagic)] == dhcpmagic:
             return DHCP
@@ -59,7 +59,7 @@ class BOOTP(Packet):
             self.options = self.options[:len(dhcpmagic)]
             return payload, None
         else:
-            return "", None
+            return b"", None
     def hashret(self):
         return struct.pack("L", self.xid)
     def answers(self, other):
@@ -202,7 +202,7 @@ class DHCPOptionsField(StrField):
         return "[%s]" % (" ".join(s))
         
     def getfield(self, pkt, s):
-        return "", self.m2i(pkt, s)
+        return b"", self.m2i(pkt, s)
     def m2i(self, pkt, x):
         opt = []
         while x:
@@ -248,19 +248,19 @@ class DHCPOptionsField(StrField):
     def i2m(self, pkt, x):
         if isinstance(x, str):
             return x
-        s = ""
+        s = b""
         for o in x:
             if isinstance(o, tuple) and len(o) >= 2:
                 name = o[0]
                 lval = o[1:]
 
                 if isinstance(name, int):
-                    onum, oval = name, "".join(lval)
+                    onum, oval = name, b"".join(lval)
                 elif name in DHCPRevOptions:
                     onum, f = DHCPRevOptions[name]
                     if  f is not None:
-                        lval = [f.addfield(pkt,"",f.any2i(pkt,val)) for val in lval]
-                    oval = "".join(lval)
+                        lval = [f.addfield(pkt,b"",f.any2i(pkt,val)) for val in lval]
+                    oval = b"".join(lval)
                 else:
                     warning("Unknown field option %s" % name)
                     continue
@@ -283,7 +283,7 @@ class DHCPOptionsField(StrField):
 
 class DHCP(Packet):
     name = "DHCP options"
-    fields_desc = [ DHCPOptionsField("options","") ]
+    fields_desc = [ DHCPOptionsField("options",b"") ]
 
 
 bind_layers( UDP,           BOOTP,         dport=67, sport=68)
diff --git a/scapy/layers/dhcp6.py b/scapy/layers/dhcp6.py
index a170db01a7fab0df38ad341ec02835a95f4d51a7..616048600ec93903164fd14121663e29ece11fdd 100644
--- a/scapy/layers/dhcp6.py
+++ b/scapy/layers/dhcp6.py
@@ -396,7 +396,7 @@ class _OptReqListField(StrLenField):
         return r
     
     def i2m(self, pkt, x):
-        return "".join(struct.pack('!H', y) for y in x)
+        return b"".join(struct.pack('!H', y) for y in x)
 
 # A client may include an ORO in a solicit, Request, Renew, Rebind,
 # Confirm or Information-request
@@ -747,8 +747,8 @@ class DomainNameField(StrLenField):
 
     def i2m(self, pkt, x):
         if not x:
-            return ""
-        tmp = "".join(chr(len(z)) + z for z in x.split('.'))
+            return b""
+        tmp = b"".join(chr(len(z)) + z for z in x.split('.'))
         return tmp
 
 class DHCP6OptNISDomain(_DHCP6OptGuessPayload):             #RFC3898
diff --git a/scapy/layers/dns.py b/scapy/layers/dns.py
index 8a0cd32957db99a78cec502c820be7c676285b2a..e35fa9d29942d0bbb7e8ef8fd7962df8300e1bd6 100644
--- a/scapy/layers/dns.py
+++ b/scapy/layers/dns.py
@@ -34,16 +34,16 @@ class DNSStrField(StrField):
           return b"\x00"
 
         # Truncate chunks that cannot be encoded (more than 63 bytes..)
-        x = "".join(chr(len(y)) + y for y in (k[:63] for k in x.split(".")))
+        x = b"".join(chr(len(y)) + y for y in (k[:63] for k in x.split(".")))
         if x[-1] != b"\x00":
             x += b"\x00"
         return x
 
     def getfield(self, pkt, s):
-        n = ""
+        n = b""
 
         if ord(s[0]) == 0:
-          return s[1:], "."
+          return s[1:], b"."
 
         while True:
             l = ord(s[0])
@@ -53,7 +53,7 @@ class DNSStrField(StrField):
             if l & 0xc0:
                 raise Scapy_Exception("DNS message can't be compressed at this point!")
             else:
-                n += s[:l]+"."
+                n += s[:l]+b"."
                 s = s[l:]
         return s, n
 
@@ -82,7 +82,7 @@ class DNSRRCountField(ShortField):
 
 
 def DNSgetstr(s,p):
-    name = ""
+    name = b""
     q = 0
     jpath = [p]
     while True:
@@ -104,7 +104,7 @@ def DNSgetstr(s,p):
             jpath.append(p)
             continue
         elif l > 0:
-            name += s[p:p+l]+"."
+            name += s[p:p+l]+b"."
             p += l
             continue
         break
@@ -122,7 +122,7 @@ class DNSRRField(StrField):
         self.passon = passon
     def i2m(self, pkt, x):
         if x is None:
-            return ""
+            return b""
         return str(x)
     def decodeRR(self, name, s, p):
         ret = s[p:p+10]
@@ -150,7 +150,7 @@ class DNSRRField(StrField):
         c = getattr(pkt, self.countfld)
         if c > len(s):
             warning("wrong value: DNS.%s=%i" % (self.countfld,c))
-            return s,""
+            return s,b""
         while c:
             c -= 1
             name,p = DNSgetstr(s,p)
@@ -183,7 +183,7 @@ class RDataField(StrLenField):
         elif pkt.type == 12: # PTR
             s = DNSgetstr(s, 0)[0]
         elif pkt.type == 16: # TXT
-            ret_s = ""
+            ret_s = b""
             tmp_s = s
             # RDATA contains a list of strings, each are prepended with
             # a byte containing the size of the following string.
@@ -204,12 +204,12 @@ class RDataField(StrLenField):
             if s:
                 s = inet_aton(s)
         elif pkt.type in [2, 3, 4, 5, 12]: # NS, MD, MF, CNAME, PTR
-            s = "".join(chr(len(x)) + x for x in s.split('.'))
+            s = b"".join(chr(len(x)) + x for x in s.split('.'))
             if ord(s[-1]):
                 s += b"\x00"
         elif pkt.type == 16: # TXT
             if s:
-                ret_s = ""
+                ret_s = b""
                 # The initial string must be splitted into a list of strings
                 # prepended with theirs sizes.
                 while len(s) >= 255:
diff --git a/scapy/layers/dot11.py b/scapy/layers/dot11.py
index 2e33d80d74781b8eb1a026f126e58f545adb1971..383af0821f42739aa1957ccbb4c2646264e62077 100644
--- a/scapy/layers/dot11.py
+++ b/scapy/layers/dot11.py
@@ -304,7 +304,7 @@ class Dot11WEP(Packet):
     def build_payload(self):
         if self.wepdata is None:
             return Packet.build_payload(self)
-        return ""
+        return b""
 
     @crypto_validator
     def encrypt(self, p, pay, key=None):
@@ -313,7 +313,7 @@ class Dot11WEP(Packet):
         if key:
             if self.icv is None:
                 pay += struct.pack("<I", crc32(pay))
-                icv = ""
+                icv = b""
             else:
                 icv = p[4:8]
             e = Cipher(
@@ -324,7 +324,7 @@ class Dot11WEP(Packet):
             return p[:4] + e.update(pay) + e.finalize() + icv
         else:
             warning("No WEP key set (conf.wepkey).. strange results expected..")
-            return ""
+            return b""
 
     def post_build(self, p, pay):
         if self.wepdata is None:
diff --git a/scapy/layers/hsrp.py b/scapy/layers/hsrp.py
index f7a042f9eb3319d65fd8c801c8f8efb952978dbb..a8fdc078209b1144c80437bbb09f2319961a06eb 100644
--- a/scapy/layers/hsrp.py
+++ b/scapy/layers/hsrp.py
@@ -49,7 +49,7 @@ class HSRP(Packet):
         ByteField("priority", 120),
         ByteField("group", 1),
         ByteField("reserved", 0),
-        StrFixedLenField("auth", "cisco" + b"\00" * 3, 8),
+        StrFixedLenField("auth", b"cisco" + b"\00" * 3, 8),
         IPField("virtualIP", "192.168.1.1")]
 
     def guess_payload_class(self, payload):
diff --git a/scapy/layers/inet.py b/scapy/layers/inet.py
index e38a0990db288f52d90f3cbfd7d4e601b71d8513..b266a698fd9705278f6bb6b77d7c233aecb68419 100644
--- a/scapy/layers/inet.py
+++ b/scapy/layers/inet.py
@@ -287,7 +287,7 @@ class TCPOptionsField(StrField):
         return opt
     
     def i2m(self, pkt, x):
-        opt = ""
+        opt = b""
         for oname,oval in x:
             if isinstance(oname, str):
                 if oname == "NOP":
diff --git a/scapy/layers/inet6.py b/scapy/layers/inet6.py
index e7e73cc48aff8a724a0a9593cbe8d1ed304b8a8c..901f94f5253f22913446e7f49948088fc00001f7 100644
--- a/scapy/layers/inet6.py
+++ b/scapy/layers/inet6.py
@@ -334,7 +334,7 @@ class IP6ListField(StrField):
             c = self.count_from(pkt)
 
         lst = []
-        ret = ""
+        ret = b""
         remain = s
         if l is not None:
             remain,ret = s[:l],s[l:]
@@ -349,7 +349,7 @@ class IP6ListField(StrField):
         return remain+ret,lst
 
     def i2m(self, pkt, x):
-        s = ''
+        s = b""
         for y in x:
             try:
                 y = inet_pton(socket.AF_INET6, y)
@@ -846,7 +846,7 @@ class _HopByHopOptionsField(PacketListField):
             c = self.count_from(pkt)
 
         opt = []
-        ret = ""
+        ret = b""
         x = s
         if l is not None:
             x,ret = s[:l],s[l:]
@@ -868,7 +868,7 @@ class _HopByHopOptionsField(PacketListField):
                 x = op.payload.load
                 del(op.payload)
             else:
-                x = ""
+                x = b""
         return x+ret,opt
 
     def i2m(self, pkt, x):
@@ -879,10 +879,10 @@ class _HopByHopOptionsField(PacketListField):
             autopad = 1
 
         if not autopad:
-            return "".join(map(str, x))
+            return b"".join(map(str, x))
 
         curpos = self.curpos
-        s = ""
+        s = b""
         for p in x:
             d = p.alignment_delta(curpos)
             curpos += d
@@ -981,7 +981,7 @@ class IPv6ExtHdrSegmentRoutingTLV(Packet):
                     StrLenField("value", "", length_from=lambda pkt: pkt.len) ]
 
     def extract_padding(self, p):
-        return "",p
+        return b"",p
 
     registered_sr_tlv = {}
     @classmethod
@@ -1117,13 +1117,13 @@ def defragment6(packets):
         del(l[min_pos])
 
     # regenerate the fragmentable part
-    fragmentable = ""
+    fragmentable = b""
     for p in res:
         q=p[IPv6ExtHdrFragment]
         offset = 8*q.offset
         if offset != len(fragmentable):
             warning("Expected an offset of %d. Found %d. Padding with XXXX" % (len(fragmentable), offset))
-        fragmentable += "X"*(offset - len(fragmentable))
+        fragmentable += b"X"*(offset - len(fragmentable))
         fragmentable += str(q.payload)
 
     # Regenerate the unfragmentable part.
@@ -1724,7 +1724,7 @@ class ICMPv6NDOptRedirectedHdr(_ICMPv6NDGuessPayload, Packet):
                     FieldLenField("len", None, length_of="pkt", fmt="B",
                                   adjust = lambda pkt,x:(x+8)/8),
                     StrFixedLenField("res", b"\x00"*6, 6),
-                    TruncPktLenField("pkt", "", IPv6, 8,
+                    TruncPktLenField("pkt", b"", IPv6, 8,
                                      length_from = lambda pkt: 8*pkt.len-8) ]
 
 # See which value should be used for default MTU instead of 1280
@@ -1845,7 +1845,7 @@ class _IP6PrefixField(IP6Field):
         if l is None:
             return x
         if l in [0, 1]:
-            return ""
+            return b""
         if l in [2, 3]:
             return x[:8*(l-1)]
 
@@ -1917,9 +1917,9 @@ class DomainNameListField(StrLenField):
 
     def i2m(self, pkt, x):
         def conditionalTrailingDot(z):
-            if z and z[-1] == b'\x00':
+            if z and z[-1] == '\x00':
                 return z
-            return z+b'\x00'
+            return z+'\x00'
         # Build the encode names
         tmp = [[chr(len(z)) + z for z in y.split('.')] for y in x]
         ret_string  = "".join(conditionalTrailingDot("".join(x)) for x in tmp)
@@ -2165,9 +2165,9 @@ def names2dnsrepr(x):
         termin = b"\x00"
         if n.count('.') == 0: # single-component gets one more
             termin += b'\x00'
-        n = "".join(chr(len(y)) + y for y in n.split('.')) + termin
+        n = b"".join(chr(len(y)) + y for y in n.split('.')) + termin
         res.append(n)
-    return "".join(res)
+    return b"".join(res)
 
 
 def dnsrepr2names(x):
@@ -2257,7 +2257,7 @@ class NIQueryDataField(StrField):
     def getfield(self, pkt, s):
         qtype = getattr(pkt, "qtype")
         if qtype == 0: # NOOP
-            return s, (0, "")
+            return s, (0, b"")
         else:
             code = getattr(pkt, "code")
             if code == 0:   # IPv6 Addr
@@ -2265,12 +2265,12 @@ class NIQueryDataField(StrField):
             elif code == 2: # IPv4 Addr
                 return s[4:], (2, inet_ntop(socket.AF_INET, s[:4]))
             else:           # Name or Unknown
-                return "", (1, s)
+                return b"", (1, s)
 
     def addfield(self, pkt, s, val):
         if ((isinstance(val, tuple) and val[1] is None) or
             val is None):
-            val = (1, "")
+            val = (1, b"")
         t = val[0]
         if t == 1:
             return s + val[1]
@@ -2403,31 +2403,31 @@ class NIReplyDataField(StrField):
     def addfield(self, pkt, s, val):
         t,tmp = val
         if tmp is None:
-            tmp = ""
+            tmp = b""
         if t == 2:
             ttl,dnsstr = tmp
             return s+ struct.pack("!I", ttl) + dnsstr
         elif t == 3:
-            return s + "".join(map(lambda x_y1: struct.pack("!I", x_y1[0])+inet_pton(socket.AF_INET6, x_y1[1]), tmp))
+            return s + b"".join(map(lambda x_y1: struct.pack("!I", x_y1[0])+inet_pton(socket.AF_INET6, x_y1[1]), tmp))
         elif t == 4:
-            return s + "".join(map(lambda x_y2: struct.pack("!I", x_y2[0])+inet_pton(socket.AF_INET, x_y2[1]), tmp))
+            return s + b"".join(map(lambda x_y2: struct.pack("!I", x_y2[0])+inet_pton(socket.AF_INET, x_y2[1]), tmp))
         else:
             return s + tmp
 
     def getfield(self, pkt, s):
         code = getattr(pkt, "code")
         if code != 0:
-            return s, (0, "")
+            return s, (0, b"")
 
         qtype = getattr(pkt, "qtype")
         if qtype == 0: # NOOP
-            return s, (0, "")
+            return s, (0, b"")
 
         elif qtype == 2:
             if len(s) < 4:
-                return s, (0, "")
+                return s, (0, b"")
             ttl = struct.unpack("!I", s[:4])[0]
-            return "", (2, [ttl, s[4:]])
+            return b"", (2, [ttl, s[4:]])
 
         elif qtype == 3: # IPv6 addresses with TTLs
             # XXX TODO : get the real length
@@ -2450,7 +2450,7 @@ class NIReplyDataField(StrField):
             return s, (4, res)
         else:
             # XXX TODO : implement me and deal with real length
-            return "", (0, s)
+            return b"", (0, s)
 
     def i2repr(self, pkt, x):
         if x is None:
@@ -2905,10 +2905,10 @@ class _MobilityOptionsField(PacketListField):
             autopad = 1
 
         if not autopad:
-            return "".join(map(str, x))
+            return b"".join(map(str, x))
 
         curpos = self.curpos
-        s = ""
+        s = b""
         for p in x:
             d = p.alignment_delta(curpos)
             curpos += d
@@ -3120,7 +3120,7 @@ class  AS_resolver6(AS_resolver_riswhois):
 
         _, asn, desc = AS_resolver_riswhois._resolve_one(self, addr)
 
-        if asn.startswith("AS"):
+        if asn.startswith(b"AS"):
             try:
                 asn = int(asn[2:])
             except ValueError:
diff --git a/scapy/layers/isakmp.py b/scapy/layers/isakmp.py
index 25268debc8f1281712a9f05bf6979515f51babef..0bd3ad3aff97b4580abc4c50cdcb8274eb988baa 100644
--- a/scapy/layers/isakmp.py
+++ b/scapy/layers/isakmp.py
@@ -107,7 +107,7 @@ class ISAKMPTransformSetField(StrLenField):
         typ, val = type_val_tuple
         type_val,enc_dict,tlv = ISAKMPTransformTypes.get(typ, (typ,{},0))
         val = enc_dict.get(val, val)
-        s = ""
+        s = b""
         if (val & ~0xffff):
             if not tlv:
                 warning("%r should not be TLV but is too big => using TLV encoding" % typ)
@@ -126,9 +126,9 @@ class ISAKMPTransformSetField(StrLenField):
         return (val[0],enc)
     def i2m(self, pkt, i):
         if i is None:
-            return ""
+            return b""
         i = [self.type2num(e) for e in i]
-        return "".join(i)
+        return b"".join(i)
     def m2i(self, pkt, m):
         # I try to ensure that we don't read off the end of our packet based
         # on bad length fields we're provided in the packet. There are still
diff --git a/scapy/layers/ppp.py b/scapy/layers/ppp.py
index f195ac2cb27a70bd3d8ebf5c1b0a5a3ca4348f62..3aacafea65bccde4ca53b73e412ce72fec944189 100644
--- a/scapy/layers/ppp.py
+++ b/scapy/layers/ppp.py
@@ -246,7 +246,7 @@ class PPP_IPCP_Option(Packet):
                     FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+2),
                     StrLenField("data", "", length_from=lambda p:max(0,p.len-2)) ]
     def extract_padding(self, pay):
-        return "",pay
+        return b"",pay
 
     registered_options = {}
     @classmethod
@@ -314,7 +314,7 @@ class PPP_ECP_Option(Packet):
                     FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+2),
                     StrLenField("data", "", length_from=lambda p:max(0,p.len-2)) ]
     def extract_padding(self, pay):
-        return "",pay
+        return b"",pay
 
     registered_options = {}
     @classmethod
@@ -370,7 +370,7 @@ class PPP_LCP(Packet):
         return self.sprintf('LCP %code%')
 
     def extract_padding(self, pay):
-        return "", pay
+        return b"", pay
 
     @classmethod
     def dispatch_hook(cls, _pkt = None, *args, **kargs):
@@ -411,7 +411,7 @@ class PPP_LCP_Option(Packet):
                    StrLenField("data", None, length_from=lambda p:p.len-2)]
 
     def extract_padding(self, pay):
-        return "", pay
+        return b"", pay
 
     registered_options = {}
 
diff --git a/scapy/layers/smb.py b/scapy/layers/smb.py
index c1b478c1f089a9335e1201464637c4c803dc71e5..3c49269d97395597be602356cfc408c96ad9e87f 100644
--- a/scapy/layers/smb.py
+++ b/scapy/layers/smb.py
@@ -55,7 +55,7 @@ class SMBMailSlot(Packet):
                    LEShortField("priority", 1),
                    LEShortField("class", 2),
                    LEShortField("size", 135),
-                   StrNullField("name","\MAILSLOT\NET\GETDC660")]
+                   StrNullField("name","\\MAILSLOT\\NET\\GETDC660")]
 
 # SMB NetLogon Protocol Response Tail SAM
 class SMBNetlogon_Protocol_Response_Tail_SAM(Packet):
diff --git a/scapy/layers/tls/cert.py b/scapy/layers/tls/cert.py
index d2ad36bee7e28cc13406acc037d4a5f791de2ec3..e6c4816ecaaaa69ab6f70752b4e59d9ab0895f8f 100644
--- a/scapy/layers/tls/cert.py
+++ b/scapy/layers/tls/cert.py
@@ -66,24 +66,24 @@ _MAX_CRL_SIZE = 10*1024*1024   # some are that big
 def der2pem(der_string, obj="UNKNOWN"):
     """Convert DER octet string to PEM format (with optional header)"""
     # Encode a byte string in PEM format. Header advertizes <obj> type.
-    pem_string = "-----BEGIN %s-----\n" % obj
+    pem_string = b"-----BEGIN %s-----\n" % obj
     base64_string = base64.b64encode(der_string)
     chunks = [base64_string[i:i+64] for i in range(0, len(base64_string), 64)]
-    pem_string += '\n'.join(chunks)
-    pem_string += "\n-----END %s-----\n" % obj
+    pem_string += b'\n'.join(chunks)
+    pem_string += b"\n-----END %s-----\n" % obj
     return pem_string
 
 @conf.commands.register
 def pem2der(pem_string):
     """Convert PEM string to DER format"""
     # Encode all lines between the first '-----\n' and the 2nd-to-last '-----'.
-    pem_string = pem_string.replace("\r", "")
-    first_idx = pem_string.find("-----\n") + 6
-    if pem_string.find("-----BEGIN", first_idx) != -1:
+    pem_string = pem_string.replace(b"\r", b"")
+    first_idx = pem_string.find(b"-----\n") + 6
+    if pem_string.find(b"-----BEGIN", first_idx) != -1:
         raise Exception("pem2der() expects only one PEM-encoded object")
-    last_idx = pem_string.rfind("-----", 0, pem_string.rfind("-----"))
+    last_idx = pem_string.rfind(b"-----", 0, pem_string.rfind(b"-----"))
     base64_string = pem_string[first_idx:last_idx]
-    base64_string.replace("\n", "")
+    base64_string.replace(b"\n", b"")
     der_string = base64.b64decode(base64_string)
     return der_string
 
@@ -92,12 +92,12 @@ def split_pem(s):
     Split PEM objects. Useful to process concatenated certificates.
     """
     pem_strings = []
-    while s != "":
-        start_idx = s.find("-----BEGIN")
+    while s != b"":
+        start_idx = s.find(b"-----BEGIN")
         if start_idx == -1:
             break
-        end_idx = s.find("-----END")
-        end_idx = s.find("\n", end_idx) + 1
+        end_idx = s.find(b"-----END")
+        end_idx = s.find(b"\n", end_idx) + 1
         pem_strings.append(s[start_idx:end_idx])
         s = s[end_idx:]
     return pem_strings
@@ -143,11 +143,11 @@ class _PKIObjMaker(type):
             raw = obj_path
 
         try:
-            if "-----BEGIN" in raw:
+            if b"-----BEGIN" in raw:
                 frmt = "PEM"
                 pem = raw
                 der_list = split_pem(raw)
-                der = ''.join(map(pem2der, der_list))
+                der = b''.join(map(pem2der, der_list))
             else:
                 frmt = "DER"
                 der = raw
diff --git a/scapy/layers/tls/crypto/pkcs1.py b/scapy/layers/tls/crypto/pkcs1.py
index baa8b7964e67f4ca37395d71646ccb31e6c864ae..9a673abbe427de90d7fff1513a98af0f316d7df7 100644
--- a/scapy/layers/tls/crypto/pkcs1.py
+++ b/scapy/layers/tls/crypto/pkcs1.py
@@ -79,8 +79,8 @@ def _legacy_pkcs1_v1_5_encode_md5_sha1(M, emLen):
         warning("pkcs_emsa_pkcs1_v1_5_encode: "
                 "intended encoded message length too short")
         return None
-    PS = '\xff'*(emLen - 36 - 3)
-    return '\x00' + '\x01' + PS + '\x00' + H
+    PS = b'\xff'*(emLen - 36 - 3)
+    return b'\x00' + b'\x01' + PS + b'\x00' + H
 
 
 #####################################################################
diff --git a/scapy/layers/tls/crypto/prf.py b/scapy/layers/tls/crypto/prf.py
index afd76d0cf86cc7f3ba7e77094caff8ad5cc2f0f6..2895234c7c35ae238f1ef96e8937eab3489433db 100644
--- a/scapy/layers/tls/crypto/prf.py
+++ b/scapy/layers/tls/crypto/prf.py
@@ -38,7 +38,7 @@ def _tls_P_hash(secret, seed, req_len, hm):
     hash_len = hm.hash_alg.hash_len
     n = (req_len + hash_len - 1) / hash_len
 
-    res = ""
+    res = b""
     a = hm(secret).digest(seed)  # A(1)
 
     while n > 0:
@@ -71,7 +71,7 @@ def _sslv2_PRF(secret, seed, req_len):
     hash_md5 = _tls_hash_algs["MD5"]()
     rounds = (req_len + hash_md5.hash_len - 1) / hash_md5.hash_len
 
-    res = ""
+    res = b""
     if rounds == 1:
         res += hash_md5.digest(secret + seed)
     else:
diff --git a/scapy/layers/x509.py b/scapy/layers/x509.py
index eb1e64d3e0746c9554dd5cd4dddb118c81b0dfc2..4d6a06405165754aeb56cf9f89cfe1fb6ebaef06 100644
--- a/scapy/layers/x509.py
+++ b/scapy/layers/x509.py
@@ -703,9 +703,9 @@ class ASN1F_X509_SubjectPublicKeyInfo(ASN1F_SEQUENCE):
     def m2i(self, pkt, x):
         c,s = ASN1F_SEQUENCE.m2i(self, pkt, x)
         keytype = pkt.fields["signatureAlgorithm"].algorithm.oidname
-        if "rsa" in keytype.lower():
+        if b"rsa" in keytype.lower():
             return ASN1F_X509_SubjectPublicKeyInfoRSA().m2i(pkt, x)
-        elif keytype == "ecPublicKey":
+        elif keytype == b"ecPublicKey":
             return ASN1F_X509_SubjectPublicKeyInfoECDSA().m2i(pkt, x)
         else:
             raise Exception("could not parse subjectPublicKeyInfo")
@@ -717,10 +717,10 @@ class ASN1F_X509_SubjectPublicKeyInfo(ASN1F_SEQUENCE):
             ktype = pkt.fields['signatureAlgorithm'].algorithm.oidname
         else:
             ktype = pkt.default_fields["signatureAlgorithm"].algorithm.oidname
-        if "rsa" in ktype.lower():
+        if b"rsa" in ktype.lower():
             pkt.default_fields["subjectPublicKey"] = RSAPublicKey()
             return ASN1F_X509_SubjectPublicKeyInfoRSA().build(pkt)
-        elif ktype == "ecPublicKey":
+        elif ktype == b"ecPublicKey":
             pkt.default_fields["subjectPublicKey"] = ECDSAPublicKey()
             return ASN1F_X509_SubjectPublicKeyInfoECDSA().build(pkt)
         else:
@@ -924,9 +924,9 @@ class ASN1F_X509_Cert(ASN1F_SEQUENCE):
     def m2i(self, pkt, x):
         c,s = ASN1F_SEQUENCE.m2i(self, pkt, x)
         sigtype = pkt.fields["signatureAlgorithm"].algorithm.oidname
-        if "rsa" in sigtype.lower():
+        if b"rsa" in sigtype.lower():
             return c,s
-        elif "ecdsa" in sigtype.lower():
+        elif b"ecdsa" in sigtype.lower():
             return ASN1F_X509_CertECDSA().m2i(pkt, x)
         else:
             raise Exception("could not parse certificate")
@@ -938,9 +938,9 @@ class ASN1F_X509_Cert(ASN1F_SEQUENCE):
             sigtype = pkt.fields['signatureAlgorithm'].algorithm.oidname
         else:
             sigtype = pkt.default_fields["signatureAlgorithm"].algorithm.oidname
-        if "rsa" in sigtype.lower():
+        if b"rsa" in sigtype.lower():
             return ASN1F_SEQUENCE.build(self, pkt)
-        elif "ecdsa" in sigtype.lower():
+        elif b"ecdsa" in sigtype.lower():
             pkt.default_fields["signatureValue"] = ECDSASignature()
             return ASN1F_X509_CertECDSA().build(pkt)
         else:
@@ -1032,9 +1032,9 @@ class ASN1F_X509_CRL(ASN1F_SEQUENCE):
     def m2i(self, pkt, x):
         c,s = ASN1F_SEQUENCE.m2i(self, pkt, x)
         sigtype = pkt.fields["signatureAlgorithm"].algorithm.oidname
-        if "rsa" in sigtype.lower():
+        if b"rsa" in sigtype.lower():
             return c,s
-        elif "ecdsa" in sigtype.lower():
+        elif b"ecdsa" in sigtype.lower():
             return ASN1F_X509_CRLECDSA().m2i(pkt, x)
         else:
             raise Exception("could not parse certificate")
@@ -1046,9 +1046,9 @@ class ASN1F_X509_CRL(ASN1F_SEQUENCE):
             sigtype = pkt.fields['signatureAlgorithm'].algorithm.oidname
         else:
             sigtype = pkt.default_fields["signatureAlgorithm"].algorithm.oidname
-        if "rsa" in sigtype.lower():
+        if b"rsa" in sigtype.lower():
             return ASN1F_SEQUENCE.build(self, pkt)
-        elif "ecdsa" in sigtype.lower():
+        elif b"ecdsa" in sigtype.lower():
             pkt.default_fields["signatureValue"] = ECDSASignature()
             return ASN1F_X509_CRLECDSA().build(pkt)
         else:
@@ -1181,9 +1181,9 @@ class ASN1F_OCSP_BasicResponse(ASN1F_SEQUENCE):
     def m2i(self, pkt, x):
         c,s = ASN1F_SEQUENCE.m2i(self, pkt, x)
         sigtype = pkt.fields["signatureAlgorithm"].algorithm.oidname
-        if "rsa" in sigtype.lower():
+        if b"rsa" in sigtype.lower():
             return c,s
-        elif "ecdsa" in sigtype.lower():
+        elif b"ecdsa" in sigtype.lower():
             return ASN1F_OCSP_BasicResponseECDSA().m2i(pkt, x)
         else:
             raise Exception("could not parse OCSP basic response")
@@ -1195,9 +1195,9 @@ class ASN1F_OCSP_BasicResponse(ASN1F_SEQUENCE):
             sigtype = pkt.fields['signatureAlgorithm'].algorithm.oidname
         else:
             sigtype = pkt.default_fields["signatureAlgorithm"].algorithm.oidname
-        if "rsa" in sigtype.lower():
+        if b"rsa" in sigtype.lower():
             return ASN1F_SEQUENCE.build(self, pkt)
-        elif "ecdsa" in sigtype.lower():
+        elif b"ecdsa" in sigtype.lower():
             pkt.default_fields["signatureValue"] = ECDSASignature()
             return ASN1F_OCSP_BasicResponseECDSA().build(pkt)
         else:
diff --git a/scapy/modules/nmap.py b/scapy/modules/nmap.py
index a6017fd9220e9e665450eb9767a8bd90c536392c..2b4162b6561363e70aff1b3def288db90557cac7 100644
--- a/scapy/modules/nmap.py
+++ b/scapy/modules/nmap.py
@@ -54,7 +54,7 @@ None.
         try:
             fdesc = open(conf.nmap_base
                          if self.filename is None else
-                         self.filename)
+                         self.filename, "rb")
         except (IOError, TypeError):
             warning("Cannot open nmap database [%s]" % self.filename)
             self.filename = None
diff --git a/scapy/packet.py b/scapy/packet.py
index ac8dd4dd00dc4438522c5cf27f628c6643b94a62..b12967bf540a144c842c84bbe5bc58e09c65e6c2 100644
--- a/scapy/packet.py
+++ b/scapy/packet.py
@@ -78,7 +78,7 @@ class Packet(six.with_metaclass(Packet_metaclass, BasePacket)):
 
     def _unpickle(self, dlist):
         """Used to unpack pickling"""
-        self.__init__("".join(dlist))
+        self.__init__(b"".join(dlist))
         return self
 
     def __reduce__(self):
@@ -101,7 +101,7 @@ class Packet(six.with_metaclass(Packet_metaclass, BasePacket)):
         """Used by copy.deepcopy"""
         return self.copy()
 
-    def __init__(self, _pkt="", post_transform=None, _internal=0, _underlayer=None, **fields):
+    def __init__(self, _pkt=b"", post_transform=None, _internal=0, _underlayer=None, **fields):
         self.time  = time.time()
         self.sent_time = None
         self.name = (self.__class__.__name__
@@ -363,7 +363,7 @@ class Packet(six.with_metaclass(Packet_metaclass, BasePacket)):
                     break
             if self.raw_packet_cache is not None:
                 return self.raw_packet_cache
-        p=""
+        p=b""
         for f in self.fields_desc:
             val = self.getfieldval(f.name)
             if isinstance(val, RawVal):
@@ -428,9 +428,9 @@ class Packet(six.with_metaclass(Packet_metaclass, BasePacket)):
         return self.payload.build_done(p)
 
     def do_build_ps(self):
-        p=""
+        p = b""
         pl = []
-        q=""
+        q = b""
         for f in self.fields_desc:
             if isinstance(f, ConditionalField) and not f._evalcond(self):
                 continue
@@ -439,7 +439,7 @@ class Packet(six.with_metaclass(Packet_metaclass, BasePacket)):
                 r = p[len(q):]
                 q = p
             else:
-                r = ""
+                r = b""
             pl.append( (f, f.i2repr(self,self.getfieldval(f.name)), r) )
             
         pkt,lst = self.payload.build_ps(internal=1)
@@ -1228,15 +1228,15 @@ class NoPayload(Packet):
         return False
     __bool__ = __nonzero__
     def do_build(self):
-        return ""
+        return b""
     def build(self):
-        return ""
+        return b""
     def build_padding(self):
-        return ""
+        return b""
     def build_done(self, p):
         return p
     def build_ps(self, internal=0):
-        return "",[]
+        return b"",[]
     def getfieldval(self, attr):
         raise AttributeError(attr)
     def getfield_and_val(self, attr):
@@ -1254,7 +1254,7 @@ class NoPayload(Packet):
             return True
         return False
     def hashret(self):
-        return ""
+        return b""
     def answers(self, other):
         return isinstance(other, NoPayload) or isinstance(other, conf.padding_layer)
     def haslayer(self, cls):
@@ -1305,7 +1305,7 @@ class Raw(Packet):
 class Padding(Raw):
     name = "Padding"
     def self_build(self):
-        return ""
+        return b""
     def build_padding(self):
         return (self.load if self.raw_packet_cache is None
                 else self.raw_packet_cache) + self.payload.build_padding()
diff --git a/scapy/pton_ntop.py b/scapy/pton_ntop.py
index 0172662883a541f926326386267bc35bfe8aed11..06e93095da53703c9594eebec48f6b7b6d77d6ee 100644
--- a/scapy/pton_ntop.py
+++ b/scapy/pton_ntop.py
@@ -24,7 +24,7 @@ used when socket.inet_pton is not available.
 
     """
     joker_pos = None
-    result = ""
+    result = b""
     if addr == '::':
         return b'\x00' * 16
     if addr.startswith('::'):
diff --git a/scapy/route.py b/scapy/route.py
index 652cb3e3502cc99157238b103fb40880c9e19767..c8b8fa4e67d9859e49b84486d056165a20d5ad42 100644
--- a/scapy/route.py
+++ b/scapy/route.py
@@ -37,7 +37,7 @@ class Route:
         rtlst = []
         
         for net,msk,gw,iface,addr in self.routes:
-	    rtlst.append((ltoa(net),
+            rtlst.append((ltoa(net),
                       ltoa(msk),
                       gw,
                       (iface.name if not isinstance(iface, six.string_types) else iface),
diff --git a/scapy/sendrecv.py b/scapy/sendrecv.py
index b09ec55d13aa7c3162a23afd2e599402c62fc0c9..b404f88fe2aa3d83490dfb69cf2f1cc747624125 100644
--- a/scapy/sendrecv.py
+++ b/scapy/sendrecv.py
@@ -167,7 +167,7 @@ def sndrcv(pks, pkt, timeout = None, inter = 0, verbose=None, chainCC=0, retry=0
                                     if r.answers(sentpkt):
                                         ans.append((sentpkt, r))
                                         if verbose > 1:
-                                            os.write(1, "*")
+                                            os.write(1, b"*")
                                         ok = 1
                                         if not multi:
                                             del hlst[i]
@@ -181,7 +181,7 @@ def sndrcv(pks, pkt, timeout = None, inter = 0, verbose=None, chainCC=0, retry=0
                                 break
                             if not ok:
                                 if verbose > 1:
-                                    os.write(1, ".")
+                                    os.write(1, b".")
                                 nbrecv += 1
                                 if conf.debug_match:
                                     debug.recv.append(r)
@@ -260,7 +260,7 @@ def __gen_send(s, x, inter=0, loop=0, count=None, verbose=None, realtime=None, r
                     sent_packets.append(p)
                 n += 1
                 if verbose:
-                    os.write(1,".")
+                    os.write(1,b".")
                 time.sleep(inter)
             if loop < 0:
                 loop += 1
diff --git a/scapy/supersocket.py b/scapy/supersocket.py
index 1c91d363f9adf42c9b54d46f3cf27be9d970d8de..81feec212db0d9e752a6614270630dc5e579d974 100644
--- a/scapy/supersocket.py
+++ b/scapy/supersocket.py
@@ -145,13 +145,13 @@ class SSLStreamSocket(StreamSocket):
     desc = "similar usage than StreamSocket but specialized for handling SSL-wrapped sockets"
 
     def __init__(self, sock, basecls=None):
-        self._buf = ''
+        self._buf = b""
         super(SSLStreamSocket, self).__init__(sock, basecls)
 
     #65535, the default value of x is the maximum length of a TLS record
     def recv(self, x=65535):
         pkt = None
-        if self._buf != '':
+        if self._buf != b"":
             try:
                 pkt = self.basecls(self._buf)
             except:
diff --git a/scapy/themes.py b/scapy/themes.py
index bf7ae4760d3879cfaa3a0f1eb9aecf91e2f8522d..46aa87cf3bcd91c6589c7d2294e937dd8cc4ac2b 100644
--- a/scapy/themes.py
+++ b/scapy/themes.py
@@ -12,20 +12,20 @@ Color themes for the interactive console.
 ##################
 
 class Color:
-    normal = b"\033[0m"
-    black = b"\033[30m"
-    red = b"\033[31m"
-    green = b"\033[32m"
-    yellow = b"\033[33m"
-    blue = b"\033[34m"
-    purple = b"\033[35m"
-    cyan = b"\033[36m"
-    grey = b"\033[37m"
+    normal = "\033[0m"
+    black = "\033[30m"
+    red = "\033[31m"
+    green = "\033[32m"
+    yellow = "\033[33m"
+    blue = "\033[34m"
+    purple = "\033[35m"
+    cyan = "\033[36m"
+    grey = "\033[37m"
 
-    bold = b"\033[1m"
-    uline = b"\033[4m"
-    blink = b"\033[5m"
-    invert = b"\033[7m"
+    bold = "\033[1m"
+    uline = "\033[4m"
+    blink = "\033[5m"
+    invert = "\033[7m"
         
 
 def create_styler(fmt=None, before="", after="", fmt2="%s"):
@@ -268,7 +268,7 @@ class ColorPrompt:
             ct = config.conf.color_theme
             if isinstance(ct, AnsiColorTheme):
                 ## ^A and ^B delimit invisible characters for readline to count right
-                return b"\001%s\002" % ct.prompt(b"\002"+config.conf.prompt+b"\001")
+                return "\001%s\002" % ct.prompt("\002"+config.conf.prompt+"\001")
             else:
                 return ct.prompt(config.conf.prompt)
         except:
diff --git a/scapy/tools/UTscapy.py b/scapy/tools/UTscapy.py
index cf93c1c6575af4dcaee783859c64427b824ffe1a..bffcc1ac8165212cf74c742c0d92f1e53f5a7430 100755
--- a/scapy/tools/UTscapy.py
+++ b/scapy/tools/UTscapy.py
@@ -52,7 +52,7 @@ class File:
     def write(self, dir):
         if dir:
             dir += "/"
-        open(dir+self.name,"w").write(self.get_local())
+        open(dir+self.name,"wb").write(self.get_local())
 
         
 # Embed a base64 encoded bziped version of js and css files
@@ -747,7 +747,7 @@ def main(argv):
                     raise getopt.GetoptError("Unknown output format %s" % msg)
                 TESTFILES = resolve_testfiles(TESTFILES)
             elif opt == "-o":
-                OUTPUTFILE = open(optarg, "w")
+                OUTPUTFILE = open(optarg, "wb")
             elif opt == "-l":
                 LOCAL = 1
             elif opt == "-n":
@@ -836,7 +836,7 @@ def main(argv):
     if FORMAT == Format.HTML:
         glob_output = pack_html_campaigns(runned_campaigns, glob_output, LOCAL, glob_title)
     
-    OUTPUTFILE.write(glob_output.encode("utf8"))
+    OUTPUTFILE.write(glob_output.encode("utf8", "ignore"))
     OUTPUTFILE.close()
 
     # Return state
diff --git a/scapy/utils.py b/scapy/utils.py
index efa3698b891ba8847861d6f2af3fb103bd2901d7..40bf5992d6c45d4dcf474b607d1c91cf3857fd61 100644
--- a/scapy/utils.py
+++ b/scapy/utils.py
@@ -343,7 +343,7 @@ def fletcher16_checkbytes(binbuf, offset):
 
 
 def mac2str(mac):
-    return "".join(chr(int(x, 16)) for x in mac.split(':'))
+    return b"".join(chr(int(x, 16)) for x in mac.split(':'))
 
 def str2mac(s):
     return ("%02x:"*6)[:-1] % tuple(map(ord, s)) 
@@ -365,14 +365,14 @@ def strxor(s1, s2):
     Returns the binary XOR of the 2 provided strings s1 and s2. s1 and s2
     must be of same length.
     """
-    return "".join(map(lambda x,y:chr(ord(x)^ord(y)), s1, s2))
+    return b"".join(map(lambda x,y:chr(ord(x)^ord(y)), s1, s2))
 
 def strand(s1, s2):
     """
     Returns the binary AND of the 2 provided strings s1 and s2. s1 and s2
     must be of same length.
     """
-    return "".join(map(lambda x,y:chr(ord(x)&ord(y)), s1, s2))
+    return b"".join(map(lambda x,y:chr(ord(x)&ord(y)), s1, s2))
 
 
 # Workaround bug 643005 : https://sourceforge.net/tracker/?func=detail&atid=105470&aid=643005&group_id=5470
@@ -696,7 +696,7 @@ class PcapReader_metaclass(type):
                 fdesc = gzip.open(filename,"rb")
                 magic = fdesc.read(4)
             except IOError:
-                fdesc = open(filename,"rb")
+                fdesc = open(filename, "rb")
                 magic = fdesc.read(4)
         else:
             fdesc = filename
@@ -1054,7 +1054,7 @@ nano:       use nanosecond-precision (requires libpcap >= 1.5.0)
                 try:
                     p = pkt.next()
                 except StopIteration:
-                    self._write_header("")
+                    self._write_header(b"")
                     return
                 self._write_header(p)
                 self._write_packet(p)
@@ -1226,7 +1226,7 @@ u'64'
         # <http://apple.stackexchange.com/questions/152682/>
         tmpfile = tempfile.NamedTemporaryFile(delete=False)
         try:
-            tmpfile.writelines(iter(lambda: pktlist.read(1048576), ""))
+            tmpfile.writelines(iter(lambda: pktlist.read(1048576), b""))
         except AttributeError:
             wrpcap(tmpfile, pktlist)
         else:
@@ -1247,13 +1247,13 @@ u'64'
                 stderr=open(os.devnull),
             )
         try:
-            proc.stdin.writelines(iter(lambda: pktlist.read(1048576), ""))
+            proc.stdin.writelines(iter(lambda: pktlist.read(1048576), b""))
         except AttributeError:
             wrpcap(proc.stdin, pktlist)
         else:
             proc.stdin.close()
     if dump:
-        return "".join(iter(lambda: proc.stdout.read(1048576), ""))
+        return b"".join(iter(lambda: proc.stdout.read(1048576), b""))
     if getfd:
         return proc.stdout
     proc.wait()
@@ -1262,7 +1262,7 @@ u'64'
 def hexedit(x):
     x = str(x)
     f = get_temp_file()
-    open(f,"w").write(x)
+    open(f,"wb").write(x)
     with ContextManagerSubprocess("hexedit()"):
         subprocess.call([conf.prog.hexedit, f])
     x = open(f).read()
@@ -1423,21 +1423,21 @@ def whois(ip_address):
         query = whois_ip
     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     s.connect(("whois.ripe.net", 43))
-    s.send(query + "\r\n")
-    answer = ''
+    s.send(query + b"\r\n")
+    answer = b""
     while True:
         d = s.recv(4096)
         answer += d
         if not d:
             break
     s.close()
-    ignore_tag = "remarks:"
+    ignore_tag = b"remarks:"
     # ignore all lines starting with the ignore_tag
-    lines = [ line for line in answer.split("\n") if not line or (line and not line.startswith(ignore_tag))]
+    lines = [ line for line in answer.split(b"\n") if not line or (line and not line.startswith(ignore_tag))]
     # remove empty lines at the bottom
     for i in range(1, len(lines)):
         if not lines[-i].strip():
             del lines[-i]
         else:
             break
-    return "\n".join(lines[3:])
+    return b"\n".join(lines[3:])
diff --git a/scapy/utils6.py b/scapy/utils6.py
index 8439e40d9dfe9295e6df5a014b785bbe29423656..e849b121f980f895fc2d43522901baf39dcfa55a 100644
--- a/scapy/utils6.py
+++ b/scapy/utils6.py
@@ -390,9 +390,9 @@ def in6_getRandomizedIfaceId(ifaceid, previous=None):
     ('fe97:46fe:9871:bd38', 'eeed:d79c:2e3f:62e')
     """
 
-    s = ""
+    s = b""
     if previous is None:
-        d = "".join(chr(x) for x in range(256))
+        d = b"".join(chr(x) for x in range(256))
         for _ in range(8):
             s += random.choice(d)
         previous = s
@@ -431,7 +431,7 @@ def in6_ctop(addr):
         res.append(struct.pack("!I", i%2**32))
         i = i/(2**32)
     res.reverse()
-    return inet_ntop(socket.AF_INET6, "".join(res))
+    return inet_ntop(socket.AF_INET6, b"".join(res))
 
 def in6_ptoc(addr):
     """
@@ -453,7 +453,7 @@ def in6_ptoc(addr):
         res.append(_rfc1924map[rem%85])
         rem = rem/85
     res.reverse()
-    return "".join(res)
+    return b"".join(res)
 
     
 def in6_isaddr6to4(x):
@@ -528,7 +528,7 @@ def _in6_bitops(a1, a2, operator=0):
             lambda x,y: x ^ y
           ]
     ret = map(fop[operator%len(fop)], a1, a2)
-    return ''.join(struct.pack('I', x) for x in ret)
+    return b"".join(struct.pack('I', x) for x in ret)
 
 def in6_or(a1, a2):
     """
@@ -569,7 +569,7 @@ def in6_cidr2mask(m):
         t.append(max(0, 2**32  - 2**(32-min(32, m))))
         m -= 32
 
-    return ''.join(struct.pack('!I', x) for x in t)
+    return b"".join(struct.pack('!I', x) for x in t)
 
 def in6_getnsma(a): 
     """
diff --git a/test/nmap.uts b/test/nmap.uts
index 6e3699ca0964489b381f02411e0819e8f414d63a..d25228851e3a3e9df503f98050cf5679702ae52a 100644
--- a/test/nmap.uts
+++ b/test/nmap.uts
@@ -11,7 +11,7 @@ load_module('nmap')
 
 = Fetch database
 import urllib
-open('nmap-os-fingerprints', 'w').write(urllib.urlopen('https://raw.githubusercontent.com/nmap/nmap/9efe1892/nmap-os-fingerprints').read())
+open('nmap-os-fingerprints', 'wb').write(urllib.urlopen('https://raw.githubusercontent.com/nmap/nmap/9efe1892/nmap-os-fingerprints').read())
 conf.nmap_base = 'nmap-os-fingerprints'
 
 = Database loading
diff --git a/test/regression.uts b/test/regression.uts
index 55b9ae9d1441649f7f6f5f13faed5ef14e741204..1faf2a211d0819f9e3335c8b99fc2d995393d26c 100644
--- a/test/regression.uts
+++ b/test/regression.uts
@@ -5182,7 +5182,7 @@ fdesc.close()
 assert list(pktpcap) == list(sniff(offline=filename))
 
 = Check offline sniff() (by file object)
-fdesc = open(filename)
+fdesc = open(filename, "rb")
 assert list(pktpcap) == list(sniff(offline=fdesc))
 fdesc.close()
 
@@ -5194,7 +5194,7 @@ assert all(list(pktpcap[proto]) == list(packets) for proto, packets in pktpcap_f
 
 = Check offline sniff() with a filter (by file object)
 ~ tcpdump
-fdesc = open(filename)
+fdesc = open(filename, "rb")
 pktpcap_tcp = sniff(offline=fdesc, filter="tcp")
 fdesc.close()
 assert list(pktpcap[TCP]) == list(pktpcap_tcp)