Step 7 840D sl - NCU-Variablen / Wireshark S7Comm-Protokolll

Biiebs

Level-2
Beiträge
40
Reaktionspunkte
12
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Community,

kurz zur Einleitung… Ich schreibe zurzeit meine Masterarbeit an einer Uni im Themenbereich von CNC-Steuerungen. Ein kleiner Teil der Arbeit beschäftigt sich mit Wireshark und ein bisschen mit „Reverse Engineering“ des S7Comm-Protokolls für CNC-Maschinen.

Als Testexemplar dient hierbei eine Sinunerik 840D sl mit einer Bedieneinheit und einer zusätzlichen PCU 50.3.

Durch die Forumssuche bin ich schon auf sehr interessante Beiträge hinsichtlich des aktuell standardmäßig implementiert Wireshark - S7Comm-Dissectors sowie auf das Auslesen von Variablen in der NCU gestoßen. Erstmal Vielen Dank an die Leute die sich über Jahre mit den genannten Forumsbeiträgen beschäftigt haben…. Eine absolute Spitzenarbeit – Respekt! ;).

Diese Forumsbeiträge waren für meine Masterarbeit schon eine sehr große Hilfe – Vielen Dank!. Jedoch bin ich mittlerweile an einem Punkt wo ich mich etwas im „Kreis drehe“.
Ich hoffe doch, dass ihr mir diesbezüglich etwas bei den nachfolgenden Fragen weiterhelfen könnt.

Allgemein:

1) TCP-Protokoll:

Nur zum Verständnis:
Das TCP-Protokoll ist datenstromorientiert, d.h. ein kontinuierlicher Strom von einzelnen Paketen ohne eindeutigen Anfang und Ende wird zwischen den einzelnen Geräten hin und hergeschickt.
Um diese Pakete abgrenzen zu können existiert eine Sequenznummer + eine entsprechende ACK-Nummer. Nach Senden einer Anfrage des Clients bestätigt der Server dies mit einer ACK-Nachricht

Nun zur eigentlichen Frage im TCP-Protokoll:
Wenn ich dieses Prinzip (Seq-Nr -> Ack-Nr (+ nächste Seq-Nr.) -> Seq-Nr -> …) in Wireshark verfolge lässt sich auch bedingt darauf zurückschließen.
Jedoch sobald 2 hintereinander folgende Userdatas (Userdata -> Cyclic data -> Memory) geschickt werden lässt sich dieses Prinzip nicht mehr nachvollziehen. Eine Userdata lässt sich entsprechend noch zuordnen, jedoch die Sequenznummer der 2. Userdata ist komplett unterschiedlich (hierzu sollte noch gesagt werden das beide Userdatas die gleiche IP besitzen, jedoch untersch. Ports).
Wieso fällt eine Userdata aus diesem Schema heraus, hätte hierzu jemand eine vorläufige Erklärung? (Screenshots kann ich bei Bedarf erst am Montag hochladen)

S7Comm

2) Userdata:

Jede Userdata enthält verschiedene Items mit Datenpaketen, lassen sich jeweiligen Items auf die „zuvor stattgefundenen Jobs“ wieder zuordnen?
Der Client stellt an den Server eine Anfrage und dieser Bestätigt den Erhalt der Anfrage mit einer ACK-Data (Je nach Modi Read/Write) beinhaltet sie ja schon entsprechende Daten.
Welche Daten beinhaltet dann eigentlich die Items in Userdata-Cyclic? (Erst hier sollten doch die Werte beinhaltet sein, da die CNC diese Anfrage erst hier bearbeitet oder?). Jedoch passt hierzu die Anzahl der Items in den zuvor gestellten „Jobanfragen“ nicht mit der Anzahl der Items in der Userdata überein.
Mit fehlt da noch eine bisschen das Verständnis dahinter wie diese Userdata aufgebaut ist und was sie wirklich beinhaltet, vllt. hat jemand einen Tipp für mich?

3) NCK-Variablen

Gibt es auch eine Möglichkeit die Zuordnung der einzelnen NCK-Variablen an die jeweiligen physikalischen Adressen ohne den NC-Var-Selektor zu tätigen?

4) Octet-String

Der Octet-String ist eigentlich eine ganz normale String-Variable nur mit Vorgabe der jeweiligen Länge oder?
Über Wireshark wird je nach Variablen ein Octet String zurückgeliefert. Diese variable Länge unterscheidet sich zwischen 36-222 Zeichen. Gibt es hierzu eine Möglichkeit diesen Octet-String in seine beinhalteten Informationen zu zerlegen? Ich denke bei einem Octet String mit 222 Zeichen werden mehrere Informationen übertragen, die in der CNC selektiert werden… Oder was fängt eine CNC mit einer Zeichenkette mit 222 Zeichen an?



