networking udp netcat

networking - netcat linux



Extraño comportamiento de netcat con UDP (3)

Cuando nc está escuchando un socket UDP, ''se bloquea'' en el puerto de origen y la IP de origen del primer paquete que recibe. Mira este rastro:

socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP) = 3 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 bind(3, {sa_family=AF_INET, sin_port=htons(10000), sin_addr=inet_addr("127.0.0.1")}, 16) = 0 recvfrom(3, "f/n", 2048, MSG_PEEK, {sa_family=AF_INET, sin_port=htons(52832), sin_addr=inet_addr("127.0.0.1")}, [16]) = 2 connect(3, {sa_family=AF_INET, sin_port=htons(52832), sin_addr=inet_addr("127.0.0.1")}, 16) = 0

Aquí puede ver que creó un socket UDP, lo configuró para la reutilización de direcciones y lo vinculó al puerto 10,000. Tan pronto como recibió su primer datagrama (desde el puerto 52,832), emitió una llamada al sistema de conexión ''conectándolo'' al 127.0.0.1:52,832. Para UDP, una connect rechaza todos los paquetes que no coinciden con la IP y el puerto en la connect .

Noté un comportamiento extraño al trabajar con netcat y UDP. Comienzo una instancia (instancia 1) de netcat que escucha en un puerto UDP:

nc -lu -p 10000

Así que lanzo otra instancia de netcat (instancia 2) y trato de enviar datagramas a mi proceso:

nc -u 127.0.0.1 10000

Veo los datagramas. Pero si cierro la instancia 2 y reinicio netcat nuevamente (instancia 3):

nc -u 127.0.0.1 10000

No puedo ver datagramas en la terminal de la instancia 1. Obstinadamente, el sistema operativo asigna un puerto fuente UDP diferente en la instancia 3 respecto a la instancia 2 y el problema está ahí: si utilizo el mismo puerto fuente de la instancia 2 (ejemplo 50000):

nc -u -p 50000 127.0.0.1 10000

de nuevo, la instancia 1 de netcat recibe los datagramas. UDP es un protocolo de menos conexión, entonces, ¿por qué? ¿Es este un comportamiento estándar de netcat?


Después de haber renunciado a netcat en mi versión del sistema operativo, esto es bastante corto y hace el trabajo:

#!/usr/bin/ruby # Receive UDP packets bound for a port and output them require ''socket'' require ''yaml'' unless ARGV.count == 2 puts "Usage: #{$0} listen_ip port_number" exit(1) end listen_ip = ARGV[0] port = ARGV[1].to_i u1 = UDPSocket.new u1.bind(listen_ip, port) while true mesg, addr = u1.recvfrom(100000) puts mesg end


Use la opción -k :

nc -l -u -k 0.0.0.0 10000

  • -k significa keep-alive, que netcat sigue escuchando después de cada conexión
  • -u significa UDP
  • -l escuchando en el puerto 10000