List  available layers, or infos on a given layer class or name.
    params:
     - obj: Packet / packet name to use
     - case_sensitive: if obj is a string, is it case sensitive?
     - verbose

def ls(obj=None, case_sensitive=False, verbose=False):
    """List  available layers, or infos on a given layer class or name.
    params:
     - obj: Packet / packet name to use
     - case_sensitive: if obj is a string, is it case sensitive?
     - verbose
    """
    is_string = isinstance(obj, six.string_types)

    if obj is None or is_string:
        tip = False
        if obj is None:
            tip = True
            all_layers = sorted(conf.layers, key=lambda x: x.__name__)
        else:
            pattern = re.compile(obj, 0 if case_sensitive else re.I)
            # We first order by accuracy, then length
            if case_sensitive:
                sorter = lambda x: (x.__name__.index(obj), len(x.__name__))
            else:
                obj = obj.lower()
                sorter = lambda x: (x.__name__.lower().index(obj),
                                    len(x.__name__))
            all_layers = sorted((layer for layer in conf.layers
                                 if (isinstance(layer.__name__, str) and
                                     pattern.search(layer.__name__)) or
                                 (isinstance(layer.name, str) and
                                     pattern.search(layer.name))),
                                key=sorter)
        for layer in all_layers:
            print("%-10s : %s" % (layer.__name__, layer._name))
        if tip and conf.interactive:
            print("\nTIP: You may use explore() to navigate through all "
                  "layers using a clear GUI")
    else:
        is_pkt = isinstance(obj, Packet)
        if issubtype(obj, Packet) or is_pkt:
            for f in obj.fields_desc:
                cur_fld = f
                attrs = []
                long_attrs = []
                while isinstance(cur_fld, (Emph, ConditionalField)):
                    if isinstance(cur_fld, ConditionalField):
                        attrs.append(cur_fld.__class__.__name__[:4])
                    cur_fld = cur_fld.fld
                if verbose and isinstance(cur_fld, EnumField) \
                   and hasattr(cur_fld, "i2s"):
                    if len(cur_fld.i2s) < 50:
                        long_attrs.extend(
                            "%s: %d" % (strval, numval)
                            for numval, strval in
                            sorted(six.iteritems(cur_fld.i2s))
                        )
                elif isinstance(cur_fld, MultiEnumField):
                    fld_depend = cur_fld.depends_on(obj.__class__
                                                    if is_pkt else obj)
                    attrs.append("Depends on %s" % fld_depend.name)
                    if verbose:
                        cur_i2s = cur_fld.i2s_multi.get(
                            cur_fld.depends_on(obj if is_pkt else obj()), {}
                        )
                        if len(cur_i2s) < 50:
                            long_attrs.extend(
                                "%s: %d" % (strval, numval)
                                for numval, strval in
                                sorted(six.iteritems(cur_i2s))
                            )
                elif verbose and isinstance(cur_fld, FlagsField):
                    names = cur_fld.names
                    long_attrs.append(", ".join(names))
                class_name = "%s (%s)" % (
                    cur_fld.__class__.__name__,
                    ", ".join(attrs)) if attrs else cur_fld.__class__.__name__
                if isinstance(cur_fld, BitField):
                    class_name += " (%d bit%s)" % (cur_fld.size,
                                                   "s" if cur_fld.size > 1
                                                   else "")
                print("%-10s : %-35s =" % (f.name, class_name), end=' ')
                if is_pkt:
                    print("%-15r" % (getattr(obj, f.name),), end=' ')
                print("(%r)" % (f.default,))
                for attr in long_attrs:
                    print("%-15s%s" % ("", attr))
            if is_pkt and not isinstance(obj.payload, NoPayload):
                print("--")
                ls(obj.payload)

        else:
            print("Not a packet class or name. Type 'ls()' to list packet classes.")