Estivemos com um problema em um projeto que precisava verificar se o serviço xdmcp estava aberto, porém ele não é um processo independente, ele fica interligado ao X, kdm, gdm, xdm, para tanto a solução mais cabível era procurar saber se a porta estava aberta na máquina. 
Sim, talvez pudesse existir outras maneiras de resolver isso, mas esta se fez mais interessante. A clássica solução que me veio a cabeça foi usar o netstat, mas pensei em porque não ir mais a fundo e como resultado venho por este artigo mostrar algumas coisas que aprendi.
As formas que executei este processo foram:
-  Geek hacker ninja style form - procura no proc pelas conexões abertas (mais interessante e a que mais aprendi);
-  Status network - usa o comando de status de rede para listar;
-  Open Files - Procura baseado nos arquivos abertos o que está ligado a porta.
Geek hacker ninja style form
A forma mais baixo nível e estilosa =], vamos aos arquivos de kernel analisar suas saídas, está é a base utilizada por programas como o netstat, o qual converte os dados deste e mostra com uma saída personalizada. Foi publicado um artigo antes explicando sobre a conversão de bases, então não vou abordar este assunto aqui.
O arquivo em questão utilizado é o 
/proc/net/tcp.
Exemplo de /proc/net/tcp:
sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
0: 9E00A8C0:D3FD E1D7BCCD:1F4A 01 00000000:0003163C 00:00000000 00000000  1000        0 383991 1 cb042500 102 12 4 2 100
1: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 626508 1 c299db80 750 0 0 2 -1
Onde:
-  sl: O número de identificador da linha.
-  local_address: O endereço local e o número da porta do socket. O endereço local está codificado em little-endian em quatro seqüências de números em hexadecimal, isso significa que o byte mais importante é listado primeiro e você necessita fazer a inversão da ordem dos bytes para converter para o endereço de IP. O número da porta é um hexadecimal simples utilizado pelo programa.
-  rem_address - O endereço remoto e o número da porta do socket. O endereço local está codificado em little-endian em quatro seqüências de números em hexadecimal, isso significa que o byte mais importante é listado primeiro e você necessita fazer a inversão da ordem dos bytes para converter para o endereço de IP. O número da porta é um hexadecimal simples.
-  st: Status do socket (depois de muita busca encontrei onde estava o padrão de código daqui e o porque do valor ficar com 0A - segue tabela de referência no final).
-  tx_queue rx_queue: O tamanho de transmissão e recebimento das filas de pacotes.
-  
-  tr tm->when:  tr é o campo que indica se o medidor de tempo está ativo para este socket. Um valor zero indica que o medidor de tempo não está ativo. O tm->when indica tempo que o sock está sendo utilizado em jiffies (usado basicamente para debug).
-  retrnsmt: Campo de informação interna do socket do kernel (usado basicamente para debug).
-  uid: O uid do usuário dono da conexão.
-  time-out: Campo de informação interna do socket do kernel (usado basicamente para debug).
-  inode: Um número encriptado de identificação do socket para o sistema de arquivos do Linux (não encontrei qual é a criptografia utilizada aqui).
Achei a representação padrão do cat do arquivo /proc/net/tcp muito extensa, então refiz ela na horizontal para melhor explanar o exemplo acima e traduzi alguns dados:
sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
0: 9E00A8C0:D3FD E1D7BCCD:1F4A 01 00000000:0003163C 00:00000000 00000000  1000        0 383991 1 cb042500 102 12 4 2 100
1: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 626508 1 c299db80 750 0 0 2 -1
sl : 0 - linha indicadora da primeira conexão
local_address: 9E00A8C0:D3FD - convertendo fica 192.168.0.158:151775
rem_address: E1D7BCCD:1F4A - convertendo fica 205.188.215.225:8010
st: 01 - TCP ESTABELISHED - conexão estabelecida
tx_queue rx_queue: 00000000:0003163C - fila de dados transmitidos
tm->when retrnsmt: 00:00000000 00000000 - dados utilizados para debug
uid: 1000 - id do usuário dono da conexão
timeout: 0 - dado utilizado para debug
inode: 383991 1 cb042500 102 12 4 2 100 - identificador criptografado
sl : 1 - linha indicadora da primeira conexão
local_address: 00000000:0016 - convertendo fica localhost:22
rem_address: 00000000:0000 - não tem ninguém conectado
st: 0A - TCP_LISTEN - escutando conexão
tx_queue rx_queue: 00000000:0003163C - fila de dados transmitida
tm->when retrnsmt: 00:00000000 00000000 - dados utilizados para debug
uid: 1000 - id do usuário dono da conexão
timeout: 0 - dado utilizado para debug
inode: 383991 1 cb042500 102 12 4 2 100 - identificador criptografado
Status network
Podemos ver as conexões abertas através do comando 
netstat. O mesmo é um programa de estatísticas de rede utilizado amplamente para este fim. Não tem muitos segredos e as informações que ele mostra são muito legíveis. Alguém percebeu a similaridade com um outro arquivo no modo que as informações aparecem? :)
# netstat -tl - lista as conexões abertas de tcp em modo de escuta
# netstat -t - lista as conexões tcp estabelecidas
# netstat -p - lista os programas que estão usando a conexão
# netstat --numeric-ports - não converte o número da porta para ser listado
# netstat --numeric-hosts - não converte o número de ip para nome do host
Comando que resolveu meu problema:
# netstat -t -l -p --numeric-ports
Open Files
Vendo as conexões abertas através do comando 
lsof. O comando lsof lista os arquivos abertos, através disto vamos procurar o arquivo aberto relacionado às portas tcp.
Obs.: Ele pode pegar muitas informações interessantes sobre os arquivos abertos, mas não é escopo deste artigo. :)
Sintaxe: 
lsof -i protocolo
Exemplo:
# lsof -i tcp
Tabela de dados para o status do socket  - versão do kernel 2.6.21.5 Slackware Linux 12
| st status socket values | 
| significado | valor | 
| TCP_ESTABLISHED | 01 | 
| TCP_SYN_SENT | 02 | 
| TCP_SYN_RECV | 03 | 
| TCP_FIN_WAIT1 | 04 | 
| TCP_FIN_WAIT2 | 05 | 
| TCP_TIME_WAIT | 06 | 
| TCP_CLOSE | 07 | 
| TCP_CLOSE_WAIT | 08 | 
| TCP_LAST_ACK | 09 | 
| TCP_LISTEN | 0A | 
| TCP_CLOSING | 0B | 
| TCP_MAX_STATES | 0C | 
Ambiente de teste
-  Slackware 12.0
-  kernel 2.6.21.5
Conclusão
Estas foram apenas algumas maneiras, devem ter mais. Espero que tenham gostado e que algum dia isto seja útil a alguém =], bom para mim foi um grande aprendizado.
(Desculpe qualquer erro de português :X)
Definições
jiffy - medida utilizada para representar o uso de uma tarefa em chamadas de interrupção no processador (medida em um Linux com kernel 2.6.13 em um Intel 386 é de 4 ms ou 1/250th de um segundo)
Referências