Ich würde mich über eure Mithilfe sehr freuen und hoffe mit dem Beitrag doch noch die ein oder andere hilfreiche Erkenntnis mit euch teilen zu dürfen.

Vielen Dank erstmal.

Gruß

Biiebs


 
TCP ist zwar datenstromorientiert, aber das S7-Protokoll verwendet bei TCP als Transportschicht zusätzlich ISO-On-TCP nach RFC1006.
Durch diesen Zusatz wird es dann wieder paketorientiert, d.h. ein Paket enthält im Kopf die Längenangabe der Nutzlast welche übertragen wird.
In Wireshark sind das die Baumelemente "TPKT" und "ISO 8073" welche beide zu ISO-on-TCP gehören. Die Nutzlast von ISO-On-TCP ist dann das S7-Protokoll.

Das S7-Protokoll ist nicht auf TCP beschränkt, es kann auch auf diversen anderen Schichten verwendet werden, wie RS485 mit MPI oder Profibus, oder auch auf Ethernet aber ohne TCP und ohne IP. Zumindest bei S7 SPS existieren diese Varianten.

Für die Zugehörigkeit von Anfrage und Antwort im S7-Protokoll gibt es im Kopf das Feld "Protocol Data Unit Reference".
Es besteht die Möglichkeit, mehrere Anfragen abzuschicken ohne auf die Antwort zu warten. Die mögliche maximale Anzahl solcher Pakete wird beim Verbindungsaufbau "Setup Communikation" ausgehandelt. Das sind die beiden Werte für "Max AmQ calling" und "Max AmQ called". Dann muss der Anfrager für jede Anfrage eine eindeutige "Protocol Data Unit Reference" angeben, und kann dann anhand der Nummer in der Antwort feststellen, zu welcher Anfrage die Antwort gehört.

Dieses Prinzip der Zuordnung wird für alle Funktionen immer verwendet. Bei manchen Varianten kommen aber noch weitere Mechanismen und Felder hinzu.

Zu der "Userdata" Bezeichnung muss ich vielleicht noch kurz was schreiben.
Als Anfang für den Wireshark-Dissector habe ich die Informationen aus libnodave verwendet, und dort wurden diese Telegrammtypen als Userdata bezeichnet. Bei einer S7 sind das aber hauptsächlich Bausteindienste (Programmup-/download, Diagnosen etc.) und das andere sind Variablendienste (d.h. Lesen und Schreiben von Variablen). Wobei sich das bei zyklischen Lesediensten auch wieder überschneidet, denn diese werden als "Userdata" abgewickelt. Da mir noch nichts besseres eingefallen ist, heißt es immer noch "Userdata". Letztenendes ist das aber alles außer den Variablendiensten.

Bei den zyklischen Lesediensten wird die Zugehörigkeit zur Anfrage über das Feld "Data unit reference number" im Parameterteil hergestellt. Wenn Variablen dafür bei der SPS angemeldet werden, dann gibt es in der ersten Antwort von der SPS dieses Feld mit einem Wert. Diesen muss sich der Antragsteller merken, und kann daran die Zugehörigkeit der Antwort zu seiner Anfrage herstellen.

Zu deiner Frage nach dem Aufbau verstehe ich gerade nicht was du genau meinst. Vielleicht kannst du ja eine entsprechende Wireshark-Aufzeichnung mit Angabe einer Frame-Nummer dessen Aufbau dich interessiert hier anhängen.

Ein Octet-String ist eine Aneinanderkettung (String) von 8-Bit Bytes. Das hat mit Strings in Form von Text nichts zu tun. Das ist bei Netzwerkprotokollen ein verbreitete Bezeichnung.

Zu deinen NCK Fragen kann ich dir nicht groß weiterhelfen, weil ich selber mit diesen Geräten nicht arbeite und ich nicht einmal weiß was ein NC-Var Selektor ist.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Thomas,

Vielen Dank für diese ausführliche Informationen, dies hilft mir aufjedenfall schonmal das Verständnis des Protokolls "etwas näher" zu Verstehen. (Ich hab mich darin erst seit kurzem eingearbeitet und Versuche solangsam dieses Protokoll zu Verstehen :).... Da ihr aber Jahrelang daran gearbeitet habt bin ich mit meinem Kenntnissstand noch lange nicht soweit :)).

