Context -- I have been running python automation scripts for Common Industrial Protocol using scapy as the means to create packets in this format.
There were no problems running the scripts in a python 3.4 environment, but when trying to migrate to a new environment, basically running the same scripts in a slightly upgraded environment using python 3.6 I get the error below.
2020-08-26T12:14:02: %EASYPY-ERROR: Caught error during task execution: Task-2: id_cip_test1.py
2020-08-26T12:14:02: %EASYPY-ERROR: Traceback (most recent call last):
2020-08-26T12:14:02: %EASYPY-ERROR: File "/users/alpeck/pyats3.6/lib/python3.6/site-packages/pyats/aetest/main.py", line 187, in run
2020-08-26T12:14:02: %EASYPY-ERROR: testscript = TestScript.from_source(self.testable, self.reporter)
2020-08-26T12:14:02: %EASYPY-ERROR: File "/users/alpeck/pyats3.6/lib/python3.6/site-packages/pyats/aetest/script.py", line 68, in from_source
2020-08-26T12:14:02: %EASYPY-ERROR: module = loader.load(testable)
2020-08-26T12:14:02: %EASYPY-ERROR: File "/users/alpeck/pyats3.6/lib/python3.6/site-packages/pyats/utils/import_utils/flex.py", line 64, in load
2020-08-26T12:14:02: %EASYPY-ERROR: module = self.load_module_from_file(obj)
2020-08-26T12:14:02: %EASYPY-ERROR: File "/users/alpeck/pyats3.6/lib/python3.6/site-packages/pyats/utils/import_utils/flex.py", line 117, in load_module_from_file
2020-08-26T12:14:02: %EASYPY-ERROR: module = loader.load_module()
2020-08-26T12:14:02: %EASYPY-ERROR: File "<frozen importlib._bootstrap_external>", line 399, in _check_name_wrapper
2020-08-26T12:14:02: %EASYPY-ERROR: File "<frozen importlib._bootstrap_external>", line 823, in load_module
2020-08-26T12:14:02: %EASYPY-ERROR: File "<frozen importlib._bootstrap_external>", line 682, in load_module
2020-08-26T12:14:02: %EASYPY-ERROR: File "<frozen importlib._bootstrap>", line 265, in _load_module_shim
2020-08-26T12:14:02: %EASYPY-ERROR: File "<frozen importlib._bootstrap>", line 684, in _load
2020-08-26T12:14:02: %EASYPY-ERROR: File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
2020-08-26T12:14:02: %EASYPY-ERROR: File "<frozen importlib._bootstrap_external>", line 678, in exec_module
2020-08-26T12:14:02: %EASYPY-ERROR: File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
2020-08-26T12:14:02: %EASYPY-ERROR: File "/users/alpeck/pyats/Automation/CIP_Automation/cip_sanity/17_4/petra/id_cip_test1.py", line 40, in <module>
2020-08-26T12:14:02: %EASYPY-ERROR: client = plc.PLCClient(str(cip_interface.connections['a'].ip))
2020-08-26T12:14:02: %EASYPY-ERROR: File "/users/alpeck/pyats3.6/lib/python3.6/site-packages/plc.py", line 65, in __init__
2020-08-26T12:14:02: %EASYPY-ERROR: self.sock.send( bytes(sessionpkt,'utf-8'))
2020-08-26T12:14:02: %EASYPY-ERROR: TypeError: encoding without a string argument
This error points to a few scripts, but I have narrowed this issue down to clarify this problem further.
File "/users/alpeck/pyats3.6/lib/python3.6/site-packages/plc.py", line 65, in __init__
self.sock.send( bytes(sessionpkt,'utf-8'))
-- This traceback points to the plc.py block below --
class PLCClient(object):
"""Handle all the state of an Ethernet/IP session with a PLC"""
def __init__(self, plc_addr, plc_port=44818):
if not NO_NETWORK:
try:
self.sock = socket.create_connection((plc_addr, plc_port))
print('Printing self sock') --> Printing self sock
print(self.sock) --> <socket.socket fd=17, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('64.101.134.34', 15065), raddr=('10.89.157.229', 44818)>
except socket.error as exc:
logger.warn("socket error: %s", exc)
logger.warn("Continuing without sending anything")
self.sock = None
else:
self.sock = None
self.session_id = 0
self.enip_connid = 0
self.sequence = 1
# Open an Ethernet/IP session
sessionpkt = ENIP_TCP() / ENIP_RegisterSession()
print('Printing session packet') --> Printing session packet
print(sessionpkt) --> b'e\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00'
if self.sock is not None:
self.sock.send( bytes(sessionpkt,'utf-8'))
reply_pkt = self.recv_enippkt()
self.session_id = reply_pkt.session
The problem is highlighted above, there is either no data or corrupt data in the session packet being shown.
sessionpkt = ENIP_TCP() / ENIP_RegisterSession()
The session packet is created in another directory shown below.
class ENIP_RegisterSession(scapy_all.Packet):
name = "ENIP_RegisterSession"
fields_desc = [
scapy_all.LEShortField("protocol_version", 1),
scapy_all.LEShortField("options", 0),
]
class ENIP_TCP(scapy_all.Packet):
"""Ethernet/IP packet over TCP"""
name = "ENIP_TCP"
fields_desc = [
scapy_all.LEShortEnumField("command_id", None, {
0x0004: "ListServices",
0x0063: "ListIdentity",
0x0064: "ListInterfaces",
0x0065: "RegisterSession",
0x0066: "UnregisterSession",
0x006f: "SendRRData", # Send Request/Reply data
0x0070: "SendUnitData",
}),
scapy_all.LEShortField("length", None),
scapy_all.LEIntField("session", 0),
scapy_all.LEIntEnumField("status", 0, {0: "success"}),
scapy_all.LELongField("sender_context", 0),
scapy_all.LEIntField("options", 0),
]
If there is anything else that would help to solve this error I can give further information.