@@ -36,8 +36,8 @@ class ModbusMBAP(Packet):
3636 name = "Modbus TCP"
3737 fields_desc = [ ShortField ("transId" , 0 ),
3838 ShortField ("protoId" , 0 ),
39- ShortField ("len" , 6 ),
40- XByteField ("UnitId " , 247 ),
39+ ShortField ("len" , 0 ),
40+ XByteField ("unitId " , 0 ),
4141 ]
4242
4343# Can be used to replace all Modbus read
@@ -252,10 +252,27 @@ class ModbusPDUXX_Custom_Request(Packet):
252252 FieldListField ("customBytes" , [0x00 ], XByteField ("" , 0x00 ))
253253 ]
254254
255+ class ModbusPDUXX_Custom_Exception (Packet ):
256+ name = "Custom Command Exception"
257+ fields_desc = [
258+ XByteField ("funcCode" , 0x00 ),
259+ ByteEnumField ("exceptCode" , 1 , modbus_exceptions )
260+ ]
261+
262+ # Custom command respond
263+ class ModbusPDUXX_Custom_Answer (Packet ):
264+ name = "Custom Command Answer"
265+ fields_desc = [
266+ ConditionalField (XByteField ("funcCode" , 0x00 ), lambda pkt : (type (pkt .underlayer ) is ModbusADU_Response )),
267+ ConditionalField (FieldListField ("customBytes" , [0x00 ], XByteField ("" , 0x00 ), count_from = lambda pkt : pkt .underlayer .len if pkt .underlayer is not None else 0 ), lambda pkt : type (pkt .underlayer ) is ModbusADU_Response )
268+ ]
269+
255270# 0x11 - Report Slave Id
256271class ModbusPDU11_Report_Slave_Id (Packet ):
257272 name = "Report Slave Id"
258- fields_desc = [ XByteField ("funcCode" , 0x11 ) ]
273+ fields_desc = [
274+ XByteField ("funcCode" , 0x11 )
275+ ]
259276
260277class ModbusPDU11_Report_Slave_Id_Answer (Packet ):
261278 name = "Report Slave Id Answer"
@@ -279,7 +296,8 @@ class ModbusADU_Request(ModbusMBAP):
279296 XShortField ("transId" , 0x0000 ), # needs to be unique
280297 XShortField ("protoId" , 0x0000 ), # needs to be zero (Modbus)
281298 XShortField ("len" , None ), # is calculated with payload
282- XByteField ("unitId" , 0x00 )] # 0xFF or 0x00 should be used for Modbus over TCP/IP
299+ XByteField ("unitId" , 0x00 ) # 0xFF or 0x00 should be used for Modbus over TCP/IP
300+ ]
283301
284302 def mb_get_last_exception (self ):
285303 return _mb_exception
@@ -372,7 +390,8 @@ def my_show(self, p):
372390class ModbusADU_Response (ModbusMBAP ):
373391 name = "ModbusADU Response"
374392 _mb_exception : modbus_exceptions = 0
375-
393+ _current_main_packet : Packet = None
394+ _modbus_pdu : Packet = None
376395 fields_desc = [
377396 XShortField ("transId" , 0x0000 ), # needs to be unique
378397 XShortField ("protoId" , 0x0000 ), # needs to be zero (Modbus)
@@ -381,6 +400,15 @@ class ModbusADU_Response(ModbusMBAP):
381400
382401 def mb_get_last_exception (self ):
383402 return _mb_exception
403+
404+ # def extract_padding(self, s):
405+ # print(f'Extract pedding: {self, s, self.len, self.underlayer}')
406+ # return self.guess_payload_class( s) #, s #self.extract_pedding(self, s)
407+
408+ def pre_dissect (self , s ):
409+ print (f'Pre desect: { self , s , self .len , self .underlayer } ' )
410+ _current_main_packet = self
411+ return s
384412
385413 # Dissects packets
386414 def guess_payload_class (self , payload ):
@@ -443,11 +471,14 @@ def guess_payload_class(self, payload):
443471 return ModbusPDU10_Write_Multiple_Registers_Exception
444472
445473 elif funcCode == 0x11 :
446- print (f'Packet answer: { payload } , func: { funcCode } ' )
447474 return ModbusPDU11_Report_Slave_Id_Answer
448475 elif funcCode == 0x91 :
449476 self ._mb_exception = int (payload [1 ])
450477 return ModbusPDU11_Report_Slave_Id_Exception
451478
452479 else :
453- return Packet .guess_payload_class (self , payload )
480+ if (funcCode & 0x80 ):
481+ self ._mb_exception = int (payload [1 ])
482+ return ModbusPDUXX_Custom_Exception
483+ return ModbusPDUXX_Custom_Answer
484+ #return Packet.guess_payload_class(self, payload)
0 commit comments