Basically my requirement is to know the total number of free anonymous ports.
anonymous port range is 32768- 65535.
i wrote a script for that
**********************************************
for i in {32768..65535}
do
netstat -an | grep $i > /dev/null
if [ $? -ne 0 ]
then
portcount=$((portcount+1))
fi
done
echo "Totat free anonymous ports are portcount"
netstat -an > $HOME/netstat.out
for i in {32768..65535}
do
grep $i $HOME/netstat.out > /dev/null
if [ $? -ne 0 ]
then
portcount=$((portcount+1))
fi
done
echo "Totat free anonymous ports are:$portcount"
Surely you want to start at free ports = 32767 and subtract from there if they are used in netstat?
try the following
ports=$((65535-32768))
for i in $(netstat -an | grep -Eo '[0-9]+' )
do
if [ $i -gt 32768 -a $i -lt 65535 ]
then
ports=$((ports-1))
fi
done
echo "There are $ports free "
Note that I used netstat -atu, which will show only TCP and UDP ports, without UNIX sockets present in netstat -an, which might confuse your calculations (6th column in UNIX sockets output shows inode number which might fall into the port range while grepping).
for i in {32768..65535}
do
netstat -an | grep $i > /dev/null
if [ $? -ne 0 ]
then
portcount=$((portcount+1))
fi
done
echo "Totat free anonymous ports are portcount"
Well no wonder it's slow. You're running netstat, a program which can take seconds to run if you've got a lot of traffic, thirty-two thousand separate times. Just run it once, and process its output once.
I was going to write an awk solution but the perl one looks more elegant.
I'd suggest netstat -atun, to avoid domain unnecessary name lookups. They don't care who's connected to where for this, just what ports are being used.
bash> uname -a
SunOS mypc 5.10 Generic_144488-07 sun4v sparc SUNW,SPARC-Enterprise-T5220
Also, wanted to understand if you script runs from 32767 to 65535
Thanks for your quick reply.
---------- Post updated at 11:22 AM ---------- Previous update was at 11:11 AM ----------
My grep does not have the E,o option.
grep: illegal option -- E
grep: illegal option -- o
Usage: grep -hblcnsviw pattern file . . .
SunOS 5.10 Last change: 26 Feb 2008 1
User Commands grep(1)
OPTIONS
The following options are supported for both /usr/bin/grep
and /usr/xpg4/bin/grep:
-b Precedes each line by the block number on which it was
found. This can be useful in locating block numbers by
context (first block is 0).
-c Prints only a count of the lines that contain the pat-
tern.
-h Prevents the name of the file containing the matching
line from being prepended to that line. Used when
searching multiple files.
-i Ignores upper/lower case distinction during comparis-
ons.
-l Prints only the names of files with matching lines,
separated by NEWLINE characters. Does not repeat the
names of files when the pattern is found more than
once.
-n Precedes each line by its line number in the file
(first line is 1).
-s Suppresses error messages about nonexistent or unread-
able files.
-v Prints all lines except those that contain the pat-
tern.
-w Searches for the expression as a word as if surrounded
by \< and \>.
uname -a
SunOS mypc 5.10 Generic_144488-07 sun4v sparc SUNW,SPARC-Enterprise-T5220
Scott Thanks for your inputs here. Your script runs like a CHAMP !!!
Below is the output based on the copy paste execution of your script.
./"nettest.sh"
Ports in use: 991
Couple of concerns:
1) (I'm naive to unix shell scripting) I am using a parameter input for my script and collecting that in $1.
example
/dumps.sh 4456
I believe my $1 will conflict with the $1 that you use in the script, you shared above.
I changed $1 to $2 at two places in your script but then you script did not yield the correct output.
Can you please help fix this ?
2) Does your script search for the number of used anonymous port which range from 32768- 65535. Because, I dont see 65535 anywhere in your script. HOwever I believe it looks for all ports greater than 32768 that are busy and are 991 in number. Please confirm the same.
I have test your script and have found it to be good, however just wanted to know the logic that you applied to it.
Again, the $1's inside awk have nothing to do with the $1's in your shell. They're in single quotes.
echo '$1'
$1
So you're feeding a literal $1 into awk, not the script's first parameter, and don't need to change it to $2 to avoid your $1. Awk understands $1 as "the first token in the record".
OK maybe I was incorrect in removing the END {} block. Maybe your netstat doesn't have SCTP as mine does. But we'll keep it in there just in case, since i dont use solaris and am unsure if that section comes and goes. heh.
free=`netstat -an -f inet | awk '
$1 ~ /\.[0-9]+$/ { p = $1
while (i = index(p, ".")) p = substr(p, i+1)
if (0+p >= 32768) a[0+p] = 1 }
$1 ~ /SCTP/ { exit }
END { for (p in a) count++
print 32768 - count }'`
echo Free ports $free