In deze les

Wat deze les behandelt

  • Een capture die alleen Modbus bevat, en waar je daarvoor meet
  • Vraag en antwoord aan elkaar knopen met de transaction id
  • Een filter dat alle exceptions toont, en Decode As op een andere poort

Lees eerst: Poort 502, de MBAP header en de unit id, Modbus TCP oefenen met een gratis simulator

Met Wireshark zie je wat er echt over de lijn gaat: elk Modbus TCP frame byte voor byte, met vraag en antwoord onder elkaar. Een capture filter en drie displayfilters vertellen je binnen een minuut of het probleem bij jouw verzoek ligt, bij het apparaat of bij de gateway ertussen. Na deze les heb je zelf een capture gemaakt van een geslaagde en een mislukte transactie.

Een capture maken die alleen Modbus bevat

Zet het capture filter voordat je op start drukt: tcp port 502, en niets anders. Op het startscherm van Wireshark staat dat veld bij de interfacelijst, met het label ...using this filter:. Wireshark bewaart het per interface, dus kies eerst de juiste interface en typ daarna je filter. Wat je daar wegfiltert komt niet in het bestand, en dat scheelt op een druk netwerk het verschil tussen een handvol frames en tienduizend.

Waar je meet is de tweede beslissing. Draai Wireshark op de machine die zelf pollt, dan heb je al het verkeer van en naar die client. Wil je meekijken op een verbinding tussen twee andere apparaten, dan heb je een mirror port op je switch nodig: een gewone switchpoort levert alleen het verkeer dat voor jou bestemd is.

Wat je in het pakketvenster ziet staan

Wireshark toont een Modbus TCP frame als twee lagen: eerst de MBAP header, daaronder de Modbus PDU. Dat is exact de opbouw uit de les over de MBAP header en de unit id. Klik een verzoek open en je vindt deze twaalf bytes:

00 01 00 00 00 06 FF 03 00 6B 00 03
BytesVeldWaarde
00 01transaction id1
00 00protocol id0
00 06length6
FFunit id255
03function codeFC03
00 6BstartadresPDU-adres 107
00 03aantal registers3

Het antwoord staat er een regel onder:

00 01 00 00 00 09 FF 03 06 02 2B 00 00 00 64

Zes van de zeven MBAP-bytes zijn identiek aan het verzoek: de server kopieert ze. Alleen Length verandert, van 0x0006 naar 0x0009, want dat is het enige veld dat de server zelf berekent: 1 byte unit id plus 8 bytes PDU. Achter de byte count 06 staan de registerwaarden 555, 0 en 100.

MBAP header, 7 bytesPDU, function code en dataTID2 BPID2 BLEN2 BUID1 BFC1 BDATAN BCRC-16
TIDTransaction id, koppelt antwoord aan verzoek
PIDProtocol id, altijd 0
LENLength, 1 plus de PDU-lengte
UIDUnit id, adres achter de gateway
FCFunction code
DATAData

Geen CRC: Ethernet en TCP controleren de integriteit al.

Wireshark splitst elk Modbus TCP frame in precies deze twee lagen: zeven bytes header, daarna de PDU.

De rekenregel: Length is 1 plus het aantal PDU-bytes. Klopt dat niet met wat je aan bytes ziet, dan kijk je naar een afgekapt of samengevoegd bericht en niet naar een protocolfout.

Drie filters die je altijd gebruikt

Displayfilters typ je in de balk boven de pakketlijst. Met deze drie doe je vrijwel al je werk:

FilterWat je overhoudt
mbtcpalle Modbus TCP frames, verzoeken en antwoorden
modbus.func_code == 3alleen FC03, Read Holding Registers
modbus.exception_codealleen de frames waarin een exception zit

De derde is je "wat gaat er mis"-filter en levert de meeste tijdwinst op. Een opname van tien minuten wordt vaak een lijst van drie regels, en die drie vertellen je welk adres of welke function code geweigerd wordt. Blijft de lijst leeg terwijl er wel klachten zijn, dan is er geen logisch probleem en zoek je verder bij ontbrekende antwoorden of verkeerd uitgelegde waarden. Apparaten vinden doe je trouwens niet met een sniffer maar met een scanner, zoals beschreven in de gids over een Modbus-netwerk scannen.

Vraag en antwoord aan elkaar knopen

