כיצד לפתוח פורטים של TCP\UDP בעזרת פונקציות מובנות ב-BASH?
The syntax is
$ exec {file-descriptor}<>/dev/{protocol}/{host}/{port}
{file-descriptor}
– 0, 1 and 2 are seserved for stdin, stout and stderr respectively. At least 3 must be used. The Bash manual suggest to be careful in using descriptors above 9 since there could be conflict with descriptors used internally by the shell.<>
– the file is open for both reading and writing{protocol}
– TCP or UDP{host}
– ip address or domain name of the host{port}
– logic port
Sockets can be closed using
$ exec {file-descriptor}<>&-
To send a message through the socket
echo -e -n "$MSG_OUT" >&3
or
printf "$MSG_OUT" >&3
To read a message from the socket
read -r -u -n $MSG_IN <&3
Output can be printed recursively
while read LINE <&3
do
done
echo $LINE >&1
Or read entirely in one variable
OUTPUT=$(dd bs=$BYTES count=1 <&3 2> /dev/null)
Example:
$ exec 3<>/dev/tcp/127.0.0.1/1234
We are opening a socket for reading and writing to the 1234 port in the loopback interface.
The /dev/tcp
and /dev/udp
files aren’t real devices but are keywords interpreted by the Bash shell. Being a “bashism” this solution is not portable even if seems that ksh and zsh shells have the same feature enabled.
In this example we fetch the Google main page:
$ exec 3<>/dev/tcp/www.google.com/80
$ echo -e "GET / HTTP/1.1\n\n" >&3
$ cat <&3
It’s good practice to always close file descriptors
$ exec 3<&-
$ exec 3>&-
Finally, IRC server example:
#!/bin/bash
##########################################################
# Config NICK="CyberPunk" SERVER="irc.n0where.net"
##########################################################
PORT=6667 CHANNEL="#CyberPunk" # Main
echo "USER ${NICK} 8 * : ${NICK}" >&3
exec 3<>/dev/tcp/${SERVER}/${PORT} echo "NICK ${NICK}" >&3
exit $?
echo "JOIN ${CHANNEL}" >&3 cat <&3
Enable/disable net redirections
More the feature must be enabled in Bash at compile time. To enable it if you want to compile the Bash yourself include the flag
--enable-net-redirections
while to disable it explicitly use
--disable-net-redirections
Each distribution may or not have the feature enabled in their precompiled Bash.