docs: 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.")