# Wireshark Plugin für S7-Protokoll



## Thomas_v2.1 (15 Juni 2009)

Hallo,
ich habe mal etwas Zeit gefunden um ein Wireshark Plugin für das S7-Protokoll zu schreiben.

Die entsprechende s7comm.dll befindet sich im Anhang.
Diese muss ich das plugin Verzeichnis von Wireshark kopiert werden. Im Normalfall ist das
_C:\Programme\Wireshark\plugins\_ 
und dann die Versionsnummer (aktuell ist _1.0.8_).

Über eine Heuristik versucht das Plugin in den Nutzdaten des überlagerten COTP (ISO 8073) Protokolls ein S7-Telegramm zu erkennen.

Das Telegramm wird dann in Header, Parameter und Data-Teil zerlegt.

Der Datenaustausch über Read-Request/Response und Write-Request/Response wird noch weiter bis hin zu den
SPS-Adressen aufgeschlüsselt. Die SPS-Adressen werden wie ein ANY-Pointer in Step 7 dargestellt (z.B. DB5.DBX0.0 BYTE 5).

Dies ist die Kommunikation die üblicherweise zwischen Visualisierung und der SPS
abläuft. Diese wird mehr oder weniger komplett aufgeschlüsselt.

Ein paar Teile konnte ich noch nicht entschlüsseln, wie:
- Header: Bytes 3,4 Reserve?
- Parameter bei "Negotioate PDU Length", Bytes 2-6


Eine große Frage stellt sich mir bei User-Data PDUs.
Da es hier eine schier unendliche Anzahl an Telegrammen zu geben scheint, habe ich es erstmal dabei
belassen nur in Header/Paramater/Data aufzusplitten.
Man könnte die bekannten Teile sicher noch in Details auflösen, aber ich weiß nicht ob das wirklich Sinn macht.
Oder es gibt dort eine Struktur die ich noch nicht erkannt habe.


Wenn jemand die Quellen haben möchte bitte PN an mich. 
Mit diesen sollte sich das Plugin auch für Wireshark unter Linux erstellen lassen (kann ich leider nicht testen, ein entsprechendes makefile
ist aber enthalten).

Gruß
Thomas


----------



## Thomas_v2.1 (15 Juni 2009)

Hüst, ich komm mit meinen VMs noch durcheinander. Im Anhang die letzte Version.


----------



## Human (15 Juni 2009)

Hi,

hab mir das mal heruntergeladen und in den Ordner C:\Programme\Wireshark\plugins\1.0.8\ kopiert.

Nach dem Starten von Wireshark bekomme ich immer die Meldung: 

```
Could'nt load module C:\Programme\Wireshark\plugins\1.0.8\s7comm.dll: Das angegebene Modul wurde nicht gefunden.
```
 
Muss ich da noch irgendwo was einstellen?


----------



## Thomas_v2.1 (15 Juni 2009)

Human schrieb:


> Hi,
> 
> hab mir das mal heruntergeladen und in den Ordner C:\Programme\Wireshark\plugins\1.0.8\ kopiert.
> 
> ...



Ja, leider :-(

Das Problem ist, dass das offizielle Wireshark Release mit VC6 erstellt  wurde, ich die dll aber mit VC2008 erstellt habe. Auf meinen  Testrechnern mit Windows 2000 funktionierte das klaglos, auf einem  XP-Rechner hatte ich aber die gleiche Meldung. 

Lösung: 
- Es muss das Redistributable Package von Microsoft installiert werden. 
http://www.microsoft.com/downloads/...34-3e03-4391-8a4d-074b9f2bc1bf&displaylang=en 
In der angehängten s7comm.dll habe ich diese Manifest Informationen  integriert. 

Damit funktioniert es. 

Vielleicht lässt sich noch jemand mit VC6 auftreiben der die dll damit  erstellt.

Dll-Hell sozusagen....


----------



## Zottel (16 Juni 2009)

Ich probiere es gerade mal aus.
Hinter den Daten erscheint folgende Fehlermeldung:
[Dissector bug, protocol S7COMM: proto.c:1378: failed assertion "hfinfo->type == FT_BYTES"]
Mein Wireshark ist möglicherweise etwas alt: Version 0.99.6a (SVN Rev 22276)


----------



## Zottel (16 Juni 2009)

Und weiter:
Ich lasse 5 "Items" lesen.  (Libnodave-Benchmark Teil 3).
Es erscheint richtig unter Parameter:
Funtion read (4)
Item count: 5
Danach wird aber nur das 1. Item aufgeführt.
In diesem werden wiederum 6 Bytes Daten aufgeführt (richtig), aber nur die ersten beiden Bytes werden im Hex-Dump markiert.


----------



## Thomas_v2.1 (16 Juni 2009)

Zottel schrieb:


> Und weiter:
> Ich lasse 5 "Items" lesen.  (Libnodave-Benchmark Teil 3).
> Es erscheint richtig unter Parameter:
> Funtion read (4)
> ...



Hallo,
meinst du mit Benchmark "testISO_TCP.exe -b"?
Das habe ich bei mir mal durchlaufen lassen (übrigens gut zum testen, habe ich garnicht dran gedacht) und bei mir sieht soweit alles OK aus. Ab Sequenz-Nr. 202 fängt der Test mit 5 Items an, und da passt es eigentlich beim Request und beim Response.

Gibts es Siemens intern einen anderen Namen für meine "Items"?


----------



## Jochen Kühner (16 Juni 2009)

*an Wireshark schicken??*

Ist es nicht möglich das Plugin direkt an die Wireshark entwickler zu schicken, so ist's beim nächsten Release gleich dabei??


----------



## Thomas_v2.1 (17 Juni 2009)

Jochen Kühner schrieb:


> Ist es nicht möglich das Plugin direkt an die Wireshark entwickler zu schicken, so ist's beim nächsten Release gleich dabei??


Da die S7-Kommunikation ja kein offenes/dokumentiertes Protokoll ist glaube ich nicht dass die sich da was von annehmen. 
In einem offiziellen Wireshark-Release sollten mMn nur wirklich 100% vollständige Protokolle vorhanden sein. 
Aber vielleicht lässt sich die Vollständigkeit bei diesem Plugin ja noch etwas erhöhen.


----------



## Thomas_v2.1 (19 Juni 2009)

So, ich konnte doch noch einen Visual C++ 6.0 Compilier auftreiben.
Jetzt lässt sich das Plugin auch ohne das Redistributable Package in der aktuellen Wireshark Version verwenden.
Also einfach die s7comm.dll in das plugin Verzeichnis kopieren und lüppt 

Zusätzlich habe ich die Userdata-Telegramme etwas weiter aufgeschlüsselt. Bei SZL Anfragen werden die angefragte ID und der Index angezeigt. Zumindest beim Request - ein Response hat eine etwas andere Struktur.

Bei der Darstellung der Daten in den Userdata war auch noch ein Fehler wie Zottel schon schrieb.

So ein paar "unbekannte" Größen sind jedoch noch vorhanden, vielleicht lassen sich diese mit der Zeit noch auflösen.

Im Anhang einmal die reine dll und die Quellen (src) zum Plugin selberbacken.


----------



## Thomas_v2.1 (4 Juli 2009)

Ich habe mal versucht in die Userdata-Telegramme eine Struktur "hineinzuinterpretieren".
Gerade diese Telegramme sind eigentlich recht interessant weil hierüber die ganzen PG-Funktionen abgewickelt werden.

Ein Request hat immer 8 Bytes Parameter-Länge, ein Response immer 12 Bytes Parameter-Länge.
Meine Beschreibung wäre soweit:

```
00 01 12 xx 1x xy xx xx .. .. .. ..
 |  |  |  |  |  |  |  |  |  |  |  |
 |  |  |  |  |  |  |  |  Sind immer Null, nur bei 12 Byte Telegrammen vorhanden
 |  |  |  |  |  |  |  xx -> Subnummer, oder fortlaufende Numerierung der Pakete?
 |  |  |  |  |  |  xx -> Sub-Funktionsnummer (abhängig von Funktionsgruppe)
 |  |  |  |  |  x=0 Folgetelegramm?, x=4 -> Request, x=8 -> Response, anscheinend immer
 |  |  |  |  |  y= Funktionsgruppe? 1=Programmier Kommandos (Force/Erase), 3=Block Funktionen, 4=SZL-Kommandos
 |  |  |  |  |  5=Security? (CPU-Passwort), 7=Zeit Funktionen,
 |  |  |  |  x=1-> Request, x=2 -> Response, außer bei Programmer commands
 |  |  |  Länge der folgenden restlichen Parameter (4 oder 8)
 |  |  Konstant 12
 |  Konstant 01
 Konstant 00
```
Eigentlich sieht diese Unterteilung in Funktionsgruppen und Unterfunktionen ganz schlüssig aus, kann aber auch sein dass sich die Siemensianer was ganz anderes dabei gedacht haben.

Ich habe das in das plugin schon soweit integriert, im Anhang ein Screenshot wie das dann aussehen würde.


----------



## Thomas_v2.1 (12 Juli 2009)

In der angehängten Version werden noch mehr Daten aufgeschlüsselt, wie z.B. SZL Anfragen, Block Informationen, CPU Befehle und Uhrzeit stellen/lesen.

Viele Stellen sind zwar weiterhin unklar, aber das meiste was ich von PG aus an Befehlen machen konnte wird zumindest ohne Fehler aufgelistet.
Die Info-Zeile ist bei manchen Funktionen jetzt etwas lang geworden, aber Breitbild ist ja in Mode.

Was mir seltsam vorkommt, dass es so viele verschiedene Formate in dem Protokoll gibt.
Mal wird eine Blocknummer als ASCII, mal als Word übertragen. Dann gibt es mindestens zwei verschiedene Arten einen Zeitstempel zu übertragen. Warum man sowas macht ist mir schleierhaft. Oder das sind noch Leichen aus alten S5-Zeiten.


----------



## cboerm (17 Februar 2010)

Ich habe das Plugin angewendet, alles läuft super.
Beim analysieren der Daten ist mir ein Problem aufgetreten.
Ich habe laufend Anforderungen (Request) und Antworten (Response) die Wireshark aufzeichnet. In der Anforderung steht immer z.B. (DB2.DBX12.0 BYTE120). In den Antworten steht das aber nicht mehr. Woher weiß ich, welche der vielen Antworten zu einer bestimmten Anforderung gehört? Ich hoffe jemand kann mir helfen!!


----------



## Rainer Hönle (17 Februar 2010)

Einfach nach der passenden sequence number schauen.


----------



## cboerm (17 Februar 2010)

Die sequence number ist bei mir aber immer eins oder null. Gibt es da noch eine andere Möglichkeit?

Im Anhang befindet sich die Wiresharkdatei. In dem Filter muss man folgendes eingeben:
ip.addr == 192.168.157.192 && s7comm

Vorraussetzung ist natürlich, das man das S7-Plugin installiert hat.


----------



## Rainer Hönle (17 Februar 2010)

Wie es aussieht, sind nie mehr als zwei Pakete unterwegs. Diese haben dann unterschiedliche sequence numbers. Das Response-Paket mit 0 gehört immer zum vorigen Request mit 0, das Response-Paket mit 1 gehört immer zum vorigen Request mit 1. Die Zuordnung ist somit eindeutig.
Nur ne Frage am Rande: welche Software kommuniziert da? Wie sieht der Connection Request / Connection Confirm aus?


----------



## cboerm (18 Februar 2010)

Danke für deine Hilfe.

Zu deiner Frage, die Kommunikation findet zwischen einer SPS (192.168.157.192) und einer über eine VMWare (192.168.157.245) laufende Visualisierung (Wonderware) statt.


----------



## cboerm (18 Februar 2010)

Ich habe nach dem ich weiß, welche Anfrage zu welcher Antwort gehört,noch eine Frage.

Und zwar ist es möglich aus der Antwort (Response) den Ursprung der Daten zu erkennen?

Bsp.ie Anfrage möchte Daten aus dem DB2.DBX 222.0 Byte 202 haben. Es folgt eine Antwort mit den angeforderten Daten. Kann man hieraus erkennen, aus welchem DB(Quelle) die Daten geschickt wurden?


----------



## Rainer Hönle (18 Februar 2010)

Nein, das sieht man nur aus der Anfrage.


----------



## shotar (25 Februar 2010)

Tolle Sache! Ich habe auf der Arbeit allerdings nur Ethereal.. morgen mal gucken obs damit auch geht..

Mal grundsätzlichen Fragen:
Wenn ich alles richtig verstehe nutzen Programme wie z.B. Libnodave ein geheimes Siemens Protokoll? Ich dachte den Aufbau ISO on TCP (RFC 1006) Telegrammen kann man offen nachlesen? Ich vertehe das nicht so ganz...

Also wie läuft die Kommunikation zw. Libnodave und SPS genau ab? Ist das ähnlich wie TCPIP über Handshake usw?


----------



## Rainer Hönle (25 Februar 2010)

shotar schrieb:


> Tolle Sache! Ich habe auf der Arbeit allerdings nur Ethereal.. morgen mal gucken obs damit auch geht..
> 
> Mal grundsätzlichen Fragen:
> Wenn ich alles richtig verstehe nutzen Programme wie z.B. Libnodave ein geheimes Siemens Protokoll? Ich dachte den Aufbau ISO on TCP (RFC 1006) Telegrammen kann man offen nachlesen? Ich vertehe das nicht so ganz...
> ...



Selbstverständlich ist RFC1006 offengelegt. Dies ist aber nur die Verpackung. Viel wichtiger ist der Inhalt. Und der ist nicht offengelegt. 

Die Kommunikation läuft über TCP/IP und verwendet zusätzlich RFC 1006. Einfach nach der Spec googeln.


----------



## Thomas_v2.1 (25 Februar 2010)

shotar schrieb:


> Tolle Sache! Ich habe auf der Arbeit allerdings nur Ethereal.. morgen mal gucken obs damit auch geht..



Warum denn nicht gleich auf Wireshark updaten? Ich weiß nicht ob das Plugin mit der alten Ethereal-Version kompatibel ist.

Ich habe mal eine kleine Dokumentation zum Plugin angehängt, bei der du am Ende auch ein paar Weblinks zu den verschiedenen Protokollen findest.


----------



## shotar (25 Februar 2010)

ja sauber, damit kann ich was anfangen! Das heisst also Libnodave kennt diesen Telegrammaufbau und kann so in die SPS schreiben/lesen, richtig? Leider wird das ja in der dll stehen, gibt es sowas offen programmiert? Am liebsten in Visual Basic oder php


----------



## Question_mark (25 Februar 2010)

*Wo ist das Problem ?*

Hallo,



			
				shotar schrieb:
			
		

> gibt es sowas offen programmiert?



Ja, in den Open Source C-Quelltexten von Libnodave, erhältlich bei sourceforge.net und bereitgestellt von unserem Forumsmitglied Zottel 

Gruß

Question_mark


----------



## animesm999 (28 Februar 2010)

*Beispiele aus Doku*

Hey Thomas,

super Sache das Plugin. Kurze Frage: In der Doku hast du ein par Beispieldateien angegeben. Allerdings weis ich nicht wo man die runterladen kann. Könntest du sie bitte noch reinstellen, bzw den Link schicken.

Danke


----------



## Thomas_v2.1 (1 März 2010)

animesm999 schrieb:


> Hey Thomas,
> 
> super Sache das Plugin. Kurze Frage: In der Doku hast du ein par Beispieldateien angegeben. Allerdings weis ich nicht wo man die runterladen kann. Könntest du sie bitte noch reinstellen, bzw den Link schicken.



Hallo,
eigentlich ist das meine interne Dokumentation die ich dazu geschrieben habe.
Ich habe aber mal das komplette Paket inklusive html-Dateien, Beispiel-Aufzeichnungen etc. angehängt.

Wär natürlich schön wenn es Rückmeldungen bezüglich Fehlern, falschen Bezeichungen, Verbesserungen an der Darstellung etc. gäbe. Ich arbeite ja auch nicht bei Siemens ;-)
Mit den Aufzeichnungen von der S7-1200 passt die Struktur zumindest nicht so recht zusammen, auch wenn der Grundaufbau der Telegramme gleich zu sein scheint.

Thomas


----------



## shotar (3 März 2010)

wofür ist diese Kommunikation von Siemens denn eingentlich gedacht? Ihr redet immer von S7 Kommunikation, aber damit ist doch eigentlich die Kommunikation zw. 2 SPSen gemeint die man im NetPro verbindet, oder?


----------



## animesm999 (4 März 2010)

shotar schrieb:


> wofür ist diese Kommunikation von Siemens denn eingentlich gedacht? Ihr redet immer von S7 Kommunikation, aber damit ist doch eigentlich die Kommunikation zw. 2 SPSen gemeint die man im NetPro verbindet, oder?



Wir reden hier unter anderem von der Kommunikation eines Programms auf einem PC mit der S7 SPS von Siemens. Step 7 z.B. kommuniziert auch über das S7-Protokoll.

Bei Ethernet sind die oberen Protokolle z.B. 

..
TCP/IP 
 -> ISO on TCP 
      -> S7 Protokoll
..

Dank dem super Plugin  ist es jetzt möglich mittels WireShark diese Kommunikation zu analysieren. 
Die Open Source Bib Libnodava implementiert das S7 Protokoll.

Natürlich kann man damit auch die Kommunikation zwischen 2 SPS analysieren, wenn man mithört ;-)


----------



## shotar (4 März 2010)

Warum muss ich dafür keine Verbindung in NetPro einrichten? Zählt die Verbindung über Libnodave zu den "normalen" verbindungen oder zählt die als PG/OP verbindung?


----------



## Rainer Hönle (4 März 2010)

Zählt als PG/OP-Verbindung und nicht als projektierte.


----------



## dieterb (15 März 2010)

*Wireshark stürzt mit S7-Plugin ab*

Hallo zusammen,

ich hab heute versucht das S7-Plugin unter der Wireshark Development Version 1.3.2 (Windows XP) zu installieren. Sobald die S7Comm-Dll (Version von 20.01.2010) im Plugin Verzeichnis liegt, stürzt Wireshark beim Programmstart mit einer Schutzverletzung ab.  Gibt's da sonst noch was zu beachten ? 

Gruß
Dieter


----------



## Thomas_v2.1 (15 März 2010)

dieterb schrieb:


> ich hab heute versucht das S7-Plugin unter der Wireshark Development Version 1.3.2 (Windows XP) zu installieren. Sobald die S7Comm-Dll (Version von 20.01.2010) im Plugin Verzeichnis liegt, stürzt Wireshark beim Programmstart mit einer Schutzverletzung ab.  Gibt's da sonst noch was zu beachten ?



Hallo,
ich glaube die Development-Version von Wireshark wird nicht mehr mit den VC6 Compiler gebaut. Zumindest kommt die Fehlermeldung von der C++ Runtime Library, darum schätze ich dass die Development Version mit einer neueren Version des VS gebaut wurde. 
Meine erste Version habe ich auch mit dem VC2008 übersetzt, da ließ sich das aber nicht ohne Installation des Redistributable Package benutzen (siehe erste Seite dieses Threads).

Lange Rede kurzer Sinn:
Solange die Version 1.2.x das offizielle Release ist, bitte diese Version in Verbindung mit der s7comm.dll verwenden.

Wenn unbedingt die Entwicklungsversion von Wireshark verwendet werden soll, muss das Plugin selber übersetzt werden. Quellcode liegt ja bei.
Wenn es mit einem offiziellen Wireshark-Release nicht zusammenspielen sollte, werde ich nochmal sehen ob ich das mit einem aktuellen VS übersetze.


----------



## heitecler (15 April 2010)

*Malformed Package*

Guten Tag
Ich habe Ihr S7 Plugin für Wireshark getestet.
Der TEstaufbau ist eine Kommunikation zwischen einer S7300 und einem WinCC 7.0.
ICh schreibe und lese (testhalber) aus Merkern und DBs.
Die Write Pakete können durch ihr Plugin einwandfrei interpretiert werden. 
jedoch die Zyklischen Lesepakete, die von der S7 nach WinCC haben die Form:
207    4.834325    10.64.80.60    10.64.1.63    S7COMM    102 > 1679 PDU-Type:[Userdata] Function:[Follow ?] ->:[Cyclic data] ->:[Memory][Malformed Packet]

(rot markierter S7comn-Bereich)

gibt es eine Möglichkeit auch diese Pakete zu interpretieren.

(Verwendete Wireshark version: Version 1.2.7)   

Vielen Dank für die Hilfe
Gruß


----------



## Thomas_v2.1 (15 April 2010)

Hallo,
wie kann man bei WinCC denn solche Pakete erzeugen?

Ich habe diese Pakete bisher nur bei den Meldevariablen (also die eine Störung erzeugen) in WinCC flexible entdecken können.
Kannst du mal eine kurze Anleitung geben wie man das in WinCC anlegt? Dann gucke ich mal ob ich rausfinden kann wie das funktioniert.


----------



## heitecler (15 April 2010)

Vielen Dank dür die schnelle Antwort
Solche Pakete entstehen, dadurch, dass wenn Variablenwerte z.B. in einem EA Feld nach einem eingestellten Zyklus aktualisiert werden (z.B. alle 1s).
jedoch kommt das gepostete Paket ja von der S7 (10.64.80.60).
Wie der genaue Datenverkehr bei einem Lesevorgang von WnCC funktioniert kann ich dir leider nicht genau sagen.

Gruß


----------



## Thomas_v2.1 (15 April 2010)

So, ich habe mir das nochmal angesehen. Es gibt im Protokoll verschiedene Angaben für die "Transport size", also z.b. Bit, Byte, Word, etc., und die Längenangabe muss man dann auf diese größe umrechnen.
Als ich diese zyklischen Dienste bei WinCC flex zum ersten mal gesehen habe, hat die Steuerung mit der ich damals getestet habe sich etwas seltsam verhalten, sodass ich da eine Ausnahme reinprogrammiert habe.

Ich habe das aber eben nochmal mit WinCC und WinCCflex an einer anderen Steuerung probiert, und da ist diese Ausnahme nicht mehr notwendig. So ist das Ganze auch wenigstens etwas konsistenter.

Im Anhang die geänderte s7comm.dll

Edit: Abmelden der zyklischen Dienste im Plugin ergänzt.


----------



## heitecler (15 April 2010)

Vielen Dank für die Hilfe
Ich hätte nur noch eine Frage:
Ich sehe jetzt alle Zusammenhängende Datenbereiche, die in einem 
Zyklus aktualisiert werden, und kann deren Werte bei einem einfachem 
Beispiel nachvollziehen, jedoch nicht, auf welchen Datenbereich (in der S7) bzw. auf welche Variablen(im WinCC) sich dieser Datenblock bezieht. gibt es da noch ne Möglichkeit das aus einem Datenpaket herauszulesen????

Aber nochmal vielen Dank bisher :TOOL:
Gruß


----------



## Rainer Hönle (15 April 2010)

Aus dem Antwortpaket ist dies nicht herauszulesen.


----------



## Thomas_v2.1 (15 April 2010)

Wie Rainer schon schrieb geht das aus einem einzelnen Antwortpaket nicht mehr.

Soweit ich das sehe läuft die zyklsche Kommunikation folgendermaßen:

Client stellt eine Anfrage an die SPS mit dem gewünschten Datenbereich und der gewünschten Aktualisierungsrate
Client schickt daraufhin ein Response mit den Daten (soweit verfügbar). Im Parameter-Teil steht dann in der ersten Antwort eine eindeutige Nummer (von mir im Plugin "Sequence Number" genannt)
Die SPS schickt im angeforderten Intervall selbständig die Daten ohne weitere Anfrage vom Client. Der Client bestimmt die Zugehörigkeit der Daten über die "Sequence Number" die er in der ersten Antwort erhalten hat
Abmelden des Clients: Der Client schickt eine Anfrage an die SPS um sich abzumelden. Im Daten-Teil steht 0x01 und die "Sequence Number" des Bereiches den er abmelden möchte.


----------



## Thomas_v2.1 (2 Oktober 2010)

Im Laufe der Zeit habe ich noch ein paar kleine Fehlerbereinigungen beim Plugin gemacht. Neue Funktionen sind nicht hinzugekommen.

Allerdings bin ich am Überlegen die SZL Aufschlüsselung rauszuschmeißen, da solche Telegramme über mehrere Pakete gehen können, und ich sowas nicht wieder zusammenfügen kann. Mal sehn.


----------



## - chris - (2 Oktober 2010)

Bei Wireshark V1.4.0 erhalte ich folgende Fehlermeldung:

Err  Field 'Parameter data' (s7comm.param.data) is an FT_BYTES
 but is being displayed as BASE_HEX instead of BASE_NONE


----------



## Thomas_v2.1 (2 Oktober 2010)

- chris - schrieb:


> Bei Wireshark V1.4.0 erhalte ich folgende Fehlermeldung:
> 
> Err  Field 'Parameter data' (s7comm.param.data) is an FT_BYTES
> but is being displayed as BASE_HEX instead of BASE_NONE



Hallo chris,
danke für deine Rückmeldung.

Bei der Version 1.4.0 wurde bei Wireshark in der Hinsicht wohl etwas geändert. Nicht-numerische Typen verlangen jetzt BASE_NONE statt BASE_HEX. Ich habe die entsprechenden Stellen angepasst und nun funktioniert es mit der 1.4.0 sowie mit der 1.2.0 (für die Windows 2000 Nutzer wie mich ;-) ). 
Vielleicht war das auch das Problem das dieterb damals mit der Development Version von Wireshark hatte.

Wenn jemand noch falsch dargestellte Pakete hat, wäre es natürlich hilfreich mir diese Fehler mitzuteilen, bzw. solche Pakete aufzuzeichnen. Es gibt so viele Funktionen in dem Protokoll dass ich nicht alle Funktionen simulieren kann.

Gruß


----------



## NeXoR (18 Januar 2011)

Hallo Thomas,

Erst mal danke für die viele Arbeit die du hier rein gesteckt hast.

Mir ist aufgefallen, dass die 64-bit Version von Wireshark inkompatibel mit dem zuletzt hochgeladenen Plugin ist.
Kann man da eventuell was machen? Oder muss ich zwangsläufig auf x86 zurückgreifen?

Danke


----------



## Thomas_v2.1 (18 Januar 2011)

NeXoR schrieb:


> Mir ist aufgefallen, dass die 64-bit Version von Wireshark inkompatibel mit dem zuletzt hochgeladenen Plugin ist.
> Kann man da eventuell was machen? Oder muss ich zwangsläufig auf x86 zurückgreifen?



Naja, die üblichen 64-bit Probleme halt...

Ich habe kein 64-bit System (eben aufgrund der Probleme mit diversen Programmen) zur Verfügung, meine VC6 Entwicklungsumgebung läuft in einer virtuellen Maschine unter Windows 2000 ;-)
Ich könnte dir höchstens die Quellen zum selbstübersetzen zur Verfügung stellen.


----------



## Thomas_v2.1 (8 Mai 2011)

Bevor das Projekt auf meiner Festplatte ganz einschlummert, habe ich es mal bei Sourceforge angelegt:

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

Folgende Aktualisierungen habe ich im Vergleich zur letzten hier veröffentlichten Version vorgenommen:
- Darstellung der SZL-IDs in hex geändert
- Einige "interessante" SZL-Anfragen werden im Klartext aufgeschlüsselt
- Diverse Fehlerbereinigungen

Leider gab es von den 64-Bit Nutzern noch keine Rückmeldung, ob und wie jemand das Plugin übersetzt bekommen hat. Darum kann ich momentan nur sagen dass die dll unter 32-Bit Windows mit Wireshark lauffähig ist (bei mir läuft momentan Version 1.4.1 unter Windows 7 32 bit).


----------



## NeXoR (8 Mai 2011)

Also zum Thema 64-bit,

ich wollte das Plugin für 64-bit kompilieren, habs aber leider nicht wirklich geschafft.

Dann hab ich einfach unter Win7x64 Wireshark (1.4.3) in der 32-bit Version installiert, und dort die 32-bit Version des Plugins verwendet, was einwandfrei funktioniert.
Deshalb hab ich mich auch nicht weiter um die 64-bit Variante gekümmert, da es ja problemlos lief.

Ich versuche bei Gelegenheit nochmal eine x64 Dll hinzubekommen, kann aber nichts versprechen!


----------



## Thomas_v2.1 (8 Mai 2011)

NeXoR schrieb:


> ich wollte das Plugin für 64-bit kompilieren, habs aber leider nicht wirklich geschafft.
> 
> Dann hab ich einfach unter Win7x64 Wireshark (1.4.3) in der 32-bit Version installiert, und dort die 32-bit Version des Plugins verwendet, was einwandfrei funktioniert.
> Deshalb hab ich mich auch nicht weiter um die 64-bit Variante gekümmert, da es ja problemlos lief.
> ...



Ah, na wenn es unter 64-Bit Windows mit der 32-Bit Wireshark Version läuft, ist es wenigstens irgendwie für die Win64 Nutzer benutzbar.

Wie weit bist du mit dem Übersetzen denn gekommen? Dir ist aber schon klar, dass du quasi erst das komplette Wireshark selber übersetzen musst, damit du letztendlich das Plugin übersetzen kannst. Zumindest benötigst du die Wireshark Sourcen und das komplette Build-System (Platform SDK, Python, Cygwin).
Hier gibt es eine Schritt-für-Schritt Anleitung mit der das bei mir problemlos geklappt hat:
http://www.wireshark.org/docs/wsdg_html_chunked/ChSetupWin32.html


----------



## Thomas_v2.1 (31 Oktober 2012)

Wer hat denn die Möglichkeit und Lust mal die s7comm.dll mit der 64-Bit Version von Wireshark zu testen?
Übersetzt habe ich diese jetzt soweit, kann es aber mangels 64 Bit PC selber nicht testen.


----------



## Jochen Kühner (31 Oktober 2012)

schick mir se zu, ich probiers am we!


----------



## Jochen Kühner (1 November 2012)

@Thomas: Funktioniert wunderbar, die 64Bit Version!


----------



## Jochen Kühner (14 November 2012)

Wärs denn keine Idee das ganze an Wireshark zu senden, so das es in die offiziellen Releases mit aufgenommen wird?

