scapy icon indicating copy to clipboard operation
scapy copied to clipboard

[Doc] automaton example does not work

Open matsievskiysv opened this issue 3 years ago • 2 comments

Brief description

The very first Automaton example does not work. Python throwing TypeError on class creation and gets stuck somewhere in the initialization function.

Scapy version

9c1731bc31d30f5b28535f9d38abcf157321dfb0

Python version

3.10

Operating system

GNU/Linux 5.17.0 Debian bookworm/sid

Additional environment information

No response

How to reproduce

Run the following:

from scapy.automaton import Automaton, ATMT


class HelloWorld(Automaton):
    @ATMT.state(initial=1)
    def BEGIN(self):
        print("State=BEGIN")

    @ATMT.condition(BEGIN)
    def wait_for_nothing(self):
        print("Wait for nothing...")
        raise self.END()

    @ATMT.action(wait_for_nothing)
    def on_nothing(self):
        print("Action on 'nothing' condition")

    @ATMT.state(final=1)
    def END(self):
        print("State=END")


a = HelloWorld()
print("hello world")

Actual result

Error in the output:

Exception in thread scapy.automaton _do_start:
Traceback (most recent call last):
  File "/usr/lib/python3.10/threading.py", line 1009, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.10/threading.py", line 946, in run
    self._target(*self._args, **self._kwargs)
  File "/mnt/mstorage/Projects/Python/scapy/scapy/automaton.py", line 954, in _do_control
    self.send_sock = self.send_sock_class(**self.socket_kargs)
TypeError: 'NoneType' object is not callable

and the print("hello world") is never executed.

Expected result

No errors in the output and execution to reach print("hello world") line.

Related resources

No response

matsievskiysv avatar May 25 '22 03:05 matsievskiysv

This looks extremely broken, because it would mean that your conf.L3socket and conf.L2listen are None, meaning nothing in Scapy likely works.

gpotter2 avatar Jun 16 '22 22:06 gpotter2

The problem seems to be with importing conf in the script. When I import conf from scapy.all

from scapy.all import conf
print(conf)

I get

ASN1_default_codec = <ASN1Codec BER[1]>
AS_resolver = <scapy.as_resolvers.AS_resolver_multi object at 0x7fb48c036680>
BTsocket   = <BluetoothRFCommSocket: read/write packets on a connected L2CAP...
L2listen   = <L2ListenSocket: read packets at layer 2 using Linux PF_PACKET ...
L2socket   = <L2Socket: read/write packets at layer 2 using Linux PF_PACKET ...
L3socket   = <L3PacketSocket: read/write packets at layer 3 using Linux PF_P...
L3socket6  = functools.partial(<L3PacketSocket: read/write packets at layer ...

However, when I import conf from scapy.config, it seems to be incompletely initialized

from scapy.config import conf
print(conf)
ASN1_default_codec = None
AS_resolver = None
BTsocket   = None
L2listen   = None
L2socket   = None
L3socket   = None
L3socket6  = None

Internally, Automaton also imports conf from scapy.config. Therefore, the state machine above only works correctly if I trigger conf initialization by importing conf before Automaton:

from scapy.all import conf
from scapy.automaton import Automaton, ATMT

matsievskiysv avatar Jun 17 '22 04:06 matsievskiysv

I made some slight changes in https://github.com/secdev/scapy/pull/3743 that should help

gpotter2 avatar Sep 23 '22 08:09 gpotter2