# Buggy code
def fuzz(p, _inplace=0):
    """Transform a layer into a fuzzy layer by replacing some default values by random objects"""  # noqa: E501
    if not _inplace:
        p = p.copy()
    q = p
    while not isinstance(q, NoPayload):
        for f in q.fields_desc:
            if isinstance(f, PacketListField):
                for r in getattr(q, f.name):
                    print("fuzzing", repr(r))
                    fuzz(r, _inplace=1)
            elif f.default is not None:
                if not isinstance(f, ConditionalField) or f._evalcond(q):
                    rnd = f.randval()
                    if rnd is not None:
                        q.default_fields[f.name] = rnd
        q = q.payload
    return p


# Traceback (TypeError)
faucet@faucet:~$ sudo bash
root@faucet:~# python3
Python 3.6.8 (default, Jan 14 2019, 11:02:34)
[GCC 8.0.1 20180414 (experimental) [trunk revision 259383]] on linux
Type "help", "copyright", "credits" or "license" for more information.
from scapy.all import *
scapy.all.send(fuzz(ARP(pdst='127.0.0.1')))
Traceback (most recent call last):
File "/usr/local/lib/python3.6/dist-packages/scapy/compat.py", line 117, in raw
return bytes(x)
File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 441, in __bytes__
return self.build()
File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 556, in build
p = self.do_build()
File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 541, in do_build
pay = self.do_build_payload()
File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 528, in do_build_payload
return self.payload.do_build()
File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 538, in do_build
pkt = self.self_build()
File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 519, in self_build
p = f.addfield(self, p, val)
File "/usr/local/lib/python3.6/dist-packages/scapy/fields.py", line 134, in addfield
return s + struct.pack(self.fmt, self.i2m(pkt, val))
File "/usr/local/lib/python3.6/dist-packages/scapy/fields.py", line 1314, in i2m
f = fld.i2len(pkt, fval)
File "/usr/local/lib/python3.6/dist-packages/scapy/fields.py", line 343, in i2len
return self._find_fld_pkt_val(pkt, val).i2len(pkt, val)
File "/usr/local/lib/python3.6/dist-packages/scapy/fields.py", line 884, in i2len
return len(i)
TypeError: object of type 'NoneType' has no len()

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.6/dist-packages/scapy/sendrecv.py", line 314, in send
realtime=realtime, return_packets=return_packets)
File "/usr/local/lib/python3.6/dist-packages/scapy/sendrecv.py", line 287, in __gen_send
s.send(p)
File "/usr/local/lib/python3.6/dist-packages/scapy/arch/linux.py", line 533, in send
sx = raw(ll(x))
File "/usr/local/lib/python3.6/dist-packages/scapy/compat.py", line 119, in raw
return bytes(x, encoding="utf8")
TypeError: encoding without a string argument

# Fixed code
def fuzz(p, _inplace=0):
    """
    Transform a layer into a fuzzy layer by replacing some default values
    by random objects.

    :param p: the Packet instance to fuzz
    :returns: the fuzzed packet.
    """
    if not _inplace:
        p = p.copy()
    q = p
    while not isinstance(q, NoPayload):
        new_default_fields = {}
        multiple_type_fields = []
        for f in q.fields_desc:
            if isinstance(f, PacketListField):
                for r in getattr(q, f.name):
                    print("fuzzing", repr(r))
                    fuzz(r, _inplace=1)
            elif isinstance(f, MultipleTypeField):
                # the type of the field will depend on others
                multiple_type_fields.append(f.name)
            elif f.default is not None:
                if not isinstance(f, ConditionalField) or f._evalcond(q):
                    rnd = f.randval()
                    if rnd is not None:
                        new_default_fields[f.name] = rnd
        # Process packets with MultipleTypeFields
        if multiple_type_fields:
            # freeze the other random values
            new_default_fields = {
                key: (val._fix() if isinstance(val, VolatileValue) else val)
                for key, val in six.iteritems(new_default_fields)
            }
            q.default_fields.update(new_default_fields)
            # add the random values of the MultipleTypeFields
            for name in multiple_type_fields:
                rnd = q.get_field(name)._find_fld_pkt(q).randval()
                if rnd is not None:
                    new_default_fields[name] = rnd
        q.default_fields.update(new_default_fields)
        q = q.payload
    return p