Ich werde die Informationen am Montag aufjedenfall mal ausarbeiten und mich nochmals mit einem entsprechenden Wireshark Mitschnitt melden (um den Part mit der Userdata nochmals Kenntlich zu machen), da ich erst am Montag wieder Zugriff darauf hab.
 
Hallo Thomas,

ich habe den letzten Post mittlerweile ausgearbeitet, auch dieser hat mich ein Stückchen weitergebracht, Vielen Dank erstmal. Die Seite von dem Link ist mir bereits bekannt und war für die SPS-Seite eine sehr große Hilfe.

Mir ist jedoch noch nicht ganz klar die Bedeutung hinter der Data Unit Reference Nummerer…
Ist dies eine von der SPS-Seite inkrementierende Nummer oder existiert auch eine gewisse Bedeutung hinter der Nummernvergabe? In meinem Beispiel wird der Wert erstmal hochgezählt mit 1,2,3 ein anderes Mal wird der Wert dekrementiert und wiederum existiert irgendwann der Wert 40. Sollte die Data Unit Reference Nummer nicht eine fortlaufende Nummer sein? Oder was bewirkt die Rücksetzung der Nummer auf den Wert 0?

Zur Userdata: Die Unterscheidung der einzelnen Telegrammtypen ist mir mittlerweile auch klar, was mir jedoch noch nicht ganz klar ist, ist das Beinhalten der einzelnen Informationen zwischen der Read/Ack_Data.
Bei Anfrage eines "Read-Jobs“ enthält die dazugehörige ACK_Data ja den aktuellen Wert der Adresse oder? Aber was wird wiederum in der Funktion „Userdata -> Push-Undef -> Cyclic data -> Memory“ mitgeliefert? Sollte dort nicht auch der aktuelle Wert der Job-Anfrage beinhaltet sein?
Desweiteren lässt sich die Userdata, an keine Adresse oder Anfrage zuordnen, da weder eine zugehörige Reference Nummer noch eine Adressierung vorhanden ist. Lassen sich die entsprechenden Werte aus den einzelnen Items zu den zugehörigen Adressen der Jobanfrage zuordnen?
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hast du mal eine konkrete Wireshark-Aufzeichnung? Denn gerade bei den NC-Funktionen existieren ein paar Besonderheiten und Funktionen die es bei einer SPS so nicht gibt.
Was in Wireshark als "Cyclic data" erkannt wird, das wird bei einer SPS zumindest soweit ich das bisher gesehen habe wirklich immer für zyklische Variablendienste verwendet.

Bei einer SPS funktionieren diese Dienste so, dass der Client einmal bestimmte Variablen bei der SPS zum Lesen in einem bestimmten Intervall anmeldet, und diese schickt diese dann automatisch an den Client ohne dass dazu eine weitere Aufforderung notwendig ist (Push). Dort geschieht die Zuordnung meines Wissens nach über die "Data unit reference number" welche von der SPS nach Bestätigung der Anmeldung vergeben wird.

Dann habe ich Aufzeichnungen von der Kommunikation zu einer 840d bekommen, und dort lassen sich auch Variablen über die Funktionen "Userdata"/ "Cyclic data" lesen. Hier ist der Parameterteil nur 8 Bytes groß und dort gibt es keine "Data unit reference number", ohne es zu wissen muss dort die Zuordnung von Anfrage zu Antwort wieder über die "Protocol data unit reference" im Header geschehen. Das ist die einzige Möglichkeit die bleibt und bei den Aufzeichnungen einer 840d die ich vorliegen habe, passt das auch.

Auf jeden Fall fällt die NC-Kommunikation etwas aus dem Rahmen und mag in Wireshark auch nicht überall zu 100% korrekt von mir interpretiert werden, weil ich so etwas noch nie zum Testen verfügbar hatte. Aber anhand der Tatsache, dass mit dem Wissen daraus ein funktionierender Treiber geschrieben werden konnte, würde ich sagen ist es nicht ganz falsch.

Apropos falsch: Ich sehe gerade, dass ich in dem Wireshark Dissector einen kleinen Fehler eingebaut habe der vorher nicht da war. Das Parameter-Feld "Method" schaut nicht auf das richtige Byte, darum steht dort auch "Undef". Wenn es korrekterweise auf das Byte nach der Parameter-Länge schauen würde, dann hättest du dort bei einem Push nochmal ein "Req" (für Request 0x11) oder "Res" (für Response 0x12).
 
