Bash – Using bash’s `/dev/udp`, how would I know if the port was open

bashdevicesnetworking

I do not have access to netcat or nmap so I'm trying to use bash and the /dev/udp/ special files to test ports.

I could do something like:

echo "" > /dev/udp/example.com/8000

But $? is always 0 when using UDP. I'm assuming that's because that is the return value of the echo "" command correct?

I am basically trying to replicate what I am able to do with nmap and netcat:

nmap -sU -p 8000 example.com | grep open >/dev/null && echo 'open'
nc -z -u example.com 8000 && echo 'open'

How would I do this with /dev/udp?

Best Answer

For tcp, just checking $?. If connection failed, $? won't be 0:

$ >/dev/tcp/google.com/81
bash: connect: Network is unreachable
bash: /dev/tcp/google.com/81: Network is unreachable
$ echo $?
1

It will take time for bash to realize that the connection failed. You can use timeout to trigger bash:

$ timeout 1 bash -c '>/dev/tcp/google.com/80' &&
  echo Port open ||
  echo Port close
Port open

Testing udp port is more complex.

Strictly speaking, there is no open state (of course, udp is stateless protocol) with udp. There're only two states with udp, listening or not. If the state is not, you will get an ICMP Destination Unreachable.

Unfortunately, firewall or router often drop those ICMP packets, so you won't be sure what state of udp port.

Related Question