// the find
s-pms/siemens_plc_s7_net
Siemens PLC S7 Protocol
A small C library for talking to Siemens S7-family PLCs (S200 through S1500) over Ethernet — handles the TCP/COTP/TPKT handshake, PDU length negotiation, and typed read/write against M/I/Q/DB/T/C addresses. Useful if you want a dependency-free S7 client in C/C++ without pulling in something heavier like snap7.
The latest rework replaced a blocking connect() with non-blocking connect+select and a real timeout, and swapped naive length-only response checking for actual TPKT/COTP/S7 header field validation — both are the kind of bugs that make naive S7 clients hang or silently misparse. PDU length negotiation is now tracked per-connection (s7_get_pdu_length(fd)) instead of only in a global, and the README documents exactly where in the handshake response the negotiated value comes from (tail bytes, ntohs, minimum clamp to 200), which means someone actually traced the wire protocol instead of copying magic constants. Address parsing got boundary validation and now rejects malformed input (empty string, MX0.8, MX0.A) with dedicated regression tests for those cases.
PLC slot, rack, connection type, and TSAP are still process-global state via get_plc_slot/set_plc_slot and friends — fine for one PLC per process, but breaks immediately if you need two PLCs with different rack/slot from the same binary. s7_read_string returns a malloc'd buffer the caller must free, while the rest of the API returns by value, so there's no consistent ownership convention and it's an easy leak or double-free source. The 'regression test' is a single binary covering address parsing and packet validation only — there's no test against a real PLC or a simulator, so the actual connect/read/write path is only exercised manually through main.c. The README claims support for S200 through S1500 but the project was only tested against an S1200, so the family-specific handshake templates for the other PLC types are unverified against real hardware.