| 279 | |
| 280 | |
| 281 | class LayersList(List[Type['scapy.packet.Packet']]): |
| 282 | def __init__(self): |
| 283 | # type: () -> None |
| 284 | list.__init__(self) |
| 285 | self.ldict = {} # type: Dict[str, List[Type[Packet]]] |
| 286 | self.filtered = False |
| 287 | self._backup_dict = {} # type: Dict[Type[Packet], List[Tuple[Dict[str, Any], Type[Packet]]]] # noqa: E501 |
| 288 | |
| 289 | def __repr__(self): |
| 290 | # type: () -> str |
| 291 | return "\n".join("%-20s: %s" % (layer.__name__, layer.name) |
| 292 | for layer in self) |
| 293 | |
| 294 | def register(self, layer): |
| 295 | # type: (Type[Packet]) -> None |
| 296 | self.append(layer) |
| 297 | |
| 298 | # Skip arch* modules |
| 299 | if layer.__module__.startswith("scapy.arch."): |
| 300 | return |
| 301 | |
| 302 | # Register in module |
| 303 | if layer.__module__ not in self.ldict: |
| 304 | self.ldict[layer.__module__] = [] |
| 305 | self.ldict[layer.__module__].append(layer) |
| 306 | |
| 307 | def layers(self): |
| 308 | # type: () -> List[Tuple[str, str]] |
| 309 | result = [] |
| 310 | # This import may feel useless, but it is required for the eval below |
| 311 | import scapy # noqa: F401 |
| 312 | try: |
| 313 | import builtins # noqa: F401 |
| 314 | except ImportError: |
| 315 | import __builtin__ # noqa: F401 |
| 316 | for lay in self.ldict: |
| 317 | doc = eval(lay).__doc__ |
| 318 | result.append((lay, doc.strip().split("\n")[0] if doc else lay)) |
| 319 | return result |
| 320 | |
| 321 | def filter(self, items): |
| 322 | # type: (List[Type[Packet]]) -> None |
| 323 | """Disable dissection of unused layers to speed up dissection""" |
| 324 | if self.filtered: |
| 325 | raise ValueError("Already filtered. Please disable it first") |
| 326 | for lay in self.ldict.values(): |
| 327 | for cls in lay: |
| 328 | if cls not in self._backup_dict: |
| 329 | self._backup_dict[cls] = cls.payload_guess[:] |
| 330 | cls.payload_guess = [ |
| 331 | y for y in cls.payload_guess if y[1] in items |
| 332 | ] |
| 333 | self.filtered = True |
| 334 | |
| 335 | def unfilter(self): |
| 336 | # type: () -> None |
| 337 | """Re-enable dissection for all layers""" |
| 338 | if not self.filtered: |