(Sonst muss Ich mir jetzt doch noch ne Build Umgebung aufbauen, würd das Plugin nämlich gerne in meinem MacBook nutzen :-( )


----------



## Thomas_v2.1 (14 November 2012)

Jochen Kühner schrieb:


> Wärs denn keine Idee das ganze an Wireshark zu senden, so das es in die offiziellen Releases mit aufgenommen wird?


Meiner Meinung nach sollten im offiziellen Wireshark nur 100%ig vollständig und richtige Protokolle enthalten sein. Davon ist das hier ja noch sehr weit entfernt, und der Stand wird ohne Protokollbeschreibung auch wohl nie erreicht werden.

Ich bin momentan dabei viele Dinge aufgrund von neuen Erkenntnissen umzubenennen. Die PDU-Type nennt sich unter anderem jetzt ROSCTR (Remote Operating Service Control), denn auf der Siemens Seite lassen sich Informationen über das Sinec AP Protokoll finden, und Teile davon sind wohl in das S7 Protokoll eingeflossen. Darum übernehme ich jetzt die Bezeichnungen die dort verwendet werden.
Ein paar Bezeichnungen lässt Siemens auch in Dokumentationen für die Sinumerik Steuerungen fallen. Wenn man mal ein paar offizielle Bezeichnungen gefunden hat, stößt man mit der google Suche nach diesen auch auf weitere Dokumente aus denen sich was raussaugen lässt.


----------



## Jochen Kühner (15 November 2012)

Kann ich dir denn noch mit was weiterhelfen? Hab ja z.B. die Anfrage für Baustein Diagnosedaten beim mir in der Bibliothek drin. Willst du in die Richtung auch was einbauen?


----------



## Thomas_v2.1 (15 November 2012)

Ich würde am liebsten erstmal den Parameter-Teil vollständig haben.

Was haben z.B. die ersten 3 Bytes bei Userdata-Telegrammen zu bedeuten? Bzw. ist "Userdata" als Name für diese Telegramme überhaupt richtig, denn in diesen Telegrammen steckt alles andere außer den Variablendiensten. Die anderen Kennungen lauten in Siemens original-Sprech z.B. "Auftrag mit Quittung", was ich einfach mal "Job" übersetzt habe. Die Antworten heißen dann im original "Quittung ohne Zusatzfeld" und "Quittung mit Zusatzfeld", bei mir "Ack" und "Ack_Data" genannt.

Wenn man das Schema wie bei den Variablendiensten annimmt, wäre das erste Byte im Parameter der Funktionscode. Der ist dabei aber immer Null.
Das zweite Byte ist immer 1. Vielleicht gibt dieses die Anzahl der Parameter-Datensätze an. Ich habe aber immer nur einen Satz gesehen.
Das dritte Byte ist immer 0x12, vielleicht gibt das an wie der Parameter-Satz aufgebaut ist? Irgendeine Bedeutung muss das aber haben, denn es ergibt ja keinen Sinn 3 Bytes für hier überflüssige Konstanten einzusetzen.

Bei den Bytes 4, 5 und 6 scheint das was ich mir da überlegt habe von der Funktion her zwar zu passen, aber so einen verrückten Aufbau traue ich nichtmal Siemens zu. Da muss irgendeine andere Logik hinterstecken.
Dann gibt es noch ein Byte vor dem Byte welches kennzeichnet dass dieses die letzte Dateneinheit zu einem Datensatz ist. Dort steht immer ein Wert ungleich Null wenn dieses nicht der letzte Datensatz ist, aber die Werte darin sind immer unterschiedlich. Ich habe schon 2, 5 und 7 gesehen. Keine Ahnung was das soll.
Technisch sinnvoll wäre eigentlich dem Partner die Anzahl der noch folgenden Pakete mitzuteilen wenn fragmentiert wird, aber das scheint es nicht zu sein.

Ich habe meinen aktuellen Arbeitsstand mal angehängt, kannst dir das ja mal ansehen (hab' die 32 und 64 Bit reingepackt). Ich habe im Laufe der Zeit noch ein paar andere Dinge geändert.


----------



## Jochen Kühner (17 November 2012)

Wenn die immer gleich sind, kann ich dir leider auch nicht mehr dazu sagen. Ich hab leider auch keine internen Infos, sondern nur das was Ich durch probieren rausgefunden habe. 
Also falls du bei den Telegrammen zum Up/Download weitere Infos über den Baustein, oder bei den Bausteindiagnosetelegrammen weitere Details einbauen willst, dazu hab Ich halt noch Infos...
Wenn Ich aber was rausfinde, gibt's natürlich hier weitere Infos... Ich mach mich mal wieder an die Bausteinprüfsumme


----------



## Thomas_v2.1 (17 November 2012)

Ich habe mir gerade nochmal ein paar Aufzeichnungen angesehen. So wie es aussieht ist diese Nummer doch nicht konstant, sondern eine weitere Referenz-Nummer auf die man sich beziehen kann/muss wenn ein Telegramm aufgrund der Größe fragmentiert wird. In einigen Aufzeichnungen wird diese Nummer von der SPS bei jedem neuen fragmentierten Telegramm erhöht. Eine Abfrage dieser Nummer ist nur notwendig wenn man mehrere Telegramme gleichzeitig auf die Reise schickt. Darum funktioniert das auch in libnodave ohne die Abfrage der Nummer, da dort immer nur eine einzige Anfrage zur Zeit läuft.


----------



## Thomas_v2.1 (17 November 2012)

Hast du zu den Diagnosetelegrammen irgendwas dokumentiert, oder steht das meiste bei dir im Quellcode drin?


----------



## Jochen Kühner (17 November 2012)

Thomas_v2.1 schrieb:


> Ich habe mir gerade nochmal ein paar Aufzeichnungen angesehen. So wie es aussieht ist diese Nummer doch nicht konstant, sondern eine weitere Referenz-Nummer auf die man sich beziehen kann/muss wenn ein Telegramm aufgrund der Größe fragmentiert wird. In einigen Aufzeichnungen wird diese Nummer von der SPS bei jedem neuen fragmentierten Telegramm erhöht. Eine Abfrage dieser Nummer ist nur notwendig wenn man mehrere Telegramme gleichzeitig auf die Reise schickt. Darum funktioniert das auch in libnodave ohne die Abfrage der Nummer, da dort immer nur eine einzige Anfrage zur Zeit läuft.



Welche Software gibt es denn die mehrere Telegramme losschickt? Bringt das überhaupt was? D.h. Ich kann noch ein Telegramm absenden bevor die S7 auf das vorherige geantwortet hat?



			
				Thomas_v2.1 schrieb:
			
		

> Hast du zu den Diagnosetelegrammen irgendwas dokumentiert, oder steht das meisten bei dir im Quellcode drin?



Im Quellcode. Die PLCConnection.cs Funktion: PLCStartRequestDiagnosticData.

Zum aufbau von den S7 Blöcken ist noch was in der MC7Converter.cs Funktion GetAWLBlock, das bringt aber ja nur was bei der ersten anfrage, wenn der block gesplittet wird bringts ja nichts mehr...


----------



## Thomas_v2.1 (17 November 2012)

Jochen Kühner schrieb:


> Welche Software gibt es denn die mehrere Telegramme losschickt? Bringt das überhaupt was? D.h. Ich kann noch ein Telegramm absenden bevor die S7 auf das vorherige geantwortet hat?


Beim Simatic.Net OPC Server kann man das beispielsweise einstellen. Die Anzahl wird wie die PDU Größe beim Verbindungsaufbau ausgehandelt.
In der letzten Version "Max amq calling/called" genannt, so heißt es auch in den Siemens Dokumentationen. Wie bei der PDU Größe ist das vom Anfrager ein Vorschlag, und die SPS verringert diesen ggf. auf ihre maximale Anzahl.
"Called" ist die Anzahl des Partners, und "Calling" die eigene. Die Anzahl gilt für Aufträge mit Quittung.

Ob das was bringt? Keine Ahnung. Auf einer langsamen Datenleitung wie MPI wohl eher als auf einer schnellen wie Ethernet im LAN, da nicht so viel Zeit mit Warten verbracht werden muss.


----------



## Thomas_v2.1 (23 Januar 2013)

Man sollte ja nicht mit was neuem anfangen wenn das alte noch nicht fertig ist, aber ich war grad neugierig 

Ich habe in das Plugin auf die Schnelle eine Weiche eingebaut damit die symbolischen Adressangaben der 1200 zumindest grundsätzlich aufgeschlüsselt werden.
Der Telegrammaufbau bei der Kommunikation der 1200 mit dem integrierten TIA HMI ist grundsätzlich identisch einer 300/400er Steuerung (Kopf-, Parameter- und Datenteil). Nur die Variablenspezifikation ist eben anders.
Die magische Zahl die dem SPS-Symbol zugeordnet scheint auf jeden Fall 12 Byte lang zu sein.

Hat sich das schonmal jemand näher angesehen ob man aus der Zahl an sich noch weitere Informationen extrahieren kann? Und gibt es schon einen Mitschnitt der Kommunikation mit der neuen 1500er?


----------



## Jochen Kühner (24 Januar 2013)

Thomas_v2.1 schrieb:


> Man sollte ja nicht mit was neuem anfangen wenn das alte noch nicht fertig ist, aber ich war grad neugierig
> 
> Ich habe in das Plugin auf die Schnelle eine Weiche eingebaut damit die symbolischen Adressangaben der 1200 zumindest grundsätzlich aufgeschlüsselt werden.
> Der Telegrammaufbau bei der Kommunikation der 1200 mit dem integrierten TIA HMI ist grundsätzlich identisch einer 300/400er Steuerung (Kopf-, Parameter- und Datenteil). Nur die Variablenspezifikation ist eben anders.
> ...


Kannst du denn mal das Projekt mit welchem du diesen Ausug erstellt hast zur Verfügung stellen? Mich würd mal Interessieren ob ich es schaffe diesen Code für die Variablen aus dem Projektfile zu extrahieren!


----------



## Jochen Kühner (25 Januar 2013)

Noch was: Geht denn der Symbolische Zugriff nur auf VollSymbolische DBs, oder auch auf Werte aus der Variablentabelle?


----------



## Thomas_v2.1 (25 Januar 2013)

Ich habe nur einen "optimierten" DB angelegt in dem Variablen verschiedenen Datentyps liegen, und ein Merkerwort als Integer und ein Merkerdoppelwort als Real. Es wird auch auf die Merker symbolisch zugegriffen.

Einen Teil im Protokoll konnte ich schonmal zuordnen. In der Projekt plf gibt es zu jeder Variable eine LID, und dieser Wert entspricht schonmal den letzten 2 Bytes in der 12-Byte Anfrage - zumindest bei Variablen aus einem DB. Ob und wie die RID da hineinverwurstet wird habe ich noch nicht herausgefunden.


----------



## LowLevelMahn (25 Januar 2013)

*Was bedeutet LID und RID?*

für was stehen denn die Kürzel LID und RID?


----------



## Thomas_v2.1 (25 Januar 2013)

Hier mal eine Tabelle:

```
Member ID	RID	Type	Version	LID	S7Proto
intVar1	 51	0x02000005	Int	2	10	8a0e 0001 2413 4d05 4000 000a

intVar2	 52	0x02000005	Int		11	8a0e 0001 cd4a bb23 4000 000b

dintVar1 53	0x02000007	Dint	2	13	8a0e 0001 11c2 1437 4000 000d

dwordVar1 54	0x02000006	Dword	2	15	8a0e 0001 9544 bf6e 4000 000f

realVal	 55	0x02000008	Real	2	17	8a0e 0001 a796 82be 4000 0011

MW100							0000 0052 cc45 a2c8 4000 0009
MW100int
MD160							0000 0052 a767 ab4f 4000 000c
MD160real
```
Die LID und RID stehen in einer Art XML-Datei die sich in der Projektdatei verbirgt.
Zur Zeit mach ich das mittels meditieren über einem Hex-Editor, das ist nicht sonderlich effektiv ;-)


----------



## Thomas_v2.1 (25 Januar 2013)

Vermutung:
LID = Lokal Id (Zuordnungs ID innerhalb eines Blocks wie Datenbaustein oder Merkerbereich)
RID = Relation Id (Irgendeine ID des übergeordneten Blocks)


----------



## Jochen Kühner (25 Januar 2013)

Auch bei dem MW100 und dem MD160 ist die LID im Projektfile 9 und 12. Wobei im XMLFile heist das LocalIdentifier!


----------



## Jochen Kühner (25 Januar 2013)

Könnte ja sein, das die mittleren 4 bytes der crc sind welcher in dem Patent beschrieben ist? Die ersten 4 Bytes Speicherbereich? Oder etwas in die Richtung und die letzten 4 Bytes die laufende ID... Sind aber alles nur Ideen...


----------



## Thomas_v2.1 (25 Januar 2013)

Die letzten 4 Bytes sind auf jeden Fall diese LID. In das Nibble dieser 4 Bytes ganz links werden noch irgendwelche Statusbits gespeichert, vielleicht für Arrays oder sowas. Für "flache" Variablen ist dort wohl immer eine 4.


----------



## Rainer Hönle (25 Januar 2013)

Jochen Kühner schrieb:


> Könnte ja sein, das die mittleren 4 bytes der crc sind welcher in dem *Patent* beschrieben ist?


Ist das nicht ein heißes Eisen?


----------



## Jochen Kühner (25 Januar 2013)

wegen? weil man analysiert wie das protokoll funktioniert? denke nicht das dies verboten ist!


----------



## Thomas_v2.1 (25 Januar 2013)

Rainer Hönle schrieb:


> Ist das nicht ein heißes Eisen?



Ich mach mir auch schon so meine Gedanken...
Aber ich hoffe mal herauszufinden wie etwas funktioniert ist noch erlaubt. Was anderes wird es sein das Patent wirklich anzuwenden.
Und um den CRC zu berechnen muss einem so wie es scheint das komplette SPS Projekt vorliegen.

Was nur blöd ist dass sich aus dem TIA Portal die magischen Nummern für die Symbole nicht exportieren lassen. Denn mit diesen Nummern ließe sich ja durchaus eine Visualisierung erstellen die von den Details im Patent garnichts wissen muss und trotzdem damit Daten aus der SPS lesen kann. Im HMI-Projekt des TIA Portal sind auch nur noch die kompletten Nummern hinterlegt.


----------



## Rainer Hönle (25 Januar 2013)

Habe mal gesucht (ohne rechtliche Gewähr):
"Eine Patentverletzung ist gegeben, wenn eine durch ein Patent geschützte Technologie - ohne die Zustimmung des Patentinhabers - gewerblich hergestellt, angeboten, verkauft,  gebraucht oder zu einem dieser Zwecke importiert oder auch nur besessen wird."


----------



## Thomas_v2.1 (25 Januar 2013)

Da bin ich ja aus dem Schneider - ist ja nicht gewerblich. Zur Not mach ich eine Version die gewerbliche Zwecke ausschließt.

Aber Teile dieses Patents sind echt ein schlechter Witz:
"Verfahren zur Adressierung nach einem der vorangegangenen Ansprüche, mit einer Integerzahl als eindeutiger Kennwert (ID1) der Variablen (ANNA)."

Bestärkt mal wieder meine Einstellung gegenüber Softwarepatenten.


----------



## Rainer Hönle (25 Januar 2013)

Wie gesagt, meine Angaben sind ohne rechtliche Gewähr (bin ja schließlich kein Anwalt).


----------



## Thomas_v2.1 (25 Januar 2013)

Naja, sich da mal ein paar Gedanken drum zu machen ist sicher nicht verkehrt. Die Siemens-Anwalts-Keule haben ja schon andere zu spüren bekommen.

Hab den grundlegenden Aufbau so ziemlich raus.
Syntax Id, 0xff, 2 Byte Bereichs-Identifier, 2 Byte DB Nummer, 4 Byte super-wichtig-patentierte-Spezialnummer, und dann pro Schachtelungstiefe 4 Byte mit 4 Bits Flags und rest super-wichtig-spezial-patentierte-Zahl-für-einen-Namen.

Hab mir grade einen Kaffee gekocht. 7 Löffel Pulver rein, glaub das lass ich mir mal schnell patentieren.


----------



## Thomas_v2.1 (25 Januar 2013)

Es gibt ja immer noch dieses unsägliche FAT Patent von Microsoft. Wie das funktioniert ist natürlich schon seit Ewigkeiten dokumentiert.
Wenn man das prinzipiell auf diese Geschichte hier anwendet würde ich ja sagen, wir dürfen hier reinschreiben wie das Telegramm aufgebaut ist, aber ich darf es nicht in das Wireshark Plugin einbauen - oder wenn dann nur für den Eigengebrauch.

Verzwickte Sache. Kennt nicht jemand einen Anwalt der einem da Klarheit verschaffen könnte?


----------



## Thomas_v2.1 (26 Januar 2013)

Solange die Rechtsabteilung kein grünes Licht gibt, erstmal nur einen Screenshot:
Anhang anzeigen 19596


----------



## LowLevelMahn (26 Januar 2013)

*jetzt fehlt noch das 0x72 Protokoll und ein Profinet-Stack...*

jetzt fehlt noch das 0x72 Protokoll: fuer Beobachtungstabellen Lesen/Schreiben

und ein kleiner Profinet-Stack: für so Blinken-Lassen, IP-Setzen, Gerät-Erkennen

dann sieht es ja schon ganz gut aus - mit der Hoffnung das die 1500er nicht wieder alles über Bord schmeisst


----------



## Jochen Kühner (26 Januar 2013)

@Thomas:

Hats du denn auch was Rausgefunden wie das ganze begrenzt ist? Gibts bei der 1200er wieder eine maximale PDU Größe? Anfragen an verschachtelte Variablen in DBs werden durch diese Aneinanderreihung ja schon ziemlich lang...


----------



## Thomas_v2.1 (26 Januar 2013)

Jochen Kühner schrieb:


> Hats du denn auch was Rausgefunden wie das ganze begrenzt ist? Gibts bei der 1200er wieder eine maximale PDU Größe? Anfragen an verschachtelte Variablen in DBs werden durch diese Aneinanderreihung ja schon ziemlich lang...



Aus dem Grunde musste wohl die Schachtelungstiefe bei der Programmierung begrenzt werden. Es ist eine maximale Schachtelungstiefe von 8 erlaubt, dann lässt sich das Programm nicht mehr übersetzen. Eine Variablenspezifikation benötigt dann 42 bzw. 44 Bytes.

Ich habe auch schonmal ein paar andere Versuche gemacht:
Bei Zugriffe auf Array-Variablen kann man den Array-Index ändern ohne die CRC anpassen zu müssen. Aber man kann nicht über den letzten Array-Index hinaus lesen, das wird dann wohl doch in der SPS irgendwie abgefragt. Man kann ohne Probleme libnodave durch diese Adressierung erweitern, man benötigt lediglich die Nummern aus dem TIA-Projekt. Und in libnodave müssen noch die restlichen Transport-Size Angaben wie z.B. 5 für Integer ergänzt werden.


----------



## Jochen Kühner (26 Januar 2013)

Thomas_v2.1 schrieb:


> Aus dem Grunde musste wohl die Schachtelungstiefe bei der Programmierung begrenzt werden. Es ist eine maximale Schachtelungstiefe von 8 erlaubt, dann lässt sich das Programm nicht mehr übersetzen. Eine Variablenspezifikation benötigt dann 42 bzw. 44 Bytes.
> 
> Ich habe auch schonmal ein paar andere Versuche gemacht:
> Bei Zugriffe auf Array-Variablen kann man den Array-Index ändern ohne die CRC anpassen zu müssen. Aber man kann nicht über den letzten Array-Index hinaus lesen, das wird dann wohl doch in der SPS irgendwie abgefragt. Man kann ohne Probleme libnodave durch diese Adressierung erweitern, man benötigt lediglich die Nummern aus dem TIA-Projekt. Und in libnodave müssen noch die restlichen Transport-Size Angaben wie z.B. 5 für Integer ergänzt werden.



Und wie groß ist die pdu size bei der 1200er? D.h. für eine große visu ist der symboblische db zugriff wohl nichts, da man ja damit auch keine anfragen zusamenfassen kann.


----------



## Thomas_v2.1 (26 Januar 2013)

Die PDU Größe bei einer 1200 sind 240 Byte. Wobei WinCCflexible auch keine Variablen gepackt hat, und das hat bisher auch niemanden gestört
Ich kann mir auch vorstellen kann dass die 1200er künstlich eingeschränkt wurde, damit man einen Grund hat auf die größeren Steuerungen zu wechseln.


----------



## Jochen Kühner (26 Januar 2013)

Ja, aber mit flexible hat man ja auch keine großen Visus gemacht. ;-)


----------



## Jochen Kühner (26 Januar 2013)

Laos ich finde das mit der je Schachtelungstiefe angehängten Bytes schon ein bischen doof. Wenn man nun von einem DB aus Schachtelungstiefe 2 Werte abfrägt, können auf einmal in einer PDU nur noch maximal 10 Werte statts vorher 17 (bei absoluter Adressierung) in einer PDU übertragen werden. Das kann dann schon schön auf die Performance einer Visu drücken, und das sollte man beim projektieren auf jeden Fall beachten!


----------



## Thomas_v2.1 (16 Februar 2013)

Ich habe mal eine neue Version der s7comm.dll veröffentlicht.

Änderungen in der Version 0.0.3
- Bezeichnungen im Kopfteil entsprechend den des Sinec AP Protokolls angepasst. Dürfte den originalen Bezeichnungen am nächsten kommen.
- Bausteindienste entspechend den Bezeichnungen der 840 Dokumentation angepasst
- Diagnosetelegramme (Anfragen Typ 1) beim Baustein beobachten werden aufgeschlüsselt
- Support für Telegramme S71200 symbolisch
- einige SZL IDs/Indexe ergänzt

Download unter:
http://sourceforge.net/projects/s7commwireshark/

Es ist auch eine dll für die 64 Bit Version von Wireshark verfügbar.


----------



## Jochen Kühner (16 Februar 2013)

Thomas_v2.1 schrieb:


> - Diagnosetelegramme (Anfragen Typ 1) beim Baustein beobachten werden aufgeschlüsselt



Zu den Diagnsetelegrammen, hast du da noch weitere Infos, welche ich noch nicht in meiner DLL habe, wo Ich vielleicht noch was verbessern muß?


----------



## Thomas_v2.1 (16 Februar 2013)

Nein, ich habe meine Analysen der Diagnosetelegramme auch nicht abgeschlossen.
Und ich habe auch noch nicht alles das was du in deinem Programm hast übernommen.
Mehr oder neues ist auf jeden Fall nicht drin. Ich wollte aber mal einen Zwischenstand
veröffentlichen, weil ich da nicht immer kontinuierlich dran weiterarbeite sondern nur
wenn ich mal Lust darauf habe ;-)

Wenn ich das richtig verstanden habe, lässt sich der Aufbau der Antwort auf eine
Baustein-Beobachten Anfrage auch nur auswerten wenn man die Anfrage kennt.
Das lässt sich mit den Wireshark Plugin glaube ich nicht erledigen - zumindest weiß ich
noch nicht wie das gehen könnte.


----------



## Jochen Kühner (16 Februar 2013)

Thomas_v2.1 schrieb:


> Wenn ich das richtig verstanden habe, lässt sich der Aufbau der Antwort auf eine
> Baustein-Beobachten Anfrage auch nur auswerten wenn man die Anfrage kennt.
> Das lässt sich mit den Wireshark Plugin glaube ich nicht erledigen - zumindest weiß ich
> noch nicht wie das gehen könnte.



Jo, das ist aber auf jeden Fall so! Mann muss sich immer merken was man für eine bestimmte Codezeile angefragt hatte...


----------



## Jochen Kühner (16 Februar 2013)

Bei einer Zeile mit einem Call kann man ja auch noch Werte driekt abfragen, d.h. ein DB, MW, ... auslesen. Das hab Ich bei mir auch noch nicht implementiert. Wie es funktioniert hab Ich zwar analysiert, aber implementiert ist da noch nichts ;-)


----------



## MW (17 Februar 2013)

Ich hätte da mal ne Zwischenfrage:

Ich versuche momentan aus dem Datenverkehr zwischen einer CPU und mehreren TP's ein Schreibbefehl für ein Bit aufzuzeichnen, weil gerade dieses Bit scheinbar durch eines der TP's zur falschen Zeit gesetzt wird bzw. nicht zurückgesetzt wird und ich nicht genau sagen kann, von welchem nun es kommt.
Ich kann ja die aufgezeichneten Telegramme genau auf dieses Bit filtern, dass klappt dank dem Plugin ganz gut. 

Jetzt ich würde es aber noch viel schöner finden wenn auch schon beim Capture nur Telegramme aufzeichnen könnte die z.B. einen Schreibauftrag in einen bestimmten DB enthalten. 
Geht das irgendwie ?


----------



## Jochen Kühner (17 Februar 2013)

MW schrieb:


> Ich hätte da mal ne Zwischenfrage:
> 
> Ich versuche momentan aus dem Datenverkehr zwischen einer CPU und mehreren TP's ein Schreibbefehl für ein Bit aufzuzeichnen, weil gerade dieses Bit scheinbar durch eines der TP's zur falschen Zeit gesetzt wird bzw. nicht zurückgesetzt wird und ich nicht genau sagen kann, von welchem nun es kommt.
> Ich kann ja die aufgezeichneten Telegramme genau auf dieses Bit filtern, dass klappt dank dem Plugin ganz gut.
> ...



Den gleichen filter welchen du zum anzeigen verwendest, solltest du auch für das aufzeichenen verwenden können. Einfach in den optionen des netzwerkadapters festlegen, in Wireshark


----------



## Thomas_v2.1 (17 Februar 2013)

MW schrieb:


> Jetzt ich würde es aber noch viel schöner finden wenn auch schon beim Capture nur Telegramme aufzeichnen könnte die z.B. einen Schreibauftrag in einen bestimmten DB enthalten.
> Geht das irgendwie ?



Es gibt sog. Capture Filter die schon bei der Aufzeichnung der Daten wirken. Diese Filter haben allerdings eine andere Syntax als die Wireshark Display Filter, da diese auf die Bibliothek libpcap, welche Wireshark zum Abgreifen der Netzwerkdaten verwendet, wirken. Vor allem kennt diese Bibliothek nicht die Protokolle die Wireshark kennt.
Darum ist leider bei der Aufzeichnung kein Filter für s7comm möglich.

Sinnvolle Filter bei der S7 Kommunikation sind z.B. "port 102", oder um nur die Kommunikation zu oder von einer IP-Adresse zu filtern mit "host x.x.x.x".
Dann hat man die Datenmenge bei einer Langzeitaufzeichnung schonmal erheblich reduziert. 
Dazu in den Capture Options auf das Interface welches überwacht werden soll doppelklicken, und dort unter "Capture Filter" entweder einen vorher abgespeicherten auswählen oder direkt dort eintragen.

Man kann bei Wireshark auch diverse Aufzeichnungsoptionen einstellen, beispielsweise alle x Megabyte eine neue Datei anlegen, oder alle x Stunden. Wenn man später den ungefähren Zeitpunkt eines Fehlers kennt, kann man sich die passende Logdatei laden und dort suchen.


----------



## Jochen Kühner (17 Februar 2013)

Thomas_v2.1 schrieb:


> Es gibt sog. Capture Filter die schon bei der Aufzeichnung der Daten wirken. Diese Filter haben allerdings eine andere Syntax als die Wireshark Display Filter, da diese auf die Bibliothek libpcap, welche Wireshark zum Abgreifen der Netzwerkdaten verwendet, wirken. Vor allem kennt diese Bibliothek nicht die Protokolle die Wireshark kennt.
> Darum ist leider bei der Aufzeichnung kein Filter für s7comm möglich.
> 
> Sinnvolle Filter bei der S7 Kommunikation sind z.B. "port 102", oder um nur die Kommunikation zu oder von einer IP-Adresse zu filtern mit "host x.x.x.x".
> ...



Ah ok, ich dachte die Syntax wäre gleich. Hab die nie wirklich verwendet! Wieder was gelernt!


----------



## MW (18 Februar 2013)

Thomas_v2.1 schrieb:


> Es gibt sog. Capture Filter die schon bei der  Aufzeichnung der Daten wirken. Diese Filter haben allerdings eine andere  Syntax als die Wireshark Display Filter, da diese auf die Bibliothek  libpcap, welche Wireshark zum Abgreifen der Netzwerkdaten verwendet,  wirken. Vor allem kennt diese Bibliothek nicht die Protokolle die  Wireshark kennt.
> Darum ist leider bei der Aufzeichnung kein Filter für s7comm möglich.



Ich hab das schon befürchtet, ich hatte nämlich schon einige Filterbefehle erfolglos durchprobiert, aber wenn es sowieso nicht möglich ist, war ich zumindest nicht zu blöd beim eintippen.  



Thomas_v2.1 schrieb:


> Sinnvolle Filter bei der S7 Kommunikation sind z.B. "port 102", oder um  nur die Kommunikation zu oder von einer IP-Adresse zu filtern mit "host  x.x.x.x".
> Dann hat man die Datenmenge bei einer Langzeitaufzeichnung schonmal erheblich reduziert.
> Dazu in den Capture Options auf das Interface welches überwacht werden  soll doppelklicken, und dort unter "Capture Filter" entweder einen  vorher abgespeicherten auswählen oder direkt dort eintragen.



Ich filtere beim capture schon nach dem destination host, port 102 und ether proto 0x0800. Das macht in meinem Fall in einer Stunde ein Capture von ca. 100MB.
Leider ist wireshark übers Wochenende beim aufzeichnen abgestürzt, trotz splittung der Capturedateien auf 100MB und Ringspeicher mit 30 Dateien, mal schauen ob es morgen früh noch läuft.


----------



## Thomas_v2.1 (23 März 2013)

Ich habe mal für die 72er Telegramme vom TIA-Portal einen Test-Disssector gebaut. Im Anhang die dll für die 32-Bit Wireshark Version.
Filtern lassen sich diese Telegramme über "s7commt".

Der grundlegende Aufbau dieser Telegramme scheint Kopf-, Daten- und Fußteil zu sein. Für Telegramme die größer als die ISO-Paketlänge sind nutzt man nicht die dort vorhandene Möglichkeit zur Fragmentierung, sondern eine eigene im TIA-S7-Protokoll. D.h. bei fragmentierten Telegrammen entfällt der Fuß-Teil.
Was im Datenteil enthalten ist wird nicht entschlüsselt. Viele Funktionen werden aber wohl nicht binär sondern als Text, oder Text und Binärwert übermittelt.

Ich habe hier zu Hause eine 1200er CPU. Für die 1500er habe ich nur die Aufzeichnung aus dem anderen Thread mit der Variablentabelle. Demnach scheint die Kommunikation zur 1200 und 1500 zumindest "ähnlich" zu sein.

Die Kommunikation scheint aber auf hohe Bandbreite ausgelegt zu sein. Zumindest bei der 1200er wird beim Übertragen nur eines OB1 mit einem Netzwerk eine nicht unerhebliche Datenmenge hin- und hergeschickt. Auch wenn man eine Variablentabelle aufmacht und nur einen Wert beobachten will, wird immer gleich das ganze Programm abgeglichen.


----------



## ober (11 Oktober 2013)

Hallo Thomas,

Wirst du den Quellcode der aktuellen Version deines Wireshark Plugins auch Posten?
Unter Linux kann ich die dlls leider nicht benutzen.

Leibe Grüße
Ober


----------



## Thomas_v2.1 (11 Oktober 2013)

Hi Ober,
der aktuellste Stand liegt immer bei Sourceforge im SVN repository (trunk/src/s7comm).

Kannst ja mal von deinen Erfahrungen berichten, ob und wie das unter Linux geklappt hat.


----------



## Thomas_v2.1 (11 Dezember 2013)

Als ich heute WinCC V7.2 mit einer 416 und Ethernet-CP verbunden und da etwas mitgelauscht habe, ist mir eine bisher unbekannte Adressierungsart aufgefallen.
Die meistbenutzte Adressierung ist die über den 10 Byte langen S7-Anypointer mit Syntax Id 0x10.

Ich habe in einem Testprojekt nur zwei Variablen gehabt, eine auf DB50.DBD0 und DB55.DBD0 adressiert. Nun hat WinCC diese Variablen anders aus der SPS gelesen, und zwar über eine Adresse mit Syntax Id 0xb0 und einer folgenden Adressangabe mit 7 Bytes Länge, also inkl. Vorkopf 9 Bytes.

Wahrscheinlicher Aufbau:
1: 	0x12		// Varspec
2:	0x07		// Länge
3:	0xb0		// Sytax Id

4:	0x01		// Size-Type???

5:	0x04		// Anzahl

6:	0x00		// DB-Nummer
7: 	0x37

8:	0x00		// Offset
9:	0x00

Eigentlich wollte ich das an einer 300er CPU weiter erforschen, musste aber feststellen dass diese mit den Daten nichts anfangen kann. D.h. das ist etwas 400er spezifisches.
Ich sehe das bei der WinCC Version auch das erste mal. Diese Adressierungsart spart gegenüber der anderen 3 Byte pro Datenbereich ein, bei gestückelten Datenbereichen könnte man z.B. bei einer 240er PDU 25 anstelle 19 Bereiche in einer PDU lesen.

Hat einer eine Ahnung was das ist, bzw. wie Siemens das nennt?


----------



## Jochen Kühner (12 Dezember 2013)

Ich hab im Geschäft auch noch ein paar 400er könnte noch probieren ob das bei diesen auch funzt! Vielleicht steht die Unterstützung dieser Adressierung auch wieder in einer SZL (so wie die Unterstützung der 2 versch. Statusanfragen).


----------



## Jochen Kühner (12 Dezember 2013)

Ich werds am Freitag mal noch mit verschiedenen CPUs testen und auch mit verschiedenen Werten für den von dir geschätzten Size Type Parameter...
Hab das ganze auch schonmal in meine modifizierte libnodave gebaut... muss aber erst am Fr testen, und dann mal schaun wie Ich das in meine Leseoptimierung in der .net Bibliothek einbauen kann, aber erst muss ich mal noch rausfinden wie man feststellen kann ob das protokoll unterstützt ist...


----------



## Jochen Kühner (12 Dezember 2013)

In der SZL xy31 INDEX 2 steht ja z:b. das 7te Bit für das mögliche Statustelegram und laut der Doku ist das ja Reserviert... Man bräuchte mal ne neuere Doku der SZLs...


----------



## Rainer Hönle (12 Dezember 2013)

Thomas_v2.1 schrieb:


> Als ich heute WinCC V7.2 mit einer 416 und Ethernet-CP verbunden und da etwas mitgelauscht habe, ist mir eine bisher unbekannte Adressierungsart aufgefallen.
> Die meistbenutzte Adressierung ist die über den 10 Byte langen S7-Anypointer mit Syntax Id 0x10.
> 
> Ich habe in einem Testprojekt nur zwei Variablen gehabt, eine auf DB50.DBD0 und DB55.DBD0 adressiert. Nun hat WinCC diese Variablen anders aus der SPS gelesen, und zwar über eine Adresse mit Syntax Id 0xb0 und einer folgenden Adressangabe mit 7 Bytes Länge, also inkl. Vorkopf 9 Bytes.
> ...


Ist zyklisches Lesen bei Änderung. Funktioniert nur bei DB-Operanden.


----------



## Thomas_v2.1 (12 Dezember 2013)

Rainer Hönle schrieb:


> Ist zyklisches Lesen bei Änderung. Funktioniert nur bei DB-Operanden.



Aber es wird vorher von WinCC nichts zyklisches angemeldet. Es wird wie auch bei der anderen Adressierungsart von WinCC gepollt, also das übliche Frage- und Antwortspiel.
Vor allem habe ich bei den WinCC Systemparametern das zyklische Lesen deaktiviert.


----------



## Rainer Hönle (12 Dezember 2013)

Ich glaube WinCC macht das automatisch unter dem Blech.


----------



## Jochen Kühner (12 Dezember 2013)

Rainer Hönle schrieb:


> Ist zyklisches Lesen bei Änderung. Funktioniert nur bei DB-Operanden.



Heist das dann eines der Bits der SZL 0x131 Index 3 sagt aus ob es Funktioniert ? (in funkt 0 gibts ja die Bits "2=Initialize Cyclic Reading (start implicitely)","3=Initialize Cyclic Reading (start explicitly)","4=start cyclic reading")


----------



## Thomas_v2.1 (12 Dezember 2013)

Ich habe gerade mal ein Logfile mit WinCC7.0 wo die "echten" zyklischen Dienste verwendet werden, mit einem Logfile einer CPU mit diesem Spezialtelegramm verglichen.
Bei SZL 0x131 Index 3 ist bei funkt_0 im Bit 7 wirklich ein Unterschied. Bei der CPU welche jetzt dieses Spezialtelegramm kann ist das auf True, bei der anderen auf False. Bei funkt_1 sind aber auch noch die ersten beiden Reservebits 1 und 2 auf True.

In den Siemens Dokus die mir vorliegen steht an den Stellen leider überall Reserve. Vlt. hat noch jemand ein Handbuch in dem das erläutert war (die Anzahl der Informationen wurde immer mal wieder geändert).

WinCC 7.2 schiebt dem Ganzen jetzt noch eine SZL Abfrage auf 132/4 vorweg, dort verbergen sich im Reserve-Teil auch noch viele Daten (sind nicht alle Null).

Ich habe auch noch keine Idee wie ich diese Anfrage bezeichnen soll, wirklich zyklisch ist es nicht.


----------



## Rainer Hönle (12 Dezember 2013)

Auch auf die Gefahr hin, dass Du mir wieder nicht glaubst: es handelt sich um ein zyklisches Lesen bei Änderung. Wenn Du nichts zyklisches siehts, dann gab es an dem Operanden keine Änderung.


----------



## Thomas_v2.1 (12 Dezember 2013)

Gut, ich sehe natürlich nicht was da im Hintergrund noch abläuft.
Ich sehe nur dass WinCC die Variablen über diese Syntax-Id im eingestellten Zyklus (z.B. 2s) pollt, also alle 2 Sekunden Anfrage- und Antworttelegramm. Im Prinzip genauso wie wenn WinCC die Daten über die Syntax-Id 0x10 lesen würde. Im Anworttelegramm bei Syntax-Id 0xb0 ist den Daten noch ein 0xff vorangestellt.

Zumindest habe ich festgestellt, dass die Option bei den WinCC Systemparameter überhaupt keine Auswirkung zu haben scheint.


----------



## Jochen Kühner (13 Dezember 2013)

Also Ich hab nun mal versucht den read request auch so zu starten... funzt auch, auch in kombination mit normalen requests in einer PDU. Nur wenn Ich 2 oder mehr Datenblöcke gleichzeitig über einen solchen Request anfragen will -> kommt gar keine Antwort mehr...


----------



## Thomas_v2.1 (13 Dezember 2013)

Wenn es dann nur möglich ist einen Datenbereich abzufragen, lässt sich mit dieser Adressierung ja nicht viel gewinnen.
Naja, ich ergänze es mal im Plugin insofern, dass die Werte wenigstens angezeigt werden. Neben dem Item wird die angefragte Adresse in der bekannten Any-Pointer Syntax angezeigt (siehe Screenshot).
Der Aufbau der Antwort lässt sich nur erschließen wenn man diese mit der vorigen Anfrage kombinieren würde. Das erste Byte in der Antwort hat die gleiche Bedeutung wie auch im übergeordneten Datenteil, ebenfalls Return-code: 0xff bei Erfolg, 0x05 beispielsweise wenn die Adresse in der SPS nicht vorhanden ist.

Was noch fehlt ist das erste Byte bei der Anfrage, da habe ich bisher immer eine 0x01 gesehen. Entweder das ist nochmal eine Art Dienstkennung, oder wieder eine Angabe über die Transport-Größe, wobei 0x01 nicht mit den anderen bekannten Werten zusammenpasst.

Hat schonmal jemand ein Logfile einer S7-Verbindung zwischen zwei S7-CPUs gemacht? Das sollte eigentlich auch vom plugin entschlüsselt werden können, aber das konnte ich mir noch nie ansehen.


----------



## Jochen Kühner (13 Dezember 2013)

Kann dir gerne auch mal meine geänderte libnodave zukommen lassen, dort hab ich die anfrage eingebaut...


----------



## Thomas_v2.1 (13 Dezember 2013)

Jochen Kühner schrieb:


> Kann dir gerne auch mal meine geänderte libnodave zukommen lassen, dort hab ich die anfrage eingebaut...


Wird dein Projekt bei Github nicht mehr weiter gepflegt? 
Mir fehlt nur die Bedeutung des ersten Bytes.


----------



## Rainer Hönle (13 Dezember 2013)

Thomas_v2.1 schrieb:


> Wenn es dann nur möglich ist einen Datenbereich abzufragen, lässt sich mit dieser Adressierung ja nicht viel gewinnen.
> Naja, ich ergänze es mal im Plugin insofern, dass die Werte wenigstens angezeigt werden. Neben dem Item wird die angefragte Adresse in der bekannten Any-Pointer Syntax angezeigt (siehe Screenshot).
> Der Aufbau der Antwort lässt sich nur erschließen wenn man diese mit der vorigen Anfrage kombinieren würde. Das erste Byte in der Antwort hat die gleiche Bedeutung wie auch im übergeordneten Datenteil, ebenfalls Return-code: 0xff bei Erfolg, 0x05 beispielsweise wenn die Adresse in der SPS nicht vorhanden ist.
> 
> ...


Da ist nur 0x01 gültig.


----------



## Jochen Kühner (13 Dezember 2013)

Thomas_v2.1 schrieb:


> Wird dein Projekt bei Github nicht mehr weiter gepflegt?
> Mir fehlt nur die Bedeutung des ersten Bytes.



doch, aber die änderungen hab ich nicht gepusht, wenn da wirklich nur eine anfrage geht machts nicht wirklich sinn das einzubauen


----------



## Rainer Hönle (15 Dezember 2013)

Hallo Thomas,
hast Du mal ein komplettes wireshark-Log vom CR bis zur (mehrfachen) Verwendung von 0xB0? Eventuell verwendet Siemens diese Struktur nicht nur in dem von mir erkannten Kontext "Zyklisches Lesen bei Änderung".


----------



## Thomas_v2.1 (15 Dezember 2013)

Moin Rainer,
im Anhang ein komplettes Logfile vom WinCC Systemstart bis zur Abfrage der Variablen, WinCC 7.2 mit einer S7-416 (Mlfb kann ich dir nicht sagen).
Ich habe die aktuelle s7comm.dll für 32-Bit Wireshark mit reingepackt, damit werden auch alle in der Anfrage aufgeführten SZL-IDs aufgeschlüsselt.

Wenn jemand irgendwelche Fehler im Dissector hat, oder Dinge die evtl. besser anders dargestellt werden sollte: Ich habe die nächste Woche etwas Zeit mich dadrum zu kümmern.


----------



## Rainer Hönle (15 Dezember 2013)

Jochen Kühner schrieb:


> Also Ich hab nun mal versucht den read request auch so zu starten... funzt auch, auch in kombination mit normalen requests in einer PDU. Nur wenn Ich 2 oder mehr Datenblöcke gleichzeitig über einen solchen Request anfragen will -> kommt gar keine Antwort mehr...


Die Struktur ist 7 Bytes lang, da musst Du ein 0x00 anhängen, damit die Strukturen immer an gerader Adresse beginnen (kann und muss bei der letzten Struktur entfallen). Führe dann Deinen Test mal nach der Änderung mit mehreren Strukturen durch.


----------



## Jochen Kühner (16 Dezember 2013)

Rainer Hönle schrieb:


> Die Struktur ist 7 Bytes lang, da musst Du ein 0x00 anhängen, damit die Strukturen immer an gerader Adresse beginnen (kann und muss bei der letzten Struktur entfallen). Führe dann Deinen Test mal nach der Änderung mit mehreren Strukturen durch.



Ah alles klar... probiers morgen nochmals... wenns geht push Ich meine geänderte libnodave in meine toolbox, dort hab ich den support auch drinn. Muss nur mal schaun wie Ich das in libnodave mache mit dem 0x00 anhängen, da ich im moment nur eine Funktion zusätzlich habe, mal schaun..


----------



## Thomas_v2.1 (16 Dezember 2013)

Kannst ja vielleicht auch nochmal testen ob das erste Byte wirklich konstant 0x01 sein muss, oder ob das der ORG-Kennung aus dem Fetch/Write-Protokoll entspricht. Dann sollte man z.B. mit 0x02 an der Stelle auch Merker lesen können. Komme dieses Jahr zum Testen an keine 400er mehr ran.


----------



## Jochen Kühner (16 Dezember 2013)

Thomas_v2.1 schrieb:


> Kannst ja vielleicht auch nochmal testen ob das erste Byte wirklich konstant 0x01 sein muss, oder ob das der ORG-Kennung aus dem Fetch/Write-Protokoll entspricht. Dann sollte man z.B. mit 0x02 an der Stelle auch Merker lesen können. Komme dieses Jahr zum Testen an keine 400er mehr ran.



Also mit 02 Kommt "Invalid Adress" als Result, also geht nicht! Aber mit dem Füllbyte funzt die anfrage mehrerer Blöcke!

Könntest du mir das Wireshark Plugin auch als 64 Bit Version anhängen? Und kannst du denn dann auch das Füllbyte in der Anfrage auswerten?


----------



## Jochen Kühner (16 Dezember 2013)

Noch was: In der Antwort ist ein Byte mehr enthalten weißt du denn was es bedeutet?


----------



## Jochen Kühner (16 Dezember 2013)

Also Ich hab die Funktionalität nun mal in meine ToolBox eingebaut, mit der WPF Var Tab hab Ich es getestet! Man muss im Konfigurationsbildschirm aber einen Haken setzten das er diesen RequestTyp nutzt!


----------



## Thomas_v2.1 (16 Dezember 2013)

Das erste Byte in der Antwort ist nochmal ein Return-Code, also 0xff bei Erfolg, z.B. 0x05 wenn die Adresse nicht vorhanden ist. 0x05 habe ich selber auch schon gesehen, hab einfach Online aus der SPS den DB gelöscht und dann steht dort 0x05. Scheint also die gleiche Bedeutung zu haben wie auch im übergeordneten Datenteil, lässt sich im Wireshark Plugin aber nicht implementieren.

Im Anhang die dll als 32 und 64 Bit Version bei denen ich auch das Füllbyte im Parameterteil eingebaut habe. Kannst ja mal ein logfile von so einer Anfrage anhängen.

Ich habe zwischenzeitlich noch ein paar andere Sachen ergänzt, hauptsächlich bei den SZL Anfragen. Die Tage gibts dann auch mal ein offizielles Release.


----------



## Jochen Kühner (16 Dezember 2013)

Thomas_v2.1 schrieb:


> Das erste Byte in der Antwort ist nochmal ein Return-Code, also 0xff bei Erfolg, z.B. 0x05 wenn die Adresse nicht vorhanden ist. 0x05 habe ich selber auch schon gesehen, hab einfach Online aus der SPS den DB gelöscht und dann steht dort 0x05. Scheint also die gleiche Bedeutung zu haben wie auch im übergeordneten Datenteil, lässt sich im Wireshark Plugin aber nicht implementieren.
> 
> Im Anhang die dll als 32 und 64 Bit Version bei denen ich auch das Füllbyte im Parameterteil eingebaut habe. Kannst ja mal ein logfile von so einer Anfrage anhängen.
> 
> Ich habe zwischenzeitlich noch ein paar andere Sachen ergänzt, hauptsächlich bei den SZL Anfragen. Die Tage gibts dann auch mal ein offizielles Release.



Könnte man denn nicht die Transport Size auswerten? und durch diese darauf schließen das es eine antwork auf eine andere anfrage ist? oder kann das 0x09 auch bei der Normalen Anfrage vorkommen?


----------



## Thomas_v2.1 (16 Dezember 2013)

Jochen Kühner schrieb:


> Könnte man denn nicht die Transport Size auswerten? und durch diese darauf schließen das es eine antwork auf eine andere anfrage ist? oder kann das 0x09 auch bei der Normalen Anfrage vorkommen?



0x09 kann auch normal vorkommen, z.B. wenn du eine Anfrage mit Size-type 0x03 (Char) stellst, antwortet die SPS mit transport-size 0x09. Oder wenn man aus der S7-1200 per symbolischem Zugriff eine Stringvariable liest.


----------



## Jochen Kühner (16 Dezember 2013)

Thomas_v2.1 schrieb:


> 0x09 kann auch normal vorkommen, z.B. wenn du eine Anfrage mit Size-type 0x03 (Char) stellst, antwortet die SPS mit transport-size 0x09. Oder wenn man aus der S7-1200 per symbolischem Zugriff eine Stringvariable liest.



Ok, danke für die Info... Laufen tuts mal...


----------



## Zottel (17 Dezember 2013)

Jochen Kühner schrieb:


> Ah alles klar... probiers morgen nochmals... wenns geht push Ich meine geänderte libnodave in meine toolbox, dort hab ich den support auch drinn. Muss nur mal schaun wie Ich das in libnodave mache mit dem 0x00 anhängen, da ich im moment nur eine Funktion zusätzlich habe, mal schaun..


Schau mal in addToWriteRequest, Zeile 609, da wird auch so etwas gemacht.


----------



## Thomas_v2.1 (18 Dezember 2013)

Es ist eine neue s7comm.dll in der Version 0.0.4 verfügbar.

Folgende Erweiterungen / Ergänzungen:
- Ergänzung 1200 symbolischer Zugriff
- SZL ID/Index 0x0131 Index 0x0010 ergänzt
- Bei Variablendiensten die Syntax-Id 0xb0 ergänzt
- SZL partial list extracts ergänzt
- Optimierte Darstellung von SZL ID/Index Anfragen die über mehrere PDU gehen (Fragmentierung)
- Keine Unterscheidung mehr zwischen SZL ID 0x0111 und 0x0011
- Filtermöglichkeiten bei Variablendiensten erweitert
- Für einige SZL IDs die Index-Beschreibungen ergänzt
- SZL ID 0xxy74 ergänzt

Dann habe ich mal getestet wie man das plugin unter Linux übersetzt, und eine Kurzanleitung wie es unter Debian (und wahrscheinlich auch Ubuntu und anderen Debian-basierenden Linuxen) funktionieren sollte.
Die Kurzanleitung liegt unter:
http://sourceforge.net/projects/s7commwireshark/files/

Für das Linux-build ist die letzte Version aus dem SVN zu verwenden.


----------



## Thomas_v2.1 (29 Dezember 2013)

Mir ist grad noch ein Unterschied zwischen dem TIA-Portal V11 und V12 aufgefallen. Wenn man eine HMI-Simulation mit der V11 auf dem PC mit einer S7-1200 gestartet hat, wurden die Daten per LID, CRC usw. wie auch schon rausgefunden über die 0x32er Protokolle (was auch libnodave kann) abgefragt.

Jetzt habe ich das gleiche mal mit der V12 gemacht, und dort läuft das jetzt über die 0x72er Protokolle. Irgendwie werden die Daten auch per Request/Response ausgetauscht, aber in den Datensätzen steckt der LID zwar noch drin, aber der CRC wird (wenn es noch ein CRC ist) dann wieder anders berechnet. Entweder mit einem anderen Generatorpolynom oder nicht nur über den Symbolnamen. Habs noch nicht rausgefunden.

Ich verstehe nicht wieso man bei einem komplett neuen System wieder mit zig verschiedenen Protokollen anfangen musste. Es hätte doch gereicht wenn man Variablen auf eine einzige Weise lesen und schreiben kann. Naja, ich muss das Zeugs ja nicht warten...


----------



## Thomas_v2.1 (28 Februar 2014)

Gibt noch eine neue Erkenntnis zur Syntax-Id 0xb0 welche WinCC gerne zusammen mit einer S7-400 verwendet. 
Damit lassen sich doch mehrere Bereiche in einer PDU auslesen, die Anzahl steht in dem einen Byte was ich erst mit 1 als konstant angenommen habe. So wie es aussieht lassen sich maximal 32 Bytes am Stück lesen, warum auch immer (siehe Screenshot). Diese Adressierungsart scheint bei WinCC7.2 voll in Mode zu sein, dort wird das nur noch verwendet.
Im Antworttelegramm gibt es dann pro Datenblock ein Byte Vorkopf mit dem Return code, das lässt sich in Wireshark aber nicht zerlegen weil dazu in dem Telegramm die Informationen fehlen.

Ich bin ja immer noch skeptisch dass das wie Rainer schrieb zyklische Daten, bzw. Telegramme um Daten auf Änderung abzufragen sind. Mir scheint als werden damit ganz normal wie auch mit der anderen Adressierungsart Daten angefordert und zurückgeschickt, denn in den Telegrammen dich ich aufgezeichnet habe gab es in der SPS garantiert keine Änderung.


----------



## Jochen Kühner (28 Februar 2014)

Dann muss Ich meine realisierung in libnodave nochmal umbauen... welche größe zeigt den dieses Byte nun an? Die Anzahl der SubItems? Oder die Byte größe?

Hasst du denn eine Ahnung ob Ich über irgendeine SZL auslesen kann ob denn diese Adressierungsart möglich ist?

Muss auch mal schaun wie Ich das ganze in meine Leseoptimierung einbaue...


----------



## Thomas_v2.1 (28 Februar 2014)

Ja, die Anzahl der Subitems, kommt direkt nach der Syntax-Id. Ich hab eben schon gesehen dass das in den Screenshot noch fehlt, ich habe noch ein paar Filtermöglichkeiten ergänzt und da ist das Feld unter den Tisch gefallen.
Aber ein relevanter Geschwindigkeitsgewinn ist damit meiner Meinung nach nicht zu erwarten. Für die Anfrage in dem Screenshot hätte auch ein einziger "klassischer" Lesebefehl mit 256 Bytes funktioniert. Einen Unterschied gibt es evtl. bei vielen verschiedenen kleinen Datenbereichen, da die Adressangabe ein paar Bytes weniger hat.
Ich hänge mal ein komplettes Wireshark Log an, von WinCC Start bis Ende - es wird alles über diese Syntax-Id gelesen.


----------



## Jochen Kühner (1 März 2014)

Thomas_v2.1 schrieb:


> Ja, die Anzahl der Subitems, kommt direkt nach der Syntax-Id. Ich hab eben schon gesehen dass das in den Screenshot noch fehlt, ich habe noch ein paar Filtermöglichkeiten ergänzt und da ist das Feld unter den Tisch gefallen.
> Aber ein relevanter Geschwindigkeitsgewinn ist damit meiner Meinung nach nicht zu erwarten. Für die Anfrage in dem Screenshot hätte auch ein einziger "klassischer" Lesebefehl mit 256 Bytes funktioniert. Einen Unterschied gibt es evtl. bei vielen verschiedenen kleinen Datenbereichen, da die Adressangabe ein paar Bytes weniger hat.
> Ich hänge mal ein komplettes Wireshark Log an, von WinCC Start bis Ende - es wird alles über diese Syntax-Id gelesen.



Hast du denn mal versucht mehr als 32 Bytes zu lesen, also selbst, ohne WinCC?


----------



## Rainer Hönle (1 März 2014)

Es können maximal 255 Bytes am Stück gelesen werden (mehr Längenangabe passt nicht in ein Byte).


----------



## Jochen Kühner (1 März 2014)

Nochmal, gibts ne möglichkeit rauszufinden ob ne CPU das unterstützt? Oder unterstützt das z.B. jede 400er und keine 300er? Dann könnte Ich ja einfach per SZL die MLFB lesen und dann nur bei 400ern verwenden?


----------



## Thomas_v2.1 (1 März 2014)

Jochen Kühner schrieb:


> Nochmal, gibts ne möglichkeit rauszufinden ob ne CPU das unterstützt? Oder unterstützt das z.B. jede 400er und keine 300er? Dann könnte Ich ja einfach per SZL die MLFB lesen und dann nur bei 400ern verwenden?


Funktioniert das bei einer 300er denn nicht? Vielleicht war die Funktion in WinCC auch schon immer vorhanden, und mit ist das bisher nur nicht aufgefallen, weil ich nur selten eine 400er mit Ethernet-CP zum Test da habe.

Wenn es bei einer 300er bei dir nicht funktioniert, könnte man die Inhalte der SZL-Abfragen von WinCC vergleichen. Ich habe hier eine IM151-8 CPU mit der ich mal verglichen habe.
WinCC fragt ab:
1) 0x0424 Index 0x0000
-> imho irrelevant für Kommunikation

2) 0x0131 Index 0x0003
-> Unterschiede nur in den bisher unbekannten Reservebits von funkt_0 und funkt_1. In dem großen Reserveblock am Ende ist auch noch ein Unterschied

3) 0x0131 Index 0x0010
-> In der IM151-8 überhaupt nicht vorhanden

4) 0x132 Index 0x0006
-> Keine Unterschiede

Möglich wäre jetzt, mit meiner ersten Nettoplcsim-Version die SZL Daten in den entsprechenden Bits zu modifizieren und testen wann WinCC auf den anderen Modus umschaltet.
In der Version fehlt aber noch die Antwort auf diesen seltsamen S7CHN -Request, da weiß ich überhaupt nicht wozu das gut sein soll. Vielleicht kann eine S7-300 das auch nicht.


----------



## Thomas_v2.1 (1 März 2014)

Fehlt noch einer:
5) 0x0132 Index 0x004
In dem großen Reserveblock gibt es auch Unterschiede


----------



## Jochen Kühner (3 März 2014)

Thomas, könntest du auch eine MacOS Version des Plugins compilieren?


----------



## Thomas_v2.1 (3 März 2014)

Jochen Kühner schrieb:


> Thomas, könntest du auch eine MacOS Version des Plugins compilieren?


Von Macs habe ich keine Ahnung, kann nur für Windows und Linux übersetzen.


----------



## Thomas_v2.1 (3 März 2014)

Jochen Kühner schrieb:


> Thomas, könntest du auch eine MacOS Version des Plugins compilieren?



Hast du denn einen C-Compiler für MacOS? Das Übersetzen von Wireshark unter Linux ist zumindest wesentlich einfacher als unter Windows. Wenn das Entwicklungssystem steht, braucht man nur die Wireshark-Quellen herunterladen, einmal Wireshark übersetzen, dann mein Plugin an passender Stelle dazukopieren und im plugin-Verzeichnis nochmal "make"n. Das ist unter Windows zwar generell auch so, nur ist da kein fertiges Entwicklungssystem wie bei Linux von Haus aus an Bord.
Bei sourceforge habe ich eine Textdatei hochgeladen wie das unter Linux mit Debian bei mir zumindest funktioniert.


----------



## Jochen Kühner (3 März 2014)

Thomas_v2.1 schrieb:


> Hast du denn einen C-Compiler für MacOS? Das Übersetzen von Wireshark unter Linux ist zumindest wesentlich einfacher als unter Windows. Wenn das Entwicklungssystem steht, braucht man nur die Wireshark-Quellen herunterladen, einmal Wireshark übersetzen, dann mein Plugin an passender Stelle dazukopieren und im plugin-Verzeichnis nochmal "make"n. Das ist unter Windows zwar generell auch so, nur ist da kein fertiges Entwicklungssystem wie bei Linux von Haus aus an Bord.
> Bei sourceforge habe ich eine Textdatei hochgeladen wie das unter Linux mit Debian bei mir zumindest funktioniert.



Werd's die nächsten Tage mal probieren...


----------



## Thomas_v2.1 (2 Mai 2014)

Vielleicht gibts von Siemens ja demnächst ein offizielles Plugin. Stellenanzeige für Praktikanten gibts schon:

https://jobsearch.siemens.biz/caree...ntroller_jobAlertName=&_s.crb=DQcKPcr0+M3q+Gc


----------



## Rainer Hönle (3 Mai 2014)

Kanst Dich ja mal bewerben, wäre doch sicher interessant wie die reagieren


----------



## rostiger Nagel (3 Mai 2014)

Die suchen nur ein Praktikanten, der arbeitet mal eben 6 Wochen an den Projekt 
und wir bekommen das dann wieder als unfertige Software, so wie TIA.
Dann sind da so viele Bugs drin die sich aber nicht mehr beheben lassen und es
wird ein Softwaremoloch, deren Endwicklung weiter über viele Jahre in die falsche 
Richtung geht, da man sich den lapidaren Fehler nicht eingestehen will.

Der Praktikant hat in den 6 Wochen soviel Erfahrung sammeln können, wie man es
nicht machen sollte und geht nach dem Studium als er erfahrener Entwickler zu 
Beckhoff und macht Karriere und wird sogar noch anständig bezahlt.

Den Service für die wiederholende Fehlentwicklung bei Siemens macht dann das SPS-Forum.
der Support bei Siemens verschickt weiterhin Standard Antworten wie:
'Da muß etwas bei ihrer Installation schief gelaufen sein, deinstallieren sie die Software und
spielen sie diese neu ein.'

Als nächstes Schritt:
'Ihr neu erworbener Rechner i7 mit 188GB RAM und 88 Terabyte SSD ist für diese Software
nicht leistungsfähig genug, denken Sie mal darüber nach sich für ihr Projekt sich eine Sitzung
bei einen super Rechner anzumieten'.


----------



## Thomas_v2.1 (3 Mai 2014)

Rainer Hönle schrieb:


> Kanst Dich ja mal bewerben, wäre doch sicher interessant wie die reagieren



Und dann mal kurz einen Blick in die offiziellen Dokumente nehmen 
Die Frage ist, ob Siemens da überhaupt ein Dokument mit einer Protokollbeschreibung pflegt, oder ob der Praktikant sich alles aus C-Quellen zusammensuchen darf.
Wenn es wirklich eine Dokumentation zu dem Protokoll gibt, sind sicher 3/4 der Arbeit reine Fleißarbeit.

Mal abgesehen davon wofür Praktikanten sonst so eingesetzt werden, ist es in diesem Fall aber durchaus möglich, da es sich um einen eigenen abgeschlossenen Teil handelt der nichts mit anderen Produkten zu tun hat. Und wenn bei der Arbeit letztenendes Mist bei rauskommt, kann man das Projekt ohne großen Verlust einstampfen.


----------



## Rainer Hönle (3 Mai 2014)

So nach dem Motto: was Günter Wallraff bei Burger King getan hat, könnte auch bei Siemens funktionieren. Wenn mir im Augenblick langweilig wäre, könnte ich daran glatt Gefallen finden ;-)


----------



## Rainer Hönle (3 Mai 2014)

@Thomas_v2.1: Kommst Du eigentlich zum Forumstreffen? Wir könnten dann da mal ein bischen fachsimpeln.


----------



## Thomas_v2.1 (3 Mai 2014)

Rainer Hönle schrieb:


> @Thomas_v2.1: Kommst Du eigentlich zum Forumstreffen? Wir könnten dann da mal ein bischen fachsimpeln.



Ja, hab das Thema schon gesehen, wäre sicher interessant. Klappt aber leider nicht.


----------



## Rainer Hönle (4 Mai 2014)

Schade, wäre sicher sehr interessant gewesen


----------



## Blockmove (4 Mai 2014)

rostiger Nagel schrieb:


> Der Praktikant hat in den 6 Wochen soviel Erfahrung sammeln können, wie man es
> nicht machen sollte und geht nach dem Studium als er erfahrener Entwickler zu
> Beckhoff und macht Karriere und wird sogar noch anständig bezahlt.



TIA hin oder her aber ist Beckhoff wirklich besser?
In den Bereichen Software und Support höre ich über Beckhoff genau soviel Gejammere wie über Siemens.
Von der Ankündigung bis zur Produktverfügbarkeit / brauchbarkeit vergeht bei Beckhoff auch einiges an Zeit.

Von daher muss der Praktikant woanders hin und Karriere machen 

Gruß
Dieter


----------



## Question_mark (3 August 2014)

*S7Comm.DLL Fehler beim Start von Wireshark*

Hallo,

ich habe ein Problem mit Wireshark und der S7comm.dll, beim Start von Wireshark kommen 2 Fehlermeldungen.







Die S7Comm.DLL ist die aktuelle 64-Bit Version von Sourceforge (V 0.0.0.4 vom 17.12.2013).

Und hier ein Screenshot mit der installierten Wireshark Version :




Das OS ist Win7 Prof SP1 64-Bit mit aktuellen Updates. Tante Google konnte mir nicht weiterhelfen, vielleicht hat einer 
von Euch eine Idee zur Problemlösung ?

Gruß

Question_mark

PS : Das Protokoll T.125 habe ich schon deaktiviert, hat aber nicht geholfen


----------



## Thomas_v2.1 (3 August 2014)

Hi,
das liegt an der neueren Wireshark Version. Bei der Version 1.12 wurde an der Wireshark-API etwas geändert, sodass meine s7comm.dll mit dieser Version nicht mehr kompatibel ist.
Momentan kannst du die s7comm.dll nur mit Wireshark bis Version 1.10 verwenden.

Ich hatte mir das vor einiger Zeit als die 1.12 in den Startlöchern stand schonmal angesehen, wollte dann aber nicht zwei dlls für die verschiedenen Wireshark Versionen anbieten, weil der Ersatz für die entfallene Funktion nicht in der alten Wireshark Version verfügbar wäre.

Am sinnvollsten wäre es wenn das Plugin direkt in das Wireshark Release eingebaut wird. Aber da habe ich noch einiges zu tun, und es wird wohl auch eine Weile dauern bis es durch den Review-Prozess kommt und in einer Release-Version erscheint.


----------



## Question_mark (3 August 2014)

*Danke für den Tip*

Hallo,

@thomas_v2.1

Vielen Danl für die schnelle Antwort. Ich habe jetzt die Wireshark Version 1.10.0.9 installiert, 
mein Problem hat sich damit erledigt. Ich muss nur in Zukunft aufpassen, nicht versehentlich ein
Update von Wireshark anzustossen   

Gruß

Question_mark


----------



## Thomas_v2.1 (3 August 2014)

Question_mark schrieb:


> Vielen Danl für die schnelle Antwort. Ich habe jetzt die Wireshark Version 1.10.0.9 installiert,
> mein Problem hat sich damit erledigt. Ich muss nur in Zukunft aufpassen, nicht versehentlich ein
> Update von Wireshark anzustossen



Die Version 1.12.0 von Wireshark ist auch grade mal drei Tage draußen, hatte ich selber bis eben auch noch nicht drauf. Die Qt-Preview von Wireshark haut mich nicht unbedingt vom Hocker, ist wohl eher für Apfel-Nutzer interessant.

Ich habe gerade eine Version 0.0.5 des Plugins veröffentlicht welches mit der Wireshark Version 1.12.0 funktioniert.
Mit älteren Versionen von Wireshark (alles vor 1.12.0) lässt sich die dll allerdings nicht mehr verwenden. 
Es gab sonst keine Änderungen oder Erweiterungen am Plugin.

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


----------



## egal (4 August 2014)

Hi,

besten Dank dafür;
funktioniert bestens mit Linux | Debian 64bit.

(es reicht nach Installation des Quellpaketes und Plugin 'Custom'-Einbindung nur das Plugin allleine zu compilen und die Lib anschließend enstpr. zu kopieren, man muß nicht den ganzen 'Moloch' übersetzen ;-)


----------



## Thomas_v2.1 (4 August 2014)

egal schrieb:


> funktioniert bestens mit Linux | Debian 64bit.
> 
> (es reicht nach Installation des Quellpaketes und Plugin 'Custom'-Einbindung nur das Plugin allleine zu compilen und die Lib anschließend enstpr. zu kopieren, man muß nicht den ganzen 'Moloch' übersetzen ;-)



Kannst du nochmal genauer schreiben wie du das hinbekommst?
Ich lade mir die Wireshark Quellen runter, lade mir die Quellen für das s7comm-plugin in das plugins Verzeichnis von Wireshark und dann?

Damit das funktioniert muss aber auf deinem Rechner die libwireshark vorhanden sein, sonst müsste eigentlich der Linker beim Übersetzen meckern.


----------



## egal (4 August 2014)

Hi,



Thomas_v2.1 schrieb:


> Kannst du nochmal genauer schreiben wie du das hinbekommst?
> Ich lade mir die Wireshark Quellen runter, lade mir die Quellen für das s7comm-plugin in das plugins Verzeichnis von Wireshark und dann?
> 
> Damit das funktioniert muss aber auf deinem Rechner die libwireshark vorhanden sein, sonst müsste eigentlich der Linker beim Übersetzen meckern.



Ja, wireshark (+damit auch libwireshark5) und wireshark-dev sind ja vorher bereits installiert:

```
$ apt-cache show wireshark
Package: wireshark
Version: 1.12.0+git+4fab41a1-1
Installed-Size: 2745
Maintainer: Balint Reczey <balint@balintreczey.hu>
Architecture: amd64
Replaces: ethereal (<< 1.0.0-3)
Depends: libc6 (>= 2.15), libcairo2 (>= 1.2.4), libgdk-pixbuf2.0-0 (>= 2.22.0), libglib2.0-0 (>= 2.31.8), libgtk-3-0 (>= 3.7.10), libnl-3-200 (>= 3.2.7), libnl-genl-3-200 (>= 3.2.7), libnl-route-3-200 (>= 3.2.7), libpango-1.0-0 (>= 1.14.0), libpangocairo-1.0-0 (>= 1.14.0), libpcap0.8 (>= 0.9.8), libportaudio2 (>= 19+svn20101113), libwireshark5 (>= 1.12.0~rc3), libwiretap4 (>= 1.12.0~rc1), libwsutil4 (>= 1.12.0~rc3), zlib1g (>= 1:1.1.4), wireshark-common (= 1.12.0+git+4fab41a1-1), xdg-utils
```


```
$ apt-cache policy wireshark wireshark-dev libwireshark5
wireshark:
  Installiert:           1.12.0+git+4fab41a1-1
  Installationskandidat: 1.12.0+git+4fab41a1-1
  Versionstabelle:
 *** 1.12.0+git+4fab41a1-1 0
        500 http://http.debian.net/debian/ unstable/main amd64 Packages
        100 /var/lib/dpkg/status
wireshark-dev:
  Installiert:           1.12.0+git+4fab41a1-1
  Installationskandidat: 1.12.0+git+4fab41a1-1
  Versionstabelle:
 *** 1.12.0+git+4fab41a1-1 0
        500 http://http.debian.net/debian/ unstable/main amd64 Packages
        100 /var/lib/dpkg/status
libwireshark5:
  Installiert:           1.12.0+git+4fab41a1-1
  Installationskandidat: 1.12.0+git+4fab41a1-1
  Versionstabelle:
 *** 1.12.0+git+4fab41a1-1 0
        500 http://http.debian.net/debian/ unstable/main amd64 Packages
        100 /var/lib/dpkg/status
```
Nach Kopieren der Wireshark-Quellen und Plugin im ../plugins-Verzeichnis die Dataein custom.*.example nach custom.* kopieren und in diesen Files 'foo' durch 's7comm' ersetzen (> ../doc/Readme.plugins, Kapitel 3.1)
Anschließend im Wireshark-Quellverzeichnis autogen.sh + configure aufrufen +  evtl. make clean
Abschließend im Verzeichnis ../plugins/s7comm/ ein make
Die fertige Library aus ../s7comm/lib entspr. kopieren, hier z.B. (multiarch) nach /usr/lib/x86_64-linux-gnu/wireshark/plugins/1.12.0/


----------



## Thomas_v2.1 (4 August 2014)

Ah, ok. Du bist im unstable Debian Zweig. Ich habe stable mit einer dementsprechend alten offiziellen Wireshark Version laufen.

Die Custom.* Dateien sind übrigens im SVN-Repository meines Plugins vorhanden, wie auch eine Vorab-Version für S7comm-plus (also 1200/1500) - wobei die noch nicht ganz viel erkennt.
Wenn man ein svn checkout direkt ins plugins-Verzeichnis der Wireshark Quellen macht, muss eigentlich nichts mehr angepasst werden.


----------



## egal (4 August 2014)

Thomas_v2.1 schrieb:


> Ah, ok. Du bist im unstable Debian Zweig. Ich habe stable mit einer dementsprechend alten offiziellen Wireshark Version laufen.


yep, Desktop seitig immer, embedded Devices bleiben stable.



> Die Custom.* Dateien sind übrigens im SVN-Repository meines Plugins vorhanden, wie auch eine Vorab-Version für S7comm-plus (also 1200/1500) - wobei die noch nicht ganz viel erkennt.
> Wenn man ein svn checkout direkt ins plugins-Verzeichnis der Wireshark Quellen macht, muss eigentlich nichts mehr angepasst werden.


Ah, ich sehe es, noch einfacher das ist 
	

	
	
		
		

		
			





S7comm_plus ist z.B. für TIA-Kommunikation, dann wird es hier im wireshark sichtbar (S7-1200).


----------



## Jochen Kühner (15 August 2014)

*MacOs Version*

Hier eine Version für MacOS Wireshark (64 Bit version 1.12)


----------



## Thomas_v2.1 (4 September 2014)

Der s7comm Dissector ist jetzt im offiziellen Wireshark Code-Repository. Ich denke mal dass er bei einem der nächsten Releases dabei sein wird.

An der grundsätzlichen Darstellung habe ich nur Kleinigkeiten geändert (es hat sich niemand beschwert). Ich musste aber noch einige Dinge ändern damit er durch den Code-Review Prozess kommt.
So sind jetzt für alle Felder die aufgeschlüsselt werden Filtermöglichkeiten vorhanden. Wenn man also nach einem bestimmten Feldwert suchen will, klickt man mit der rechten Maustaste auf das Feld und wählt "Apply as Filter".

Das s7comm-plus Plugin (für 1200/1500) ist noch nicht soweit dass man es einreichen könnte.


----------



## Thomas_v2.1 (10 September 2014)

Ich habe mir eben mal angesehen wie ein HMI Daten aus einer 1200er über s7comm-plus ausliest.
Im Antworttelegramm gibt es ein Byte für die diversen in der SPS vorhandenen Datentypen.
Alles mehr oder weniger normal, die Daten werden in der Network Byte Order übertragen.

Bis auf Datentyp DInt, also ein vorzeichenbehafteter 32 Bit Wert. Das scheint so exotisch zu sein dass Siemens sich da was ganz besonderes hat einfallen lassen. Ich schreibe mal ein paar Werte und die Bytes dazu:

```
-1 = 7f 00 00 00
  -2 = 7e 00 00 00
  -3 = 7d 00 00 00
  -4 = 7c 00 00 00
  +1 = 01 00 00 00
  +2 = 02 00 00 00
 +15 = 0f 00 00 00
 +16 = 10 00 00 00
 +32 = 20 00 00 00
 +48 = 30 00 00 00
 +63 = 3f 00 00 00
 +64 = 80 40 00 00

+126 = 80 7e 00 00
+127 = 80 7f 00 00
+128 = 81 00 00 00
+129 = 81 01 00 00

+254 = 81 7e 00 00
+255 = 81 7f 00 00
+256 = 82 00 00 00

-127 = ff 01 00 00
-128 = ff 00 00 00
-129 = fe 7f 00 00

123456789 = ba ef 9a 15
```

Hat da jemand eine Erklärung wie sich so ein Format nennt, und welchen Grund es hat nur bei diesem Datentyp eine Ausnahme vom Übertragungsformat von allen anderen Daten zu machen?


----------



## Jochen Kühner (10 September 2014)

Vielleicht gehts da um bytes zu sparen, d.h. Immer wenn das höchste bit im byte sitzt, folgt noch eins...


----------



## Jochen Kühner (11 September 2014)

d.h. 8 Bit => überlaufbyte
7 Bit => Negativbit

das 7te bit ist nur im ersten Byte das negativ Bit! ansonsten kann jedes byte 2^7 darstellen, wenn der Wert größer wird, wird das bit bei 2^8 gesetzt und dieses byte steht nun für die größeren werte...


----------



## Jochen Kühner (11 September 2014)

```
[COLOR=blue]private[/COLOR] [COLOR=blue]byte[/COLOR][] getBytes([COLOR=blue]int[/COLOR] value)
{
    [COLOR=blue]var[/COLOR] retVal = [COLOR=blue]new[/COLOR] [COLOR=#2b91af]List[/COLOR]<[COLOR=blue]byte[/COLOR]>();
 
    [COLOR=blue]var[/COLOR] wr = value;
    [COLOR=blue]if[/COLOR] (value < 0)
        wr *= -1;
 
    [COLOR=blue]var[/COLOR] anzBytes = 1;
    
    [COLOR=blue]var[/COLOR] anzBits = ([COLOR=blue]int[/COLOR])[COLOR=#2b91af]Math[/COLOR].Ceiling([COLOR=#2b91af]Math[/COLOR].Log(wr) / [COLOR=#2b91af]Math[/COLOR].Log(2));
    [COLOR=blue]if[/COLOR] (anzBits > 6)
    {
        anzBytes++;
        anzBits -= 6;
    }
    [COLOR=blue]while[/COLOR] (anzBits > 7)
    {
        anzBytes++;
        anzBits -= 7;
    }
    
 
    [COLOR=blue]for[/COLOR] ([COLOR=blue]int[/COLOR] i = 1; i <= anzBytes; i++)
    {
        [COLOR=blue]byte[/COLOR] wert = 0;
 
        [COLOR=blue]var[/COLOR] fakt = (anzBytes - i)*7;
        [COLOR=blue]var[/COLOR] divisor = ([COLOR=blue]int[/COLOR]) [COLOR=#2b91af]Math[/COLOR].Pow(2, fakt);
        wert = ([COLOR=blue]byte[/COLOR]) (wr/divisor);
        wr = wr%divisor;
 
        [COLOR=blue]if[/COLOR] (value < 0)
        {
            [COLOR=blue]if[/COLOR] (i == anzBytes || wr == 0)
                wert -= 1;
 
            wert = ([COLOR=blue]byte[/COLOR]) ~(wert);
            [COLOR=blue]if[/COLOR] (i == anzBytes)
                wert &= 0x7F;
 
            [COLOR=blue]if[/COLOR] (i == 1)
                wert |= 0x40;
        }
 
        [COLOR=blue]if[/COLOR] (i != anzBytes)
            wert |= 0x80;
 
 
        retVal.Add(wert);
    }
 
    [COLOR=blue]return[/COLOR] retVal.ToArray();
}
```


dieser Code funktioniert für deine Werte...


----------



## Thomas_v2.1 (11 September 2014)

Das ist doch total kaputt! Große Werte benötigen damit nämlich ein Byte mehr als normal. Dieses gepackte Format wird so wie es aussieht nur bei Ganzzahlen ab 4 Byte verwendet. Gleitkommazahlen werden nicht gepackt.
Ob sich der ganze Aufwand mit der Sonderbehandlung gelohnt hat um ein paar Bytes einzusparen, was in Summe im einstelligen Prozentbereich der Gesamtdatenmenge betragen dürfte? Ich weiß ja nicht...

In Rückwärtssrichtung sieht meine Wandlung jetzt so aus:

```
guint32 get_packed_int32(tvbuff_t *tvb, guint8 *number_of_bytes, gint32 *value, guint32 offset)
{
    int n;
    gint32 val = 0;
    guint8 b;

    for (n = 1; n <= 4+1; n++) {        /* große Werte benötigen 5 Bytes */
        b = tvb_get_guint8(tvb, offset);
        offset += 1;

        if ((n == 1) && (b & 0x40)) {   /* Vorzeichen prüfen */
            b &= ~0x40;
            val = 0xffffffff;
            val <<= 6;
        } else {
            val <<= 7;
        }
        if (b & 0x80) {                 /* es folgt noch ein Byte */
            b &= ~0x80;
            val |= b;
        } else {                        /* alle Bytes gelesen */
            val |= b;
            break;
        }
    }
    *number_of_bytes = n;
    *value = val;
    return offset;
}
```

Konstanten im Programmcode der 1200er Steuerung werden auch in einem ganz speziellen Format gepackt, aber dort nochmal komplett anders.
Bei Siemens scheint der Speicher wirklich teuer zu sein, wenn man an jeder Ecke solche Extrawürste braten musste.


----------



## Jochen Kühner (11 September 2014)

Scheint doch in die Richtung zu gehen: http://en.wikipedia.org/wiki/Variable-length_quantity


----------



## Thomas_v2.1 (11 September 2014)

Was es nicht alles gibt, das ist genau das Format.


----------



## Jochen Kühner (12 September 2014)

Also mein Algorythmus zum Codieren ist ja großer Müll... Aber hab im Moment keinen besseren Parat...


----------



## Jochen Kühner (12 September 2014)

.Net nutzt das ganze z.B. beim Serialisieren für die String Länge, aber dann nur für UInts, und da sieht der Algorithmus ja viel einfacher aus...


----------



## Thomas_v2.1 (13 September 2014)

Also was ich so gesehen habe, hat sich Siemens beim TIA-Portal wirklich viel bei Microsoft abgeguckt. Sei es hier, oder beim Bytecode für die 1200er.

Aber die Sache hier mit dem varuint Typ war wirklich ein Schlüssel. Es lüftet sich der Schleier, und man findet altbekannte Werte wie die CRC aus dem anderen Adressierungsmodus den die V11 verwendet hat wieder.


----------



## Zottel (16 September 2014)

Jochen Kühner schrieb:


> Also mein Algorythmus zum Codieren ist ja großer Müll... Aber hab im Moment keinen besseren Parat...


Wie ist es damit?
http://msdn.microsoft.com/en-us/library/system.io.binarywriter.write7bitencodedint.aspx

Mono macht das so:
https://github.com/mono/mono/blob/master/mcs/class/corlib/System.IO/BinaryWriter.cs

```
[TABLE="class: highlight tab-size-8 js-file-line-container"]
[TR]
[TD="class: blob-code js-file-line"]protected void Write7BitEncodedInt(int value) {
[/TD]
       [/TR]
       [TR]
                  [TD="class: blob-code js-file-line"]			do {
[/TD]
       [/TR]
       [TR]
                  [TD="class: blob-code js-file-line"]				int high = (value >> 7) & 0x01ffffff;[/TD]
       [/TR]
       [TR]
                  [TD="class: blob-code js-file-line"]				byte b = (byte)(value & 0x7f);[/TD]
       [/TR]
       [TR]
                  [TD="class: blob-code js-file-line"] 
[/TD]
       [/TR]
       [TR]
                  [TD="class: blob-code js-file-line"]				if (high != 0) {
[/TD]
       [/TR]
       [TR]
                  [TD="class: blob-code js-file-line"]					b = (byte)(b | 0x80);[/TD]
       [/TR]
       [TR]
                  [TD="class: blob-code js-file-line"]				}[/TD]
       [/TR]
       [TR]
                  [TD="class: blob-code js-file-line"] 
[/TD]
       [/TR]
       [TR]
                  [TD="class: blob-code js-file-line"]				Write(b);[/TD]
       [/TR]
       [TR]
                  [TD="class: blob-code js-file-line"]				value = high;[/TD]
       [/TR]
       [TR]
                  [TD="class: blob-code js-file-line"]			} while(value != 0);
[/TD]
       [/TR]
       [TR]
                  [TD="class: blob-code js-file-line"]		}
[/TD]
[/TR]
[/TABLE]
```


----------



## Thomas_v2.1 (16 September 2014)

Das Siemens Format ist aber etwas anders.
Bei den .Net Funktionen werden negative Zahlen zwar komprimiert aber immer noch als Zweierkomplement abgelegt.
-127 = 0x 81 ff ff ff 0f
+127 = 0x 7f

Da ist das Siemens Format bei negativen Zahlen platzsparender.


----------



## Jochen Kühner (16 September 2014)

Das .NET Format ist auch bei Positiven Zahlen anderst... schau dir mal 

+126 = 80 7e 00 00
+127 = 80 7f 00 00
+128 = 81 00 00 00
+129 = 81 01 00 00

an...


----------



## Jochen Kühner (16 September 2014)

Hab mal beide Funktionen in eine Klasse gebaut... wie gesagt, meine gehört noch verbessert, aber funzt im Moment...


```
[FONT=Consolas][COLOR=#0433ff]using[/COLOR] System;[/FONT]
[FONT=Consolas][COLOR=#0433ff]using[/COLOR] System.Collections.Generic;[/FONT]
[FONT=Consolas][COLOR=#0433ff]using[/COLOR] System.Linq;[/FONT]
[FONT=Consolas][COLOR=#0433ff]using[/COLOR] System.Text;[/FONT]
[FONT=Consolas]
[/FONT]
[FONT=Consolas][COLOR=#0433ff]namespace[/COLOR] DotNetSiemensPLCToolBoxLibrary.PLCs.S7_1xyy[/FONT]
[FONT=Consolas]{[/FONT]
[COLOR=#33A2BD][FONT=Consolas][COLOR=#000000]    [/COLOR][COLOR=#0433ff]public[/COLOR][COLOR=#000000] [/COLOR][COLOR=#0433ff]static[/COLOR][COLOR=#000000] [/COLOR][COLOR=#0433ff]class[/COLOR][COLOR=#000000] [/COLOR]VariableLengthQuantityHelper[/FONT][/COLOR]
[FONT=Consolas]    {[/FONT]
[FONT=Consolas]        [COLOR=#0433ff]public[/COLOR] [COLOR=#0433ff]static[/COLOR] [COLOR=#0433ff]int[/COLOR] DecodeInt([COLOR=#0433ff]byte[/COLOR][] bytes, [COLOR=#0433ff]int[/COLOR] offset)[/FONT]
[FONT=Consolas]        {[/FONT]
[FONT=Consolas]            [COLOR=#0433ff]int[/COLOR] n;[/FONT]
[FONT=Consolas]            [COLOR=#0433ff]uint[/COLOR] val = 0;[/FONT]
[FONT=Consolas]            [COLOR=#0433ff]byte[/COLOR] b;[/FONT]
[FONT=Consolas]
[/FONT]
[FONT=Consolas]            [COLOR=#0433ff]for[/COLOR] (n = 1; n <= 4 + 1; n++)[/FONT]
[COLOR=#008F00][FONT=Consolas][COLOR=#000000]            {        [/COLOR]/* große Werte benötigen 5 Bytes */[/FONT][/COLOR]
[FONT=Consolas]                b = bytes[offset];[/FONT]
[FONT=Consolas]                offset += 1;[/FONT]
[FONT=Consolas]
[/FONT]
[FONT=Consolas]                [COLOR=#0433ff]if[/COLOR] ((n == 1) && ((b & 0x40) > 0))[/FONT]
[COLOR=#008F00][FONT=Consolas][COLOR=#000000]                {   [/COLOR]/* Vorzeichen prüfen */[/FONT][/COLOR]
[FONT=Consolas]                    b &= [COLOR=#0433ff]unchecked[/COLOR](([COLOR=#0433ff]byte[/COLOR])~0x40);[/FONT]
[FONT=Consolas]                    val = 0xffffffff;[/FONT]
[FONT=Consolas]                    val <<= 6;[/FONT]
[FONT=Consolas]                }[/FONT]
[FONT=Consolas]                [COLOR=#0433ff]else[/COLOR][/FONT]
[FONT=Consolas]                {[/FONT]
[FONT=Consolas]                    val <<= 7;[/FONT]
[FONT=Consolas]                }[/FONT]
[FONT=Consolas]                [COLOR=#0433ff]if[/COLOR] ((b & 0x80) > 0)[/FONT]
[FONT=Consolas]                {                 [COLOR=#008f00]/* es folgt noch ein Byte */[/COLOR][/FONT]
[FONT=Consolas]                    b &= [COLOR=#0433ff]unchecked[/COLOR](([COLOR=#0433ff]byte[/COLOR])~0x80);[/FONT]
[FONT=Consolas]                    val |= b;[/FONT]
[FONT=Consolas]                }[/FONT]
[FONT=Consolas]                [COLOR=#0433ff]else[/COLOR][/FONT]
[FONT=Consolas]                {                        [COLOR=#008f00]/* alle Bytes gelesen */[/COLOR][/FONT]
[FONT=Consolas]                    val |= b;[/FONT]
[FONT=Consolas]                    [COLOR=#0433ff]break[/COLOR];[/FONT]
[FONT=Consolas]                }[/FONT]
[FONT=Consolas]            }[/FONT]
[FONT=Consolas]
[/FONT]
[FONT=Consolas]            [COLOR=#0433ff]return[/COLOR] ([COLOR=#0433ff]int[/COLOR])val;[/FONT]
[FONT=Consolas]        }[/FONT]
[FONT=Consolas]
[/FONT]
[FONT=Consolas]        [COLOR=#0433ff]public[/COLOR] [COLOR=#0433ff]static[/COLOR] [COLOR=#0433ff]byte[/COLOR][] EncodeInt([COLOR=#0433ff]int[/COLOR] value)[/FONT]
[FONT=Consolas]        {[/FONT]
[FONT=Consolas]            [COLOR=#0433ff]var[/COLOR] retVal = [COLOR=#0433ff]new[/COLOR] [COLOR=#33a2bd]List[/COLOR]<[COLOR=#0433ff]byte[/COLOR]>();[/FONT]
[FONT=Consolas]
[/FONT]
[FONT=Consolas]            [COLOR=#0433ff]var[/COLOR] wr = value;[/FONT]
[FONT=Consolas]            [COLOR=#0433ff]if[/COLOR] (value < 0)[/FONT]
[FONT=Consolas]                wr *= -1;[/FONT]
[FONT=Consolas]
[/FONT]
[FONT=Consolas]            [COLOR=#0433ff]var[/COLOR] anzBytes = 1;[/FONT]
[FONT=Consolas]
[/FONT]
[FONT=Consolas]            [COLOR=#0433ff]var[/COLOR] anzBits = ([COLOR=#0433ff]int[/COLOR])[COLOR=#33a2bd]Math[/COLOR].Ceiling([COLOR=#33a2bd]Math[/COLOR].Log(wr) / [COLOR=#33a2bd]Math[/COLOR].Log(2));[/FONT]
[FONT=Consolas]            [COLOR=#0433ff]if[/COLOR] (anzBits >= 6)[/FONT]
[FONT=Consolas]            {[/FONT]
[FONT=Consolas]                anzBytes++;[/FONT]
[FONT=Consolas]                anzBits -= 6;[/FONT]
[FONT=Consolas]            }[/FONT]
[FONT=Consolas]            [COLOR=#0433ff]while[/COLOR] (anzBits > 7)[/FONT]
[FONT=Consolas]            {[/FONT]
[FONT=Consolas]                anzBytes++;[/FONT]
[FONT=Consolas]                anzBits -= 7;[/FONT]
[FONT=Consolas]            }[/FONT]
[FONT=Consolas]
[/FONT]
[FONT=Consolas]
[/FONT]
[FONT=Consolas]            [COLOR=#0433ff]for[/COLOR] ([COLOR=#0433ff]int[/COLOR] i = 1; i <= anzBytes; i++)[/FONT]
[FONT=Consolas]            {[/FONT]
[FONT=Consolas]                [COLOR=#0433ff]byte[/COLOR] wert = 0;[/FONT]
[FONT=Consolas]
[/FONT]
[FONT=Consolas]                [COLOR=#0433ff]var[/COLOR] fakt = (anzBytes - i) * 7;[/FONT]
[FONT=Consolas]                [COLOR=#0433ff]var[/COLOR] divisor = ([COLOR=#0433ff]int[/COLOR])[COLOR=#33a2bd]Math[/COLOR].Pow(2, fakt);[/FONT]
[FONT=Consolas]                wert = ([COLOR=#0433ff]byte[/COLOR])(wr / divisor);[/FONT]
[FONT=Consolas]                wr = wr % divisor;[/FONT]
[FONT=Consolas]
[/FONT]
[FONT=Consolas]                [COLOR=#0433ff]if[/COLOR] (value < 0)[/FONT]
[FONT=Consolas]                {[/FONT]
[FONT=Consolas]                    [COLOR=#0433ff]if[/COLOR] (i == anzBytes || wr == 0)[/FONT]
[FONT=Consolas]                        wert -= 1;[/FONT]
[FONT=Consolas]
[/FONT]
[FONT=Consolas]                    wert = ([COLOR=#0433ff]byte[/COLOR])~(wert);[/FONT]
[FONT=Consolas]                    [COLOR=#0433ff]if[/COLOR] (i == anzBytes)[/FONT]
[FONT=Consolas]                        wert &= 0x7F;[/FONT]
[FONT=Consolas]
[/FONT]
[FONT=Consolas]                    [COLOR=#0433ff]if[/COLOR] (i == 1)[/FONT]
[FONT=Consolas]                        wert |= 0x40;[/FONT]
[FONT=Consolas]                }[/FONT]
[FONT=Consolas]
[/FONT]
[FONT=Consolas]                [COLOR=#0433ff]if[/COLOR] (i != anzBytes)[/FONT]
[FONT=Consolas]                    wert |= 0x80;[/FONT]
[FONT=Consolas]
[/FONT]
[FONT=Consolas]
[/FONT]
[FONT=Consolas]                retVal.Add(wert);[/FONT]
[FONT=Consolas]            }[/FONT]
[FONT=Consolas]
[/FONT]
[FONT=Consolas]            [COLOR=#0433ff]return[/COLOR] retVal.ToArray();[/FONT]
[FONT=Consolas]        }[/FONT]
[FONT=Consolas]    }[/FONT]
[FONT=Consolas]}[/FONT]
```


----------



## Jochen Kühner (16 September 2014)

Ich denke im TIA Projekt sind Bausteine Daten mit ZLib komprimiert gespeichert... Bin mir da aber nicht sicher, könnte aber ja auch sein das auf die PLC etwas komprimiert übertragen wird...


----------



## Thomas_v2.1 (18 September 2014)

Ich habe nur Zugriff auf eine S7-1200, aber bei dem Aufbau der Kommunikation eines Panels zur SPS bin ich ein ganzes Stück weiter. Zumindest beim Aufbau der Variablenanfragen und der Werte in den Antworttelegrammen.

Um einen Kommunikationstreiber zu schreiben der symbolisch auf eine 1200er zugreifen kann reicht es aber noch nicht ganz aus, wobei auf jeden Fall die LIDs aus dem TIA-Projekt ausgelesen werden müssen. Die CRC kann man sich aus dem Symbol ja selber berechnen.
Vielleicht hat ja jemand Lust am rätseln wie der Aufbau der fehlenden Stücke wohl sein könnte. Vor allem beim Antworttelegramm zum ersten Verbindungsaufbau gibt es mittendrin eine seltsame Struktur, bei der ich nicht weiterkomme. Ich denke mal man wird irgendetwas von diesen Werten benötigen um die Session-Id für den weiteren Datenverkehr zu bestimmen.

Das unpraktische an den varuint-Typen ist, dass man im Telegramm nicht sehen kann ob ein Feld ein Typ mit fester Größe oder eben der varuint ist, außer wenn man Werte größer 2^7 für das Feld provizieren kann.

Ich hänge mal den aktuellen Stand der dll für 32 Bit, und zwei Logfiles an, bei denen ein Panel mit einer 1200er kommuniziert.


----------



## Jochen Kühner (19 September 2014)

Die symbolische anfrage bei der 1200er geht doch auch ähnlich wie bei der s7 300/400, oder gehts bei dir um eine andere kommunikation?


----------



## Thomas_v2.1 (19 September 2014)

Ja, das ist ein komplett anderes Protokoll als bei der 300/400 mit der 0x32 als Protokoll-Id, welche jetzt 0x72 lautet.
Innendrin steckt zumindest für die 1200 aber immer noch der Zugriffsmechanismus über die Symbol-Prüfsumme und den LID-Nummern, nur die LID-Flags sind weggefallen. Seit V12 verwendet die HMI-Simulation nur noch diese Telegramme. Ich weiß nicht ob die vorige Variante von neuen CPUs überhaupt noch unterstützt wird.

Von der 1500 habe ich selber nur ein paar Logfiles gesehen. Die verwendet was ich da gesehen habe vom Prinzip her den gleichen Telegramm-Aufbau wie die 1200 (also die 0x72er Telegramme), aber innendrin sieht es etwas anders aus.


----------



## Jochen Kühner (19 September 2014)

Also kann die alte Kommunikation nur verwendet werden wenn es in den CPU eigenschaften sitzt, und die mit 0x72 immer?


----------



## Jochen Kühner (19 September 2014)

Ich hab ne 518 hier im Büro, und hoff das Ich die nächsten Monate mal dazu komm mir die Kommunikation dazu genauer anzuschauen...


----------



## inspectorgadjet (19 September 2014)

Hallo,

nachdem ich das Thema schon eine Zeit verfolge und auch versucht habe das 0x72 Protokol zu verstehen, möchte ich nun meine Ergebnisse einbringen:

Berechnung Session ID:
Zuminstes das letzte Byte der Session ID wird aus dem Byte 17 der Resopnse auf Start Session berechnet -> Byte 18 + 0x80


```
Response auf Start Session:

0000   72 01 00 7a 32 00 00 04 ca 00 00 00 01 36 11 02
0010   87 [B]20[/B] 87 53 a1 00 00 01 20 82 1f 00 00 a3 81 69
0020   00 15 00 a3 82 32 00 17 00 00 01 3a 82 3b 00 04
0030   82 00 82 3c 00 04 81 40 82 3d 00 04 84 80 c0 40
0040   82 3e 00 04 84 80 c0 40 82 3f 00 15 1b 31 3b 36
0050   45 53 37 20 32 31 34 2d 31 41 45 33 30 2d 30 58
0060   42 30 20 3b 56 32 2e 32 82 40 00 15 05 32 3b 37
0070   39 34 82 41 00 03 00 03 00 a2 00 00 00 00 72 01
0080   00 00

=> 0x20 + 0x80 = a0

Request Write:
0000   72 02 00 66 31 00 00 05 42 00 00 00 02 00 00 03
0010   [B]a0[/B] 34 00 00 03 a0 01 01 82 32 01 00 17 00 00 01
0020   3a 82 3b 00 04 82 00 82 3c 00 04 81 40 82 3d 00
0030   04 84 80 c1 00 82 3e 00 04 84 80 c0 40 82 3f 00
0040   15 00 82 40 00 15 00 82 41 00 03 00 03 00 00 00
0050   00 04 e8 89 69 00 12 00 00 00 00 89 6a 00 13 00
0060   89 6b 00 04 00 00 00 00 00 00 72 02 00 00
```

Was ich bis heute nicht geschafft habe ist die SYM-CRC Berechnung erfolgreich durchzuführen. Weiß jemand mehr darüber?


----------



## Thomas_v2.1 (19 September 2014)

inspectorgadjet schrieb:


> Berechnung Session ID:
> Zuminstes das letzte Byte der Session ID wird aus dem Byte 17 der Resopnse auf Start Session berechnet -> Byte 18 + 0x80


Für das eine Byte scheint das ja schonmal zu passen.
Liegt natürlich in dem Datenteil der irgendwie keiner Struktur zu folgen scheint.



inspectorgadjet schrieb:


> Was ich bis heute nicht geschafft habe ist die SYM-CRC Berechnung erfolgreich durchzuführen. Weiß jemand mehr darüber?



Siemens nutzt das gleiche Generatorpolynom wie auch beim Profibus, nämlich:
x^32+x^31+x^30+x^29+x^28+x^26+x^23+x^21+x^19+x^18+x^15+x^14+x^13+x^12+x^9+x^8+x^4+x+1

Das hat der Jochen auch schon in seiner Lib drin, funktioniert einwandfrei:
https://github.com/jogibear9988/Dot...DaveConnectionLibrary/General/TiaCrcHelper.cs


----------



## Thomas_v2.1 (19 September 2014)

Ich habe nochmal meine Logfiles durchgesehen. Der variable Teil in der Session-Id scheint nur das rechte Byte zu sein, zumindest steht in dem Byte davor immer eine 3.
Wenn man die Daten an Wort-Grenzen ausrichtet gehört die 3 zur Id, muss aber nicht sein.
Aber da beim Verbindungsabbau auch die Session-Id inkl. der 3 im Datenteil vorhanden ist, würde ich sagen sie gehört mit dazu.


----------



## inspectorgadjet (19 September 2014)

Thomas_v2.1 schrieb:


> Siemens nutzt das gleiche Generatorpolynom wie auch beim Profibus, nämlich:
> x^32+x^31+x^30+x^29+x^28+x^26+x^23+x^21+x^19+x^18+x^15+x^14+x^13+x^12+x^9+x^8+x^4+x+1
> 
> Das hat der Jochen auch schon in seiner Lib drin, funktioniert einwandfrei:
> https://github.com/jogibear9988/Dot...DaveConnectionLibrary/General/TiaCrcHelper.cs



Danke für den Tipp, muss ich mir mal genauer anschauen.



Thomas_v2.1 schrieb:


> Ich habe nochmal meine Logfiles durchgesehen. Der variable Teil in der Session-Id scheint nur das rechte Byte zu sein, zumindest steht in dem Byte davor immer eine 3.
> Wenn man die Daten an Wort-Grenzen ausrichtet gehört die 3 zur Id, muss aber nicht sein.
> Aber da beim Verbindungsabbau auch die Session-Id inkl. der 3 im Datenteil vorhanden ist, würde ich sagen sie gehört mit dazu.



Bei mir steht im Byte davor auch immer eine 3. 

Ich habe deine und meine Start Session Response verglichen (sind leider beides 1214c) folgendes kommt dabei raus:


----------



## juergi (25 September 2014)

Hallo,

Das Posting ist zwar schon etwas älter, aber vieleicht erinnert sich noch jemand:



Jochen Kühner schrieb:


> Könnte ja sein, das die mittleren 4 bytes der crc sind welcher in dem Patent beschrieben ist? Die ersten 4 Bytes Speicherbereich? Oder etwas in die Richtung und die letzten 4 Bytes die laufende ID... Sind aber alles nur Ideen...



Welches Patent meint Ihr hier?


----------



## Thomas_v2.1 (25 September 2014)

juergi schrieb:


> Welches Patent meint Ihr hier?



Dieses:
http://www.google.com/patents/EP2246757A1?cl=de

Es wurde aber mittlerweile von Siemens zurückgezogen.


----------



## juergi (13 Oktober 2014)

Hallo,

mir ist noch nicht klar, worüber die Sym-CRC bei der S7-1500 berechnet wird. Und ob diese Sym-CRC Berechnung auch für die S7-1500 unterstützt wird.
Aus einem TIA Projekt kann ich zum Beispiel folgendes herausziehen:
<dataBlock name="DB6" logicalAddress="%DB6" supportsAddressingByOffset="false" subtype="DB" CRC="0xD4FD3326">
...
<dataTag name="Array_Byte" offset="32.0" datatype="Array[0..10] of Byte" id="60" lid="22" rid="0x02010002" />
...
<dataTag name="IEC_COUNTER" offset="148.0" datatype="IEC_COUNTER" id="89" lid="67" rid="0x0200001E" subPartIndex="-5" />
...
<dataTag name="IEC_LTIMER" offset="190.0" datatype="IEC_LTIMER" id="92" lid="70" rid="0x02000044" subPartIndex="-8" />