Ich werde morgen nochmals genauer über die Aufzeichnungen drüber schauen und diese vor allem im Punkt der "Cyclic-Data" genauer analysieren, da ich diese nur auf meinem Arbeitsrechner zur Verfügung habe.

Ich habe durch Beispielaufzeichnungen von Wireshark gesehen, dass bei der SPS-Kommunikation, wie du oben geschrieben hast erst eine Anfrage vom Client gestellt wird und diese durch die SPS beantwortet wird. Dies trifft bei der CNC aber nicht ganz zu, da diese ohne jegliche Anfragen vom Client zyklische Daten sendet. Die beinhalteten Datenpakete lassen sich auch, weder über eine Adresse noch über die "Protocol Data Unit Reference"-Nummer zuordnen. Die beinhaltete Anzahl der Itempakete stimmt nicht mit den zuvor gestellten Anfragen des Clients überein. Desweiteren lässt sich die "PDUR"-Nummer keiner Anfrage zuordnen.

Zuerst einmal, dadurch dass du den Wireshark-Dissector in Richtung der CNC nur mit Wissen aufgebaut hast funktioniert dieser 1A... Hut ab ;)

Zu deinem Punkt mit dem Parameterfeld "undef", dies hat mich auch schon etwas verwundert, aber das Problem wurde ja nun gelöst :). Wird es hierzu in nächster Zeit einen Patch geben? Oder könntest du mir eine aktuelle Version des Dissectors zukommen lassen (Oder lässt sich der Bug in der .dll fixen, wenn ja in welcher Zeile müsst ich denn etwas verändern?)
 
Wir können ja eine Aufzeichnung aus diesem Thread verwenden:
https://www.sps-forum.de/hochsprachen-opc/87089-siemens-840dsl-alarme-auslesen-2.html#post655147

Im dort angehängten rar-Archiv ist eine Datei "HMI-Hochlauf_filter.pcapng" bei der in Frame#25 und #28 NC-Variablen über "Userdata"-Telegramme gelesen werden.
Diese beiden werden abgesendet bevor auf eine Antwort gewartet wird, in Frame#20 siehst du die Antwort der NC vom Verbindungsaufbau, welche sogar 12 davon erlauben würde.
Frame#25 besitzt die "Protocol data unit reference" pduref=3 und Frame#28 besitzt die pduref=2. Diese pduref-Nummern findest du auch in den Antworten in Frame #35 und #36 wieder, die Anzahl der Items stimmt ebenfalls mit der angefragten Anzahl überein.

Warum manche Variablen bei der NC über die normalen Variablendienste wie in Frame #30 gelesen werden, und manche wie oben beschrieben über "Userdata" kann ich dir nicht sagen. Vielleicht hat das etwas mit der Erreichbarkeit zu tun. Wenn ich so ein Gerät zur Verfügung hätte, dann würde ich es ganz einfach austesten ob und wann welche Variante möglich ist.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich werde morgen nochmals genauer über die Aufzeichnungen drüber schauen und diese vor allem im Punkt der "Cyclic-Data" genauer analysieren, da ich diese nur auf meinem Arbeitsrechner zur Verfügung habe.

Ich habe durch Beispielaufzeichnungen von Wireshark gesehen, dass bei der SPS-Kommunikation, wie du oben geschrieben hast erst eine Anfrage vom Client gestellt wird und diese durch die SPS beantwortet wird. Dies trifft bei der CNC aber nicht ganz zu, da diese ohne jegliche Anfragen vom Client zyklische Daten sendet. Die beinhalteten Datenpakete lassen sich auch, weder über eine Adresse noch über die "Protocol Data Unit Reference"-Nummer zuordnen. Die beinhaltete Anzahl der Itempakete stimmt nicht mit den zuvor gestellten Anfragen des Clients überein. Desweiteren lässt sich die "PDUR"-Nummer keiner Anfrage zuordnen.

Zuerst einmal, dadurch dass du den Wireshark-Dissector in Richtung der CNC nur mit Wissen aufgebaut hast funktioniert dieser 1A... Hut ab ;)

Zu deinem Punkt mit dem Parameterfeld "undef", dies hat mich auch schon etwas verwundert, aber das Problem wurde ja nun gelöst :). Wird es hierzu in nächster Zeit einen Patch geben? Oder könntest du mir eine aktuelle Version des Dissectors zukommen lassen (Oder lässt sich der Bug in der .dll fixen, wenn ja in welcher Zeile müsst ich denn etwas verändern?)


