Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

170 Commits

Repository files navigation

S7commPlusDriver

Kommunikationstreiber für den Datenaustausch mit S7-1200/1500 Steuerungen.

Entwicklungsstand

Dies ist aktuell ein Entwicklungsstand und nicht für den Produktiveinsatz vorgesehen.

Ziel ist es, einen Kommunikationstreiber zu entwickeln, welcher den Zugriff auf den Variablenhaushalt von S7 1200/1500 Steuerungen über den symbolischen Zugriff auf sogenannte "optimierte" Bereiche erlaubt.

Diese Implementierung ist vollständig in C# verfasst. Für die TLS-Verschlüsselung wird die OpenSSL-Bibliothek verwendet.

Systemvorraussetzungen

CPU

Der Kommunikationstreiber unterstützt ausschließlich CPUs mit einer Firmware welche die sichere Kommunikation über das TLS-Protokoll erlaubt. Das wären nach aktuellem Wissensstand

  • S7 1200 mit einer Firmware >= V4.3 (TLS 1.3 ab V4.5)
  • S7 1500 mit einer Firmware >= V2.9

Wichtig ist dabei, dass nicht nur nur eine CPU mit entsprechender Firmware vorhanden ist, sondern auch in der Entwicklungsumgebung mit der ensprechenden Version projektiert wurde. Das ist nur mit einer TIA-Portal Version >= V17 möglich.

OpenSSL

Für die TLS-Kommunikation wird OpenSSL verwendet. Ist OpenSSL in der entsprechenden Version installiert, dann sollte ein entsprechender Systempfad zum Installationsverzeichnis eingetragen sein. Die notwendigen dlls sind aber auch im Projekt abgelegt, und werden im Buildprozess in der notwendigen Version (x86 oder x64) in das Ausgabeverzeichnis kopiert. Die notwendigen dlls mit Dateinamen je nach verwendetem Betriebssystem:

Für 32 Bit (x86):

  • libcrypto-3.dll
  • libssl-3.dll

Für 64 Bit (x64):

  • libcrypto-3-x64.dll
  • libssl-3-x64.dll

Getestete Kommunikation

Mit folgenden Geräten wurde bisher erfolgreich getestet:

  • S7 1211 mit Firmware V4.5
  • TIA Plcsim V17 (mit Nettoplcsim)
  • TIA Plcsim V18 (mit Nettoplcsim)

Analyse mit Wireshark

Aufgrund der Verschlüsselung können die übertragenen Daten ohne weitere Informationen mit Wireshark nicht mehr eingesehen werden. Zur Treiberentwicklung ist im Projekt eine Funktion integriert, welche die ausgehandelten Secrets in eine Textdatei (key_YYYYMMDD_hhmmss.log) ausgibt. Mit diesen Informationen ist es Wireshark möglich die Kommunikation zu entschlüsseln und darzustellen. Wichtig ist dabei, dass die Aufzeichnung den TLS-Verbindungsaufbau enthalten muss!

Um Wireshark diese Information verfügbar zu machen, existieren zwei Möglichkeiten:

  1. Die Log-Datei in ein Verzeichnis abzulegen und Wireshark dieses bekannt zu machen. Dazu in Wireshark MenüEinstellungen aufrufen. Unter Protocols den Punkt TLS anwählen, und im Feld (Pre)-Master-Secret log filename die entsprechende Datei auswählen
  2. Die Secrets direkt in die Wireshark-Aufzeichnung integrieren

Zur Weitergabe an andere Personen zur Analyse, ist Punkt 2 zu bevorzugen, da alles notwendige in einer Aufzeichnung vorhanden ist. Die Integration geschieht über das Programm "editcap.exe" im Wireshark Installationsverzeichnis. Dazu muss eine Aufzeichnung in Wireshark mit der Endung .pcapng gespeichert werden.

Über die Eingabeaufforderung werden mit folgender Anweisung in die Aufzeichnung "test-capture.pcapng" die Secrets aus "key.log" integriert, und in der Datei "test-capture-with-keys.pcapng" gespeichert. Wird letztere Datei dann in Wireshark geöffnet, kann die Kommunikation dort entschlüsselt, dekodiert und dem Protokoll entsprechend dargestellt werden. Die key.log kann bei Bedarf anschließend gelöscht werden.

"C:\Program Files\Wireshark\editcap.exe" --inject-secrets tls,key.log test-capture.pcapng test-capture-with-keys.pcapng