In einem Wireshark-Mitschnitt, einer Abfrage der Daten aus DB6 sehe ich unter anderem:
Item Address: SYM-CRC=8db85e63, LID=DB6.22

Weiß jemand, ob und wie sich aus den Daten oben berechnen lässt?

BTW: Mit dem .xml File und dem Wireshark-Mitschnitt habe ich die im S/COMM-Plus Wireshark Plugin noch unbekannten Typen 
0x10 = IEC_COUNTER
und 
0x11 = IEC_LTIMER
gefunden.


Gruß
  Jürgen


----------



## Jochen Kühner (13 Oktober 2014)

juergi schrieb:


> Hallo,
> 
> mir ist noch nicht klar, worüber die Sym-CRC bei der S7-1500 berechnet wird. Und ob diese Sym-CRC Berechnung auch für die S7-1500 unterstützt wird.
> Aus einem TIA Projekt kann ich zum Beispiel folgendes herausziehen:
> ...



Also für die 1200er hab ich Code in der Klasse TiaCrcHelper, ob das aber auch für die 1500er funktioniert weiß ich nicht... https://github.com/jogibear9988/DotNetSiemensPLCToolBoxLibrary


----------



## Thomas_v2.1 (13 Oktober 2014)

juergi schrieb:


> mir ist noch nicht klar, worüber die Sym-CRC bei der S7-1500 berechnet wird. Und ob diese Sym-CRC Berechnung auch für die S7-1500 unterstützt wird.
> Aus einem TIA Projekt kann ich zum Beispiel folgendes herausziehen:
> <dataBlock name="DB6" logicalAddress="%DB6" supportsAddressingByOffset="false" subtype="DB" CRC="0xD4FD3326">
> ...
> ...



Bei der 1200 hätte ich gesagt, mit LID=22 wird die Variable "Array_Byte" gelesen. D.h du müsstest die CRC aus dem Symbol "Array_Byte" bilden. Wenn ich das so mache wie für die 1200 kommt aber ein anderer Wert heraus.
Was für Daten werden denn mit deinem abgehörten CRC/LID gelesen?

Bei der 1200 kann man überhaupt kein komplettes Array lesen, zumindest nicht mit einem Basic-Panel, dort lassen sich nur einzelne Array-Elemente lesen. In dem Fall folgt nach der LID noch der Array-Index. Als die symbolische Adressierung noch in den 0x32er Telegrammen verpackt war, gab es pro LID zusätzlich ein Byte mit Flags, die kennzeichneten auf welchen LID-Typ zugegriffen wurde. Man hat aber wohl festgestellt dass die Kombination aus CRC und LID schon eindeutig ist und dieses Flag-Byte dann entfernt. Denn über die LID weiß der Partner schon dass es sich in einem Array, Struct oder sonstiges befindet.



juergi schrieb:


> BTW: Mit dem .xml File und dem Wireshark-Mitschnitt habe ich die im S/COMM-Plus Wireshark Plugin noch unbekannten Typen
> 0x10 = IEC_COUNTER
> und
> 0x11 = IEC_LTIMER
> gefunden.



a) Was für ein xml File?
b) Wenn ich in einem DB eine Variable von Typ "IEC_COUNTER" anlege, ist das eine Struktur. Was liest das HMI wenn es ein Typ "IEC_COUNTER" liest? Alle Elemente, oder nur ein einziges? Bei TIA-V12 kann ich so eine Variable überhaupt nicht anlegen.

Mir steht keine 1500 zum Testen zur Verfügung, falls das alles 1500-spezifisch sein sollte.


----------



## Thomas_v2.1 (14 Oktober 2014)

Ich habe mir das mit der CRC-Berechnung auch bei der 1200er angesehen.
Bisher habe ich mir das entweder bei Merkervariablen oder bei Variablen dir direkt in einem DB liegen (z.B. DB99.VAR) angesehen. In den beiden Fällen wird die CRC einzig und allein aus dem Symbol berechnet.
Liegt die Variable aber beispielsweise innerhalb einer Struktur eines DBs, z.B. DB.STRUCT.VAR, dann gibt es eine andere CRC.

Naheliegend wäre es die aus dem kompletten Symbol zu bilden, also "STRUCT.VAR" mit dem "." als Trennzeichen. Passt nicht. Ein "/" als Trennzeichen probiert, passt auch nicht.

Kleines Such-Skript geschrieben:

```
public static void SucheCrcTrenner()
{
    bool found = false;
    byte[] bytes1 = Encoding.ASCII.GetBytes("VAR_STRUCT1");
    byte[] bytes2 = Encoding.ASCII.GetBytes("VAR_STRUCT1_INT");
    byte[] delim = { 0x00 };

    byte[] combined = bytes1.Concat(delim).Concat(bytes2).ToArray();

    int delim_pos = bytes1.Length;

    string search_crc = "b1c00672";
    string crc;

    search_crc = search_crc.ToUpper();

    for (byte i = 0; i < 255; i++)
    {
        combined[delim_pos] = i;
        crc = getcrc(combined).ToString("X").PadLeft(8, '0');
        if (crc == search_crc)
        {
            Console.WriteLine("Gefunden! Trennzeichen = " + i);
            found = true;
            break;
        }
    }
    if (!found)
    {
        Console.WriteLine("Nicht gefunden");
    }
    Console.ReadKey();
}
```

Das Trennzeichen ist 0x09.

D.h. bei einer 1200 gilt für eine Variable im DB: DB.STRUCT.VAR, die CRC über den Namen der "STRUCT" plus 0x09 plus Namen der "VAR" zu bilden.
Siemens hätte so schön ein "." nehmen können, aber das wäre wohl zu naheliegend gewesen.


----------



## klaly (22 Oktober 2014)

@Thomas_v2.1,

hallo Thomas, ich setze dein Plugin seit einiger Zeit ein und es hat mir immer gute Dienste geleistet.
Danke schön für dieses hervorragende Tool.

Verbesserungswunscht, bezüglich nicht erkanntem "AnyPointer":
Es gibt zum datensatz Les4en/Schreiben "erweiterte AnyPojnter" evtl ist dir das bisher nicht bekannt.
Eben wollte ich was untersuchen, dabei kam diese "Schwäche" wieder mal zum Vorschein.
Daher sende ich dir Info, womit du das Implementieren kannst:

Ich versuch ert mal mit einem kommentierten HexDump:

Datensatz schreiben, z.B. an eine Profibus Teilnehmer

PG --> CPU 32 01 00 00 04 00 00 0e 00 08
           05 01                                                                   Write, 1 Tag
           12 0a
           10 03 00 04 00 ff 01 00 07 fb      
              ## ##### ##### ##       #####--------- Logische Adresse
               |     |   |       +------------------ Kennung für Datensatz
               |         |   +----------------------- Datensatz Nummer
               |         +--------------------------- Anzahl Elemente
               +--------------------------------- Element Typ Char (so liest der simatic Manager)
                      ff 09 00 04                                                       Datenkennung ... ganz normal
           08 00 fd e8                                                       Nutzdaten

CPU --> PG 32 03 00 00 04 00 00 02 00 01 00 00       Antwort
                                                                                  #####--- Retval OK
           05 01 ff                                                             Alles OK.


Datensatz lesen

PG --> CPU 32 01 00 00 05 00 00 0e 00 00
           04 01                                                                   Lesen, 1 Tag
           12 0a
           10 03 00 44 00 ff 01 00 07 fb  
              ## ##### ##### ##       #####--------- Logische Adresse
               |     |   |       +------------------ Kennung für Datensatz
               |         |   +----------------------- Datensatz Nummer
               |         +--------------------------- Anzahl Elemente
               +--------------------------------- Element Typ Char (so liest der simatic Manager)


CPU --> PG 32 03 00 00 05 00 00 02 00 48 00 00
           04 01                                                                   Lesen, 1 Tag
           ff 04 02 20                                                       Nutzdaten  Zählung in Bit
           08 00 fd e8 00 00 ...                                   Nutzdaten ...


Das kann jede normale S7-CPU, sowohl für lokal 300er Module,
oder für Profibus, bzw. Profinet Module, bzw. deren datensätze.

Der "AnyPointer" siehr wie folgt aus:

10 03 nn nn dd dd 01 00 aa aa

10     ist die normale Kennung
03     ist der Elementtyp, evtl. gehen auch andere, aber 03 ist üblich.
nn nn  ist die Anzahl der Elemente, überlicherweise char, d.h. Bytes
dd dd  Datensatz Nummer
01     ist die Kennung für Datensatz bei disem "speziellen AnyPointer"
aa aa  ist die logische Adresse für Eingänge), bei Ausgängen wird 0x8000
       aufadddiert, oder umgekehrt, genau wie beim SFB52

Das war es schon, Implementierung sollte kein großes Problem sein.


mfG. klaly


----------



## klaly (22 Oktober 2014)

So ein "Mist", 

ich krieg die Formatierung im Hexdump nicht hin. 
Im Edit Feld sieht es immer gut aus, dann wirft das Forum aber scheinbar die "überflüssigen" 
Leerzeichen wieder raus und es siehr "blöd" aus. 

Ich bitte um Entschuldigung. 
Es ist aber hoffentlich zu erkennen was die Felder bedeuten. 

mfG. klaly


----------



## Thomas_v2.1 (22 Oktober 2014)

Hi,
womit werden denn solche Telegramme erzeugt? Ich würde mir das gerne mal selber ansehen wenn möglich. Oder falls du eine Logdatei hast, wäre es nicht schlecht wenn du diese mal anhängst.

Nach dem was du oben geschrieben hast, sehe ich keinen Anhaltspunkt um den Aufbau vom S7-ANY zu unterscheiden. Die Kennungswerte für eine Variablenadresse sind demnach identisch:
0x12 = Variablenspezifikation
0x0a = Länge der folgenden Spezifikation in Bytes
0x10 = Syntax-ID, 0x10 steht für S7-Any-Pointer

Bei allem was danach folgt gehe ich davon aus dass es sich um einen S7-Any-Pointer handelt.

Alles andere was ich bisher an Adressformaten gesehen habe, geben auch eine andere Syntax-ID mit.


----------



## SoftMachine (22 Oktober 2014)

.


klaly schrieb:


> So ein "Mist",
> 
> ich krieg die Formatierung im Hexdump nicht hin.
> Im Edit Feld sieht es immer gut aus, dann wirft das Forum aber scheinbar die "überflüssigen"
> ...




Vielleicht hilft dir die Benutzung der "CodeTags (#)" mit dem Doppelkreuz bei deiner Antwort weiter.
.


----------



## Thomas_v2.1 (22 Oktober 2014)

So wie es aussieht müsste ich die Bereichskennung 0x01 an der Position, an der bei einer normalen S7-Adresse z.B. 0x84 für den Bereich Datenbausteine steht, ergänzen. Dort dürfte momentan "unknown area" angezeigt werden.
Dann wäre der Aufbau prinzipiell gleich mit den S7-Any Pointer, wenn ich annehme dass die Adresse ebenfalls 3 und nicht nur 2 Bytes beinhaltet. Die Datenbausteinnummer wäre in den Fall die Datensatznummer (Dataset number).

Mach doch mal einen Vorschlag wie ich die Adresse in Textform in Wireshark darstellen soll.
Also z.B.:

```
Item[1]: (Dataset 256 Address 2043 CHAR 68)
- Variable specification: 0x12
- Length of following address specification: 10
- Syntax Id: S7ANY (0x10)
- Transport size: CHAR (3)
- Length: 68
- Dataset number: 256
- Area: Dataset (0x01)
- Address: 0x0007fb
```

Ich weiß überhaupt nicht wozu diese Adressierung benutzt wird.

Die Antworttelegramme sollten doch schon korrekt dekodiert werden können oder?


----------



## klaly (23 Oktober 2014)

Hi SoftMachine, 

danke. Leider schreibe ich so selten im Forum, so dass ich diese "Feinheiten" leider nicht kannte. 
Ich hatte meinen Text "schön" auf Courier umgestellt, schön formatier, abgesvhickt. Hmm, ...
Nochmal edititiert, das gleiche wieder, dann hatte ich keine Lust mehr. 

mfG. klaly


----------



## klaly (23 Oktober 2014)

@Thomas_v2.1, 

du bekommst solche Telegramme, wenn du im HW-Konfigurator in der online Ansicht auf Profibus DP-V1 oder Profinet Teilnehmer, bzw. der Untereigenschaften klickst. Da werden dann nicht nur SZLs, sondern auch Datensätze gelesen. 

Mal schaun was ich da zusammen klicken kann, dann schneide ich mit Wireshark mal ein paar Telegramme mit. 

Oder wenn du bei einem lokal gesteckten Analogmodul den Diagnosestatus sehen willst, dann werden da auch Datensätze gelesen. 

Das war jetzt gar nicht so einfach zu konstruieren. 
Zuerst wollte ich die Drahtbrucherkennung eines Ananlogmoduls, z.B. 332-5HD01 dafür her nehmen. 
Aber da wird von der Onlineansicht des HW-Konfigurator, nur eine entsprechende SZL gelesen, welche die CPU dann 
in eine DS-Lesen Anfrage am Rückwandbus umsetzt. Das sind die Datensätze 1 und 2, welche z.B. auch mit dem SFB52 gelsen werden können. 

War wohl nix. 
Dann habe ich es mit einem CP341 versucht, da geht es. 
Der muss z.B. lokal an der CPU hängen, ginge aber auch über Profibuis ET200M über Profinet auch ET200M. 
Wenn du in der HW-Konfig die Online Ansicht auf machst und dann auf den CP341 doppelklickst, dann bekommst du den 
Baugruppenzustand des CP341, da steht auch sein Name drin. Diesen wird über DS-Lesen geholt. 

siehe folgenden Screenshot und Wireshark Aufzeichnung. 
Ich vermute, das Hochladen der Anhänge macht mir Probleme (Firefox), mal schaun.

mfG. klaly


----------



## klaly (23 Oktober 2014)

*Anhang 1 (Bild) zu Datensatz lesen schreiben.*



Screenshot der Onlineansicht.


----------



## klaly (23 Oktober 2014)

*Anhang2 Wireshark Aufzeichnung zu DS-Read*

Das Hochladen mit dem Plugin ist ja ganz schön eigenartig.

@Thomas_v2.1, 


> So wie es aussieht müsste ich die Bereichskennung 0x01 an der Position,  an der bei einer normalen S7-Adresse z.B. 0x84 für den Bereich  Datenbausteine steht, ergänzen. Dort dürfte momentan "unknown area"  angezeigt werden.



Ja, Thomas, genau da steht unknown Area. 
Diese Kennung 0x01 kommt einfach statt der Kennung 0b10000zzz im Bereichsübergreifenden zeiger. Damit wird dieser Zeiger zu einem "Zeiger" auf einen datensatz. Anzahl Bytes (bzw. Char) und Datensatznummer stehen weiter oben.

Fortsetzung folgt gleich. 

mfG. klaly


----------



## klaly (23 Oktober 2014)

@Thomas_v2.1, 

eine Anwendung zum DS-Schreiben ist u.a. Firmwareupdate für z.B. den CP341.
Dafür brauchst du die Projektiersoftware CP341 und eine passente Firmware.

Mitschnitt folgt.

Auch Firmwareupdate für Profibus und Profinet koppler erfolgen über DS-schreiben/lesen. 
Allerdings macht es Step7 anders, wenn das PG direkt am Profinet hängt, dann werden direkt "Profinet Telegramme" zu den Devices geschickt. 
Wenn es aber über MPI, oder über einen TCP/IP CP geht, dann gehts es auch über Datensatz lesen/schreiben. 

In wie weit diese s7comm Erweiterung für andere nützlich ist kann ich dir nicht sagen. 
Ich jedenfalls treffe hin und wieder darauf. 

Wenn noch Fragen sind, einfach melden. 

mfg. klaly


----------



## Thomas_v2.1 (23 Oktober 2014)

Ich habe es jetzt mit der Bezeichnung "Dataset" für den Bereich eingebaut, siehe Screenshot.
Aber wenn es auch möglich ist darüber ein Firmwareupdate aufzuspielen, entspricht es vlt. eher dem Bereich "Systemdaten"?

Naja, exotisch ist es schon etwas. Aber wenn die Funktion bekannt ist kann man es auch einbauen.


----------



## klaly (23 Oktober 2014)

@Thomas_v2.1, 

schön, aber ich denke die Bezeichnungen sind so noch nicht ganz stimmig. 
Da muss ich morgen auf der Arbeit mal schaun, wie die Bezeichnungen bei Profibus u. Profinet dafür sind. 
So solltest du es dann auch bezeichnen. 

Die Sache mit Firmwareupdate ist eher ein Sonderfall.
Mit den Datensätzen kannst du Diagnose machen und auch Module, z.B. Analogmodule zur laufzeit umparametrieren. 
Dies geschieht normalerweise aus dem SPS-Programm heraus. 
Aber es geht auch über die PG-Kommunikation. 

mfg. klaly


----------



## foo (27 Oktober 2014)

Hallo,

ich bin auch gerade damit beschäfigt, das s7comm-plus Protokoll zu entwirren. Was hat Siemens da nur verbrochen...

Erst mal allen voran: Vielen Dank für eure hervorragende Leistung was das bisherige Reverse Engineering und den Dissector angeht! Ich bin sehr verwundert, wie fürchterlich Siemens dieses Protokoll designed hat, aber noch mehr überrascht es mich daher was ihr bisher rausfinden konntet.

Nun zu dem, was ich noch rausfinden konnte:

* Ich habe captures, welche _immer_ vor dem Trailer 32 Byte zufällige Wustdaten enthalten (unabhängig von der Funktion, und unabhängig davon, ob es Request/Response/Cyclic ist). Es deutet einiges darauf hin, dass es sich dabei um eine Art Integritätsblock oder Signatur handelt, um Replay Attacken oder unauthorisierte Pakete zu verhindern. Grund für meine Annahme: diese Daten ändern sich selbst dann, wenn der Rest des Pakets - welcher ja im Klartext übertragen wird - gleich bleibt.

Habt ihr solche Pakete auch schon mal beobachten können? Gibt es für die "neuen" S7er wohl eine Art "secure mode"?

Mein erster Ansatz war, über alle möglichen Permutationen eines Pakets Prüfsummen mit verschiedensten (auch sehr exotischen) Prüfsummenverfahren zu bilden, aber keines hat gematcht. Vielleicht verwenden sie noch eine Art geheimen Salt um eine Art HMAC zur Authentisierung der Pakete zu verwenden? Mein nächster Ansatz wird sein, zu versuchen, ob eben diese 32 Byte einer Normalverteilung entsprechen oder nicht - eventuell gibt das ja einen Anhaltspunkt, was sich da drin verbirgt....

* Thomas, du kommentierst in deinem Code, bei zyklischen Paketen käme bei den Feldern unknown1:unknown2 immer nur 0x1000:0x0400 vor. Eben diese captures, welche die 32-Byte Garbage am Ende enthalten, haben 0x7000:0x0400 im unknown1:unknown2 field. Es scheint mir also so, als würde es sich bei unknown1 und unknown2 um eine Art Bitmaske handeln. Handelt es sich aber um Requests / Reads, so bleibt unknown1:unknown2 auf 0x0000:0x0000.

* Ich konnte glaub ich (aber noch nicht wirklich sicher) eine Funktionen identifizieren: 0x04f2. Das kommt bei mir immer kurz vor einer Endsession, wenn cyclic packets subscribed sind. Nach dem 0x04f2 Request+Respone stoppt die PLC mit dem senden ihrer cyclic packets. Also vielleicht eine Art Cyclic Unsubscribe?

* In dem Dissector wird der Trailer genauso gehandelt wie der Header. Aber das DataLength field im Trailer ist _immer_ 0x0000. Ist es dann logisch, das datalength zu nennen? Was wollte Siemens eigentlich mit dem Trailer bezwecken?

* Was haben sie sich nur mit den variable length quantities gedacht? Das ist so tierisch gefährlich. Warum nicht einfach ein Byte Länge und dann die sagen wir Integer-Daten in Big Endian übertragen? Bei fixen Längen, wie z.B. der Symbolic-CRC ist es doch total idiotisch, Variable length quantities zu verwenden?! Noch idiotischer is es, das ganze nicht einmal konsequent durchzuziehen, wenn man es schon macht.

Es ist also echt gefährlich, wie Siemens das Protokoll aufbaut. Wegen der Variable-length Quantities braucht man keine Längenfelder, was das ganze meiner Ansicht nach zu einer hochexplosiven Mischung macht: Ein kleinster Parserfehler, und das ganze fliegt einem um die Ohren. Selbst wenn der Parser passt, und man stellt sich vor, man möchte ein fragmentiertes Telegramm übermittelt und dummerweise ist genau das viertletzte Byte eine 0x72.
        - Hmm, haben wir jetzt einen Trailer oder gehört es noch zu den Nutzdaten?
Sehr gefährlich.

So far, so good.

Investigative Grüße


----------



## Thomas_v2.1 (27 Oktober 2014)

foo schrieb:


> * Ich habe captures, welche _immer_ vor dem Trailer 32 Byte zufällige Wustdaten enthalten (unabhängig von der Funktion, und unabhängig davon, ob es Request/Response/Cyclic ist). Es deutet einiges
> 
> darauf hin, dass es sich dabei um eine Art Integritätsblock oder Signatur handelt, um Replay Attacken oder unauthorisierte Pakete zu verhindern. Grund für meine Annahme: diese Daten ändern sich
> 
> ...



Das habe ich bisher nur bei der 1500er gesehen. Alleine von den Werten her sieht es mir auch nach einer Signatur oder sowas in der Art aus.
Kritik an möglichen Replay-Angriffen beim alten S7-Protokoll gab es zu genüge, da würde ich davon ausgehen dass Siemens da etwas eingebaut hat. 
Die Session-Id alleine ist aufgrund des begrenzten Wertebereiches von einem Byte (das andere ist ja immer 0x03) dafür nur bedingt tauglich. Die hat man schnell durchprobiert.



foo schrieb:


> Mein erster Ansatz war, über alle möglichen Permutationen eines Pakets Prüfsummen mit verschiedensten (auch sehr exotischen) Prüfsummenverfahren zu bilden, aber keines hat gematcht. Vielleicht
> 
> verwenden sie noch eine Art geheimen Salt um eine Art HMAC zur Authentisierung der Pakete zu verwenden? Mein nächster Ansatz wird sein, zu versuchen, ob eben diese 32 Byte einer Normalverteilung
> 
> entsprechen oder nicht - eventuell gibt das ja einen Anhaltspunkt, was sich da drin verbirgt....



In sowas habe ich selber keine Erfahrung. Ich habe aber mit Interesse verfolgt, wie ein paar Leute das Meteo-Time-Protokoll in DCF77 auseinandergenommen haben. Da war der erste Ansatz, eine größe Menge an Logfiles zu sammeln.
Sinnvoll wäre es, bei sowas zumindest die ersten beiden Telegramme (StartSession und das erste Write) mitzuprotokollieren. Denn erst danach werden die Bytes ergänzt. Und für irgendetwas müssen die ganzen Strings die an die SPS geschickt werden ja gut sein.



foo schrieb:


> * Thomas, du kommentierst in deinem Code, bei zyklischen Paketen käme bei den Feldern unknown1:unknown2 immer nur 0x1000:0x0400 vor. Eben diese captures, welche die 32-Byte Garbage am Ende
> 
> enthalten, haben 0x7000:0x0400 im unknown1:unknown2 field. Es scheint mir also so, als würde es sich bei unknown1 und unknown2 um eine Art Bitmaske handeln. Handelt es sich aber um Requests / Reads,
> 
> so bleibt unknown1:unknown2 auf 0x0000:0x0000.



Ich teste immer noch nur mit einer 1200, und bei der fehlt der "Garbage" / die "Signatur" auch bei den zyklischen Daten. Daher kommen die Werte im Kommentar.



foo schrieb:


> * Ich konnte glaub ich (aber noch nicht wirklich sicher) eine Funktionen identifizieren: 0x04f2. Das kommt bei mir immer kurz vor einer Endsession, wenn cyclic packets subscribed sind. Nach dem
> 
> 0x04f2 Request+Respone stoppt die PLC mit dem senden ihrer cyclic packets. Also vielleicht eine Art Cyclic Unsubscribe?



Das sieht so aus. Zumindest findet sich dort die Referenznummer wieder. Das Anmelden der Variablen geschieht so wie es aussieht über die Funktion 0x04ca-Block, welche auch beim Upload von Bausteinen verwendet wird.
Da bin ich aber gerade dabei, ich denke mal das wird noch rauszufinden sein.



foo schrieb:


> * In dem Dissector wird der Trailer genauso gehandelt wie der Header. Aber das DataLength field im Trailer ist _immer_ 0x0000. Ist es dann logisch, das datalength zu nennen? Was wollte Siemens
> 
> eigentlich mit dem Trailer bezwecken?



Das habe ich erstmal so benannt, weil der Aufbau dann identisch mit dem Header ist. Warum sollte man unnütze 4 Bytes anhängen? Ich verstehe es auch nicht.
Wenn du einen großen Baustein hochlädst lässt sich damit eine Fragmentierung der PDU erkennen - zumindest bei der ersten. Den Trailer gibt es dann nur im letzten Teil der Serie. Dann liest der Partner so lange die Daten ein, 
bis er einen Trailer sieht. Ob das zuverlässig ist weiß ich auch nicht. Eigentlich müsste man die 0x72 dann im Bytestrom entsprechend escapen. In Wireshark selber lässt sich die Erkennung glaube ich nicht zuverlässig realisieren, bzw. kann die Erkennung auch fehlschlagen, falls in den Fragmenten das erste Byte im Data-Teil einen bekanntem Code entspricht.



foo schrieb:


> * Was haben sie sich nur mit den variable length quantities gedacht? Das ist so tierisch gefährlich. Warum nicht einfach ein Byte Länge und dann die sagen wir Integer-Daten in Big Endian übertragen?
> 
> Bei fixen Längen, wie z.B. der Symbolic-CRC ist es doch total idiotisch, Variable length quantities zu verwenden?! Noch idiotischer is es, das ganze nicht einmal konsequent durchzuziehen, wenn man
> 
> es schon macht.


Ich sehe darin auch keinen Sinn, die Ersparnis an Bandbreite dürfte in niedrigen einstelligen Prozentbereich liegen.
Wenn es wenigstens einheitlich wäre, sodass alles >=32 Bit als variable Länge übertragen wird. Aber nicht mal das.

Das "mal so mal so" nervt vor allem Dingen beim Reverse-Engineeren, weil man erst erkennen kann ob es eine variable Länge ist wenn die Werte entsprechend groß werden.

Dagegen hatte das alte S7-Protokoll eine glasklare Struktur.


----------



## foo (27 Oktober 2014)

Ich hab hier leider kein Testsystem, sondern bekomme lediglich die captures. Das ist mein großes Problem, denn ich weis nur grob, was während den captures vor sich geht. Sonst könnte ich da selbst etwas mehr rumspielen und Testpakete erzeugen.

Hab mir heute die letzten 32 Byte genauer angesehen: Es ist wohl diskret gleichverteilt. Und gleiche Pakete erhalten unterschiedliche Signaturen, was das ganze schwer macht. Es gibt mir aber auch gewisse weitere Information, dass vermutlich alte Paketinformationen in irgendeiner Art und Weise einfließen. Weist du zufälligerweise ob man die (ich nenns einfach mal so ab jetzt, weil alles darauf hindeutet) Integrität abschalten kann, sprich, ist es optional? Ich bin mal gespannt, ob ich da noch dahinter komm...

Interessant wäre zu wissen, ob zwei StartConnections von einer 1500er die gleiche "initiale" Integrität hätten, dann könnte man versuchen weiter drauf loszugehen.

Bei dem Trailer bin ich auch absolut bei dir - ergibt keinen Sinn.

Auch mit dem Varint erst am >32 Bit bin ich voll bei dir! Evtl. ist es aber absicht. Security by obscurity und so, um eben Reverse Engineering hart (aber nicht unmöglich) zu machen. Selbst wenn es eine Ersparnis bringt, hebt sich die durch die (wenn auch geringe) Rechenlast beim Umrechnen wieder auf... und wie gesagt - ich finds gefährlich...

Auch die Struktur der Read/Write Req/Res geht mir noch nicht ganz ein, bei meinen captures wird da im Moment noch relativ viel fehlinterpretiert, muss da mal genauer schauen, was da los ist.

Schönen Abend!


----------



## Thomas_v2.1 (27 Oktober 2014)

foo schrieb:


> Auch die Struktur der Read/Write Req/Res geht mir noch nicht ganz ein, bei meinen captures wird da im Moment noch relativ viel fehlinterpretiert, muss da mal genauer schauen, was da los ist.



Du meinst mit Anzeige als "malformed packet"? Bei den Telegrammen bei denen wirklich Variablenwerte gelesen / geschrieben werden sollte das eigentlich passen. Bis auf die Erkennung der Fehlercodes wenn z.B. die CRC oder die LID nicht mit dem SPS-Programm übereinstimmen.
Es gibt noch andere Read/Write Telegramme die ein mir bis jetzt unbekanntes Datenformat nutzen, dann schlägt die Erkennung fehl und es wird sozusagen "Schrott" erkannt und ggf. übers Paketende hinaus eingelesen, das würgt Wireshark dann mit "malformed packet" ab.

Ich kann ja noch ein paar Telegramme mit zyklischen Daten einer 1200 ins Repository hochladen, für eine 1500 habe ich aber auch nicht mehr.


----------



## Jochen Kühner (27 Oktober 2014)

Also falls Interesse besteht mit einer 1500er rumzuexperimentieren, Ich kann eine an mein Netz hängen und dir übers Internet zugänglich machen... Ich komm im Moment einfach nicht dazu mich näher mit der 1500er zu beschäftigen, sonst würde Ich gern auch in die Protokollanalyse mit einsteigen...


----------



## juergi (28 Oktober 2014)

Thomas_v2.1 schrieb:


> Das habe ich erstmal so benannt, weil der Aufbau dann identisch mit dem Header ist. Warum sollte man unnütze 4 Bytes anhängen? Ich verstehe es auch nicht.
> Wenn du einen großen Baustein hochlädst lässt sich damit eine Fragmentierung der PDU erkennen - zumindest bei der ersten. Den Trailer gibt es dann nur im letzten Teil der Serie. Dann liest der Partner so lange die Daten ein,
> bis er einen Trailer sieht. Ob das zuverlässig ist weiß ich auch nicht. Eigentlich müsste man die 0x72 dann im Bytestrom entsprechend escapen. In Wireshark selber lässt sich die Erkennung glaube ich nicht zuverlässig realisieren, bzw. kann die Erkennung auch fehlschlagen, falls in den Fragmenten das erste Byte im Data-Teil einen bekanntem Code entspricht.



Die 0x72 braucht man nicht zu Escapen, da im Header bereits die Länge bis zum Trailer steht. Somit ist klar, dass jeder Wert 0x72 innerhalb dieser Länge zur Payload gehört.
Evtl. ist der "Trailer" als zukünftige Erweiterung gedacht, um direkt an ein Telegramm ein weiteres Anhängen zu können.

Gruß
  Jürgi


----------



## foo (28 Oktober 2014)

juergi schrieb:


> Die 0x72 braucht man nicht zu Escapen, da im Header bereits die Länge bis zum Trailer steht. Somit ist klar, dass jeder Wert 0x72 innerhalb dieser Länge zur Payload gehört.
> Evtl. ist der "Trailer" als zukünftige Erweiterung gedacht, um direkt an ein Telegramm ein weiteres Anhängen zu können.
> 
> Gruß
> Jürgi



Oh, das ist ein verdammt guter Ansatz! Vielleicht wollten die das tatsächlich damit bezwecken. Das wäre nämlich dann auch konsistent mit der aktuelen 0x0000 im length field des Trailers.

@Jochen: Vielen lieben Dank für dein Angebot. Ich hab bisher noch keine Erfahrung mit dem Programmieren der S7er. Mir mangelt es auch an nötiger (vermutlich teurer...) Software dafür... Aber danke für das tolle Angebot. Ich komm auf dich zurück, sollte es mich weiterbringen!

@Thomas: Doch genau das meine ich, ich hab Write Requests, die z.B. falsch interpretiert werden. Bin gerade noch am herausfinden, woran das liegt. 

Viele Grüße


----------



## foo (28 Oktober 2014)

@juergi: Oh, das ist eine verdammt gute Idee! Vielleicht wollten die das tatsächlich damit bezwecken. Das wäre nämlich dann auch konsistent mit der aktuellen 0x0000 im length field des Trailers, und würde diese Zahl auch erklären.

@Jochen: Vielen lieben Dank für dein Angebot. Ich hab bisher noch keine Erfahrung mit dem Programmieren der S7er. Mir mangelt es auch an nötiger (vermutlich teurer...) Software dafür... Aber danke für das tolle Angebot. Ich komm auf dich zurück, sollte es die Entwirrung des Protokolls weiterbringen!

@Thomas: Doch genau das meine ich, ich hab Write Requests, die z.B. falsch interpretiert werden. Bin gerade noch am herausfinden, woran das liegt.

Viele Grüße


----------



## Thomas_v2.1 (1 November 2014)

Ich habe eine neue Erkenntnis zur Session-Id. Diese muss nicht anhand des Wertes der von der SPS zurückkommt berechnet werden (+ 0x380), sondern kommt direkt aus der SPS zurück. Nur im Format varuint32, also als Wert mit variabler Länge. In den folgenden Telegrammen wird die Id dann als Wert mit 32 Bit fixer Länge verwendet. Die verschiedenen Datentypen machen die Erkennung natürlich schwer nur durch ansehen der Werte erkennbar. Zumindest fallen damit auch zwei unbekannte Bytes raus.

Eine Session wird ebenfalls aufgebaut um diverse andere Dienste zu nutzen, wie zyklische Variablendienste, die Abfrage des Baugruppenzustands, und auch der Bausteinupload scheint über eine Session eingeleitet zu werden.
Bei Sitzungsaufbau sieht es auch so aus, als ob angegeben werden kann wie lange diese gültig ist. Bei den Variablendiensten konnte ich die zugehörige ID schon lokalisieren, genauso wie auch die ID um das Aktualisierungsintervall festzustellen.

Ganz verkehrt scheint die Interpretation zumindest nicht zu sein.


----------



## foo (2 November 2014)

Ohje, mit der Session ID hast du vollkommen Recht, hatte da wohl auch Tomaten auf den Augen...

Ich hab gesehen, dass du am WE auch an den cyclic packets weiter gemacht hast.
Bist du dir bei der Cyclic Session ID sicher, dass sich die immer über 4 Byte erstreckt?

Dieses Feld ist ja an und für sich bei anderen Funktionen (z.B. Data Req/Res, StartConn Req/Res) auch vorhanden, und da ist es immer 0x0000.

Wie ich oben schon mal erwähnt hab, glaub ich, dass es nicht Teil der Session ID ist, sondern eher eine Art Bitmaske (Ich konnte in dem Feld 0x1000 und 0x7000 beobachten, daher meine Vermutung auf ne Bitmaske).

Eventuell könnte man sogar Pakete immer konsequent in vier statt in drei Teile aufteilen:

Header -> Data Header -> Data -> Trailer

Über alle Pakete ist der Data Header im Prinzip immer der gleiche (Type of Data, Funktionsnummer (bzw. Cyclic Reference), bisschen was unbekanntes, Sequence Number).
Der Data Header bestimmt quasi, um welchen expliziten Typen es sich bei Data handelt.

Viele Grüße


----------



## Thomas_v2.1 (2 November 2014)

foo schrieb:


> Bist du dir bei der Cyclic Session ID sicher, dass sich die immer über 4 Byte erstreckt?


Ja. Weil die Id bei den zyklischen Daten glücklicherweise einen Wert hat der alle 32 Bit benötigt, wie 0x1000006a. Und die Id kommt bei Start-Session von der SPS zurück, und wird auch beim Beenden der Session so verwendet. Darum bin ich überhaupt drauf gekommen dass es varuint32 ist, denn so eine Zahl hat in diesem Format verdächtig viele 8en in den Bytes ;-)



foo schrieb:


> Wie ich oben schon mal erwähnt hab, glaub ich, dass es nicht Teil der Session ID ist, sondern eher eine Art Bitmaske (Ich konnte in dem Feld 0x1000 und 0x7000 beobachten, daher meine Vermutung auf ne Bitmaske).
> 
> Eventuell könnte man sogar Pakete immer konsequent in vier statt in drei Teile aufteilen:
> 
> ...



Ich habe schon einiges vereinheitlichen können. Bei dem was ich am WE gemacht habe, ist die Anzahl der Zeilen zumindest weniger geworden.
Es fallen nur die Telegramme mit den zyklischen Daten aus dem Rahmen. Ich glaube nicht dass sich die in das andere Schema pressen lassen, dazu sieht es mit der Referenz-Id an der Stelle zu gut aus.

Die Angabe einer Variablenadresse bei den zyklischen Daten unterscheidet sich auch von dem Format, welches bei einem 'normalen' Zugriff verwendet wird. Sieht mir so aus als ob das verschiedene Abteilungen bearbeitet haben, und jeder den Teil so gestalten kann wie es ihm gerade gefällt.


----------



## foo (2 November 2014)

Hihi,

aah, jetzt seh ich das gerade auch mit der Cyclic Reference, dass die auch bei Antworten genau so wiedergegeben wird, du hast recht...
Ach verdammt, dann muss ich meine Idee mit dem gemeinsamen Data Header wieder verwerfen.

Hmm, jetzt wissen wir also, dass das UNKNOWN1 Field bei Cyclic Daten zu der Cyclic Reference gehört.
Wir wissen auch, dass UNKNOWN1 bei nicht zyklischen Daten IMMER 0x0000 ist. Zumindestens hab ich noch nie was anderes gesehen.

Vielleicht lässt sich ja fest halten, dass es bei nicht zyklischen Daten einfach nur ein Reserved field ist, mit dem etwas rumgepadded wird, damit der (ich nenns jetzt einfach mal so) "Data Header" bei zyklischen genauso groß ist wie bei nicht zyklischen Daten.

VG


----------



## Thomas_v2.1 (2 November 2014)

Das mit den zyklischen Daten müsste eigentlich noch eine andere Bezeichnung bekommen, mir ist dafür nur noch nichts besseres eingefallen.

Nach Aufbau einer Session ist es möglich, dass sich die Teilnehmer Daten ohne Quittungstelegramme zuschicken. Das wird benutzt bei den zyklischen Variablendiensten eines HMIs, oder auch wenn der Baugruppenzustand beobachtet wird.
Beim Bausteinupload kann das PG in Folge dieser Session mehrere PDUs mit dem Bausteindaten ohne Quittung (auf S7commp Ebene) an die SPS schicken.

Da muss ich mal vergleichen, ob diese Telegramme an der von dir erwähnten Stelle auch immer die gleichen Werte haben, und ob das bei einer 1500 auch so ist.


----------



## foo (2 November 2014)

Huhu,

nochmal zurück zu dem "Integritätsteil" bei den 1500er. Das hab ich heut gefunden:

http://de.slideshare.net/AlexanderTimorin/industrial-protocols-for-pentesters
http://de.slideshare.net/AlexanderTimorin/scada-deep-inside-protocols-and-security-mechanisms
https://github.com/atimorin/scada-tools

Der Kerl hat scheinbar rausgefunden, dass es sich bei der Authentifizierung (ich nehme an, das ist ein Teil der Kommunikation, welcher sich unter den ersten paar Paketen befinden muss) um ein Challenge Response System handelt, mit HMAC und SHA1 als Prüfsummenalgo.
Es liegt also nahe, dass auch für den Rest SHA1 verwendet wurde. (Warum sollte man zig verschiedene Prüfsummenverfahren implementieren)
SHA1 hat als Output 160 Bit, sprich 20 Byte. Wir haben aber 32 Byte Integritätspart am Ende. Stellt sich die Frage, wofür der Rest verwendet werden könnte.

Ich hab meine Captures mal durchgekuckt, solche Authentication Pakete, von denen er spricht aber nicht gefunden.
Hat jemand von euch vielleicht solche Caps?

VG


----------



## Thomas_v2.1 (2 November 2014)

Was in dem Dokument beschrieben wird, geht von einer 1200er aus. Bei einer 1200 (zumindest mit meinem FW-Stand) ist der Passwortschutz nur für PG-Funktionen relevant. HMI-Kommunikation ist immer möglich.
Ich habe mal bei meiner 1200er ein Passwort gesetzt und einen Baustein hochgeladen (siehe Anhang).
Das im Dokument beschriebene "7202000f32" findet man auch wieder. Die Erkennung anhand dieses Wertes ist natürlich nur zufällig richtig, weil es nur die Längenangaben des Datenteile abfragt.

Zumindest weiß ich jetzt, dass die Funktion "0x04f2" nicht "Modify cyclic", sondern "Modify session" heißen sollte, weil damit wohl ganz allgemein der Zustand einer Session bearbeitet werden kann.

Ob das was mit dem Anhängsel der 1500er bei der HMI-Kommunikation gemein hat weiß ich nicht, da ich bei den 1500er Logfiles die mir vorliegen nicht weiß ob dort eine und welche Schutzstufe / Login verwendet wurde.


----------



## foo (3 November 2014)

Ah cool super, danke dir!

Deine Challenge/Response ist:
e8c952612362b63222c725c400c6b6c47b6204e5 // 5501bdf9a628dc618f00f9e48836ae8e8313d3be

Und dein Passwort lautete test 

Danke für die Pakete!


----------



## Thomas_v2.1 (3 November 2014)

foo schrieb:


> Deine Challenge/Response ist:
> e8c952612362b63222c725c400c6b6c47b6204e5 // 5501bdf9a628dc618f00f9e48836ae8e8313d3be
> 
> Und dein Passwort lautete test



Fazit: Man sollte beim TIA-Portal ein starkes Passwort verwenden wenn es was bringen soll.


----------



## foo (13 November 2014)

Ich glaub ich konnte den Unknown 3B Type entziffern.

Der hat nicht wie angenommen immer nur 3B, sonder ist eher ein  Byte-Vector und verhält sich ähnlich wie ein String.

Er besteht aus 2Byte length indication und wird dann  gefolgt von genau dieser Länge an Bytes.
Das geht sich perfekt in einer meiner Captures aus:


```
a39505 00 14 0005 0102030405
          ^^ ^^^^      5 Byte Daten
           |    5 Byte Längenindikator
       "3B" Type
```

Viele Grüße!


----------



## Thomas_v2.1 (13 November 2014)

Da musste ich erstmal ein Logfile suchen bei denen in der Längenangabe ein Wert ungleich 0 steht, bei der HMI-Kommunikation steht dort als Länge fast immer eine 0.
Aber die Daten einer Variablentabelle werden in so einem Blob (so hab ich das jetzt genannt) verpackt.

Ich verstehe es eh nicht warum so viele Arrays und Strings mit Länge Null durch die Gegend geschickt werden, für mich ergibt das keinen Sinn.


----------



## Thomas_v2.1 (13 November 2014)

Worin ich auch noch kein Schema sehe, ist das immer gleich aussehende "Anhängel" am Datenteil das es bei vielen Telegrammen gibt. Vor allem ist das mal 25, 26 oder 27 Bytes lang. Am Ende hängt immer eine unterschiedliche Anzahl 0-Bytes. Es wird auf jeden Fall nicht der Datenteil auf eine gerade oder ungerade Anzahl an Bytes aufgefüllt. Sehr seltsam.


```
1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
04:e8:89:69:00:12:00:00:00:00:89:6a:00:13:00:89:6b:00:04:00:00:00:00:00:00:72
04:e8:89:69:00:12:00:00:00:00:89:6a:00:13:00:89:6b:00:04:00:00:00:01:00:00:00:00:72	-> bei 0x0586 Request
04:e8:89:69:00:12:00:00:00:00:89:6a:00:13:00:89:6b:00:04:00:00:00:00:00:00:72
04:e8:89:69:00:12:00:00:00:00:89:6a:00:13:00:89:6b:00:04:00:00:00:01:00:00:00:00:72
04:e8:89:69:00:12:00:00:00:00:89:6a:00:13:00:89:6b:00:04:00:00:00:00:00:00:00:72	-> bei Modify session
04:e8:89:69:00:12:00:00:00:00:89:6a:00:13:00:89:6b:00:04:00:00:00:00:00:00:72
04:e8:89:69:00:12:00:00:00:00:89:6a:00:13:00:89:6b:00:04:00:00:00:00:00:00:00:72
```


----------



## Thomas_v2.1 (14 Dezember 2014)

Für den interessierten Mitleser habe ich vom aktuellen Stand des s7comm-plus plugins kompilierte dlls für 32 und 64 Bit veröffentlicht. Die kann unter:
http://sourceforge.net/projects/s7commwireshark/files/s7comm-plus-dev/
heruntergeladen werden.

Es gibt zwar noch einige weiße Flecken auf der Landkarte, aber ich würde sagen dass ca. 80% vom Protokoll erkannt werden.

Theoretisch könnte man sich mit den Informationen schon daran machen einen Treiber für die symbolische Anbindung einer 1200/1500 zu schreiben. Als Basis für den TCP/ISO-Stack wäre Snap7 sicher nicht die schlechteste Wahl. Das wäre doch mal was, wenn es zuerst eine Open-Source Lösung gäbe 

Bei der 1500 kommt aber noch das Problem der Integritätsinformationen hinzu die jedem Telegramm anhängen. Wobei da zu prüfen ist, ob diese bei entsprechendem Verbindungsaufbau evtl. auch entfallen können.


----------



## Thomas_v2.1 (3 Januar 2015)

Ich habe nochmal eine aktuelle Version veröffentlicht. Die Bezeichnungen der Funktionen wurden geändert, sodass sich ein schlüssiges Bild über das ergibt was dort abläuft.
Alle Telegramme die ich mit meiner 1200er erzeugen konnte werden erkannt. Alle die mir für eine 1500er vorliegen ebenfalls, zumindest gibt es mit diesen keinen Dissector-Fehler. Was mir noch fehlt wären Telegramme einer 1500er bei denen Alarme von der SPS an ein HMI übertragen werden. Bei der 1200 ist diese Funktion nicht vorhanden.

Alles was ein HMI zum Lesen und Schreiben benötigt, wie auch das Auslesen der Variableninformationen aus der SPS wird erkannt. Es lässt sich dabei auch erkennen wie intern die "optimierte" Speicherablage funktioniert, d.h. die absoluten Speicheradressen, welche vom TIA-Portal bei "optimierten" Bausteinen nicht angezeigt werden.

https://sourceforge.net/projects/s7commwireshark/files/s7comm-plus-0-0-1/


----------



## Jochen Kühner (9 Februar 2015)

Was ist den jetzt mit der integration von S7Comm direkt in Wireshark? Dachte die hätten das schon gemerged?


----------



## Thomas_v2.1 (9 Februar 2015)

Ist bisher nur in der Development Version, die kann man auch separat herunterladen, z.B. in der 1.99.2 sollte es enthalten sein.
In die 1.12er Reihe kommen keine neuen Protokolle mehr. Glaub die Entwickler sind stark mit der Umstellung von GTK auf Qt beschäftigt. Bisher haut mich die Qt Version noch nicht vom Hocker, ist aber vielleicht nur Gewöhnungssache.


----------



## Jochen Kühner (9 Februar 2015)

Thomas_v2.1 schrieb:


> Ist bisher nur in der Development Version, die kann man auch separat herunterladen, z.B. in der 1.99.2 sollte es enthalten sein.
> In die 1.12er Reihe kommen keine neuen Protokolle mehr. Glaub die Entwickler sind stark mit der Umstellung von GTK auf Qt beschäftigt. Bisher haut mich die Qt Version noch nicht vom Hocker, ist aber vielleicht nur Gewöhnungssache.



Ok, danke für die Info!


----------



## Thomas_v2.1 (28 Februar 2015)

Hat jemand die Möglichkeit, mit TIA V13+SP1 ein paar Logfiles zu erstellen wenn er mit einer S7-1500 kommuniziert? Am Besten nur ein paar Mal die Verbindung zur CPU verbinden und trennen. Mich würde mal interessieren was Siemens da mit dem SP1 geändert hat, bezüglich:


> Vulnerability 1 (CVE-2015-1601)
> Attackers with access to the network path between client and server could possibly
> intercept or modify Siemens industrial communications at port 102/tcp and conduct a
> Man-in-the-Middle attack.



aus:
http://www.siemens.com/innovation/pool/de/forschungsfelder/siemens_security_advisory_ssa-315836.pdf

Evtl. kann man anhand der Änderungen auf einige Funktionsweisen schließen.


----------



## Kall (5 Mai 2015)

Ich habe das S7Comm-Plus Plugin mal ausprobiert (CPU S7-1500 <->  HMI TP700, Symbolischer Zugriff auf Variablen im DB und kein optimierter  Datenbaustein, TIAv12 SP1).
Kann man mit Hilfe der Item reference number feststellen wie der Variablenname im Projekt heißt?


----------



## Thomas_v2.1 (5 Mai 2015)

Kall schrieb:


> Ich habe das S7Comm-Plus Plugin mal ausprobiert (CPU S7-1500 <->  HMI TP700, Symbolischer Zugriff auf Variablen im DB und kein optimierter  Datenbaustein, TIAv12 SP1).
> Kann man mit Hilfe der Item reference number feststellen wie der Variablenname im Projekt heißt?



Theoretisch ja, praktisch so naja ;-)
Die Nummern und die zugehörigen Symbole sind in der TIA-Projektdatei wie auch in der SPS gespeichert. Nur gibt es im TIA-Portal keine (offizielle) Möglichkeit an diese IDs heranzukommen. Ich weiß nicht in wie weit Jochen Kühners Programm die TIA-Projektdatei einlesen kann, um an diese Informationen heranzukommen.

Nur über Wireshark funktioniert das nicht. Aber es gibt eine Möglichkeit die Symbolik der SPS zu browsen (z.B. mit WinCC V7.3), dort bekommt man dann den kompletten Symbolhaushalt mit IDs auch in Wireshark zu Gesicht.


----------



## Kall (5 Mai 2015)

Thomas_v2.1 schrieb:


> Theoretisch ja, praktisch so naja ;-)
> Die Nummern und die zugehörigen Symbole sind in der TIA-Projektdatei wie auch in der SPS gespeichert. Nur gibt es im TIA-Portal keine (offizielle) Möglichkeit an diese IDs heranzukommen. Ich weiß nicht in wie weit Jochen Kühners Programm die TIA-Projektdatei einlesen kann, um an diese Informationen heranzukommen.
> 
> Nur über Wireshark funktioniert das nicht. Aber es gibt eine Möglichkeit die Symbolik der SPS zu browsen (z.B. mit WinCC V7.3), dort bekommt man dann den kompletten Symbolhaushalt mit IDs auch in Wireshark zu Gesicht.



Vielen Dank für die schnelle Antwort. 
Ich habe in der Zwischenzeit mal versucht mit einem Hexeditor (Ultraedit)  die Item reference number im Projektfile (.pfl) zu finden. Es gibt sie dort mehrmals aber leider ist dort weit und breit der Variablenname nicht in Sicht. Der Asciiname der Variable ist auch mehrmals im File vorhanden. Da ich auf Grund der angezeigten Variablenwerte in Wireshark weiß um welchen es sich handelt ist die Zuordnung klar. 
Wenn ich die Adressierungsart von symbloisch auf absolut stellen würde, würde man dann die DB Number usw. im Telegramm sehen?
Mir ist aufgefallen dass Stringvariablen als USINT-Arrays übertragen werden und dann vorne 2 Felder mehr besitzen. 
Die erste Ziffer gibt die Feldlänge an und die 2. Ziffer die Anzahl der belegten Felder. Sehe ich das richtig?


----------



## Thomas_v2.1 (5 Mai 2015)

Kall schrieb:


> Wenn ich die Adressierungsart von symbloisch auf absolut stellen würde, würde man dann die DB Number usw. im Telegramm sehen?


Das hängt davon ab wie der Partner auf die Daten in der SPS zugreift. Den Zugriff über LID/CRC beherrscht momentan ja nur Siemens. D.h. bei allen Nicht-Siemens-Kommunikationspartnern musst auf Absolutadressierung bzw. "nicht-optimierten Zugriff" in Siemens-Sprech wechseln. Dann wird das übliche s7comm (ohne plus) Protokoll verwendet.

Ich vermute aber mal, dass auch auf "nicht-optimierte" Bereiche über LID/CRC zugegriffen werden kann. Und dass Siemens-HMIs zum Beispiel wenn integriert immer darüber auf die SPS-Daten zugreifen werden. Ich habe das aber noch nicht getestet, kannst du ja mal machen. Was hast du denn für ein Kommunikationspartner / HMI-Software?



Kall schrieb:


> Mir ist aufgefallen dass Stringvariablen als USINT-Arrays übertragen werden und dann vorne 2 Felder mehr besitzen.
> Die erste Ziffer gibt die Feldlänge an und die 2. Ziffer die Anzahl der belegten Felder. Sehe ich das richtig?


Beim Variablentyp String ist das so, ja. Der Aufbau ist identisch mit den Strings aus der S7-300/400er Welt.

Mit der V13 ist der Datentyp WString hinzugekommen. Hab mir das zwar noch nicht live auf dem Draht ansehen können, aber es gibt jetzt schon einen entsprechenden Datentyp bei dem diese Strings dann UTF8-codiert übertragen werden.


----------



## Jochen Kühner (5 Mai 2015)

Kall schrieb:


> Vielen Dank für die schnelle Antwort.
> Ich habe in der Zwischenzeit mal versucht mit einem Hexeditor (Ultraedit)  die Item reference number im Projektfile (.pfl) zu finden. Es gibt sie dort mehrmals aber leider ist dort weit und breit der Variablenname nicht in Sicht. Der Asciiname der Variable ist auch mehrmals im File vorhanden. Da ich auf Grund der angezeigten Variablenwerte in Wireshark weiß um welchen es sich handelt ist die Zuordnung klar.
> Wenn ich die Adressierungsart von symbloisch auf absolut stellen würde, würde man dann die DB Number usw. im Telegramm sehen?
> Mir ist aufgefallen dass Stringvariablen als USINT-Arrays übertragen werden und dann vorne 2 Felder mehr besitzen.
> Die erste Ziffer gibt die Feldlänge an und die 2. Ziffer die Anzahl der belegten Felder. Sehe ich das richtig?



Falls du dich weiter mit dem TIA File format beschäftigen willst: in dem Thread siehst du was Ich schon weiss: http://www.sps-forum.de/hochsprache...fileanalyse-tia-file-format-grammar-file.html


----------



## Kall (5 Mai 2015)

Thomas_v2.1 schrieb:


> Das hängt davon ab wie der Partner auf die  Daten in der SPS zugreift. Den Zugriff über LID/CRC beherrscht momentan  ja nur Siemens. D.h. bei allen Nicht-Siemens-Kommunikationspartnern  musst auf Absolutadressierung bzw. "nicht-optimierten Zugriff" in  Siemens-Sprech wechseln. Dann wird das übliche s7comm (ohne plus)  Protokoll verwendet.
> 
> Ich vermute aber mal, dass auch auf "nicht-optimierte" Bereiche über  LID/CRC zugegriffen werden kann. Und dass Siemens-HMIs zum Beispiel wenn  integriert immer darüber auf die SPS-Daten zugreifen werden. Ich habe  das aber noch nicht getestet, kannst du ja mal machen. Was hast du denn  für ein Kommunikationspartner / HMI-Software?



Die S7-1513-1 kommuniziert mit der HMI TP700 Comfort. Das HMI-Projekt wurde WinCC Advanced V12 SP1 erstellt. 
Ich kann das gerade nicht testen werd's die Tage mal versuchen.

Bei der Kommunikation zwischen einer HMI und einer LOGO 0BA7 sieht man  schön wie die HMI ein Telegramm zur Logo schickt und dort Variablen  lesen will. Die Logo antwortet dann der HMI und schickt ihr die  Variablenwerte.

Bei der S7Comm-Plus Kommunikation kann ich das so mit meiner Aufzeichung nicht feststellen. 
Für mich sieht es so aus als ob die CPU in gewissen Abständen der HMI  ein Notifikation Telegramm mit Variablenwerten schickt ohne dass die HMI  das angefordert hat.
Es kommt vor dass die HMI ein Request -Funktion - Set Variable -  Telegramm verschickt auf das die CPU mit einem Responce  - Funktion -  Set Variabe - Telegramm antwortet das wars dann schon. Hat sich da was  geändert?


Ich schicke mit den S7-Kommunikationsbausteinen BSEND / BREV Daten zwischen der S7-1513-1 und der S7-1516-3 hin und her.
Wenn die S7-1513-1 mit BSend sendet erscheint das Telegramm  ROSCTR:[Userdata] Function:[Request] ->:[Unknown function: 0x06]
Warum steht bei Function Request ? Die andere CPU hat das senden nicht angefordert.
S7COMM    87    ROSCTR:[Userdata] Function:[Response] ->:[Unknown function: 0x06]


----------



## Thomas_v2.1 (5 Mai 2015)

Kall schrieb:


> Bei der S7Comm-Plus Kommunikation kann ich das so mit meiner Aufzeichung nicht feststellen.
> Für mich sieht es so aus als ob die CPU in gewissen Abständen der HMI  ein Notifikation Telegramm mit Variablenwerten schickt ohne dass die HMI  das angefordert hat.
> Es kommt vor dass die HMI ein Request -Funktion - Set Variable -  Telegramm verschickt auf das die CPU mit einem Responce  - Funktion -  Set Variabe - Telegramm antwortet das wars dann schon. Hat sich da was  geändert?


Das sind zyklische Variablendienste, welche es auch schon bei der S7-300/400 gab. Es gibt dabei ein Telegramm bei dem der Client bei der SPS Variablen für die zyklische Aktualisierung anmeldet. Die SPS bestätigt dieses, und schickt dann von sich aus z.B. im angeforderten Aktualisierungsintervall den Datensatz mit den Variablenwerten. Um die Zugehörigkeit festzustellen gibt es in jedem Telegramm eine Referenznummer. Um zu wissen welche Variablen in diesem Telegramm sind, muss das Telegramm gefunden werden bei dem die zyklischen Dienste für diese Referenznummer initialisiert werden.



Kall schrieb:


> Ich schicke mit den S7-Kommunikationsbausteinen BSEND / BREV Daten zwischen der S7-1513-1 und der S7-1516-3 hin und her.
> Wenn die S7-1513-1 mit BSend sendet erscheint das Telegramm  ROSCTR:[Userdata] Function:[Request] ->:[Unknown function: 0x06]
> Warum steht bei Function Request ? Die andere CPU hat das senden nicht angefordert.
> S7COMM    87    ROSCTR:[Userdata] Function:[Response] ->:[Unknown function: 0x06]



BSEND/BRECV ist das alte s7comm Protokoll. Die Erkennung der BSEND/BRECV-Telegramme habe ich erst vor 2 Wochen eingebaut. Ist z.Zt. nur im SVN-Repository vorhanden und noch nicht in der kompilierten dll (evtl. schon im nightly build vom offiziellen Wireshark vorhanden). Ich habe das bisher nie benötigt, darum habe ich das nicht eingebaut. Außerdem habe ich auch nicht für alle Exoten die passende Hardware zum Testen da.


----------



## Kall (6 Mai 2015)

Thomas_v2.1 schrieb:


> BSEND/BRECV ist das alte s7comm Protokoll. Die Erkennung der BSEND/BRECV-Telegramme habe ich erst vor 2 Wochen eingebaut. Ist z.Zt. nur im SVN-Repository vorhanden und noch nicht in der kompilierten dll (evtl. schon im nightly build vom offiziellen Wireshark vorhanden). Ich habe das bisher nie benötigt, darum habe ich das nicht eingebaut. Außerdem habe ich auch nicht für alle Exoten die passende Hardware zum Testen da.



Ich habe gerade mal die neuste nightly ausprobiert und dort funktioniert es. Parameter: (Request) ->(PBC BSEND/BRECV) ! Super!


----------



## Thomas_v2.1 (23 Dezember 2015)

Ich bin gerade dabei die Bausteinmeldungen zu ergänzen. Nur fehlt mit zur Zeit mangels Hardware die Möglichkeit die symbolbezogenen Meldungen (SCAN) zu testen. Hat jemand evtl. ein Wireshark Log in dem diese Meldungen auftauchen?

Sonst gibt es ja so weit ich weiß nur die Varianten AlarmS (S7-300) und Alarm8 (S7-400).


----------



## SiemensUser (23 Juni 2016)

Ich habe gerade die aktuelle Version vom s7comm-plus plugin (s7comm-plus-0-0-2) ausprobiert. Sieht soweit gut aus.

Ich habe aber noch zwei Punkte, die ich beim 72er-Protokoll nicht verstehe:

Die SYM-CRC-Berechnung der symbolischen Adressen bei einer 1500er:
Die in Jochens DotNetSiemensPLCToolBoxLibrary verwendetet Funktion zum Berechnen der CRC funktioniert nur bei 1200er Symbolen. Bei 1500er Symbolen wird eine andere Checksumme gebildet.
Im WireShark-Mitschnitt 
	

		
			
		

		
	

Anhang anzeigen S7-1500-HMI_DB10_Sym.zip

	

		
			
		

		
	
 wird die symbolische Adresse "Variable" aus dem DB10 gelesen. Mit der ToolBox-CRC-Funktion ergibt sich der Wert "0xf7355bd6" und WireShark zeigt "0xd577798b" an.
Hat einer von euch eine Idee, wie die CRC bei einer 1500 berechnet wird?
In vielen 72er-Paketen ist ein Integrity part-Paket vorhanden.
Hier gibt es eine ID, die scheinbar immer hochgezählt wird und eine 32 Byte langes Paket ("Packet Digest")
Was ist dies genau für ein Packet? Kann man das irgendwie berechnen?


----------



## Thomas_v2.1 (23 Juni 2016)

zu 2)
Meine Vermutung:
Beim Verbindungsaufbau wird ein geheimer Schlüssel ausgehandelt, der später in die Berechnung das Wertes mit einfließt. Das Verfahren entspricht also MAC bzw. HMAC. Beim Verbindungsaufbau verraten auch ein paar Objekt-ID was da ablaufen könnte. Bei einer S7-1200 die keine Integrität beherrscht, fehlen diese Objekt-IDs beim Verbindungsaufbau. Ich habe ein paar zaghafte Versuche unternommen um herauszufinden woraus die sich die Objekt-Daten beim Verbindungsaufbau zusammensetzen, denn da gibt es feste und variable Teile. Wie das im Detail funktioniert weiß ich aber auch nicht.
Damit keine Replay-Angriffe möglich sind, muss es eine Wertänderung im Datenpaket geben, darum die Integritäts-ID. Diese erhöht sich nicht nur, sondern laut meinen Berechnungen wird diese aus der letzten Response usw. berechnet (glaub ich habs im Code-Kommentar vermerkt). D.h. selbst wenn der Datenteil komplett identische Daten aufweist, ist die Signatur aufgrund des sich ändernden ID und dem Hashverfahren völlig unterschiedlich.
Wie die Signatur berechnet wird ist mir nicht bekannt, ich vermute (und es wäre für Siemens auch empfehlenswert) etwas standardisiertes wie SHA-256 (würde von der Byteanzahl passen) zu verwenden.

Wahrscheinlich gab es da mal ein Sicherheitsproblem im Übertragungsprotokoll, denn die Struktur mit FW 1.5 geändert (Position des Integritätsblocks hat sich geändert). Evtl. lässt sich daraus noch etwas ableiten.

zu 1)
Muss ich mir mal ansehen, ich habe das bei der 1500 selber noch nicht nachgerechnet. Bei den ersten 1200er ließen sich noch über die 0x32er Telegramme mit LID/CRC Variablenwerte abfragen. Ob das bei der 1500er überhaupt noch funktioniert weiß ich nicht. Ich hatte bisher kein Zugang zu einer 1500.


----------



## SiemensUser (23 Juni 2016)

zu 1) Ja das funktioniert bei der 1500er auch, wie hier im Ausschnitt des Wireshark-Protokolls zu sehen ist.
Anhang anzeigen 33191

Wie gesagt, die Variable heißt "Variable"

zu 2) Ja, SHA256 könnte passen. In einem älteren Post gab es mal eine Passwortübergabe mit SHA1 bzw. HMACSHA1. Da konnte das Passwort auch mit einem Python-Programm ermittelt werden. Evtl. ist es hier ja ähnlich. Allerdings ist hier natürlich die Frage, welcher Hashkey hier verwendet wird. Vielleicht folgende Kandidaten:
- Beim Connect (CreateObject)-Response wird u.a. ein ServerSessionChallenge zurückgeliefert. Dies sind 20 Byte Daten (evtl. SHA1?)
- Beim anschließenden SetMultiVariables-Request wird u.a ein SecurityKeyEncryptedKey gesetzt: 180 Byte Daten (Blob)

Keine Ahnung, ob diese Daten irgendetwas mit der Bildung des Integrity parts zu tun haben.


----------



## Thomas_v2.1 (23 Juni 2016)

SiemensUser schrieb:


> zu 1) Ja das funktioniert bei der 1500er auch, wie hier im Ausschnitt des Wireshark-Protokolls zu sehen ist.



Das in deinem Logfile gezeigte ist aber sozusagen die aktuelle "Standardzugriffsart".
Bei meiner 1200 mit FW2 hier wurde diese Adressierungsart in das alte S7-Protokoll, d.h. mit 0x32 im Kopf, integriert. Bzw. wurde diese nur von einem HMI in TIA V11 verwendet, ab V12 verwendet das HMI die gleiche Zugriffsvariante wie in deinem angehängten Logfile. Anstelle der Anfrageadresse in Form des Any-Pointers gibt es dort eben Zugriff über LID und CRC.  Das Wireshark-Baumelement "Item Address" aus S7comm-plus ist identisch in S7comm vorhanden. Das hätte den Vorteil, dass sich damit relativ einfacher Zugriff auf symbolische adressierte Variablen möglich ist, weil eben der ganze bisher unbekannte Schritt mit Authentifizierung und Integrität entfällt, und es sich auch einfach in bestehende Kommunikationsbibliotheken (z.B. libnodave) integrieren lässt. Man muss nur vorab die IDs und das Symbol kennen, das Auslesen der Symbolik inkl. IDs ist nur über S7comm-plus möglich.



