Strange behaviour of netcat with UDP

前端 未结 4 586
天命终不由人
天命终不由人 2020-12-13 13:36

I noticed a strange behaviour working with netcat and UDP. I start an instance (instance 1) of netcat that listens on a UDP port:

nc -lu -p 10000


        
相关标签:
4条回答
  • 2020-12-13 13:38

    Use the -k option:

    nc -l -u -k 0.0.0.0 10000
    
    • -k means keep-alive, that netcat keeps listening after each connection
    • -u means UDP
    • -l listening on port 10000
    0 讨论(0)
  • 2020-12-13 13:48

    As the accepted answer explains, ncat appears not to support --keep-open with the UDP protocol. However, the error message which it prints hints at a workaround:

    Ncat: UDP mode does not support the -k or --keep-open options, except with --exec or --sh-exec. QUITTING.
    

    Simply adding --exec /bin/cat allows --keep-open to be used. Both input and output will be connected to /bin/cat, with the effect of turning it an "echo server" because whatever the client sends will be copied back to it.

    To do something more useful with the input, we can use the shell's redirection operators (thus requiring --sh-exec instead of --exec). To see the data on the terminal, this works:

    ncat -k -l -u -p 12345 --sh-exec "cat > /proc/$$/fd/1"
    

    Caveat: the above example sends data to the stdout of ncat's parent shell, which could be confusing if combined with additional redirections. To simply append all output to a file is more straightforward:

    ncat -k -l -u -p 12345 --sh-exec "cat >> ncat.out"
    
    0 讨论(0)
  • 2020-12-13 13:50

    Having given up on netcat on my OS version this is pretty short and gets the job done:

    #!/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
    
    0 讨论(0)
  • 2020-12-13 13:57

    When nc is listening to a UDP socket, it 'locks on' to the source port and source IP of the first packet it receives. Check out this trace:

    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
    

    Here you can see that it created a UDP socket, set it for address reuse, and bound it to port 10,000. As soon as it received its first datagram (from port 52,832), it issued a connect system call 'connecting' it to the 127.0.0.1:52,832. For UDP, a connect rejects all packets that don't match the IP and port in the connect.

    0 讨论(0)
提交回复
热议问题