Filter op mbtcp.trans_id == 5 en je houdt precies een transactie over, vraag en antwoord samen. De client kiest dat nummer en de server kopieert het ongewijzigd terug. Op een TCP-verbinding hoort zo'n nummer op enig moment bij precies een openstaand verzoek, want er mogen meerdere verzoeken tegelijk onderweg zijn en de volgorde van de antwoorden ligt niet vast.

Twee frames in beeld is een complete transactie. Blijft er een over, dan heb je een timeout in plaats van een weigering. Kijk ook naar de tijdkolom, want traag is niet hetzelfde als stuk: een SMA-omvormer mag volgens de fabrikant 5 tot 10 seconden over een antwoord doen. De veldbeschrijving van de header staat in de uitleg over Modbus TCP.

Een dissector aan een andere poort hangen

Zie je alleen kale TCP, dan hangt de dissector niet aan die poort. Rechtsklik een pakket uit de stream, kies Decode As, en zet de regel voor jouw TCP-poort op Modbus/TCP. Vanaf dat moment werken mbtcp en alle modbus.-velden gewoon. Je hebt dit nodig bij de pymodbus-simulator op poort 5020, en bij SolarEdge-omvormers met SetApp, die standaard op poort 1502 luisteren.

Wat een capture je over de gateway vertelt

Krijg je snel antwoord met exception 11, dan werkt je netwerk en zit het probleem achter de gateway. Zo'n antwoord is opvallend kort:

00 01 00 00 00 03 01 83 0B

Length is 0x0003, dus na de unit id blijven er twee PDU-bytes over. Die unit id is hier 01, het serveradres op de RS485-kant, en niet de FF van een apparaat dat rechtstreeks op het netwerk zit. De function code 0x83 is 0x03 plus 0x80, en de laatste byte 0B is exception 11, GATEWAY TARGET DEVICE FAILED TO RESPOND. Dat is de TCP-vertaling van een timeout op de seriele bus.

Exception 10 wijst naar de gateway zelf, GATEWAY PATH UNAVAILABLE: verkeerde configuratie of te veel gelijktijdige polls. Komt er niets terug, dan hangt de gateway of wacht hij nog op de RS485-kant. De instelkant staat in de handleiding voor een Modbus TCP gateway installeren.

Wat je in de capture zietWat het betekentWaar je zoektVerzoek zonderantwoordHet frame vertrok wel,maar er kwam niets terugbinnen je timeoutUnit id of poortnummerVerbindingslimiet vanhet apparaatFirewall die stilwegdruktAntwoord met eenexceptionHet frame kwam foutloosaan en het apparaatweigert dit ene verzoekException 02: adres ofaantalException 11: achter degatewayException 10: degateway zelfEen waarde die nietkloptHet transport is in orde,de interpretatie nietDatatype en word orderSchaalfactor en eenheidHet verkeerde register
Een capture levert precies drie soorten waarnemingen op, en elk daarvan wijst naar een ander zoekdomein.

Wanneer Wireshark je niet verder helpt

Wireshark leest van netwerkinterfaces, en een RS485-bus is er geen. Er valt dus niets op te nemen, hoe goed je filters ook zijn. Voor de seriele kant gebruik je de verbose uitvoer van je client en de pollstatistiek uit de les over RTU-storingen oplossen, plus de diagnosetellers van FC08.

Er is een tweede grens, en die zit binnen TCP zelf. Een capture bewijst dat de bytes klopten, niet dat je ze goed uitlegt. Leest je teller 302.024.662 waar de meter 1.234.567 aanwijst, dan is er in de capture niets mis: dezelfde vier bytes in een andere byte- en woordvolgorde leveren precies dat getal op. Word order, datatype en schaalfactor zijn afspraken van de fabrikant en geen protocolvelden. Daarvoor pak je de registerkaart.

Er is nog een praktische grens: op een beheerde werkplek mag of kun je Wireshark niet altijd installeren. De Protocol Analyzer in ModbusCloud Diagnostics toont dan de frames van zijn eigen verbinding, kleurgecodeerd per onderdeel en met een teller voor transacties en fouten. Voor meekijken op het verkeer van een andere client blijft Wireshark met een mirror port nodig.

Veelgemaakte fouten