SiemensUser schrieb:


> Wie gesagt, die Variable heißt "Variable"


Die liegt aber laut deinem Logfile in einem Datenbaustein, dann berechnet sich die CRC aus dem vollständigen Zugriffnamen "DBNAME.VARNAME", d.h. mit Punkt. Wenn die Variable innerhalb einer Struktur liegt, dann wird als Trennzeichen ein 0x09 verwendet.

Wenn du mit das vollständige Symbol sagst, kann ich das mal mit meiner "Formel" nachrechnen.



SiemensUser schrieb:


> zu 2) Ja, SHA256 könnte passen. In einem älteren Post gab es mal eine Passwortübergabe mit SHA1 bzw. HMACSHA1. Da konnte das Passwort auch mit einem Python-Programm ermittelt werden. Evtl. ist es hier ja ähnlich. Allerdings ist hier natürlich die Frage, welcher Hashkey hier verwendet wird. Vielleicht folgende Kandidaten:
> - Beim Connect (CreateObject)-Response wird u.a. ein ServerSessionChallenge zurückgeliefert. Dies sind 20 Byte Daten (evtl. SHA1?)
> - Beim anschließenden SetMultiVariables-Request wird u.a ein SecurityKeyEncryptedKey gesetzt: 180 Byte Daten (Blob)
> 
> Keine Ahnung, ob diese Daten irgendetwas mit der Bildung des Integrity parts zu tun haben.



Die Integrity-ID berechnet sich imho nach:
Response.Integrity-Id = Request.Sequenznummer + Request.Integrity-Id
Ob das "muss" oder rein zufällig so ist habe ich noch nicht überprüft.

Dieser 180 Byte Blob hat nach meinen Analysen die folgenden Eigenschaften:
Insgesamt besteht er aus 7 Teilen
- 16 Bytes immer identisch
- 8 Bytes abhängig vom Schlüssel im HMI
- 24 Bytes immer identisch
- 76 Bytes abhängig vom Schlüssel im HMI
- 16 Bytes abhängig von der Challenge
- 24 Bytes abhängig vom Schlüssel im HMI
- 16 Bytes abhängig von der Challenge

Übrigens:
Von Wonderware gibt es mittlerweile angeblich einen Treiber des das S7comm-plus vollständig unterstützt.


----------



## SiemensUser (23 Juni 2016)

Thomas_v2.1 schrieb:


> Die liegt aber laut deinem Logfile in einem Datenbaustein, dann berechnet sich die CRC aus dem vollständigen Zugriffnamen "DBNAME.VARNAME", d.h. mit Punkt. Wenn die Variable innerhalb einer Struktur liegt, dann wird als Trennzeichen ein 0x09 verwendet.



Oh, danke für den Tipp. Werde ich morgen mal checken.


----------



## SiemensUser (24 Juni 2016)

Ich habe nochmal einen Test mit einer 1500er, TIA13 und einer HMI gemacht und ein Datenwort gelesen.




Die Variable heißt: Datenbaustein_1.TEST_WORD_6
CRC in WireShark: 0x1d7def11
CRC mit Jochens getcrc: 0x22097493

Anschließend habe ich den DB umbenannt: Datenbaustein_1a.TEST_WORD_6

CRC in wireshark: 0x1d7def11
getcrc: 0x500de358

Wenn ich nur "TEST_WORD_6" mit getcrc berechne, erhalte ich: 0xf13d471e

So wie es aussieht, hat also der Bausteinname keinen Einfluss auf die CRC. Aber nur mit "TEST_WORD_6" liefert Jochens getcrc einen falschen Wert.


----------



## Thomas_v2.1 (24 Juni 2016)

Ich habs mir nochmal angesehen. Es scheint bei der Berechnung einen Unterschied zwischen S7-1200 und S7-1500 zu geben.

Bei der 1200 berechnet sich die CRC rein aus dem Symbolnamen im DB, der DB-Name ist nicht relevant. Die DB-Nummer wird aber mit übermittelt. Das bedeutet, ein DB lässt sich umbenennen und der Zugriff vom HMI funktioniert weiterhin, solange die DB-Nummer nicht geändert wird.

Was bei der 1500 in den Symbolnamen mit hineinspielt habe ich noch nicht herausgefunden. Falls dem Symbol noch etwas vorangestellt sein sollte  (z.B. "DB.variable") und die Berechnung ist identisch, so ist dieses Präfix zumindest länger als 4 Zeichen, bis dahin habe ich alle Werte durchprobiert. Dass die Prüfsummenberechnung eine völlig andere ist kann ich mir fast nicht vorstellen.


----------



## SiemensUser (24 Juni 2016)

Hmmm...

Ich habe auch mal für die CRC-Berechnung alle Startwerte von 0 bis UInt32.Max für "TEST_WORD_6" durchprobiert. Leider ohne Erfolg.


----------



## Thomas_v2.1 (24 Juni 2016)

Doch, man bekommt eine Lösung mit so einer Bruteforce-Suche. Bei TEST_WORD_6 müsstest du die 4 Bytes 0x61, 0x90, 0xc8, 0x37 voranstellen, dann kommt mit der bisherigen Berechnung 0x1d7def11 heraus.

Vermutlich ist das aber nur eine zufällige Kollision bei der CRC Berechnung, das heißt es ist eine Lösung, aber nicht die einzige.

Mit den 4 Bytes kann ich zumindest die CRC für meine Steuerung _nicht_ berechnen. Ich habe mir zum Test 4 Variablen in einem DB abgelegt, und dann für die Erste ebenfalls einen 4 Byte-Präfix gefunden um auf die CRC zu kommen. Damit lassen sich aber auch nicht die CRC für die anderen Variablen in dem DB bestimmen. Damit kann man schonmal ausschließen, dass der gefundene Präfix korrekt ist, falls dieser z.B. Steuerungsabhängig sein sollte und darum bei dir und bei mir verschieden.
Es könnte z.B. auch DATENBAUSTEIN oder TIAISTDOOF davor (oder dahinter) stehen, alleine mit Bruteforce kommt man bei großer Länge nicht dahinter. Zumal auch noch alles ganz anders sein kann.


----------



## SiemensUser (25 Juni 2016)

Ja, war wohl ein Zufallstrefffer mit 0x61, 0x90, 0xc8, 0x37.
Wenn ich die Bytes vor meine DB-Variable "Variable" stelle, kommt eine falsche CRC heraus.


----------



## SiemensUser (16 August 2016)

Ich glaub ich hab's:
An TEST_WORD_6 muss man noch den Variablentyp anhängen (für WORD = 0x04) und die CRC mit TiaCrcHelper.getcrc() berechnen. Die errechnete CRC dann nochmals an TiaCrcHelper.getcrc() übergeben:

List<byte> Var =  new List<byte>(Encoding.ASCII.GetBytes("TEST_WORD_6"));
Var.Add(0x04);
UInt32 crc = TiaCrcHelper.getcrc(BitConverter.GetBytes(TiaCrcHelper.getcrc(Var.ToArray())));

und siehe da: crc = 0x1d7def11, wie auch im TIA-Wireshark-Protokoll.


Unklar sind jetzt noch:
- Das 32 Byte lange "Packet Digest" im Integrity part und 
- Der 180 Byte Blob im SetMultiVariables-Request (SecurityKeyEncryptedKey)

Hat einer von euch noch eine Ahnung, wie diese sich zusammensetzen?


----------



## Thomas_v2.1 (16 August 2016)

Das Anfügen des Datentyps ist durchaus sinnvoll. Bisher fußte die Zuverlässigkeit darauf, dass das TIA-Portal bei einer Änderung am Programm eine neue ID generiert, was vielleicht etwas wackelig war.

Was es bringen soll das ganze zweimal durch die Prüfsummenbildung zu schicken ist mir schleierhaft. Ich könnte mir nur vorstellen, dass es damit nicht zu "zufällig" richtigen Prüfsummen kommt, wenn das Verfahren wie bei der 1200 angewendet wird.
Ansonsten gilt bei Prüfsummenverfahren nicht unbedingt "viel hilft viel", ganz im Gegenteil.


----------



## Jochen Kühner (16 August 2016)

Haben wir denn jetzt schon genügend Infos um Symbolische Variablen aus einer 1500er zu lesen? Kann msn auch die existierenden Variablen auslesen?


----------



## Thomas_v2.1 (16 August 2016)

Jochen Kühner schrieb:


> Haben wir denn jetzt schon genügend Infos um Symbolische Variablen aus einer 1500er zu lesen? Kann msn auch die existierenden Variablen auslesen?


Du kannst alle notwendigen Informationen aus der Steuerung auslesen, das TIA-Portal Projekt dazu nicht benötigt. Das funktioniert bei den ersten 1200er mit alter Firmware, wie auch bei den aktuellen 1500. Wobei es da wieder Unterschiede im Aufbau gibt. Du müsst also die Symbolik auslesen, und darin für das gewünschte Symbol die ID und den Datentyp suchen und übernehmen.

Das ist aber alles mehr oder weniger aufwändig, weil du auch wenn nur an ausgewählte Informationen kommen willst, immer das komplette Telegramm von Anfang bis Ende verstehen musst, da es so gut wie keine Längenangaben oder sonstige Ankerpunkte gibt an denen man neu aufsetzen könnte.


----------



## SiemensUser (17 August 2016)

Jochen Kühner schrieb:


> Haben wir denn jetzt schon genügend Infos um Symbolische Variablen aus einer 1500er zu lesen? Kann msn auch die existierenden Variablen auslesen?



Für das Protokoll benötigt man auch noch Infos über die Zusammensetzung dieser Pakete:
- Das 32 Byte lange "Packet Digest" im Integrity part und 
- Der 180 Byte Blob im SetMultiVariables-Request (SecurityKeyEncryptedKey)

Wenn dies klar wäre, dürfte man die symbolischen Variablen aus der 1500er lesen können.


----------



## Thomas_v2.1 (17 August 2016)

SiemensUser schrieb:


> Für das Protokoll benötigt man auch noch Infos über die Zusammensetzung dieser Pakete:
> - Das 32 Byte lange "Packet Digest" im Integrity part und
> - Der 180 Byte Blob im SetMultiVariables-Request (SecurityKeyEncryptedKey)



Hast du den Rest denn schon fertig? Meine Test-Steuerungen benötigen nämlich beide Felder nicht (eine 1200 mit alter Firmware, und TIA-Plcsim-1500). Ob die Felder notwendig sind, ist nach meiner Erkenntnis abhängig vom ersten Antworttelegramm (Response CreateObject). Ist dort ein Eintrag mit ID 299 nicht vorhanden oder hat der Wert 0, dann wird kein Key benötigt.

Als Verfahren kommt aber mit ziemlicher Sicherheit SHA256 zum Einsatz, ist nur die Frage was und wie dort mit hinein-verwurstet werden muss. 
Den Anfang mit deadfee1 haben wir ja schonmal...


----------



## SiemensUser (18 August 2016)

Thomas_v2.1 schrieb:


> Hast du den Rest denn schon fertig? Meine Test-Steuerungen benötigen nämlich beide Felder nicht (eine 1200 mit alter Firmware, und TIA-Plcsim-1500). Ob die Felder notwendig sind, ist nach meiner Erkenntnis abhängig vom ersten Antworttelegramm (Response CreateObject). Ist dort ein Eintrag mit ID 299 nicht vorhanden oder hat der Wert 0, dann wird kein Key benötigt.



Nein fertig ist noch nichts. Ich analysiere nur die unbekannten Teile des Protokolls.
Ich habe hier eine 1511 und die liefert bei ServerSessionRole (=299) den Wert 536870912 (was auch immer das bedeuten mag).



Thomas_v2.1 schrieb:


> Als Verfahren kommt aber mit ziemlicher Sicherheit SHA256 zum Einsatz, ist nur die Frage was und wie dort mit hinein-verwurstet werden muss.
> Den Anfang mit deadfee1 haben wir ja schonmal...



Stimmt addee1fe ist immer gleich. Das anschließende b4000000 könnte die Blob-Länge (=180) sein. Dann zweimal 01000000 (=1) irgendwelche Int32-Variablen.


----------



## Thomas_v2.1 (18 August 2016)

SiemensUser schrieb:


> Nein fertig ist noch nichts. Ich analysiere nur die unbekannten Teile des Protokolls.
> Ich habe hier eine 1511 und die liefert bei ServerSessionRole (=299) den Wert 536870912 (was auch immer das bedeuten mag).



536870912 = 0x20000000, das sieht schon sinnvoller aus. TIA-S7-Plcsim sagt als Antwort an dieser Stelle eine 0, bei der alten 1200 gibt es das Feld überhaupt nicht. Bei beiden Varianten wird anschließend kein Key übertragen. Ich meine das wären die einzig sichtbaren Unterschiede.



SiemensUser schrieb:


> Stimmt addee1fe ist immer gleich. Das anschließende b4000000 könnte die Blob-Länge (=180) sein. Dann zweimal 01000000 (=1) irgendwelche Int32-Variablen.


Ich habe ja oben schon aufgeschrieben welche Teile meiner Meinung nach Konstant sind. Ich habs so getestet, dass ich mir eine eigene Fake-S7 programmiert habe, die verschiedene Challenge Werte zurückschickt, oder auch andere Felder modifizieren kann.

Hast du zufällig ein Logfile von der Kommunikation mit einer aktuellen 1200 (FW V4), oder auch einer der aktuellsten 1500?


----------



## SiemensUser (18 August 2016)

Thomas_v2.1 schrieb:


> Hast du zufällig ein Logfile von der Kommunikation mit einer aktuellen 1200 (FW V4), oder auch einer der aktuellsten 1500?



Ich habe hier zwei Logfiles von 1500er-CPUs. Ein Logfile von einer 1200er V4 habe ich nicht.
1. CPU 1516F  
Anhang anzeigen 1516_F.zip


2. CPU 1511
Anhang anzeigen S7-1500-HMI_DB10_Sym.zip


----------



## stenbeitel (18 August 2016)

Hallo zusammen, 

ich verfolge mit Interesse euere Protokollanalyse evtl. helfen euch diese zwei logfiles

S7-1200 FW4.1 
Anhang anzeigen S7-1200-V41.rar

S7-1510SP 
Anhang anzeigen S7-1510SP.rar


Gruß


----------



## wkallplc (30 September 2016)

Wir haben eine aktuelle 1200 1212C im Hause. Reicht die ?
PS: Wir kommen nun auch auf die 1200er online wie zuvor schon auf die 1511.


----------



## Thomas_v2.1 (30 September 2016)

Mit dem TIA Portal V14 sind auch neue Firmware Versionen herausgekommen. 
Für die 1500 ist das V2.0.1 und für die 1200 V4.2. Vielleicht kann ja jemand der schon hochgerüstet hat mal ein Logfile erstellen. Mal sehen ob da wieder "geschraubt" wurde, oder ob das Protokoll an sich jetzt so stabil bleibt.


----------



## wkallplc (4 Oktober 2016)

Unsere S7 1200 mit Firmware V4.2 arbeitet mit dem Tani OPC Server. Das betrifft auch die optimierten Bausteine. Alles arbeitet - Verbindungsaufbau, Browse der Symbole und der Datenzugriff.


----------



## Thomas_v2.1 (26 Dezember 2016)

Ich habe nochmal eine aktualisierte plugin-dll für das s7comm-plus Protokoll erstellt (v0.0.3)-
Damit das plugin funktioniert muss die Development-Version von Wireshark verwendet werden (v2.3), mit dem aktuellen Stable Release (2.2.3) ist das plugin nicht kompatibel.

https://sourceforge.net/projects/s7commwireshark/files/s7comm-plus-0-0-3/

Neben diversen Ergänzungen und Korrekturen, ist es jetzt möglich das "Reassemblieren" von Paketen zu deaktivieren. Das geschieht über Aufrufen des Kontextmenüs einer S7comm-plus Zeile über die Protocol Preferences. Bei großen Dateiübertragungen deren Pakete gesplittet wurden, nimmt das Reassembling nicht unerhebliche Mengen an Ram-Speicher in Anspruch.

Ein Dank geht an die Firma Tani GmbH (http://www.tanindustrie.de) für die Unterstützung mit Informationen, Logfiles, usw. Diese bieten auch einen entsprechenden Protokolltreiber für die 1200/1500 an.


----------



## Gerhard Bäurle (27 Dezember 2016)

Tani <-> inaT so wirklich verloren geht in der Branche offensichtlich kaum jemand ...


----------



## wkallplc (28 Dezember 2016)

*INAT -> Tani*



Gerhard Bäurle schrieb:


> Tani  inaT so wirklich verloren geht in der Branche offensichtlich kaum jemand ...


 Nein, niemand geht verloren, bei der Tani sind alle Entwickler die bei INAT schon die Produkte erstellt haben. Die Produkte sind von Grund auf neu entwickelt, alle guten Dinge sind noch da und alle Altlasten und unschöne Designs weg. So geht die S7 1500 in allen Ausprägungen, und das arbeitet auch auf dem raspberry PI und ähnlichen Geräten. Es ist eben am Puls der Automatisierung.


----------



## juergi (12 Januar 2017)

*s7comm-plus mit wireshark Sourcen synchron halten*



Thomas_v2.1 schrieb:


> Ich habe nochmal eine aktualisierte plugin-dll für das s7comm-plus Protokoll erstellt (v0.0.3)-
> Damit das plugin funktioniert muss die Development-Version von Wireshark verwendet werden (v2.3), mit dem aktuellen Stable Release (2.2.3) ist das plugin nicht kompatibel.
> 
> https://sourceforge.net/projects/s7commwireshark/files/s7comm-plus-0-0-3/



Hallo,

um bequemer das Plugin mit den dazu passenden Wireshark-Sourcen bauen zu können, habe ich auf github folgendes Clones: 
https://github.com/JuergenKosel/wireshark.git und https://github.com/JuergenKosel/s7commwireshark.
Das wireshark Repository bindet das s7comm-plus Repository als git-submodule ein. Unter Linux werden die Sourcen als symbolische Links an die richtigen Stellen im Wireshark-Source-Tree eingebunden.
Ob das unter Windows funktioniert, habe ich nicht ausprobiert.

Unter Linux kann dann Wireshark mit dem Plugin wie folgt gebaut werden:

 git clone https://github.com/JuergenKosel/wireshark.git wireshark
 cd wireshark
 git checkout s7commwireshark
 git submodule update --init
 autoreconf --install
 ./configure
 make -j`nproc`

Gruß
 Juergi


----------



## yogi70 (1 Februar 2017)

Thomas_v2.1 schrieb:


> Ich habe nochmal eine aktualisierte plugin-dll für das s7comm-plus Protokoll erstellt (v0.0.3)-
> Damit das plugin funktioniert muss die Development-Version von Wireshark verwendet werden (v2.3), mit dem aktuellen Stable Release (2.2.3) ist das plugin nicht kompatibel.
> 
> https://sourceforge.net/projects/s7commwireshark/files/s7comm-plus-0-0-3/



Hallo,
ich habe das s7comm_plus x64 Plugin heruntergeladen und in den Plug-In-Ordner "C:\Program Files\Wireshark\plugins\2.3.0-2199-gec38330" kopiert. Vorher hatte ich die Delopment-Version 2.3.0-2199 64Bit heruntergeladen und unter meinem Windows 10 x64 installiert.
Beim Starten von Wireshark kommt nun die Fehlermeldung 
"The procedure entry point tvb_new_subset could not be located in the dynamic lik library C:\Program Files\Wireshark\plugins\2.3.0-2199-gec38330\s7comm_plus.dll"
Danach kommt noch eine zweite Fehlermeldung: "Couldn`n load module C:\Program Files\Wireshark\plugins\2.3.0-2199-gec38330\s7comm_plus.dll Die angegebene Prozedur wurde nicht gefunden.

Könntet Ihr mir einen Tipp geben, was ich falsch gemacht habe?

Gruß yogi


----------



## Thomas_v2.1 (1 Februar 2017)

Hi,

es wurde Anfang Januar an der Wireshark-Api etwas geändert, darum funktioniert die dll die ich damals erzeugt habe nicht mehr mit der letzten Version. Wenn du noch eine Version hast die ca. vor dem 10. Januar oder so erstellt wurde, dann müsstest du diese wieder installieren. Leider lassen sich auf der Wireshark Seite nur die Development Versionen der letzten paar Tage herunterladen.

Ich habe die Quellen schon dahingehend angepasst, aber noch nicht neu übersetzt. Kann natürlich immer wieder passieren dass etwas geändert wird, zumindest solange ich da im Entwicklungs-Zweig bin.
Wenn du bis heute Abend warten kannst, dann kann ich die dlls für die aktuellste Version erstellen.


----------



## yogi (1 Februar 2017)

Hi,
achso, leider habe ich keine ältere Version vom Wireshark mehr.



Thomas_v2.1 schrieb:


> Wenn du bis heute Abend warten kannst, dann kann ich die dlls für die aktuellste Version erstellen.



Danke, das wäre ganz toll.


----------



## Thomas_v2.1 (1 Februar 2017)

Es gibt jetzt auf der Sourceforge-Seite eine Version 0.0.3.1 der s7comm_plus.dll die wieder mit der aktuellsten Version funktioniert.

Allerdings nicht mehr mit einer Version von vor 10. Jan 2017. Wahrscheinlich im Sommer wird die 2.3 von Wireshark zu 2.4, dann bleibe ich erst mal auf dieser Version. Bis dahin kann das gelegentlich vorkommen.


----------



## yogi70 (3 Februar 2017)

Hallo Thomas_v2.1,
ich habe das Plugin nun einmal ausprobieren können, es funktioniert jetzt prima.
Bei der Gelegenheit muss ich einfach einmal für die gute Arbeit Danke sagen, ich kann mir gut vorstellen, dass für die Analyse und Umsetzung viele viele Feierabende ins Land gingen.

Also von mir hast Du für dieses Tool den vollsten R E S P E K T  :TOOL:

Grüße yogi


----------



## Thomas_v2.1 (3 Februar 2017)

yogi70 schrieb:


> Bei der Gelegenheit muss ich einfach einmal für die gute Arbeit Danke sagen, ich kann mir gut vorstellen, dass für die Analyse und Umsetzung viele viele Feierabende ins Land gingen.



Sowas macht man Nachts ;-)
Aber hat auch Spaß gemacht. Wenn man mal lange Zeit absolut nicht weiterkommt, und dann hat man eine Idee, sozusagen den Stein von Rosetta und dann gehts weiter...

Das traurige ist allerdings auch wenn ich weiß wie es prinzipiell funktioniert, das Erstellen eines Treibers dafür immer noch ein nicht unerheblicher Aufwand ist. Zumindest ist das nicht mit einem Treiber für die S7-300/400 zu vergleichen, da liegen bestimmt 1-2 Größenordnungen gemessen an Codezeilen dazwischen. Eine Minimalversion für die 300er nur um Variablen über Ethernet zu lesen bekomme ich in C in ~100 Codezeilen hin. Für die 1500 würde ich da eher 5000-10000 Zeilen ansetzen, und das ohne die notwendigen Crypto-Bibliotheken. Das Problem ist, du kannst da nicht mit einer Minimalversion die nur Variablen lesen kann anfangen, sondern musst gleich "fast" alles verstehen.

Und aufgrund der Authentifizierungsmethode, würde ich das niemals nachverfolgbar unter meinem Namen veröffentlichen. Meiner Meinung nach ist das ist mit Absicht so konstruiert worden, dass es schwer sein dürfte zu behaupten an die Methode ohne Reverse-Engineering des Quellcodes gelangt zu sein. Den einzigen Ausweg den es da geben könnte, ist über das womögliche Monopol von Siemens in dem Bereich. Aber ich habe keine Lust mich in der Freizeit detailliert mit Rechtsangelegenheiten zu befassen.


----------



## wkallplc (7 Februar 2017)

*Aufwand S7 1500 Treiber*



Thomas_v2.1 schrieb:


> Sowas macht man Nachts ;-)
> Aber hat auch Spaß gemacht. Wenn man mal lange Zeit absolut nicht weiterkommt, und dann hat man eine Idee, sozusagen den Stein von Rosetta und dann gehts weiter...
> 
> Das traurige ist allerdings auch wenn ich weiß wie es prinzipiell funktioniert, das Erstellen eines Treibers dafür immer noch ein nicht unerheblicher Aufwand ist. Zumindest ist das nicht mit einem Treiber für die S7-300/400 zu vergleichen, da liegen bestimmt 1-2 Größenordnungen gemessen an Codezeilen dazwischen. Eine Minimalversion für die 300er nur um Variablen über Ethernet zu lesen bekomme ich in C in ~100 Codezeilen hin. Für die 1500 würde ich da eher 5000-10000 Zeilen ansetzen, und das ohne die notwendigen Crypto-Bibliotheken. Das Problem ist, du kannst da nicht mit einer Minimalversion die nur Variablen lesen kann anfangen, sondern musst gleich "fast" alles verstehen.
> ...



Das mit der Idee in der Nacht ist auch bei mir so. Aber sonst ist es viel Arbeit, oft in Details. Wissen über die interne Arbeistweise einer Steuerung ist notwendig.
Ein SPS Protokoll präsentiert immer die interne SPS, das war schon bei der 300er oder der S5 der Fall. Sichtbar ist das in den SZLs und beim Bausteinlesen - die Bausteinköpfe zeigen das. Hilfreich ist es auch mal eine Softsps erstellt zu haben bzw mit Leuten die das machen sich auszutauschen (IBH Softec, Process Informatik, ABCIT). Mit diesem Wissen ist ein Protokoll nachzubauen - ohne Disassemblieren irgendwelchen Codes.
Ein reiner S7 1500 Protokolltreiber hat ohne Cryptlib ca 5000 Zeilen. Mit Online Browsen sind es ca 8000. Mit kompletten SPS Stati, Hardwareausbau sind es ca 12000. Soll die S7 1500 auch programmiert werden so liegen im Protokoll und dem Datenmanegement ca 18000 Zeilen C Code. Dieser Code läuft dann aber über all, auch im Raspberry PI. Damit kann dann ein komplettes SPS Backup erstellt und wieder in die SPS zurückgespielt werden, oder es werden SPS Programme mit Codegeneratoren erstellt.
Das Gleiche für die Rockwell ControlLogix sieht gleich aus, und es hat auch die gleichen Funktionen. Rockwell ist zwar etwas offener mit Informationen, um die SPS zu programmieren hilft das aber nicht.
Zusätzlich hilft Wissen über FPGA und deren Programmierung. Vieles aus den SPS Protokollen bildet solche Hardwarebausteine ab.

So sind all die Tani SPS Treiber entstanden, und so sind seinerzeit auch die INAT Treiber gebaut worden.

Vielen Dank auch für die gute Unterstützung mit der ständigen Weiterentwicklung des S7 1500 Dissektors. Es ist das klassische Beispiel guter Zusammenarbeit. Jeder hilft dem Anderen.


----------



## LowLevelMahn (7 Februar 2017)

> Ein reiner S7 1500 Protokolltreiber hat ohne Cryptlib ca 5000 Zeilen. Mit Online Browsen sind es ca 8000. Mit kompletten SPS Stati, Hardwareausbau sind es ca 12000. Soll die S7 1500 auch programmiert werden so liegen im Protokoll und dem Datenmanegement ca 18000 Zeilen C Code. Dieser Code läuft dann aber über all, auch im Raspberry PI. Damit kann dann ein komplettes SPS Backup erstellt und wieder in die SPS zurückgespielt werden, oder es werden SPS Programme mit Codegeneratoren erstellt.



Hast du den Treiber schon gemacht? die Codenzeilenangaben von dir kommt mir reichlich kurz vor - für ein Stream-Protokoll, mit Fehlerprüfung usw.
und ein S7-Treiber (fuer ein Bus-Protokoll fixer Länge) hat dann nur noch 500 Zeilen oder was?
Wie kommst du auf die Zahlen?


----------



## wkallplc (7 Februar 2017)

Ja, das Protokoll existiert - im Tani OPC Server oder der PLC Engine. Damit browsen wir die S7 1500 Familie, lesen und schreiben OPC Daten, lesen auch das SPS Programm und viele der internen Dinge der SPS die OPC Nutzer interessieren. Für bestimmte Anwender lesen wir das gesamte SPS Programm inclusive der Hardwarekonfiguration und all dem anderen Zeugs aus der SPS.
SPS Programmcodeschreiben vermarkten wir nicht, das dient nur dem Verständnis der SPS. FC oder OBs schreiben wir nur um unser Verstädnis zu testen, eine Programmiersoftware ist kein Markt. Zum Spielen und Verständnis erweitern ist das aber ideal.
Sie können die Programme testen, nach dem Start laufen sie ohne Lizenz nach jedem Start für drei Tage.


----------



## LowLevelMahn (7 Februar 2017)

trotzdem ein bisschen wenig Code dafür - aber die Details sind auch nicht sooo wichtig



> SPS Programmcodeschreiben vermarkten wir nicht, das dient nur dem Verständnis der SPS. FC oder OBs schreiben wir nur um unser Verstädnis zu testen, eine Programmiersoftware ist kein Markt. Zum Spielen und Verständnis erweitern ist das aber ideal.



vielleicht baut ihr ja mal ein Closed-Source-Tool/Lib mit dem Thomas 1200/1500 Programmblöcke lesen/schreiben kann
damals (Der S7-1200 unter den Rock geschaut) hat ihn ja die Verschluesselung ausgebremst


----------



## wkallplc (7 Februar 2017)

Thomas sein Knackpunkt ist das die "Verschlüsselung" nur mit einer über Anfrage/Antwort laufende Telegrammverfolgung arbeiten kann. Ein Wireshark Decoder enthält aber trotz Streamverfolgung normalerweise keine SPS State Machine - denn dann baut ja fast eine S7 1500 kompatible Softsps nach.

Ein Closed Source Stück Software zum SPS Programmcodeschreiben - auch wenn wir das haben - ist aus meiner Sicht zu gefährlich um das in die Wildnis zu entlassen. Anlagenhacking wollen wir nicht unterstützen.
Die einzige sichere Abwehr bei der 1500 dagegen ist es die SPSsen komplett mit Kennwort oder Zertifikaten zu schützen. Das funktioniert wunderbar, es macht aber dem Support und der Instandhaltung die Arbeit sehr schwer. Sicherheit ist in diesem Fall entweder kontraproduktiv (jede SPS hat ihr eigenes Kennwort, und das ändert sich auch nmanchmal, die Instandhaltung kann nichts instandhalten), oder unsicher (alle SPSsen gleich, alle Instandhalter und SPS Programmierer kennen das Kennwort oder haben das Zertifikat).
Thomas bekommt Unterstützung wenn er das braucht. So ist es auch in der Vergangenheit gelaufen. Er hilft uns, und wir helfen Thomas. Auf diesem Weg ist der 1500 Dissektor so geworden wie er heute ist. Und er wird ständig besser dank Austausch.


----------



## Thomas_v2.1 (16 Februar 2017)

Ich bräuchte mal eine kreative Eingabe:
Es werden einige Objekte allem Anschein nach irgendwie komprimiert übertragen. Als einfachstes Beispiel zum Testen habe ich mir mal die Netzwerktitel herausgepickt, weil sich da recht einfach diverse Texte ausprobieren lassen.

Die Werte:

```
a           98000002787d845fc605c3081dfc919888ddb3002c70173a
aa          98000002787d845fc605c3081dfc91989888ddb70044a6179b
aaa         98000002787d845fc605c3081dfc9198989888ddbb005d3d17fc
aaaa        98000002787d845fc605c3081dfc91980804d8fd0b007635185d
aaaaa       98000002787d845fc605c3081dfc91980802d83d0c008f8e18be
aaaaaa      98000002787d845fc605c3081dfc91980806d87d0c00a948191f
aaaaaaa     98000002787d845fc605c3081dfc91980801d8bd0c00c3631980
aaaaaaaa    98000002787d845fc605c3081dfc91980805d8fd0c00dddf19e1
aaaaaaaaa   98000002787d845fc605c3081dfc91980803d83d0d00f8bc1a42
aaaaaaaaaa  98000002787d845fc605c3081dfc91980807d87d0d0014091aa3
aaaaaaaaaa  98000002787d845fc605c3081dfc91980807d87d0d0014091aa3
bbbbbbbbbb  98000002787d845fc605c3081dfc91980407d87d0d00151c1aad
cccccccccc  98000002787d845fc605c3081dfc91980c07d87d0d00162f1ab7
ab          98000002787d845fc605c3081dfc91989884ddb70044bd179c
abc         98000002787d845fc605c3081dfc919898948cddbb005d8317ff
abcd        98000002787d845fc605c3081dfc919898948cc3bf0076c31863
abcde       98000002787d845fc605c3081dfc919898949c928addc300907e18c8
abcdef      98000002787d845fc605c3081dfc919898949c929a86ddc700aab5192e
abcdefg     98000002787d845fc605c3081dfc919898949c929a968eddcb00c5691995
abcdefgh    98000002787d845fc605c3081dfc919898949c929a969e81ddcf00e09b19fd
```
Da mehrfaches Verwenden des gleichen Zeichens die Daten nicht länger werden lassen, gehe ich mal davon aus dass es komprimiert wurde.

