Sometimes you need to know what services are listening to what ports on your unix box. Two utilities that can get you some of this port and process information are netstat and lsof.
With netstat, you can find out which services are listening under which ports:
# netstat -na
The n option prevents ip to hostname lookups.
The a option adds to the output the sockets used by server processes.
Part of the output of the above netstat command will look like this (foreign ips have been x'd out to protect the innocent) :
$ netstat -na
Active Internet connections (including servers)
| Proto | Recv-Q | Send-Q | Local Address | Foreign Address | (state) | |||
| tcp4 | 0 | 0 | 72.232.85.100.80 | x.x.x.x.39421 | FIN_WAIT_2 | |||
| tcp4 | 0 | 0 | 72.232.85.100.80 | x.x.x.x.65413 | TIME_WAIT | |||
| tcp4 | 0 | 0 | 72.232.85.100.80 | x.x.x.x.65412 | TIME_WAIT | |||
| tcp4 | 0 | 48 | 72.232.85.98.22 | x.x.x.x.50675 | ESTABLISHED | |||
| tcp4 | 0 | 0 | *.80 | *.* | LISTEN | |||
| tcp4 | 0 | 0 | *.443 | *.* | LISTEN | |||
| tcp4 | 0 | 0 | *.22 | *.* | LISTEN | |||
| tcp6 | 0 | 0 | *.22 | *.* | LISTEN | |||
Taking a sample line from above, we can investigate each element:
tcp4 0 0 *.80 *.* LISTEN
The first column, Proto, is well, the tcp protocol being used; In this case it is 'tcp4', version 4 of the TCP protocol. The next two columns, '0 0', show the sizes of the tcp inbound and outbound queues in bytes. The value of the 'Local Address' column, '*.80', is describing that the server is listening on all ips, the '*' part, and specifically on port 80, the ubiquitous http port. Next, the '*.*' entry in the 'Foreign Address' column dictates which ip and port combinations are allowed to connect to '*.80.' In this case, '*.*' means any ip and port combination can connect. Lastly, the '(state)' column shows what state that particular protocol is at. For a listening tcp socket, the correct protocol state is 'LISTEN.'
Netstat is a great tool to investigate what ports are open on your server. Sometimes you want to go further and find out exactly what process id is listening on which port. For that purpose, I've found that lsof fits the bill perfectly. Continuing our example, let's find what process is listening on port 80.
# lsof -i tcp
The i option restricts lsof to list files matching a particular internet address. In our case, I only want tcp related files.
Here is a partial output from lsof:
# lsof -i tcp
| COMMAND | PID | USER | FD | TYPE | DEVICE | SIZE/OFF | NODE | NAME | ||
| sshd | 641 | root | 3u | IPv6 | 0xc35b1000 | 0t0 | TCP | *:ssh | (LISTEN) | |
| sshd | 641 | root | 4u | IPv4 | 0xc35b0cb0 | 0t0 | TCP | *:ssh | (LISTEN) | |
| httpd | 764 | root | 18u | IPv4 | 0xc35b01d0 | 0t0 | TCP | *:https | (LISTEN) | |
| httpd | 764 | root | 19u | IPv4 | 0xc35b0000 | 0t0 | TCP | *:http | (LISTEN) | |
| httpd | 776 | www | 18u | IPv4 | 0xc35b01d0 | 0t0 | TCP | *:https | (LISTEN) | |
| httpd | 776 | www | 19u | IPv4 | 0xc35b0000 | 0t0 | TCP | *:http | (LISTEN) | |
| httpd | 777 | www | 18u | IPv4 | 0xc35b01d0 | 0t0 | TCP | *:https | (LISTEN) | |
| httpd | 777 | www | 19u | IPv4 | 0xc35b0000 | 0t0 | TCP | *:http | (LISTEN) | |
| httpd | 778 | www | 18u | IPv4 | 0xc35b01d0 | 0t0 | TCP | *:https | (LISTEN) | |
| httpd | 778 | www | 19u | IPv4 | 0xc35b0000 | 0t0 | TCP | *:http | (LISTEN) | |
| httpd | 779 | www | 18u | IPv4 | 0xc35b01d0 | 0t0 | TCP | *:https | (LISTEN) | |
| httpd | 779 | www | 19u | IPv4 | 0xc35b0000 | 0t0 | TCP | *:http | (LISTEN) | |
| httpd | 780 | www | 18u | IPv4 | 0xc35b01d0 | 0t0 | TCP | *:https | (LISTEN) | |
| httpd | 780 | www | 19u | IPv4 | 0xc35b0000 | 0t0 | TCP | *:http | (LISTEN) | |
| httpd | 786 | www | 18u | IPv4 | 0xc35b01d0 | 0t0 | TCP | *:https | (LISTEN) | |
| httpd | 786 | www | 19u | IPv4 | 0xc35b0000 | 0t0 | TCP | *:http | (LISTEN) | |
| httpd | 787 | www | 18u | IPv4 | 0xc35b01d0 | 0t0 | TCP | *:https | (LISTEN) | |
| httpd | 787 | www | 19u | IPv4 | 0xc35b0000 | 0t0 | TCP | *:http | (LISTEN) | |
| httpd | 788 | www | 18u | IPv4 | 0xc35b01d0 | 0t0 | TCP | *:https | (LISTEN) | |
| httpd | 788 | www | 19u | IPv4 | 0xc35b0000 | 0t0 | TCP | *:http | (LISTEN) | |
| httpd | 789 | www | 18u | IPv4 | 0xc35b01d0 | 0t0 | TCP | *:https | (LISTEN) | |
| httpd | 789 | www | 19u | IPv4 | 0xc35b0000 | 0t0 | TCP | *:http | (LISTEN) | |
| httpd | 790 | www | 18u | IPv4 | 0xc35b01d0 | 0t0 | TCP | *:https | (LISTEN) | |
| httpd | 790 | www | 19u | IPv4 | 0xc35b0000 | 0t0 | TCP | *:http | (LISTEN) |
Voila! Now I know that the pids of the 'httpd' command listening on '*.http.' Using ps and grep I can then get more details on what 'httpd' is up to. I've also found this lsof output useful when I want to attach strace (on Linux) or truss (on FreeBSD) to a specific process id for system call traces.
Both netstat and lsof have a *lot* more options, so be sure to read their man pages.