UDS in Scapy#
Overview#
Preparations#
from scapy.all import * # If you launch `scapy` directly, this import isn't necessary
conf.contribs['CANSocket'] = {'use-python-can': False}
conf.contribs['ISOTP'] = {'use-can-isotp-kernel-module': True}
load_contrib("isotp")
load_contrib("automotive.uds")
Examples#
Create a socket.
basecls
has to be set asUDS
.
sock = ISOTPNativeSocket("vcan0", tx_id=0x6f1, rx_id=0x610, ext_address=0x10, rx_ext_address=0xf1, basecls=UDS)
Create a packet and send it
rdbi_pkt = UDS()/UDS_RDBI(identifiers=[0x172a])
rx = sock.sr1(rdbi_pkt, timeout=1)
rx.show()
Begin emission
Finished sending 1 packets
*
Received 1 packets, got 1 answers, remaining 0 packets
###[ UDS ]###
service = ReadDataByIdentifierPositiveResponse
###[ ReadDataByIdentifierPositiveResponse ]###
dataIdentifier= 0x172a
###[ Raw ]###
load = b'\x00\xc0\xa8\x11\x97\xff\xff\xff\x00\xc0\xa8\x11\x01'
Alternative way to send and receive a packet
rdbi_pkt = UDS()/UDS_RDBI(identifiers=[0x172a])
rx = sock.sniff(timeout=1, count=1, started_callback=lambda: sock.send(rdbi_pkt))
rx[0].show()
###[ UDS ]###
service = ReadDataByIdentifierPositiveResponse
###[ ReadDataByIdentifierPositiveResponse ]###
dataIdentifier= 0x172a
###[ Raw ]###
load = b'\x00\xc0\xa8\x11\x97\xff\xff\xff\x00\xc0\xa8\x11\x01'
Basecls is
UDS(Packet)
UDS
implements fake layers to auto-fill fieldsIdentifiers can be customized
OEM specific packets can be added to the parser, easily
Customization of Packets#
Define identifier
0x172a
asGatewayIP
rdbi_pkt = UDS()/UDS_RDBI(identifiers=[0x172a])
print(repr(rdbi_pkt))
UDS_RDBI.dataIdentifiers[0x172a] = 'GatewayIP'
print(repr(rdbi_pkt))
<UDS service=ReadDataByIdentifier |<UDS_RDBI identifiers=[0x172a] |>>
<UDS service=ReadDataByIdentifier |<UDS_RDBI identifiers=[GatewayIP] |>>
Also the received packet is affected
print(repr(rx))
<Sniffed: TCP:0 UDP:0 ICMP:0 Other:1>
Define a payload class
class DBI_IP(Packet):
name = 'DataByIdentifier_IP_Packet'
fields_desc = [
ByteField('ADDRESS_FORMAT_ID', 0),
IPField('IP', 0),
IPField('SUBNETMASK', 0),
IPField('DEFAULT_GATEWAY', 0)]
Connect
RDBIPR
with new payload class
bind_layers(UDS_RDBIPR, DBI_IP, dataIdentifier=0x172a)
Enjoy your new packet parser (
show2()
is called to rebuild the packet)
rx[0].show2()
###[ UDS ]###
service = ReadDataByIdentifierPositiveResponse
###[ ReadDataByIdentifierPositiveResponse ]###
dataIdentifier= GatewayIP
###[ DataByIdentifier_IP_Packet ]###
ADDRESS_FORMAT_ID= 0
IP = 192.168.17.151
SUBNETMASK= 255.255.255.0
DEFAULT_GATEWAY= 192.168.17.1
Get all possible packets of a layer in Scapy
explore("scapy.contrib.automotive.uds")
Packets contained in scapy.contrib.automotive.uds:
Class |Name
---------------------|-----------------------------------------------
DTC |Diagnostic Trouble Code
DTCAndStatusRecord |DTC and status record
DTCExtendedData |Diagnostic Trouble Code Extended Data
DTCExtendedDataRecord|
DTCSnapshot |
DTCSnapshotRecord |
UDS |UDS
UDS_ATP |AccessTimingParameter
UDS_ATPPR |AccessTimingParameterPositiveResponse
UDS_AUTH |Authentication
UDS_AUTHPR |AuthenticationPositiveResponse
UDS_CC |CommunicationControl
UDS_CCPR |CommunicationControlPositiveResponse
UDS_CDTCI |ClearDiagnosticInformation
UDS_CDTCIPR |ClearDiagnosticInformationPositiveResponse
UDS_CDTCS |ControlDTCSetting
UDS_CDTCSPR |ControlDTCSettingPositiveResponse
UDS_DDDI |DynamicallyDefineDataIdentifier
UDS_DDDIPR |DynamicallyDefineDataIdentifierPositiveResponse
UDS_DSC |DiagnosticSessionControl
UDS_DSCPR |DiagnosticSessionControlPositiveResponse
UDS_ER |ECUReset
UDS_ERPR |ECUResetPositiveResponse
UDS_IOCBI |InputOutputControlByIdentifier
UDS_IOCBIPR |InputOutputControlByIdentifierPositiveResponse
UDS_LC |LinkControl
UDS_LCPR |LinkControlPositiveResponse
UDS_NR |NegativeResponse
UDS_RC |RoutineControl
UDS_RCPR |RoutineControlPositiveResponse
UDS_RD |RequestDownload
UDS_RDBI |ReadDataByIdentifier
UDS_RDBIPR |ReadDataByIdentifierPositiveResponse
UDS_RDBPI |ReadDataByPeriodicIdentifier
UDS_RDBPIPR |ReadDataByPeriodicIdentifierPositiveResponse
UDS_RDPR |RequestDownloadPositiveResponse
UDS_RDTCI |ReadDTCInformation
UDS_RDTCIPR |ReadDTCInformationPositiveResponse
UDS_RFT |RequestFileTransfer
UDS_RFTPR |RequestFileTransferPositiveResponse
UDS_RMBA |ReadMemoryByAddress
UDS_RMBAPR |ReadMemoryByAddressPositiveResponse
UDS_ROE |ResponseOnEvent
UDS_ROEPR |ResponseOnEventPositiveResponse
UDS_RSDBI |ReadScalingDataByIdentifier
UDS_RSDBIPR |ReadScalingDataByIdentifierPositiveResponse
UDS_RTE |RequestTransferExit
UDS_RTEPR |RequestTransferExitPositiveResponse
UDS_RU |RequestUpload
UDS_RUPR |RequestUploadPositiveResponse
UDS_SA |SecurityAccess
UDS_SAPR |SecurityAccessPositiveResponse
UDS_SDT |SecuredDataTransmission
UDS_SDTPR |SecuredDataTransmissionPositiveResponse
UDS_TD |TransferData
UDS_TDPR |TransferDataPositiveResponse
UDS_TP |TesterPresent
UDS_TPPR |TesterPresentPositiveResponse
UDS_WDBI |WriteDataByIdentifier
UDS_WDBIPR |WriteDataByIdentifierPositiveResponse
UDS_WMBA |WriteMemoryByAddress
UDS_WMBAPR |WriteMemoryByAddressPositiveResponse
Get all fields of a packet
ls(UDS_RC)
routineControlType : ByteEnumField = ('0')
routineIdentifier : XShortEnumField = ('0')
Tester present sender
tps = UDS_TesterPresentSender(sock)
tps.start()
print("Do whatever you need to do")
tps.stop()
Security Access Seed
Security Access Key