Backend
Reproducing PROFINET in the Lab: Discovery, AR Establishment, and Cyclic RT Boundaries
404Saint DEV Community
3 views
By RUGERO Tesla (@404Saint).
I approached this research with the same general workflow I have used for the other industrial protocols in my lab. Start with the architecture, identify a usable implementation, reproduce the visible protocol behavior, inspect the traffic, and then move toward security-relevant experiments. PROFINET made that process more complicated than I expected.
The first challenge was getting the laboratory into a useful state. I spent a considerable amount of time working through Linux namespaces, virtual interfaces, routing, and the behavior of the available open-source implementation. Once the environment was working, the next challenge appeared: some parts of PROFINET were easy to observe, while other parts depended on controller/device behavior that the available stack did not fully expose. That changed the shape of the research.
I could still examine discovery, application-relation traffic, cyclic Real-Time framing, and crafted Layer 2 inputs. I simply had to be more careful about what each experiment actually established.
The goal of this project became straightforward:
Build a reproducible PROFINET laboratory, examine its observable protocol surfaces, and document the point where packet construction, implementation output, and verified endpoint behavior stop answering the same question.
Laboratory Scope
The laboratory used Linux network namespaces to isolate the controller and device sides of the experiment. The main implementation was p-net, supported by custom Python and Scapy-based harnesses, packet captures, and Wireshark/TShark analysis.
The work followed five phases:
DCP and LLDP discovery
DCE/RPC application-relation traffic
Cyclic Real-Time frame analysis
Layer 2 traffic generation, netload, and malformed inputs
A specification-driven review of PROFINET security mechanisms
The first four phases involved direct laboratory experimentation. The final phase connected those observations to PROFINET’s historical Security Class model and newer secure application mechanisms.
The Protocol Surfaces
Before working with the captures, I needed a practical model of how the main protocol components fit together.
Controller / Engineering System
|
| DCP and LLDP
v
Device identity and topology
|
| DCE/RPC
v
Application Relationship
|
| AR and IOCR configuration
v
Cyclic Real-Time I/O
|
v
Process data and state
DCP provides Layer 2 discovery and configuration functions. LLDP contributes neighboring-device and topology information. DCE/RPC over UDP port 34964 carries acyclic application-relation traffic, including structures associated with AR and IOCR configuration. Cyclic Real-Time communication uses PROFINET’s EtherType, 0x8892, and carries process data directly over Ethernet.
These components are connected. Discovery identifies a device, but discovery alone does not create a cyclic I/O relationship. AR-related traffic has meaning within the context of a controller/device relationship. A cyclic RT frame can have a recognizable layout, but its acceptance still depends on endpoint state and implementation behavior. That relationship between architecture and packet meaning guided the rest of the research.
Evidence and Interpretation
I kept three forms of evidence separate throughout the experiments.
✔ The packet captures established things such as EtherTypes, MAC addresses, UDP ports, DCE/RPC fields, frame IDs, payload lengths, timing, and whether responses appeared.
✔ Application output added information about discovery results, parsed structures, reported state, and local transmission behavior.
✔ Security conclusions were then drawn from those observations, with care around what remained unverified. For example, a captured crafted frame proves that the frame reached the capture point. It does not tell me whether the target accepted it, rejected it, ignored it, or processed it in some other way.
That sounds obvious, but it becomes easy to lose track of when a script reports a successful send and the capture looks exactly like the frame that was intended.
Phase One: DCP and LLDP Discovery
The first phase established the identity and Layer 2 visibility of the device under test. The p-net device was placed in a separate namespace and queried from the controller side using DCP Identify traffic. The response exposed the station name, vendor and device identifiers, and active IP configuration.
The device reported:
Station name: rt-labs-dev
Vendor ID: 0x0493
Device ID: 0x0002
IP address: 192.168.1.20
Subnet mask: 255.255.255.0
Gateway: 192.168.1.1
The DCP traffic used EtherType 0x8892. The station-name information appeared under the Name of Station option, using option 0x02 and suboption 0x02. The result was useful immediately. I could identify the device and retrieve its configuration without relying on an IP-based management service.
Figure 1. DCP discovery audit showing the station name, vendor and device identifiers, and active IP configuration reported by the laboratory device.
Testing a station-name update
After discovery, I tried changing the station name to: tesla-pnet-node. The device continued reporting: rt-labs-dev. The update did not take effect. The behavior was consistent with runtime write protection, although the unchanged station name alone did not reveal the exact reason for the failure. This was a useful early reminder that a request and its intended effect are separate things. The request could be generated and transmitted successfully while the configuration remained unchanged.
LLDP topology information
LLDP provided another view of the same Layer 2 environment.
The captured information included:
Chassis ID:
P-Net Sample Application 12345 Abcdefghijk 007 3 V 0 2 0
Port ID:
port-001.rt-labs-dev
System Name:
p-net IO-Device
TTL:
20 seconds
The LLDP frames used EtherType 0x88CC and the standard LLDP multicast destination: 01:80:c2:00:00:0e. The TTL represented the validity lifetime of the advertised information. I treated it as an information lifetime rather than assuming it described the transmission interval.
Figure 2. LLDP topology information observed from the laboratory device, including chassis identity, port identity, system name, and advertisement lifetime.
Security relevance
The discovery phase exposed several useful protocol surfaces:
Station-name identity
Vendor and device identifiers
IP configuration
Layer 2 device visibility
Neighbor and port information
Configuration-related operations
An actor with suitable Layer 2 access could use these mechanisms to learn about devices and their network context. The experiment did not establish a vulnerability by itself, but it showed how much information is available before any higher-level communication relationship is created.
Phase Two: DCE/RPC and Application-Relation Traffic
DCP discovery identifies a device. It does not establish the communication relationship required for cyclic I/O.
The second phase moved into DCE/RPC traffic over UDP port 34964. The custom harness constructed a connect request containing structures associated with:
ARBlockReq
IOCRBlockReq
AlarmCRBlockReq
The request used this ARUUID:
08019a8a-9f6f-4bb1-ad46-0da8698a5bc5
The observed DCE/RPC interface UUID was:
4a823108-a078-11d0-b21a-00a0241a673b
The packet capture showed a controller-to-device request followed by a device-to-controller response.
The capture independently established:
DCE/RPC version 4
Request packet type 0x00
Response packet type 0x02
Interface UUID
Opnum 122
Response association with the original request
The response contained:
dcerpc.request_in: 1
That field associated the response with the first request in the capture.
Figure 3. DCE/RPC request and response observed during the application-relation experiment over UDP port 34964.
I also captured the broader exchange to examine the surrounding traffic and the sequence reported by the implementation.
Figure 4. Expanded view of the DCE/RPC application-relation exchange and associated traffic observed during the laboratory handshake.
AR-related structures and state progression
The application output provided additional context for the AR-related blocks and reported a state sequence resembling:
IDLE
→ CONNECT
→ PARAM
→ CONFIG
→ APPL-READY
→ RUN
I treated this as implementation and test behavior. It helped explain what the application believed was happening during the exchange, but I did not present it as a universal wire-level state machine for every PROFINET implementation. TShark exposed the DCE/RPC fields, but it did not independently decode every individual PROFINET block field in the request and response. The block-level interpretation therefore came from the combined evidence of the harness, implementation output, and packet structure. That combination was enough to make the exchange useful for research, while still leaving some endpoint-side questions open.
Security relevance
The experiment exposed several questions relevant to application-relation security:
How are ARUUID values validated?
How does an implementation bind an AR to a device and controller?
How are duplicate or conflicting relationships handled?
What prevents replay or injection of relationship-management traffic?
How does the implementation behave when relationship resources are exhausted?
Which parts of the exchange receive authentication or integrity protection?
The ARUUID identified a communication relationship. It did not function as a credential. The observed exchange also did not demonstrate mutual cryptographic authentication at the DCE/RPC layer. Questions around injection, hijacking, replay, and resource exhaustion would require additional endpoint-side experiments and implementation-specific evidence.
Phase Three: Cyclic Real-Time Framing
The third phase examined cyclic Real-Time traffic over PROFINET EtherType 0x8892.
At this point, the available p-net configuration became a limiting factor. It did not produce a usable cyclic RT stream for the experiment I wanted to perform. Rather than leave the wire format unexplored, I built a separate traffic generator to examine frame structure, field placement, timing, and controlled payload changes.
The generator was deliberately limited in scope. It could construct and transmit candidate RT frames, but it did not establish an AR, negotiate IOCRs, maintain a process image, or demonstrate receiver-side acceptance.
Observed frame layout
The generated frames were 60 bytes long and followed this layout:
Ethernet destination 6 bytes
Ethernet source 6 bytes
EtherType 2 bytes
Frame ID 2 bytes
IO/application data 40 bytes
Cycle Counter 2 bytes
DataStatus 1 byte
TransferStatus 1 byte
The capture contained:
Frame count: 515
Frame length: 60 bytes
EtherType: 0x8892
Frame ID: 0x8000
Application data: 40 bytes
Cycle Counter: 0x0000
DataStatus: 0x35
TransferStatus: 0x00
The relative PROFINET RT payload layout was:
Offset 0–1: Frame ID
Offset 2–41: IO/application data
Offset 42–43: Cycle Counter
Offset 44: DataStatus
Offset 45: TransferStatus
One representative frame contained:
Offset 14: 80 00
Offset 16: 01 59
Offset 18: 01 02 03 04
Offset 56: 00 00
Offset 58: 35
Offset 59: 00
Correcting the cycle-counter interpretation
One of the more useful moments in this phase came from checking the changing values against the actual field offsets. The sequential values initially looked like possible cycle-counter values. When I checked their position in the frame, they were inside the application-data region. The actual cycle-counter field remained: 00 00. The changing values belonged to application data.
This was a good example of why protocol analysis needs more than a changing byte sequence. Field position, length, surrounding structure, and protocol semantics all have to agree before a value can be assigned a meaning.
Controlled payload insertion
The generator inserted: FF 00 AA 55 into the application-data region. The special frames began at capture frame 346. The sequence appeared at absolute offsets 18 through 21, placing it inside application data rather than inside the cycle counter or status fields. The cycle counter remained unchanged. DataStatus and TransferStatus also remained unchanged.
Figure 5. Cyclic PROFINET RT analysis showing the observed frame structure, application-data changes, cycle-counter position, and status fields.
No PROFINET diagnostics or alarms appeared in the capture. All 515 packets used the same EtherType and Frame ID.
Timing observations
The experiment did not produce the expected 144-millisecond silence. The maximum observed packet gap was approximately: 33.972 ms. Around the controlled payload event, a normal interval of approximately 32 milliseconds was divided into shorter intervals surrounding the inserted frame. The capture therefore showed a timing change around the event, rather than a complete communication silence.
I used a watchdog model of: 32 ms × 3 = 96 ms as a laboratory assumption for discussing possible timeout behavior. That value was not treated as a universal PROFINET threshold, and the experiment did not demonstrate a watchdog transition.
Security relevance
The experiment demonstrated that a host with Layer 2 access can construct candidate PROFINET RT frames and place controlled values inside the application-data region. It did not establish that a real controller or device accepted those frames, modified its process image, triggered a diagnostic, or changed state.
The cycle counter and status fields provide continuity and communication-state information, but they do not provide cryptographic authentication. A capable Layer 2 actor can construct plausible field values. Whether an endpoint accepts those values depends on the implementation and the communication state surrounding the frame. PROFIsafe was outside the scope of this experiment.
Phase Four: Layer 2 Traffic, Netload, and Malformed Inputs
The fourth phase used an independent Scapy-based harness to generate three categories of Layer 2 traffic:
A netload-oriented burst
DCP-like station-name packets
Malformed RT-like frames
The goal was to observe the traffic-generation path and inspect the resulting captures. I also wanted to see whether the target produced any visible response, diagnostic, or recovery behavior.
Netload-oriented burst
The harness targeted approximately 15,000 packets per second. The actual measured transmission rate was approximately: 4,014.46 packets per second. The experiment transmitted 500 frames and recorded no kernel or interface drops. The resulting burst lasted approximately: 108.536 ms
The capture showed 499 packet intervals:
Minimum: 159.979 µs
Maximum: 1.708031 ms
Mean: 217.507 µs
Median: 205.040 µs
The intended rate was therefore not reproduced. The result told me more about the behavior of the traffic-generation path than about how a PROFINET endpoint would handle a genuine Class III load. That limitation was useful to record because the harness output alone could have made the experiment look more successful than the measurements supported.
DCP-like station-name packets
The harness transmitted three crafted station-name packets from a rogue source MAC address:
aa:bb:cc:dd:ee:ff
The packets claimed the station name:
rt-labs-dev
The payload included:
03 01 00 01 00 01 00 08 02 02 00 0b
72 74 2d 6c 61 62 73 2d 64 65 76
I refer to these as DCP-like station-name packets because they did not include the conventional DCP frame identifier FE FD. Calling them valid DCP Identify Responses would have gone beyond what the packet structure supported. The capture showed all three transmitted frames, but no subsequent response appeared.
Malformed RT-like frames
The harness also transmitted five frames using:
Frame ID: 0x00FF
Payload: 10 bytes
The frames appeared in the capture. No target-side diagnostic, rejection, recovery action, or state change was observed.
The complete capture contained:
500 netload-oriented frames
3 DCP-like station-name frames
5 malformed RT-like frames
All captured traffic used EtherType 0x8892. No IP, ARP, UDP, TCP, ICMP, or LLDP traffic appeared in the capture.
Figure 6. Phase 4 traffic audit showing the captured Layer 2 burst, DCP-like station-name packets, and malformed RT-like frames.
Security relevance
The phase demonstrated that crafted Layer 2 traffic could be generated and captured in the isolated laboratory. The captures did not reveal how the target parsed, rejected, ignored, or processed each frame. The harness labels described the intended test stages, while the PCAP established what was transmitted and visible at the capture point. That left the endpoint-side outcome unresolved.
Phase Five: Historical Security Classes and Newer Secure Mechanisms
The final phase connected the laboratory observations to PROFINET’s published security architecture.
The research question was:
How does the security architecture defined by PROFINET specifications address the discovery, application-relation, cyclic RT, and Layer 2 attack surfaces observed experimentally, and how has that architecture evolved from the historical Security Class 1/2/3 model toward newer secure application mechanisms?
The comparison covered:
DCP and LLDP discovery
DCE/RPC and application relations
Cyclic RT traffic
Layer 2 injection and malformed traffic
Netload robustness
Historical Security Classes 1, 2, and 3
Newer secure application mechanisms
Secure provisioning and device identity
Historical Security Classes
The historical model described three broad security classes:
Security Class 1: robustness
Security Class 2: integrity and authenticity
Security Class 3: confidentiality
This model provided a useful way to discuss increasing security requirements. It should, however, be kept separate from newer PROFINET security terminology.
Newer security architecture
Published PROFINET specification material describes newer mechanisms and architectural changes, including:
Secure-capable successors for protocols without secure variants
SXP over Layer 2
SXP over Layer 3
Secure provisioning
IDevID and certificate-based device identity
Secure SXP over TCP
Security-related GSDML application classes
SecureAccess
SecureRealtime
Updated robustness terminology
The newer architecture addresses particular communication and application requirements through more specific mechanisms.
The experimental observations can be mapped to those directions:
Observed surface
Experimental concern
Related security direction
DCP and LLDP
Device identity and topology exposure
Discovery hardening and controlled access
DCE/RPC and AR
Relationship establishment and trust
Secure-capable successors and authenticated mechanisms
Cyclic RT
Injection and freshness concerns
SecureRealtime-related protection
Layer 2 traffic
Injection, malformed input, and netload
Robustness requirements, segmentation, and access control
Device identity
Trust in device descriptions
IDevID, certificates, and secure provisioning
Historical security classes
Robustness, integrity, authenticity, and confidentiality
Newer security profiles and application classes
This phase remained specification-driven. The newer mechanisms were not implemented or validated in the laboratory.
What the Laboratory Established
The research established a reproducible environment for examining several PROFINET protocol surfaces.
The experiments demonstrated:
DCP discovery and device identity enumeration
Station-name and IP configuration visibility
LLDP chassis, port, and system information
DCE/RPC request and response behavior over UDP/34964
AR-related application output and reported state progression
Cyclic RT frame structure
Actual cycle-counter and DataStatus positions
Controlled application-data changes in generated RT frames
Transmission of crafted Layer 2 traffic
Measured behavior of the traffic-generation path
A specification-driven comparison with historical and newer security mechanisms
What Remained Outside the Laboratory’s Reach
Several questions required a more complete controller/device environment or a different implementation.
The experiments did not establish:
Universal PROFINET behavior across vendors
Complete controller/device interoperability
Endpoint acceptance of every crafted frame
Process-image modification
Target-side diagnostics or recovery
Successful Class III netload reproduction
Cryptographic protection of every observed legacy exchange
PROFIsafe behavior
Production-equivalent resilience
The behavior of a complete commercial PROFINET controller/device pair
These limits define the boundary of the results. They do not erase the discovery, packet analysis, implementation work, or corrections made during the research.
Conclusion
This study established a reproducible laboratory for examining PROFINET discovery, application-relation traffic, cyclic RT framing, and selected Layer 2 inputs.
The available open-source implementation supported meaningful wire-level analysis, but it did not expose enough controller/device behavior to verify every intended endpoint-side effect. The separate cyclic RT generator made frame construction, field placement, and timing measurable, but it could not substitute for a functioning PROFINET IO-Device relationship.
The most valuable part of the process was learning to recognize that boundary while the experiments were still in progress. A generated frame can look correct in a capture. A script can report a successful transmission. An implementation can print a state transition. Those observations become much more useful when I know exactly which part of the protocol they represent and which questions they leave unanswered.
The research therefore ended with a clearer understanding of both PROFINET and the laboratory itself. I could reproduce discovery behavior, inspect application-relation traffic, analyze cyclic RT fields, generate controlled Layer 2 inputs, and compare those surfaces with the protocol’s security architecture. I could also identify where further claims would require a more complete endpoint implementation. That is, to me, a meaningful result for protocol security research.
The protocol remains the subject. The implementation is the instrument. Sometimes the instrument exposes a complete interaction. Sometimes it gives only a partial view. The researcher’s job is to understand what the instrument can establish, preserve the evidence, and avoid turning an intended experiment into a claim that the laboratory never demonstrated.
Key Takeaways
DCP and LLDP expose useful device identity and topology information at Layer 2.
DCP discovery does not establish the application relationship required for cyclic I/O.
DCE/RPC traffic over UDP/34964 provides an observable surface for examining AR-related communication.
An ARUUID identifies a communication relationship but is not a credential.
Cyclic RT frame construction does not prove endpoint acceptance or process-image modification.
Changing values inside a frame does not make those values the cycle counter. Field offsets and protocol semantics must agree.
The observed RT cycle counter remained 0x0000, while changing values were located inside application data.
The netload experiment measured the limits of the traffic-generation path rather than reproducing a complete Class III resilience test.
DCP-like and malformed frames were captured, but target-side processing was not established.
Historical Security Classes 1, 2, and 3 should be separated from newer PROFINET security terminology.
Packet captures, application output, and specification material answer different parts of the research question.
A completed protocol study does not need to produce an exploit in every phase.
Understanding what the laboratory can and cannot prove is part of the research result.
Reproduce the Research
The complete laboratory setup, research notes, custom scripts, packet captures, and supporting material are available in the repository below. If you want to go beyond the observations in this article, the repository is the place to start reproducing the experiments yourself.
Repository: https://github.com/404saint/industrial-protocol-labs/tree/main/profinet-research
Read original: https://dev.to/null_saint/reproducing-profinet-in-the-lab-discovery-ar-establishment-and-cyclic-rt-boundaries-3oi0
← Previous
Stop Trusting the App: Enforcing Append-Only at the Database Layer
Next →
GPT-6 Astra Is Not Just a Smarter Model. It Is a Computer Operator.
Related
You Don't Need Express to Build a Microservice (Here's the Zero-Dependency Version)
Backend
3
DEV Community
Should Your Thread Keep the JVM Alive?
Backend
7
Dev.to (EN Zone)
Monitoring Jetson CPU, GPU, Temperature and Power from a Flutter Robot Dashboard
Backend
7
DEV Community
Stop Slamming Downstream Services: Singleflight Request Coalescing with Java Virtual Threads
Backend
8
DEV Community
Comments0
No comments yet — be the first