Ingeniería inversa de un convertidor RS232 a ETHERNET

Motivación:
Llevo más de 15 años usando los dispositivos del fabricante MOXA para llevar puertos serie RS232/RS485/RS422 a distancias largas a través de ethernet.
He usado principalmente los DE-311
https://www.moxa.com/en/products/industrial-edge-connectivity/serial-device-servers/general-device-servers/nport-express-series/de-311
y los NPort5210
https://www.moxa.com/en/products/industrial-edge-connectivity/serial-device-servers/general-device-servers/nport-5200-series/nport-5210

He conectado PLCs Siemens, Hiachi, Omron mediante estos dispositivos a HMI Proface, Omron, ESA VT100 (https://www.esa-automation.com/en/en-products/hmi/), transmisores de peso AUMAT4100 y DAT500 (https://www.pavonesistemi.com/es/electronica-de-pesaje-transmisores-de-peso-dat500) etc
El proceso es fácil, se conecta un dispositivo MOXA adecuadamente configurado para la red ethernet y con un cable personalizado al PLC y en el otro extremo otro al HMI, sensor etc.
Los datos serie entran por uno junto con las señales de control DTR/DSR y RTS/CTS etc y salen por el otro también con sus señales de control DTR/DSR y RTS/CTS después de viajar enrutadas por la red.

Pero una de las mejores funciones que tienen los dispositivos de MOXA es que permiten la opción «Windows Real COM Driver»!!
Cuando el dispositivo de un extremo es un PC con sistema operativo Windows no es necesario montar un MOXA conectado a un puerto serie del PC. Basta con conectar el PC a la red e instalar un driver que crea un «puerto serie virtual» en el PC conectado con un MOXA remoto.
De esta manera los programas en el PC trabajan con un puerto serie como siempre, mientras los datos se envían por la red al moxa remoto por donde salen al dispositivo.
Estos drivers tienen soporte desde Windows 95 hasta Windos 11.

Los productos de MOXA son excelentes y la calidad es excepcional, incluso indican el MTBF en la hoja de datos (más de 225000 horas!). Nunca me ha fallado uno, por lo que no tengo razones para dejar de usarlos.
Sin embargo, para aplicaciones domésticas y experimentación, siempre he ansiado poder tener un puerto serie virtual en el PC que me conecte por la red con mis micros, por ejemplo con ESP32.
De esta forma podría seguir usando los programas antiguos, que comunican por puerto serie, pero a través de la red.

Entonces… si averiguo el protocolo que usa MOXA en sus dispositivos cuando están en modo «REAL COM» podría escribir un programa para mis micros y usar su driver «Windows Real COM Driver»!

Proceso:
Para llevar a cabo la ingeniería inversa del protocolo necesitaré un sniffer de red, utilizaré WireShark: https://www.wireshark.org/
Como esto va a ser una «chapucilla de fin de semana» utilizaré la última versión bajo Windows 11 (Wireshark 4.2.0) en mi taller y una versión más antigua con soporte (no oficial) para Windows 7 para cuando trabaje en el pueblo con un viejo Packard Bell con Core2Duo T7200 http://ftp.uni-kl.de/pub/wireshark/win64/Wireshark-win64-3.6.18.msi.
Analizaré el protocolo de dos MOXA distintos, un DE-311 y un NPort5210 conectados mediante cable cruzado (aunque no es necesario los moxa tienen conexión de red RJ45 10/100 MDi/MDiX) directamente con el PC.
De esta forma minimizo el tráfico de red y no tengo que usar filtros en WireShark.

En el PC instalaré los dos programas que proporciona MOXA para gestionar estos dispositivos.
El programa que permite descubrir dispositivos en la red y asignarles IP:
DSU 2.7 build 23032110 (moxa-device-search-utility-v2.7.zip /dsu_setup_Ver2.7_Build_23032110.exe)
El instalador del driver COM que desubre dispositivos en la red y permite configurarlos como puerto serie local existe en varias versiones según el sistema operativo:
NPORT Windows Driver Manager 3.5 build 22120118 (moxa-win-driver-manager-v3.5-win-7-to-10-and-win-server-2008-r2-to-2019-whql-certified-driver-v3.5.zip / drvmgr_setup_Ver3.5_Build_22120118_whql.exe): Para Windows 7 a Windows 10 y
NPORT Windows Driver Manager 4.2 build (moxa-win-driver-manager-win-11-and-server-2022-and-later-whql-certified-driver-v4.2.zip / drvmgr_setup_Ver4.2_Build_23120717_whql.exe): Para Windows 11
También existen versiones para Windows 95 a Windows Vista que no necesito usar en este proyecto…

Alimento el DE311 y lo conecto al PC mediante un cable de red.

Arranco el WireShark como administrador para capturar de la tarjeta ethernet donde he conectado los MOXA.

Arranco el DSU como Administrador y pulso search.

Si todo va bien deberé poder ver la IP del MOXA en el DSU.

Cierro el DSU y voy a mirar los paquetes capturados por el WireShark.

Identifico varios paquetes UDP desde la IP del PC a la IP de broadcast 255.255.255.255, repetidos varias veces. Seguro que esta es la forma que tiene DSU de «llamar» a los MOXA:
PC (192.168.0.2) port 63683 envia UDP a broadcast (255.255.255.255) port 29168 con 8 bytes 0100000800000000
PC (192.168.0.2) port 63685 envia UDP a broadcast (255.255.255.255) port 4800 con 8 bytes 0100000800000000
PC (192.168.0.2) port 63687 envia UDP a broadcast (255.255.255.255) port 1029 con 6 bytes 490000060000
PC (IPV6 ) port 63691 envia UDP a multicast (IPV6 FF02::1) port 1029 con 28 bytes 7900001c000000000000000000000000000000000100000000010001

Observo que la IP del MOXA sólo contesta a uno de ellos, el sexto, enviado al port 1029 en IPV4 con la respuesta:
MOXA (192.168.0.31) port 50546 envia UDP a broadcast (255.255.255.255) port 1029 con 24 bytes C900001800007EF94CB81103EB9EC0A8006F0090E8049EEB

Supongo que el resto de paquetes no contestados que envía el PC para «llamar» a los posibles MOXA de la red son debidos a que el software DSU soporta varios modelos de MOXA y estará usando varios protocolos distintos…

A continuación el DSU envía un paquete, no ya de broadcast, sino a la dirección IP del MOXA que ha descubierto:

Posiblemente este paquete sirva para obtener información precisa del dispositivo:

PC (192.168.0.111) port 1028 envia UDP a MOXA (192.168.0.31) port 1029 con 6 bytes 010000060000
MOXA (192.168.0.31) port 1029 envia UDP a PC (192.168.0.111) port 1028 con 86 bytes 810000560000FC70148C1103EB9EC0A8006F000104730000040202014E5034303638332020202020202020202020202020202020202020202020020F0F0F0F0F0F0F0F0F0F0F0F0F0F0FC0A80021FFFFFF00C0A80001
También repito el proceso varias veces y siempre obtengo respuesta por el port 1029, también cambian cambian 4 bytes:
MOXA (192.168.0.31) port 1029 envia UDP a PC (192.168.0.111) port 1028 con 86 bytes 810000560000 E118A3CE 1103EB9EC…

Repito varias capturas cambiando la IP del MOXA y del PC para ver las diferencias en los paquetes. A continuación comparo a información que conozco con los datos obtenidos en las capturas para averiguar el significado de cada paquete:

Ahora compararé los paquetes capturados con la información que conozco para ver en que posición hay informacion reconocible.
MOXA DE-311 HW 2.1C, SW 2.4
production S/N á0BEE1240683
S/N 40683 = 9EEB hex
MAC 0090E8049EEB
IP 192.168.0.31 C0A8001F
mask 255.255.255.0 FFFFFF00
gw 192.168.0.1 C0A80001
PC Win 11 con
MAC F8:E4:3B:AF:97:87
IP 192.168.0.111 C0A8006F
mask 255.255.255.0 FFFFFF00

Estas pruebas veo que el primer paquete (comienza por 0x49) y su respuesta podrían tener esta estructura:

Y el segundo paquete, que comienza por 0x01, podría tener esta otra:

Con esta información recopilada he podido escribir un pequeño programa para ARDUINO ESP32 y probar si es correcto. He confirmado que los campos «Modelo» y «Version SW» son correctos cambiándolos por otros valores y observando en DSU la detección. Por ejemplo, en la siguiente captura hago que el ESP32 se identifique como MOXA DE-302 con un firmware version 4.2.

Esta es la captura de la salida de depuración del programa «MoxaDiscover1.ino«. (he eliminado las líneas repetidas):

Moxa discover responder (c) Heli Tejedor, V0.1, enero 2024
Reporting MOXA DE-302 SW version 4.2
Connecting to: xxxxxxxxxx:yyyyyyyyyy
……
Connected!
Signal %:86
MAC: 24:62:AB:F1:DA:44
IP: 192.168.0.165
NetMask: 255.255.255.0
Gateway: 192.168.0.1
DNS: 100.100.1.1
UDP Listening on PORT: 1029… OK
Running at Mhz: 240, Free RAM: 259432
UDP packet type: broadcast, from: 192.168.0.220:57202, to: 255.255.255.255:1029, length: 6, data: 490000060000
Response -> C900001800001214FAFB0203EB9EC0A800DC2462ABF1DA44
Discover CMD 0x49

UDP packet type: broadcast, from: 192.168.0.220:57202, to: 255.255.255.255:1029, length: 10, data: 4900000A00000203EB9E
Response -> C900001800001214FAFB0203EB9EC0A800DC2462ABF1DA44
Discover long CMD 0x49

UDP packet type: unicast, from: 192.168.0.220:1028, to: 192.168.0.165:1029, length: 6, data: 010000060000
Response -> 8100005600001214FAFB0203EB9EC0A800DC000104730000020402014E5034303638332020202020202020202020202020202020202020202020020F0F0F0F0F0F0F0F0F0F0F0F0F0F0FC0A800A5FFFFFF00C0A80001
Read Config CMD 0x01

La siguiente fase: averiguar el protocolo de configuración para cambiar a IP y los otros parámetros de la red