Zur Vereinfachung habe ich ein kleines Hilfsprogramm mit einer grafischen Oberfläche geschrieben, auf das die Dateien per Drag&Drop gezogen werden können, und das auf Tastendruck editcap aufruft. Das Programm ist hier verfügbar:

https://github.com/thomas-v2/PcapKeyInjector

Damit Wireshark das S7comm-Plus Protokoll dekodieren kann, ist die entsprechende dll in das Wireshark Installationsverzeichnis abzulegen. Näheres dazu, und Download der dll bei Sourceforge unter:

https://sourceforge.net/projects/s7commwireshark/

PlcTag-Klasse: Umsetzung der SPS Datentypen in PlcTags

Bei einigen Datentypen ist es notwendig, zur Verarbeitung der Antwort der SPS den Typ vorab zu kennen, um ihn in ein sinnvollen Datentyp in .Net zu konvertieren. Dazu wird die PlcTag Klasse bereitgestellt.

In der Tabelle sind alle in der SPS zur Zeit (TIA V18) möglichen Datentypen aufgeführt, mit dem Datentyp in dem sie auf dem Netzwerk im S7comm-Plus-Protokoll übertragen werden, sowie welchen .Net Datentyp in den PlcTag-Klassen daraus resultiert.

SupportedPLC DatentypPLC KategoriePLC InfoNetzwerk Datentyp.Net Datentyp PlcTagSonstiges
AOM_IDENTHardwaredatentypenValueDWordPlcTagDWord -> uint
AnyZeigerParameterValueUSIntArray[10]byte[10]
Array[n..m]Zugriff auf Einzelelemente direkt möglich
Block_FBParametertypenParameterValueUIntPlcTagUInt -> ushort
Block_FCParametertypenParameterValueUIntPlcTagUInt -> ushort
BoolBinärzahlenValueBoolbool
ByteBitfolgenValueBytebyte
CONN_ANYHardwaredatentypenValueWordPlcTagWord -> ushort
CONN_OUCHardwaredatentypenValueWordPlcTagWord -> ushort
CONN_PRGHardwaredatentypenValueWordPlcTagWord -> ushort
CONN_R_IDHardwaredatentypenValueDWordPlcTagDWord -> uint
CREFSystemdatentypenValueStruct / packedZugriff auf Einzelelemente direkt möglich
CharZeichenfolgenValueUSIntcharEncoding Voreinstellung ISO-8859-1 für non-ASCII
CounterParametertypenParameterValueUIntPlcTagUInt -> ushort
DateDatum und UhrzeitValueUIntDateTimeTODO: Nur Datum gültig!
Date_And_TimeDatum und UhrzeitValueUSIntArray[8]DateTime
DB_ANYHardwaredatentypenValueUIntPlcTagUInt -> ushort
DB_DYNHardwaredatentypenValueUIntPlcTagUInt -> ushort
DB_WWWHardwaredatentypenValueUIntPlcTagUInt -> ushort
DIntGanzzahlenValueDIntint
DTLDatum und UhrzeitValueStruct / packedDateTime + uint (for ns)Nanosekunden extern, da kein .Net Typ mit ns. Experimental!
DWordBitfolgenValueDWorduint
EVENT_ANYHardwaredatentypenValueDWordPlcTagDWord -> uint
EVENT_ATTHardwaredatentypenValueDWordPlcTagDWord -> uint
EVENT_HWINTHardwaredatentypenValueDWordPlcTagDWord -> uint
ErrorStructValueStruct / packedZugriff auf Einzelelemente direkt möglich
HW_ANYHardwaredatentypenValueWord
HW_DEVICEHardwaredatentypenValueWordPlcTagWord -> ushort
HW_DPMASTERHardwaredatentypenValueWordPlcTagWord -> ushort
HW_DPSLAVEHardwaredatentypenValueWordPlcTagWord -> ushort
HW_HSCHardwaredatentypenValueWordPlcTagWord -> ushort
HW_IEPORTHardwaredatentypenValueWordPlcTagWord -> ushort
HW_INTERFACEHardwaredatentypenValueWordPlcTagWord -> ushort
HW_IOHardwaredatentypenValueWordPlcTagWord -> ushort
HW_IOSYSTEMHardwaredatentypenValueWordPlcTagWord -> ushort
HW_MODULEHardwaredatentypenValueWordPlcTagWord -> ushort
HW_PTOHardwaredatentypenValueWordPlcTagWord -> ushort
HW_PWMHardwaredatentypenValueWordPlcTagWord -> ushort
HW_SUBMODULEHardwaredatentypenValueWordPlcTagWord -> ushort
IEC_COUNTERSystemdatentypenValueStruct / packed33554462, Zugriff auf Einzelelemente direkt möglich
IEC_DCOUNTERSystemdatentypenValueStruct / packedZugriff auf Einzelelemente direkt möglich
IEC_LCOUNTERSystemdatentypenValueStruct / packedZugriff auf Einzelelemente direkt möglich
IEC_LTIMERSystemdatentypenValueStruct / packedZugriff auf Einzelelemente direkt möglich
IEC_SCOUNTERSystemdatentypenValueStruct / packedZugriff auf Einzelelemente direkt möglich
IEC_TIMERSystemdatentypenValueStruct / packed33554463, Zugriff auf Einzelelemente direkt möglich
IEC_UCOUNTERSystemdatentypenValueStruct / packedZugriff auf Einzelelemente direkt möglich
IEC_UDCOUNTERSystemdatentypenValueStruct / packedZugriff auf Einzelelemente direkt möglich
IEC_ULCOUNTERSystemdatentypenValueStruct / packedZugriff auf Einzelelemente direkt möglich
IEC_USCOUNTERSystemdatentypenValueStruct / packedZugriff auf Einzelelemente direkt möglich
IntGanzzahlenValueIntshort
LDTDatum und UhrzeitValueTimestampulong
LIntGanzzahlenValueLIntlong
LRealGleitpunktzahlenValueLRealdouble
LTimeZeitenValueTimespanlongAnzahl ns
LTime_Of_Day (LTOD)Datum und UhrzeitValueULIntulongAnzahl ns seit 00:00:00 Uhr
LWordBitfolgenValueLWordulong
NREFSystemdatentypenValueStruct / packedZugriff auf Einzelelemente direkt möglich
OB_ANYHardwaredatentypenValueIntPlcTagInt -> short
OB_ATTHardwaredatentypenValueIntPlcTagInt -> short
OB_CYCLICHardwaredatentypenValueIntPlcTagInt -> short
OB_DELAYHardwaredatentypenValueIntPlcTagInt -> short
OB_DIAGHardwaredatentypenValueIntPlcTagInt -> short
OB_HWINTHardwaredatentypenValueIntPlcTagInt -> short
OB_PCYCLEHardwaredatentypenValueIntPlcTagInt -> short
OB_STARTUPHardwaredatentypenValueIntPlcTagInt -> short
OB_TIMEERRORHardwaredatentypenValueIntPlcTagInt -> short
OB_TODHardwaredatentypenValueIntPlcTagInt -> short
PIPHardwaredatentypenValueUIntPlcTagUInt -> ushort
PointerZeigerParameterValueUSIntArray[6]byte[6]
PORTHardwaredatentypenValueUIntPlcTagUInt -> ushort
RTMHardwaredatentypenValueUIntPlcTagUInt -> ushort
RealGleitpunktzahlenValueRealfloat
RemoteZeigerParameterValueUSIntArray[10]PlcTagAny -> byte[10]Identisch zu Any-Pointer
S5TimeZeitenValueWordushort, ushortTODO: TimeBase, TimeValue. Vereinheitlichen?
SIntGanzzahlenValueSIntsbyte
StringZeichenfolgenValueUSIntArray[stringlen + 2]stringEncoding Voreinstellung ISO-8859-1 für non-ASCII
StructZugriff auf Einzelelemente direkt möglich
TimeZeitenValueDIntintAnzahl ms mit Vorzeichen
Time_Of_Day (TOD)Datum und UhrzeitValueUDIntuintAnzahl ms seit 00:00:00 Uhr
TimerParametertypenParameterValueUIntPlcTagUInt -> ushort
UDIntGanzzahlenValueUDIntuint
UIntGanzzahlenValueUIntushort
ULIntGanzzahlenValueULIntulong
USIntGanzzahlenValueUSIntbyte
VariantZeigerParameterErhält keine Adresse
WCharZeichenfolgenValueUIntchar
WStringZeichenfolgenValueUIntArray[stringlen + 2]string
WordBitfolgenValueWordushort

Lizenz

Soweit nicht anders vermerkt, gilt für alle Quellcodes die GNU Lesser General Public License, Version 3 oder später.

Authors

About

Development of Communication Driver for Siemens S7-1200/1500 Plcs

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages