miércoles, enero 22, 2020

Una curiosidad del netcat (nc)

Llevo la tira de años usando netcat, esa estupenda navaja suiza para enredar con todo lo relacionado con TCP/IP. También es cierto que hace algún tiempo que no desciendo a los andurriales de la captura de paquetes y tcpdump. Hace unos días estaba depurando una aplicación que recibía paquetes de syslog (normalmente UDP, puerto 514), y me encontré que recibía unas "X" no esperadas cuando insertaba comandos y tres paquetes udp más de la cuenta. Es decir algo como:

$ echo "<1>Hola" | nc -v -u 192.168.1.1 514

Si activo la captura con tcpdump (es un Mac) veo salir lo siguiente por la interfaz de red:

bash-3.2# tcpdump -n  -i en0 port 514
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on en0, link-type EN10MB (Ethernet), capture size 262144 bytes
00:44:30.342306 IP 192.168.1.53.65436 > 192.168.1.1.514: [|syslog]
00:44:30.342309 IP 192.168.1.53.65436 > 192.168.1.1.514: [|syslog]
00:44:30.342309 IP 192.168.1.53.65436 > 192.168.1.1.514: [|syslog]
00:44:30.342309 IP 192.168.1.53.65436 > 192.168.1.1.514: [|syslog]
00:44:30.343969 IP 192.168.1.53.65436 > 192.168.1.1.514: SYSLOG kernel.alert, length: 8

¿Cuatro paquetes UDP?. ¿Para mandar una simple línea?. ¿Cuál es el motivo?. Repitamos, pero ahora sin la opción -v

$ echo "<1>Hola" | nc -u 192.168.1.1 514
bash-3.2# tcpdump -n  -i en0 port 514
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on en0, link-type EN10MB (Ethernet), capture size 262144 bytes
00:51:13.207774 IP 192.168.1.53.60478 >nbsp;192.168.1.1.514: SYSLOG kernel.alert, length: 8

Es decir, ocurre por el parámetro -v. Según la página de manual, lo único que hace es dar más información.

-v      Have nc give more verbose output

Si os vais al código fuente del netcat que usa OS X - en este ejemplo el usaro es de la versión 10.14, veréis que la causa de los paquetes extras tiene que ver con el flag -v y esta función:

int
udptest(int s)
{
    int i, ret;

    for (i = 0; i <= 3; i++) {
        if (write(s, "X", 1) == 1)
            ret = 1;
        else
            ret = -1;
    }
    return (ret);
}

No hay comentarios: