Skip to content

1.3 The TCP/IP Stack

Ethernet delivers frames between directly connected devices on the same segment. That is not enough. A PLC in one cabinet needs to reach a SCADA server in another building. That requires IP addressing and routing — the Layer 3 and 4 protocols that move data across multiple network segments. This section covers the TCP/IP stack that makes that possible.

The OSI model was designed by committee. It took years to standardize and produced a complex specification that was difficult to implement. TCP/IP was designed by engineers solving a real problem: connecting ARPANET nodes reliably across unreliable links. It was simpler, faster to implement, and already running on real hardware by the time OSI was finalized.

The US Department of Defense mandated TCP/IP for all military networks in 1982. Universities adopted it for ARPANET. By the time OSI implementations were ready, TCP/IP had won. Today, every IP network runs TCP/IP. OSI remains a reference model, not an implementation. The first thing TCP/IP needs is a way to address every device uniquely.

An IPv4 (Internet Protocol version 4) address is a 32-bit number written as four decimal octets: 192.168.10.50. The address has two parts: a network portion that identifies the subnet, and a host portion that identifies the device within that subnet. The subnet mask defines the boundary.

CIDR (Classless Inter-Domain Routing) notation expresses the mask as a prefix length: 192.168.10.0/24. The /24 means the first 24 bits are the network portion.

CIDRSubnet MaskUsable HostsTypical Use
/24255.255.255.0254Standard cell network
/25255.255.255.128126Split cell
/28255.255.255.24014Small segment
/30255.255.255.2522Point-to-point router link

Usable hosts = 2^(host bits) minus 2. Subtract the network address and the broadcast address.

Industrial networks use RFC 1918 private addresses. The default management address of a factory-fresh Hirschmann switch is 192.168.1.1/24. With addressing in place, the next question is how data is delivered reliably — or not.

TCP (Transmission Control Protocol) provides reliable, ordered, connection-oriented delivery. It uses a three-way handshake to establish a connection.

When a segment is lost, TCP retransmits it. The retransmission timer starts at 200 ms and doubles on each failure. A single lost segment can delay delivery by 200 ms or more.

This makes TCP unsuitable for hard real-time industrial control. A PLC with a 4 ms cycle time cannot tolerate a 200 ms retransmission delay. PROFINET RT and EtherNet/IP I/O use UDP or raw Ethernet frames instead. TCP is appropriate for non-real-time industrial communication: Modbus TCP configuration reads, OPC UA data access, SNMP management, HiVision topology discovery. For everything time-critical, the answer is UDP.

UDP (User Datagram Protocol) is connectionless. It sends datagrams with no handshake and no retransmission. The 8-byte header contains only source port, destination port, length, and checksum.

UDP is the right choice when a late retransmitted value is worse than no value (sensor readings), when the application handles its own reliability, or when multicast delivery is needed. Both TCP and UDP use port numbers to identify which application on a host should receive the data.

A port number is a 16-bit number that identifies the application on a host. The combination of IP address and port number uniquely identifies a communication endpoint.

PortProtocolUse
22SSHSwitch management (secure)
80 / 443HTTP / HTTPSSwitch web interface
161 / 162SNMPNetwork management (UDP)
502Modbus TCPIndustrial control
4840OPC UAIndustrial data exchange
44818EtherNet/IPIndustrial control (TCP)
2222EtherNet/IPI/O data (UDP)

Knowing which ports are in use on a segment is the first step when diagnosing communication problems.

When a device reports communication errors, the first question is: are the packets actually reaching the network? The following script captures traffic for 30 seconds and shows which industrial protocols are active and how many packets per second each is generating:

from scapy.all import sniff, IP, TCP, UDP
from collections import defaultdict
import time
INDUSTRIAL_PORTS = {502: "Modbus TCP", 44818: "EtherNet/IP",
4840: "OPC UA", 161: "SNMP", 2222: "EtherNet/IP I/O"}
counts: dict[str, int] = defaultdict(int)
start = time.time()
def inspect(pkt):
if not pkt.haslayer(IP):
return
layer = pkt[TCP] if pkt.haslayer(TCP) else pkt[UDP] if pkt.haslayer(UDP) else None
if layer:
proto = INDUSTRIAL_PORTS.get(layer.dport, None)
if proto:
counts[f"{pkt[IP].src} -> {pkt[IP].dst} ({proto})"] += 1
sniff(iface="eth0", prn=inspect, timeout=30, store=False)
elapsed = time.time() - start
for flow, n in sorted(counts.items(), key=lambda x: -x[1]):
print(f" {flow:50s} {n/elapsed:.1f} pkt/s")

If you see Modbus TCP traffic but the SCADA system reports timeouts, the packets are reaching the network but the PLC is not responding. The problem is in the PLC, not the network. If you see no traffic at all on port 502, the SCADA system is not sending requests or the traffic is on a different VLAN.

TCP retransmission makes it unsuitable for real-time control

A single lost segment delays delivery by 200 ms or more. Use UDP-based protocols for real-time I/O. Use TCP for configuration and non-time-critical data.

Use static IPs for all OT devices

Assign static IP addresses to PLCs, switches, and I/O modules. Changing an IP address in a running OT network requires production downtime.

TCP/IP handles addressing and delivery. The next section covers switching — how a switch learns which devices are on which ports and makes forwarding decisions at line rate. Switching is the mechanism that makes VLANs and MRP rings possible.

  • RFC 791 — Internet Protocol (IETF, 1981)
  • RFC 793 — Transmission Control Protocol (IETF, 1981)
  • RFC 768 — User Datagram Protocol (IETF, 1980)
  • RFC 1918 — Address Allocation for Private Internets (IETF, 1996)
  • Stevens, W. R. (1994). TCP/IP Illustrated, Volume 1. Addison-Wesley.