Zonder capture filter beginnen. Op een productienetwerk staan binnen een minuut tienduizenden pakketten in je buffer en scroll je langs precies de frames die ertoe doen. Zet tcp port 502 in het capture filter voordat je start.

Denken dat Wireshark je simulator niet ziet. Op poort 5020 hangt de dissector standaard niet, dus zie je kale TCP en matcht mbtcp niets. De bytes zijn er wel. Decode As lost dat in twee klikken op.

Op een willekeurige switchpoort meten. Een switch stuurt verkeer alleen naar de betrokken poorten. Zie je niets tussen twee andere apparaten, dan is dat geen bewijs van stilte. Meet op de client zelf of configureer een mirror port.

Een ontbrekend antwoord meteen een netwerkprobleem noemen. Zie je het verzoek wel vertrekken en komt er niets terug, kijk dan eerst of er al een andere client pollt en of je unit id klopt. Een verkeerde unit id levert stilte op die eruitziet als een kabelprobleem.

Aan de slag

Je maakt zelf een capture met een geslaagde en een mislukte transactie erin, en vindt ze allebei terug met een eigen filter. Heb je geen apparaat bij de hand, dan doe je de hele oefening op je laptop met de simulator uit de les over oefenen met de simulator.

  1. 1

    Start de simulator

    Draai pymodbus.simulator --modbus_server server --modbus_device device. De server luistert op poort 5020.

  2. 2

    Start de capture

    Kies in Wireshark de loopback-interface en zet het capture filter op tcp port 5020.

  3. 3

    Lees een register

    Vraag PDU-adres 3 op met een client. Zie je alleen kale TCP, rechtsklik dan een pakket, kies Decode As en koppel poort 5020 aan Modbus/TCP.

    from pymodbus.client import ModbusTcpClient
    
    client = ModbusTcpClient("127.0.0.1", port=5020)
    client.connect()
    client.read_holding_registers(address=3, count=1, device_id=1)
    
  4. 4

    Ontleed het verzoek

    Klik het verzoek open en benoem de zeven MBAP-bytes hardop. Noteer de transaction id die je client gebruikte.

  5. 5

    Koppel vraag en antwoord

    Zet het displayfilter op mbtcp.trans_id met jouw nummer erachter, en controleer dat er precies twee frames overblijven.

  6. 6

    Lok een exception uit

    Lees PDU-adres 1 met dezelfde client. Zet het displayfilter op modbus.exception_code en houd dat ene frame over.

  7. 7

    Vergelijk de lengtes

    Leg beide antwoorden naast elkaar. Het exception-antwoord heeft Length 0x0003, het geslaagde antwoord meer. Reken ze allebei na met de regel 1 plus de PDU-lengte.

Met echte apparatuur. Vervang 5020 door de poort uit je datasheet, meestal 502, en meet op de client zelf of op een mirror port van je switch.

Samenvatting

  • Een capture filter bepaalt wat er in het bestand komt, een displayfilter alleen wat je ziet.
  • Wireshark toont elk frame als een MBAP header van zeven bytes plus de PDU, en zes van die zeven bytes zijn in het antwoord identiek aan het verzoek.
  • Met mbtcp.trans_id koppel je vraag en antwoord, en met modbus.exception_code haal je alle weigeringen uit een opname.
  • Op een afwijkende poort zoals 5020 of 1502 werkt de dissector pas nadat je hem met Decode As hebt gekoppeld.
  • Exception 11 en exception 10 komen van de gateway en niet van het eindapparaat, dus ze bewijzen dat je netwerk werkt.

Controleer jezelf

Vier vragen over deze les. Je krijgt bij elk antwoord uitleg.

Vraag 1 van 4
Je capture toont elke seconde een verzoek en steeds een antwoord waarin het filter modbus.exception_code de waarde 11 laat zien. Waar ga je zoeken?
Je start de simulator op poort 5020, zet in Wireshark het displayfilter mbtcp en ziet niets, terwijl er wel TCP-pakketten voorbijkomen. Wat is er aan de hand?
In een capture zie je een antwoord met Length 0x0003. Wat weet je al voordat je de PDU openklikt?
Waarom helpt Wireshark je niet bij een storing op de RS485-bus?

Loopt het vast op een project?

Beschrijf wat je ziet en waar het misgaat. We kijken mee en zeggen wat we zouden doen.

Verder lezen in de kennisbank