Ein bekannter Header von gzip findet sich auf den ersten Blick nicht wieder. Ich habe auch schon mal verglichen welche Werte ich erhalten wenn ich die Texte mit gzip oder deflate komprimiere, aber da komme ich auch auf kein Ergebnis.

Die ersten 5 Bytes mit 9800000278 werden so auch von anderen Objekten übertragen.


----------



## wkallplc (17 Februar 2017)

*zip*

Es ist Zip mit Dictionary. Wenn die Dictionaries bekannt sind kann das entpackt werden. Es gibt viele Dictionaries, bei den vielen XML macht das auch Sinn. Die Dictionaries ausprobieren ist mit wem Wissen das es XML ist zwar Arbeit aber wir haben es geschafft. Später mehr.  Rockwell macht das ähnlich


----------



## Thomas_v2.1 (17 Februar 2017)

Ok, dann ist 0x787d wohl doch der zlib Header. Ohne Wörterbuch kann dann ja bei mir auch nichts rauskommen.

CM (Compression method) = 8 = deflate
CINFO (Compression info) = 7 = indicates a 32K window size

FCHECK (check bits for CMF and FLG) = 0xd
FDICT (preset dictionary) = true
FLEVEL (compression level) = 1 = compressor used fast algorithm


----------



## wkallplc (18 Februar 2017)

*zip*

Ja. Genau diese Idee hat auch bei und einen Durchbruch gebracht - vor Jahren beim Bau des OPC Servers Rockwell. Da lag es nahe das Andere die gleiche Idee hatten. Ein eigenes Packverfahren macht kaum jenand, allein wegen des Aufwands. Aber auch weil ein offenes altes verfahren keinen Patentklagen ausgesetzt ist.  Der Tani OPC Server nutzt das auch so. Wenn nun die Zip bekannt sind dann ist sicher die nächste Frage wie die vielen ID in den XML verwoben sind. Dazu gibt es mehrere Regeln, wahrscheinich haben mehrere Teams gearbeitet. Im Prinzip gibt es Regeln und Ausnahmen. Ist das Regelwerk klar so werden damit in Datenbausteinen die Strukturen erkannt und zugeweisen. Ebenso werden im Programmcode wie OB FB .. die Module zugeweisen. Manche Module beziehen sich auf Hardware, die haben dann "bekannte" id. Wer eine SPS baut der nutzt ja FPGA für komplexe schnelle Dinge. Zusätzlich werden die Möglichkeiten des Prozessors so intelligent wie möglich genutzt. An manchen Grenzen klappt das nicht. Genau da sind dann die Ausnahmen im Regelwerk. Manche Ausnahmen dienen auch dem Bugfix. Da hats geklemmt, das zu erkennen und nachzubauen kostet die große Zeit. Mit diesem Wissen kann eine komplette Programmiersoftware zur S7 1500 gebaut werden, oder eine kompatible Soft SPS entsteht. Auf jeden Fall ist ein SPS Backup und Restore so zu bauen (und wir bauen das).  Ein SPS Protokoll bildet normalerweise diese Innereien der SPSsen ab. Darum ist ein Protokollnachbau immer vom Knowhow der SPS Interna abhängig. Wichtige Info dazu kommt oft von erfahrenen SPS Programmierern die die Dinger in den Anlagen nutzen. Der Rest ist Nachdenken.
Der s7comm-plus hat uns die Arbeit oft erleichtert. Ursprünglich hatten wir selbst einen rudimentären Decoder gebaut. Es ist aber viel einfacher mit jemand zusammenzuarbeiten der sich dem Thema voll widmet.  Daher kommt auch der Spruch das Wissen sich vermehrt wenn man es teilt.

Ist es geplant s7comm-plus in Wireshark Standard aufzunehmen ?
Wenn ja, wann ?


----------



## Thomas_v2.1 (9 August 2019)

Hier gibt es ein paar Details zu den kryptografischen Funktionen, die im s7comm-plus Protokoll der 1200/1500er Steuerungen verwendet werden, nachzulesen:

https://www.darkreading.com/vulnera...pto-key-pair-researchers-find-/d/d-id/1335452


----------



## DeltaMikeAir (9 August 2019)

Thomas_v2.1 schrieb:


> Hier gibt es ein paar Details zu den kryptografischen Funktionen, die im s7comm-plus Protokoll der 1200/1500er Steuerungen verwendet werden, nachzulesen:
> 
> https://www.darkreading.com/vulnera...pto-key-pair-researchers-find-/d/d-id/1335452





> "All PLCs of the same model have the same key, which means if you crack one, you've cracked all of them,"


Oje :-(



> The researchers here today will detail the Siemens security issues, which they reported to the PLC vendor.


=>


> "No update is necessary," a Siemens spokesperson told


----------



## Thomas_v2.1 (9 August 2019)

Wenn du den Zugriff so nicht möchtest, dann musst du eben den Zugriffsschutz auf der CPU aktivieren.
Insofern hat Siemens schon Recht damit, dass kein Update notwendig ist. Der Benutzer ist dafür verantwortlich die Einstellung zu setzen wenn er meint das sei bei seiner Anlage notwendig.

Der Zugriff ist genau dafür konzipiert worden, damit es so funktioniert wie es jetzt ist. D.h. jeder der das Verfahren kennt kann im Prinzip alles auf der Steuerung machen. Ich habe hier eine 1200er mit einer alten Protokollvariante ohne Kryptografie aber ansonsten fast identischem Protokoll. Dafür habe ich einen rudimentären Treiber, und da kannst du schon einiges an Schindluder treiben auf der SPS. Ich habe sie auch mehrmals in "Defekt" gesetzt bei meinen Experimenten, so ganz robust scheint das nicht zu sein.

Vor allem die Möglichkeit einen Unterschied zwischen Binärcode und Quellcode in der Steuerung zu generieren finde ich sehr problematisch, das riecht stark nach Stuxnet 2.0. Wenn du den Code aus der Steuerung lädst dann ist das die Quelle (als XML) und nicht der Binärcode. Und wenn die Quelle eine andere ist als der Binärcode darin, dürfte das mindestens zu Verwirrung führen. Der Bausteinvergleich beim Online-gehen führt soweit ich weiß auch keinen Codevergleich durch.


----------



## DeltaMikeAir (30 Oktober 2019)

Ich bin noch eher Anfänger im Bereich Wireshark und benötige eine kleine Hilfe um mir mal auf die Sprünge zu helfen.

Ich starte Wireshark mit dem S7Comm Filter, starte die Aufnahme und öffne die Baugruppendiagnose



Ich würde gerne herausfinden, welcher SZL ID und welcher Index benutzt wird, um die 
Firmware-Erweiterung auszulesen. Leider finde ich die Information nicht in den empfangenen
Paketen bzw. deute sie vermutlich falsch. ( Also ich finde die Stelle nicht, wo die V2.5.0 steht und welche ID/Index verwendet wird)

Anhang anzeigen Wireshark.zip


Es handelt sich um eine Sinumerik 840D sl NCU 730.3

(CPU hat 10.168.0.10)

Vielleicht kann mir mal jemand auf die Sprünge helfen


----------



## Thomas_v2.1 (30 Oktober 2019)

Die Versionsstände lassen sich mit SZL ID 0x0011 und Index 0 auslesen.
Diese Abfrage hast du bei deiner Aufzeichnung nicht mit erfasst, denn diese Informationen werden nur einmalig beim Öffnen des Baugruppenzustands abgefragt, und weder bei einem Wechsel auf einen anderen Reiter, noch beim Drücken auf "Aktualisieren".


----------



## DeltaMikeAir (30 Oktober 2019)

Guten Abend Thomas,

danke für diese Info. Ich war der Meinung, das diese Werte erneut geholt werden, wenn ich den Reiter wechsle bzw. aktualisiere.
Ich schaue es mir morgen noch einmal an und melde mich noch einmal.

Vielen Dank


----------



## Thomas_v2.1 (30 Oktober 2019)

Ich habe es bei meiner CPU getestet, und mich gerade selber gewundert, dass die Daten beim Aktualisieren nicht erneut abgefragt werden. In den Daten die aktualisiert werden sind die Versionsstände auf jeden Fall nicht enthalten, nur die Baugruppenbezeichnungen die auf dem Reiter ebenfalls angezeigt werden.


----------



## DeltaMikeAir (30 Oktober 2019)

> Ich habe es bei meiner CPU getestet, und mich gerade selber gewundert,  dass die Daten beim Aktualisieren nicht erneut abgefragt werden.


Ja, ich war auch der Meinung das immer alles geholt wird, da beim Registerwechsel ein Schwung abgefragt wird.

Wieder was gelernt


----------



## Thomas_v2.1 (30 Oktober 2019)

Es sei angemerkt, dass nicht jeder SZL-Datensatz der von außen über das Netzwerk ausgelesen werden kann, auch aus dem SPS-Programm heraus ausgelesen werden kann. Da bestehen einige Unterschiede.


----------



## DeltaMikeAir (30 Oktober 2019)

Ja, ich kann bereits alles aus dem Screenshot auslesen, es fehlt nur noch die eine Info.
Ich probiere es morgen, falls es nicht geht stelle ich trotzdem mal ein Wireshark Auszug ein.

Ich zeige solche Werte immer auf einer Serviceseite am Panel an.


----------



## DeltaMikeAir (31 Oktober 2019)

Hier noch einmal der Wireshark Auszug der während des öffnen von Baugruppenzustand erstellt wurde.
Mit SZL ID 0x0011 und Index 0 werden die Versionsstände ausgelesen, nur ist scheinbar die Firmwareerweiterung
nicht dabei. Ich kann sie auch in den anderen Telegrammen nicht entdecken.




Anhang anzeigen Wireshark.zip


----------



## Thomas_v2.1 (31 Oktober 2019)

Doch die ist mit dabei. Das ist der 4. Datensatz mit Index 0x81 und der Mlfb "Boot Loader".
In den beiden Wörtern "Ausbg" und "Ausbe" stehen 56 02 05 00, das bedeutet "V2.5.0".

Eigentlich müsste ich die Daten je nach Index leicht unterschiedlich interpretieren, aber Index 0x81 ist von Siemens nicht dokumentiert, nur 1, 6 und 7.


----------



## DeltaMikeAir (31 Oktober 2019)

Danke, ich werde es mir Montag noch einmal anschauen.
Schönen Feiertag und ein schönes Wochenende


----------



## DeltaMikeAir (4 November 2019)

Guten Morgen Thomas,

kurzes Feedback. Es funktioniert mit dem (undokumentierten) Index #81. Ich habe dir zwei Screenshots angehängt:




Vielen Dank für deine Unterstützung, ich habe einiges daraus gelernt


----------



## DeltaMikeAir (4 November 2019)

Das einzigste, was mir noch nicht klar ist, im Wireshark steht SZL-ID 0x0011. Ich muss jedoch W#16#111 verwenden, damit die gewünschten Werte kommen.
Mit Index W#16#11 kommen nur (für mich) wirre Werte.

Gibt es hierfür eine Erklärung?


----------



## Thomas_v2.1 (4 November 2019)

Soweit ich weiß gibt es da keinen Unterschied.

Mit ID=0x0011 Index=0x0000 liest du die Identifikationsdaten von allen vorhandenen Modulen, dann erhältst du mehrere SZL-Datensätze in der Antwort die du dann durchgehen musst um anhand des ersten Wortes festzustellen um welches Modul es sich handelt.

Mit ID=0x0111 Index=xy kannst du die Identifikationsdaten von einem bestimmten Modul lesen, dessen Modulkennung du im Index xy angibst. Beispielsweise um die Daten der Firmware zu lesen, wäre dazu ID = 0x0111 mit Index 0x0007 notwendig.

Es sind nicht immer alle Module bei allen CPUs vorhanden, z.B. eine WinAC Soft-SPS hat keine Hardware, und den Bootloader gibt es auch nicht bei allen.


----------



## DeltaMikeAir (4 November 2019)

Ja, dann ergibt es nun auch Sinn. Siemens ruft 
mit Index 11 alle Daten ab, ich mit Index 111 einzelne


----------



## somox (6 Juli 2021)

Hallo zusammen,

Ich bin noch Anfänger im Bereich, und ich wollte die Kommunikation zwischen WinCC und SPS mit Wireshark untersuchen. Die Kommunikation erfolgt mit Ethernet. Also Wer mit Wireshark die Kommunikation prüft, sucht bestimmt irgend ein Problem in der Kommunikation.
Wie kann man die Daten aus Wireshark sinnvoll visualisieren, um Probleme zu erkennen?

für jede Hilfe oder Quellen wäre ich sehr dankbar

Liebe Grüße


----------



## Gerhard Bäurle (6 Juli 2021)

somox schrieb:


> Wie kann man die Daten aus Wireshark sinnvoll visualisieren, um Probleme zu erkennen?


Hallo, welche Probleme willst Du denn erkennen?


----------



## Blockmove (6 Juli 2021)

somox schrieb:


> Hallo zusammen,
> 
> Ich bin noch Anfänger im Bereich, und ich wollte die Kommunikation zwischen WinCC und SPS mit Wireshark untersuchen. Die Kommunikation erfolgt mit Ethernet. Also Wer mit Wireshark die Kommunikation prüft, sucht bestimmt irgend ein Problem in der Kommunikation.
> Wie kann man die Daten aus Wireshark sinnvoll visualisieren, um Probleme zu erkennen?
> ...


Welche Kenntnisse zum Thema Ethernet, TCP/IP, Protokolle bringst du denn mit?
Wireshark ist ein Tool von Spezialisten für Spezialisten.
Da musst du schon einiges an Zeit für die Einarbeitung investieren


----------



## somox (6 Juli 2021)

Zum Beispiel die Stabilität und Kommunikationsleistung des Systems. dies ist die Problemstellung meiner Thesis.  Ich habe ein Beispielprojekt erstellt und mit Hilfe von Wireshark den gegenseitigen Austausch von Informationen zwischen sps und WinCC gemessen. Kann ich die Stabilität und Kommunikationsleistung des Systems visualisieren.

Liebe Grüße


----------



## Blockmove (6 Juli 2021)

somox schrieb:


> Zum Beispiel die Stabilität und Kommunikationsleistung des Systems. dies ist die Problemstellung meiner Thesis.  Ich habe ein Beispielprojekt erstellt und mit Hilfe von Wireshark den gegenseitigen Austausch von Informationen zwischen sps und WinCC gemessen. Kann ich die Stabilität und Kommunikationsleistung des Systems visualisieren.
> 
> Liebe Grüße



Für Netzwerkanalyse ist ntop ein ganz brauchbares Tool mit einigen Visualisierungen.
Wireshark bringt ein paar Infos unter Statistics.


----------



## Thomas_v2.1 (6 Juli 2021)

Wireshark ist eher das Werkzeug zur statischen Analyse, und nicht unbedingt geeignet um Live-Daten für z.B. ein Dashboard zu generieren. Die Frage ist, was mit Stabilität und Kommunikationsleistung gemeint ist, und ob das generell für TCP/IP gelten oder spezifisch auf Siemens SPS zugeschnitten sein soll, wobei hier noch zwischen S7-300/400 und S7-1200/1500 zu unterscheiden wäre (S7-300/400 einfach, S7-1200/1500 schwer dort aus den Analysen verwertbare Informationen herauszufinden).

Ich hatte mir z.B. schon mal für den Wireshark Statistik Menüpunkt überlegt, dort zu erfassen auf welche Speicherbereiche wie oft lesend und schreibend zugegriffen wird. Also z.B. DB1.DBW0 mit 120 lesenden Zugriffen, usw. Dafür musst du aber den Wireshark Dissector Code erweitern, und der Statistik Menüpunkt hat ein mehr oder weniger starres Format, darum habe ich das nicht weiter verfolgt.

Was für eine weitere statische Analyse auch möglich ist, wäre eine Aufzeichnung der Kommunikation zu erstellen (pcap Datei), mittels tshark die gewüschten Felder die du vom S7-Protokoll oder auch tcp/ip benötigst zu exportieren, und dann auf die Daten dein eigenes Programm loszulassen.

Bei einer S7 SPS würde mir als Analyse der Kommunikationsleistung z.B. die Antwortzeit der SPS einfallen, d.h. welche Zeit von Request zu Response wird benötigt, ggf. Lese- oder Schreibvorgänge die mit Fehler beantwortet wurden oder ähnliches. So etwas habe ich mir selber mal für Profinet gebaut, welches den Jitter berechnet, die Teilnehmer auflistet, nach Verbindungsaufbau Telegrammen sucht usw.


----------



## somox (7 Juli 2021)

Thomas_v2.1 schrieb:


> welches den Jitter berechnet


Hallo Thomas,
ich bedanke mich für  die Zahlreiche Informationen, ich muss noch recherchieren, damit ich in die Reihe einsteigen kann, ich habe JITTER-Werte dargestellt, aber ich finde dass das Diagramm irgendwie komisch aussieht, ich werde mich auf jeden fall nochmal melden.

Liebe Grüße


----------



## wkallplc (7 Juli 2021)

Effekte in erier PC <-> SPS Kommunikation -
: Klar, Ping muss laufen
: Auch klar - WinCC muss die S7 Verbindung aufbauen können. Da ich Ihren SPS Typ nicht kenne - Siemens hat diverse S7 Protokolle, aktuell drei unterschiedliche. Wenn WinCC die Verbinung nicht hinbekommt dann reichen die Diagnosedinge in WinCC
: Kommen nun nicht alle Daten so helfen auch oft die WinCC Diagnosen. Es wird genau angezeigt welche Daten nicht kommen.
: Aber auch Wireshark zeigt diese Details. Die Analyse ist aber mehr Aufwand und setzt etwas Basiswissen über die SPS voraus. Handelt es sich um eine Siemens S5 oder eine S7 300/400 so zeigt der Wireshark s7comm Decoder an was angefragt oder geschrieben wird und was die SPS antwortet. Bei S7 1200/1500 wird zum Einen der s7comm_plus Decoder benötigt. Zum Anderen arbeiten diese SPS symbolisch - eine S7 300/400 kann da nur DBxDWyLEnz. Aber in der 1500 sehen Sie beim Verbindungsstart das Symbolbrowsen, später fragt WinCC dann über die damit gesammelten ID die eigentlichen daten an. Wenn Sie eine ganz neue S7 1500 mit TIA 17 und Firmware 2.9 haben dann benötigt der Wireshark Decoder für eine Anzeige die Zertifikate mit denen Sie die Verbindung gesichert haben. Diese können Sie in TIA17 exportieren und Wireshark geben.
Fazit: Immer zuerst die Netzwerk Basis und WinCC Diagnosen nutzen. Dann erst Wireshark.


----------



## MyName (7 Juli 2021)

wkallplc schrieb:


> Effekte in erier PC <-> SPS Kommunikation -
> : Klar, Ping muss laufen
> : Auch klar - WinCC muss die S7 Verbindung aufbauen können. Da ich Ihren SPS Typ nicht kenne - Siemens hat diverse S7 Protokolle, aktuell drei unterschiedliche. Wenn WinCC die Verbinung nicht hinbekommt dann reichen die Diagnosedinge in WinCC
> : Kommen nun nicht alle Daten so helfen auch oft die WinCC Diagnosen. Es wird genau angezeigt welche Daten nicht kommen.
> ...



Hallo,

ich hätte eine Frage zum Zertifikat Export aus TIA V17 und Import in Wireshark:
Ich finde nur die Möglichkeit das öffentliche Zertifikat zu exportieren (Unter Schutz & Security->Zertifikatsmanager->Gerätezertifikate).  Zur Analyse bräuchte Wireshark wohl den privaten Schlüssel, welcher dort nicht enthalten ist ( Import in Wireshark unter Protokolle->TLS  oder RSA-Schluessel?)
Gibt es hier eine mir noch unbekannte Möglichkeit für den Export und Import?
Oder muss ich hier selbst ein Zertifikate erstellen (*.der und *.pem) und diese dem TIA Portal und Wireshark geben? Wenn ja wie? Beim Tia Portal Gerätezertifikate Einstellungsseite gibt es eine Import Moeglichkeit ("Hinzufügen" Button) aber die tut nichts.

Danke und Gruss MyName


----------



## Thomas_v2.1 (7 Juli 2021)

somox schrieb:


> Hallo Thomas,
> ich bedanke mich für  die Zahlreiche Informationen, ich muss noch recherchieren, damit ich in die Reihe einsteigen kann, ich habe JITTER-Werte dargestellt, aber ich finde dass das Diagramm irgendwie komisch aussieht, ich werde mich auf jeden fall nochmal melden.



Bei "normaler" S7-Kommunikation ist der Jitter nicht sonderlich sinnvoll, da das Standard TCP/IP Kommunikation und kein Echtzeitprotokoll wie Profinet verwendet. Bei Profinet hast du einen festen Aktualisierungszyklus, z.B. 10 ms, wenn dann je nach Einstellungen z.B. nach 3 Zyklen der Teilnehmer sich nicht meldet, dann gilt er als gestört. Wenn du hier nach Daten über Profinet z.B. eine Regelung aufbaust und der Zyklus schwankt stark dann führt das u.U. bei deiner Regelung zu Problemen, auch wenn der Teilenehmer noch nicht ausgefallen ist.

Bevor du da anfängst du programmieren, würde ich mir im Detail überlegen was überhaupt sinnvoll ist. Du kannst dir ja Stichpunkte überlegen und hier zur Diskussion stellen. Wenn es sinnvoll ist, kannst du das ggf. auch direkt in Wireshark integrieren, dann hat es jeder Benutzer direkt zur Verfügung.


----------



## somox (17 Juli 2021)

Hallo,

gibt es einen s7comm-Paketfilte, die mir nur ein Ereignis oder einen bestimmten Eingang oder Ausgang in Wireshark anzeigt ?
Im Anhang findet ihr einer Aufzeichnung für Timer 10s

Danke im voraus.


----------



## Thomas_v2.1 (17 Juli 2021)

Am einfachsten ist es, wenn du dir ein entsprechendes Paket heraussuchst, und wenn du auf eine für dich interessante Eigenschaft stößt, dann kannst du dieses Feld markieren und das Kontextmenü mit der rechten Maustaste aufrufen. Dort hast du im Kontextmenü "Als Filter anwenden" und dann wählst du "Ausgewählt". Dann wird diese Eigenschaft mit dem Wert automatisch als Filter gesetzt.

Bei s7comm wäre das als Filter für Eingänge "s7comm.param.item.area == 0x81". Du kannst das noch auf Byte und Bitadressen erweitern. Z.B. Alle Eingänge mit E1.x wäre dann "s7comm.param.item.area == 0x81 && s7comm.param.item.address.byte == 1". Die beiden && stehen für logisch UND, du kannst auch || für ODER, oder noch weitere Vergleichsmöglichkeiten einsetzen.

Bei s7comm-plus was in der Aufzeichnung auch vorhanden ist, ist das nicht ganz so einfach.


----------



## somox (13 August 2021)

Hallo,

durch die Darstellung der Lese-Schreibvorgänge und die Verbindungsaufbau aus Wireshark, können die Ergebnis als Performance Wert dargestellt werden? Wenn ja, welche Aussagen können hier erläutert werden, um zu wissen, wie gut das System funktioniert oder bzw. ab welchem Wert ein Performance Wert im Zusammenhang mit der Übertragungsgeschwindigkeit zu einem Problem wird.
Im Anhang findet ihr ein Diagramm, das meine Vorstellungen beschreibt.

Für jede Hilfe oder Quellen wäre ich sehr dankbar.

Danke im voraus.


----------



## Thomas_v2.1 (13 August 2021)

Nur mit den Zeiten alleine kannst du nichts bewerten. Im übrigen würde ich wenn dann auch nicht den Verbindungsaufbau mit einrechnen, denn üblicherweise wird die Verbindung einmal aufgebaut und offen gehalten.

Ich schildere dir mal ein mögliches Problem: Jemand möchte auf dem HMI einige Werte möglichst schnell im 100ms Zyklus einlesen, alles übrige im 1 Sekunden Zyklus. Für die Daten die im 1s Zyklus gelesen werden, sind sagen wir mal 20 PDUs notwendig. Bei 6ms pro PDU wären das 120ms um diese Daten zu lesen. D.h. für deine 100ms Daten bleibt keine Zeit mehr. Das hängt dann davon am wie das HMI die Kommunikation organisiert.

Das wird zumindest nicht ganz einfach das automatisch sinnvoll auszuwerten. Interessanter wäre hier evtl. sogar wie viel Pausenzeit zwischen Abfragen sind, wobei das dann immer in Chunks geschehen wird, wenn jemand mal angenommen 100 Variablen auf 5 Sekunden Aktualisierung stehen hat und die in 5 PDUs passen, dann hast du alle 5 Sekunden eine kurze Last ohne oder mit kurzer Pause zwischen den PDUs, und dann entsprechend lang. Das macht aber jeder Kommunikationstreiber eines Herstellers auch noch anders.


----------



## Thomas_v2.1 (20 August 2022)

Ich bräuchte für das alte S7-Protokoll vielleicht mal etwas Input.
Es gibt nämlich noch eine Kommunikationsart die ich bisher noch nie im Einsatz hatte, und zwar USEND/URECV. Dabei werden Daten ohne Bestätigung vom Partner verschickt. Auf jeden Fall ist mir jetzt, und eigentlich auch schon bei den letzten Änderungen bezüglich NC-Funktionen, sowie des Datensatz-Routings, aufgefallen, dass meine bisherigen Annahmen zum Aufbau des Parameterteils bei den sog. "Userdata" Telegrammen nicht so ganz korrekt waren.

Bisher war ich davon ausgegangen, dass die ersten 3 Bytes fest sind (000112), dann folgt ein Byte für eine Länge, dann ein Byte mit der Methode (Request/Response/Push) und ein Byte welches ich in zwei Nibbles aufgeteilt habe. Wovon das Linke noch einmal für Request/Response stand, und das rechte für die Funktionsgruppe. Das passte am Anfang auch recht gut zusammen.

Nur bei eben den letzten Änderungen, passt das mit den beiden Nibbles nicht zusammen. Diese würde ich einfach zu einem Byte für die Funktion zusammenführen.
Das Byte davor mit 0x11 oder 0x12 was ich vorher als Request/Response angenommen habe, könnte auch vlt. codiert bedeuten, ob am Ende des Parameterteils Dataunit-Ref, Lastdataunit, Errorcode vorhanden sind. Aber warum dann die Längenangabe in Byte 3. Und bei USEND/URECV passt es dann auch nicht mehr, weil dort eine 0x13 steht, und anschließend noch die R_ID von den Kommunikations (S)FBs folgt.

Und beispielsweise bei Betriebszustandsübergängen wie Stop/Run ist der Aufbau komplett anders, weil der Kopf anders ist. Das war mir bisher überhaupt noch nicht aufgefallen, da ich das nur versucht habe an den anderen Bytes festzumachen. Das muss ich auf jeden Fall auch noch korrigieren.

Ich habe die Varianten im PDF im Anhang zusammengefasst. Vielleicht hat ja jemand noch eine Idee, z.B, @Rainer Hönle?


----------



## Rainer Hönle (21 August 2022)

@Thomas_v2.1: zu USend habe ich nichts. Hast Du mir ein wireshark-Log, in dem es vorkommt, dann schaue ich mir das einmal an.
btw: Das was Du als Push bezeichnest, heist bei mir Indication, da ausgelöst ohne Anfrage


----------



## Thomas_v2.1 (21 August 2022)

Den Aufbau von USEND habe ich eigentlich, ich muss nur noch einen Test mit einer 400er mit allen vier möglichen Bereichen machen. Wenn ich das mit den Siemens Zahlen rechne, sollten sich da 4 Byte wiederholen. Ich hänge ein Aufzeichnung mal an.

Mit geht es eigentlich um den Aufbau des allgemeinen Parameterteils. Also welche Bedeutung haben die ersten 3 Bytes 000112? Dann kommt ein Byte mit der Längenangabe, und dann noch ein Byte mit 0x11, 0x12 oder hier bei USEND eben 0x13. Darum muss ich die Erkennung in Wireshark grundsätzlich überarbeiten. Wenn man die Kommunikation selber programmiert, kann man ja einfach die Konstanten einsetzen ohne zu wissen um was es sich handelt. Bei Wireshark muss oder sollte schon etwas sinnvolles dran stehen. Zumindest wenn an einem Wert eine Entscheidung getroffen wird, wie die weitere Verarbeitung erfolgt.

So in der Art müsste ich es zumindest verarbeiten:


----------



## Rainer Hönle (23 August 2022)

@Thomas_v2.1: Habe dir einmal meine Erkenntnisse zu den Strukturen 0x11, 0x12 und 0x13 angehängt. Das log schaue ich mir noch an.


----------



## Rainer Hönle (23 August 2022)

0xFF = Success
0x02 = Datentype Byte
0x0001 = Itemcount (vermutlich)
Rest könnte sein:
0x00 = Success (beim Schreiben)
0x04 = Datentyp 16 Bit, macht hier keinen Sinn => keine Ahnung
0x0320 = Länge in Bits

Alternative Idee:
0xFF = Success
0x02 = Datentype Byte
0x0001 = Datalen
0x00 = Data
0x04 = Füllbyte??? Steht hier immer 0x04???
0x0320 = Länge in Bits


----------



## Thomas_v2.1 (23 August 2022)

Manchmal hat man echt ein Brett vorm Kopf, wenn ich nur die obersten 2 Bits und nicht die vier für Request/Response/Indication verwende, wie von dir geschrieben, dann passt das doch alles zusammen wie bisher. Dann muss ich meine letzten Änderungen mal wieder rückgängig machen und von vorne starten.

Indication hört sich zudem auch besser an, den Text habe ich bei den Alarm-Meldeblöcken auch verwendet. Ich meine bei Profibus wird diese Nomenklatur auch verwendet. Push hatte ich aufgrund der Verwendung in Webdiensten verwendet.


----------



## Thomas_v2.1 (24 August 2022)

Also wenn ich das richtig sehe, dann scheint für die Syntax-IDs eine globale Liste zu bestehen, die zwar theoretisch überall, aber praktisch nicht überall erlaubt sind:
0x10 = S7 Any-Pointer
0x11 = Parametersatz kurz
0x12 = Parametersatz lang
0x13 = BSEND/USEND R_ID
0x14 = Alarm lock/free Datensatz
usw.

Und vor der Spezifikation steht immer ein Byte für die Länge, und davor scheint es immer 0x12 zu geben (ich meine da gibt es auch eine andere, finde ich aber in meinen Aufzeichnungen gerade nicht wieder).

Dann könnte man annehmen, dass das 3. Byte in den Parametern von 0x07er "Userdata" Telegrammen, wo immer eine 0x12 steht, das ebenfalls dafür steht. Dann fehlt nur noch für die beiden ersten Bytes die konkrete Bedeutung.

Wenn man jetzt annehmen würde, dass der Aufbau gleich ist wie beim Parameterteil beim Lesen von Variablen, also 1. Byte Funktion und 2. Byte Anzahl der Bereiche, dann würde das für die "normalen" 0x07er Telegramme sogar passen.
1. Byte Funktion: Ist immer 0x00, eben Funktionscode 0x00
2. Byte Anzahl: Ist immer 0x01, also es folgt eine Bereich je nach Spezifikation.

So wie ich das sehe gibt es dann von den 0x07er Telegrammen nur noch die Betriebszustandsübergangs-Meldungen (z.B. Run->Stop), die enthalten:
1. Byte Funktion: Ist immer 0x01, ->Betriebszustandsübergangs-Meldung
2. Anzahl: Ist immer 0, also hier folgt keine Bereich und Spezifikation.

Von den folgenden 6 Bytes kenne ich nur die Bedeutung von einem, welches den aktuellen Betriebszustand enthält. Die anderen Bytes sind aber immer gleich.


----------



## Thomas_v2.1 (29 August 2022)

Rainer Hönle schrieb:


> @Thomas_v2.1: Habe dir einmal meine Erkenntnisse zu den Strukturen 0x11, 0x12 und 0x13 angehängt. Das log schaue ich mir noch an.


Hallo Rainer,

Bezüglich des Bytes vor der R_ID bei BSEND sehe ich keine Änderung wenn dort ein Wert 0 oder ungleich 0 eingetragen wird. Ich habe mal ein Test zwischen WinCC und einer S7 gemacht bei dem beide Seiten auf der Verbindung senden. Die eine Seite trägt 0xcc ein, und die andere 0x00. Bei anderen Aufzeichnungen die mir vorliegen sehe ich noch andere Werte, aber mir scheint egal zu sein was dort steht. Vermutung, dass es etwas mit aktiver/passiver Seite zu tun hat?

Ich hänge mal ein pdf mit ein paar Screenshots von BSEND an, und auch wie ich den Parameterteil jetzt interpretieren würde. Ich will nicht zu viel ändern, falls jemand irgendwelche Scripte zur Analyse anhand der Filteroptionen programmiert hat. Aber ganz ohne Änderung geht es nicht. Ich habe noch ein paar andere Exoten ergänzt, wie Datensatzrouting und AR_SEND.


----------



## Rainer Hönle (31 August 2022)

Hallo Thomas,

scheint zu passen bzw. habe ich nichts Unstimmiges gesehen


----------

