[Doc] automaton example does not work
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
This looks extremely broken, because it would mean that your
conf.L3socket and conf.L2listen are None, meaning nothing in Scapy likely works.
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
I made some slight changes in https://github.com/secdev/scapy/pull/3743 that should help