Ich würde mich auch sehr freuen wenn ich die aktuelle Version des Dissectors zugeschickt bekommen kann :)
 
Zu deinem Punkt mit dem Parameterfeld "undef", dies hat mich auch schon etwas verwundert, aber das Problem wurde ja nun gelöst :). Wird es hierzu in nächster Zeit einen Patch geben? Oder könntest du mir eine aktuelle Version des Dissectors zukommen lassen (Oder lässt sich der Bug in der .dll fixen, wenn ja in welcher Zeile müsst ich denn etwas verändern?)

Also die dll für s7comm benötigst du gar nicht mehr weil das schon seit ein paar Jahren direkt in Wireshark eingebaut ist. Die s7comm.dll von Sourceforge wird unter einer aktuellen Wireshark Version auch gar nicht mehr funktionieren. Für das s7comm-plus Protokoll für die 1200/1500er wird aber weiterhin die dll von Sourceforge benötigt, wenn einen das interessieren sollte.

Ich habe den Patch eingereicht (https://code.wireshark.org/review/#/c/30905/), das dauert aber in der Woche u.U. ein paar Tage bis das durchs Review geht, und dann gibt es automated Builds die du bei Wireshark herunterladen kannst (https://www.wireshark.org/download/automated/) in denen das dann eingebaut ist. Das ist aber dann "bleeding edge" obwohl ich bisher noch keine Version hatte die überhaupt nicht funktioniert. Bis zu einem offiziellen Release wird es noch etwas dauern, gab ja vor ein paar Tagen erst die 2.6.5.
 
Thomas,

ich hab mir die Aufzeichnungen eben mal angeschaut, genau diese Aufzeichnungen ähneln meinen Aufzeichnungen.

Nun ist meine Frage...

Wenn ich das Paket (35) nehme mit dem "Push -> cyclic Data -> Memory". Dies hat zwar eine Einheitliche "PDUR"-Nummer lässt sich diese Nummer jedoch zu irgendeiner Anfrage zuordnen?

In diesem Fall hat die PDUR den Wert "3" -> Es folgen daraufhin zwar noch mehrere Requ / Resp vom Client und der SPS, aber kann man diese Anfragen irgendwie in Verbindung mit der "Push"-Data bringen oder ist dies ein komplett unabhängiger Response von der CNC von allen anderen Requests? Existiert hierzu überhaupt eine Zuordnung? Diese beinhaltet ja nur ein einziges Item ohne jeglichen Adresszusatz, einzigst allein nur ein einfaches "Success" und ein mitgelieferter Informationsgehalt in der Data.
Teilausschnitt.png
Das wär somit auch meine Frage von oben, nochmal mit einer Aufzeichnung erklärt
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn du im Detailfenster den Baum aufklappst, dann siehst du die Details. Wenn du zu einer Antwort die Anfrage suchst, dann kannst du auch einen entsprechenden Filter setzen (z.B. s7comm.header.pduref == 3). Wenn die Anfrage mit aufgezeichnet wurde, dann sollte der Frame davor die gesuchte Anfrage sein.

Wobei hier bei der Anfrage im speziellen noch eine Besonderheit zu sein scheint, deren Logik ich mir nicht erklären kann. In Frame#38 werden anscheinend Alarme ausgelesen, was User Hans im anderen Thread auch erwähnte. Der Datensatz scheint aber nicht in eine PDU zu passen, und da gibt es nur in der ersten Antwort eine entsprechenden pduref=4, und alle folgenden erhalten die pduref=0. Eigentlich gäbe es für den Fall im Parameterteil das Feld "Last data unit" mit dem sich große Datensätze über mehrere PDUs verteilen lassen, das wird beispielsweise bei SZL-Datensätzen so gelöst (SPS Diagnosepuffer auslesen). Eigentlich gäbe es die Fragmentierungs-Option auch noch auf dem ISO-Layer, diese ist mir aber noch nie über den Weg gelaufen außer bei Keep-Alive Telegrammen.

Wenn du einen Protokolltreiber schreiben willst der diese Funktion unterstützen soll, dann musst du solche Dinge am realen Gerät austesten um zu sehen wie das im Detail funktioniert. Wireshark ist da nur eine Hilfe zum generellen Aufbau, aber zeigt nicht wie es im Detail funktioniert.
 

Anhänge

  • s7comm-nc.jpg
    s7comm-nc.jpg
    91,3 KB · Aufrufe: 22
Zurück
Oben