Short answer. Six TCP ports account for most of what answers on a control network, and each one narrows the vendor down considerably:
| Port | Protocol | Typically means |
|---|---|---|
102 | Siemens S7 (ISO-TSAP) | S7-300 / 400 / 1200 / 1500, and third-party devices speaking S7comm |
502 | Modbus TCP | Almost anything — PLCs, drives, meters, gateways, I/O blocks |
44818 | EtherNet/IP (CIP) | Rockwell / Allen-Bradley, and the wider ODVA ecosystem |
9600 | Omron FINS | Omron CJ / CS / NJ series |
5007 | Mitsubishi MC protocol | MELSEC Q / L / iQ-R, when an MC frame port is configured |
48898 | Beckhoff ADS | TwinCAT runtimes, often on an industrial PC rather than a PLC |
Treat a hit as a candidate, not an identification. The reasons why are the rest of this post.
You have a list of addresses that answered on an unfamiliar subnet. Some are obviously office equipment. A few are not, and those are the ones you care about. The open port is the cheapest signal available, and it is a good one — but it is weaker evidence than it looks.
Why a port number is a candidate and not an answer
Three things break the clean mapping, and all three are common.
- Gateways answer on behalf of things that are not PLCs. A serial-to-Ethernet gateway with a handful of RS-485 meters behind it presents a single address on port 502. The port says Modbus TCP, which is true; it does not say that there is a PLC there, because there isn't one.
- Vendors implement each other's protocols. Modbus TCP in particular is supported by nearly everyone, so port 502 narrows the field almost not at all. A Siemens CPU with the right module answers on 502 as readily as on 102.
- An open port is not a running service. A firewall, a NAT rule or a load balancer can leave a port apparently open at an address where nothing meaningful is listening. A TCP connect succeeds and you learn nothing.
This is why it matters whether a tool tells you "PLC" or "PLC candidate — port 502 open". The second is honest about what was actually observed. The first invites you to act on an inference someone else made.
Turning a candidate into an identification
To confirm, you have to speak the protocol. Of the six, EtherNet/IP is the friendliest: the CIP List Identity request returns vendor, product type, revision and product name with no session, no authentication and no configuration on the device side.
The request is a 24-byte encapsulation header with command 0x0063 and every other
field zeroed — length, session handle, status, sender context, options. It can be sent as a UDP
broadcast to discover devices, or as a TCP connection to a single address when you already know
where you are pointing:
request TCP 44818
63 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00
^^^^^ command 0x0063 (List Identity), little-endian
response encapsulation header (24 bytes)
item count (2 bytes)
item type 0x000C <-- CIP Identity item
+18 vendor ID (uint16, little-endian)
+32 product name (length-prefixed string)
Parse the identity item and you have the vendor and the product name straight from the device, rather than a guess derived from a port number. That is a genuine identification.
The other five are not this easy
It is worth being clear about the asymmetry, because tools rarely are.
- S7 (102) needs a COTP connection to be established first, with correct TSAP values, before any module information can be read. Getting the TSAP wrong just fails; getting it right means you have opened a real session with the CPU.
- Modbus TCP (502) has an optional Read Device Identification function, and plenty of devices simply do not implement it. There is no reliable identity request that works everywhere.
- FINS (9600), MC (5007) and ADS (48898) each expect addressing information — network and node numbers, or an AMS NetID — that you generally do not have before you have already identified the device. It is circular.
So in practice: EtherNet/IP can be confirmed cheaply and safely, and the rest stay candidates unless you bring project-specific knowledge to the network. A tool that claims otherwise is guessing on your behalf.
Where a discovery tool should stop
Reading is not writing, and the distinction is the whole safety argument. A discovery request asks a device to describe itself. A write frame changes it. Between those two sits a grey zone that is worth ruling out explicitly:
- No write or job frames. Not as an advanced option, not behind a confirmation dialog. They do not belong in a tool whose purpose is to find things.
- No automatic identity queries. A port scan is passive enough to run across a range; a protocol-level query is a conversation with one specific piece of equipment, and it should happen because a person chose that row — once, read-only, to that one address.
- No repeated polling. Discovery runs once. Anything that keeps a control device answering on a schedule is a monitoring system, and building one accidentally is worse than building one deliberately.
- Permission first. On a site you do not own, the decision to send anything at all belongs to whoever owns the equipment.
Not detected is not the same as not there
A device can be present and entirely invisible to a scan: client isolation on the wireless, VLAN separation, a wired-only control segment, a firewall between you and it, or equipment that simply does not answer unsolicited traffic. An empty result is evidence about your vantage point as much as about the network. Read it that way and you will waste less time.
Dotori WiFi Scanner lists these ports as candidates with the port and protocol shown as the reason, and runs an identity query only on a row you approve — read-only, unicast, once. It sends no write or job frames. More about Dotori WiFi Scanner
Related notes
- Finding an LS XGT PLC's IP address when you don't know it — LS equipment answers a broadcast on UDP 2007, which sidesteps port scanning entirely.
