Skip to content

Latest commit

 

History

History
185 lines (157 loc) · 22.2 KB

README.md

File metadata and controls

185 lines (157 loc) · 22.2 KB

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.

Supported PLC Datentyp PLC Kategorie PLC Info Netzwerk Datentyp .Net Datentyp PlcTag Sonstiges
AOM_IDENT Hardwaredatentypen ValueDWord PlcTagDWord -> uint
Any Zeiger Parameter ValueUSIntArray[10] byte[10]
Array[n..m] Zugriff auf Einzelelemente direkt möglich
Block_FB Parametertypen Parameter ValueUInt PlcTagUInt -> ushort
Block_FC Parametertypen Parameter ValueUInt PlcTagUInt -> ushort
Bool Binärzahlen ValueBool bool
Byte Bitfolgen ValueByte byte
CONN_ANY Hardwaredatentypen ValueWord PlcTagWord -> ushort
CONN_OUC Hardwaredatentypen ValueWord PlcTagWord -> ushort
CONN_PRG Hardwaredatentypen ValueWord PlcTagWord -> ushort
CONN_R_ID Hardwaredatentypen ValueDWord PlcTagDWord -> uint
CREF Systemdatentypen ValueStruct / packed Zugriff auf Einzelelemente direkt möglich
Char Zeichenfolgen ValueUSInt char Encoding Voreinstellung ISO-8859-1 für non-ASCII
Counter Parametertypen Parameter ValueUInt PlcTagUInt -> ushort
Date Datum und Uhrzeit ValueUInt DateTime TODO: Nur Datum gültig!
Date_And_Time Datum und Uhrzeit ValueUSIntArray[8] DateTime
DB_ANY Hardwaredatentypen ValueUInt PlcTagUInt -> ushort
DB_DYN Hardwaredatentypen ValueUInt PlcTagUInt -> ushort
DB_WWW Hardwaredatentypen ValueUInt PlcTagUInt -> ushort
DInt Ganzzahlen ValueDInt int
DTL Datum und Uhrzeit ValueStruct / packed DateTime + uint (for ns) Nanosekunden extern, da kein .Net Typ mit ns. Experimental!
DWord Bitfolgen ValueDWord uint
EVENT_ANY Hardwaredatentypen ValueDWord PlcTagDWord -> uint
EVENT_ATT Hardwaredatentypen ValueDWord PlcTagDWord -> uint
EVENT_HWINT Hardwaredatentypen ValueDWord PlcTagDWord -> uint
ErrorStruct ValueStruct / packed Zugriff auf Einzelelemente direkt möglich
HW_ANY Hardwaredatentypen ValueWord
HW_DEVICE Hardwaredatentypen ValueWord PlcTagWord -> ushort
HW_DPMASTER Hardwaredatentypen ValueWord PlcTagWord -> ushort
HW_DPSLAVE Hardwaredatentypen ValueWord PlcTagWord -> ushort
HW_HSC Hardwaredatentypen ValueWord PlcTagWord -> ushort
HW_IEPORT Hardwaredatentypen ValueWord PlcTagWord -> ushort
HW_INTERFACE Hardwaredatentypen ValueWord PlcTagWord -> ushort
HW_IO Hardwaredatentypen ValueWord PlcTagWord -> ushort
HW_IOSYSTEM Hardwaredatentypen ValueWord PlcTagWord -> ushort
HW_MODULE Hardwaredatentypen ValueWord PlcTagWord -> ushort
HW_PTO Hardwaredatentypen ValueWord PlcTagWord -> ushort
HW_PWM Hardwaredatentypen ValueWord PlcTagWord -> ushort
HW_SUBMODULE Hardwaredatentypen ValueWord PlcTagWord -> ushort
IEC_COUNTER Systemdatentypen ValueStruct / packed 33554462, Zugriff auf Einzelelemente direkt möglich
IEC_DCOUNTER Systemdatentypen ValueStruct / packed Zugriff auf Einzelelemente direkt möglich
IEC_LCOUNTER Systemdatentypen ValueStruct / packed Zugriff auf Einzelelemente direkt möglich
IEC_LTIMER Systemdatentypen ValueStruct / packed Zugriff auf Einzelelemente direkt möglich
IEC_SCOUNTER Systemdatentypen ValueStruct / packed Zugriff auf Einzelelemente direkt möglich
IEC_TIMER Systemdatentypen ValueStruct / packed 33554463, Zugriff auf Einzelelemente direkt möglich
IEC_UCOUNTER Systemdatentypen ValueStruct / packed Zugriff auf Einzelelemente direkt möglich
IEC_UDCOUNTER Systemdatentypen ValueStruct / packed Zugriff auf Einzelelemente direkt möglich
IEC_ULCOUNTER Systemdatentypen ValueStruct / packed Zugriff auf Einzelelemente direkt möglich
IEC_USCOUNTER Systemdatentypen ValueStruct / packed Zugriff auf Einzelelemente direkt möglich
Int Ganzzahlen ValueInt short
LDT Datum und Uhrzeit ValueTimestamp ulong
LInt Ganzzahlen ValueLInt long
LReal Gleitpunktzahlen ValueLReal double
LTime Zeiten ValueTimespan long Anzahl ns
LTime_Of_Day (LTOD) Datum und Uhrzeit ValueULInt ulong Anzahl ns seit 00:00:00 Uhr
LWord Bitfolgen ValueLWord ulong
NREF Systemdatentypen ValueStruct / packed Zugriff auf Einzelelemente direkt möglich
OB_ANY Hardwaredatentypen ValueInt PlcTagInt -> short
OB_ATT Hardwaredatentypen ValueInt PlcTagInt -> short
OB_CYCLIC Hardwaredatentypen ValueInt PlcTagInt -> short
OB_DELAY Hardwaredatentypen ValueInt PlcTagInt -> short
OB_DIAG Hardwaredatentypen ValueInt PlcTagInt -> short
OB_HWINT Hardwaredatentypen ValueInt PlcTagInt -> short
OB_PCYCLE Hardwaredatentypen ValueInt PlcTagInt -> short
OB_STARTUP Hardwaredatentypen ValueInt PlcTagInt -> short
OB_TIMEERROR Hardwaredatentypen ValueInt PlcTagInt -> short
OB_TOD Hardwaredatentypen ValueInt PlcTagInt -> short
PIP Hardwaredatentypen ValueUInt PlcTagUInt -> ushort
Pointer Zeiger Parameter ValueUSIntArray[6] byte[6]
PORT Hardwaredatentypen ValueUInt PlcTagUInt -> ushort
RTM Hardwaredatentypen ValueUInt PlcTagUInt -> ushort
Real Gleitpunktzahlen ValueReal float
Remote Zeiger Parameter ValueUSIntArray[10] PlcTagAny -> byte[10] Identisch zu Any-Pointer
S5Time Zeiten ValueWord ushort, ushort TODO: TimeBase, TimeValue. Vereinheitlichen?
SInt Ganzzahlen ValueSInt sbyte
String Zeichenfolgen ValueUSIntArray[stringlen + 2] string Encoding Voreinstellung ISO-8859-1 für non-ASCII
Struct Zugriff auf Einzelelemente direkt möglich
Time Zeiten ValueDInt int Anzahl ms mit Vorzeichen
Time_Of_Day (TOD) Datum und Uhrzeit ValueUDInt uint Anzahl ms seit 00:00:00 Uhr
Timer Parametertypen Parameter ValueUInt PlcTagUInt -> ushort
UDInt Ganzzahlen ValueUDInt uint
UInt Ganzzahlen ValueUInt ushort
ULInt Ganzzahlen ValueULInt ulong
USInt Ganzzahlen ValueUSInt byte
Variant Zeiger Parameter Erhält keine Adresse
WChar Zeichenfolgen ValueUInt char
WString Zeichenfolgen ValueUIntArray[stringlen + 2] string
Word Bitfolgen ValueWord ushort

Lizenz

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

Authors