Soquetes brutos TCP/IP

Um soquete bruto é um tipo de soquete que permite o acesso ao provedor de transporte subjacente. Este tópico se concentra apenas em soquetes brutos e nos protocolos IPv4 e IPv6. Isso ocorre porque a maioria dos outros protocolos com exceção do ATM não dá suporte a soquetes brutos. Para usar soquetes brutos, um aplicativo precisa ter informações detalhadas sobre o protocolo subjacente que está sendo usado.

Os provedores de serviço winsock para o protocolo IP podem dar suporte a um tipo de soquete de SOCK_RAW. O provedor windows sockets 2 para TCP/IP incluído no Windows dá suporte a esse tipo de soquete SOCK_RAW.

Há dois tipos básicos desses soquetes brutos:

  • O primeiro tipo usa um tipo de protocolo conhecido escrito no cabeçalho IP reconhecido por um provedor de serviços Winsock. Um exemplo do primeiro tipo de soquete é um soquete para o protocolo ICMP (tipo de protocolo IP = 1) ou o protocolo ICMPv6 (tipo de procotol IP = 58).
  • O segundo tipo permite que qualquer tipo de protocolo seja especificado. Um exemplo do segundo tipo seria um protocolo experimental que não tem suporte direto pelo provedor de serviços Winsock, como o Protocolo de Transmissão de Controle de Fluxo (SCTP).

Determinando se há suporte para soquetes brutos

Se um provedor de serviços Winsock der suporte a soquetes SOCK_RAW para as famílias de endereços AF_INET ou AF_INET6, o tipo de soquete de SOCK_RAW deverá ser incluído na estrutura WSAPROTOCOL_INFO retornada pela função WSAEnumProtocols para um ou mais dos provedores de transporte disponíveis.

O membro iAddressFamily na estrutura WSAPROTOCOL_INFO deve especificar AF_INET ou AF_INET6 e o membro iSocketType da estrutura WSAPROTOCOL_INFO deve especificar SOCK_RAW para um dos provedores de transporte.

O membro iProtocol da estrutura de WSAPROTOCOL_INFO pode ser definido como IPROTO_IP. O membro iProtocol da estrutura de WSAPROTOCOL_INFO também poderá ser definido como zero se o provedor de serviços permitir que um aplicativo use um tipo de soquete SOCK_RAW para outros protocolos de rede diferentes do Protocolo de Internet para a família de endereços.

Os outros membros na estrutura WSAPROTOCOL_INFO indicam outras propriedades do suporte de protocolo para SOCK_RAW e indicam como um soquete de SOCK_RAW deve ser tratado. Esses outros membros do WSAPROTOCOL_INFO para SOCK_RAW normalmente especificam que o protocolo é sem conexão, orientado a mensagens, dá suporte à transmissão/multicast (os bits XP1_CONNECTIONLESS, XP1_MESSAGE_ORIENTED, XP1_SUPPORT_BROADCAST e XP1_SUPPORT_MULTIPOINT são definidos no membro dwServiceFlags1) e podem ter um tamanho máximo de mensagem de 65.467 bytes.

No Windows XP e posterior, o comando NetSh.exe pode ser usado para determinar se há suporte para soquetes brutos. O comando a seguir executado em uma janela CMD exibirá dados do catálogo do Winsock no console:

netsh winsock show catalog

A saída incluirá uma lista que contém alguns dos dados das estruturas de WSAPROTOCOL_INFO com suporte no computador local. Pesquise o termo RAW/IP ou RAW/IPv6 no campo Descrição para encontrar os protocolos que dão suporte a soquetes brutos.

Criando um soquete bruto

Para criar um soquete do tipo SOCK_RAW, chame o soquete ou a função WSASocket com o parâmetro af (família de endereços) definido como AF_INET ou AF_INET6, o parâmetro de tipo definido como SOCK_RAW e o parâmetro de protocolo definido como o número de protocolo necessário. O parâmetro de protocolo se torna o valor do protocolo no cabeçalho IP (SCTP é 132, por exemplo).

Observação

Um aplicativo pode não especificar zero (0) como o parâmetro de protocolo para as funções socket, WSASocket e WSPSocket se o parâmetro type for definido como SOCK_RAW.

 

Soquetes brutos oferecem a capacidade de manipular o transporte subjacente, para que possam ser usados para fins mal-intencionados que representam uma ameaça à segurança. Portanto, somente membros do grupo Administradores podem criar soquetes do tipo SOCK_RAW no Windows 2000 e posterior.

Operações de envio e recebimento

Depois que um aplicativo cria um soquete do tipo SOCK_RAW, esse soquete pode ser usado para enviar e receber dados. Todos os pacotes enviados ou recebidos em um soquete do tipo SOCK_RAW são tratados como datagramas em um soquete não conectado.

As seguintes regras se aplicam às operações por meio de soquetes SOCK_RAW :

  • A função sendto ou WSASendTo normalmente é usada para enviar dados em um soquete do tipo SOCK_RAW. O endereço de destino pode ser qualquer endereço válido na família de endereços do soquete, incluindo um endereço de transmissão ou multicast. Para enviar para um endereço de transmissão, um aplicativo deve ter usado setsockopt com SO_BROADCAST habilitado. Caso contrário, sendto ou WSASendTo falhará com o código de erro WSAEACCES. Para IP, um aplicativo pode enviar para qualquer endereço multicast (sem se tornar um membro do grupo).

  • Ao enviar dados IPv4, um aplicativo tem a opção de especificar o cabeçalho IPv4 na frente do datagrama de saída para o pacote. Se a opção de soquete IP_HDRINCL estiver definida como true para um soquete IPv4 (família de endereços de AF_INET), o aplicativo deverá fornecer o cabeçalho IPv4 nos dados de saída para operações de envio. Se essa opção de soquete for false (a configuração padrão), o cabeçalho IPv4 não deverá estar incluído nos dados de saída para operações de envio.

  • Ao enviar dados IPv6, um aplicativo tem a opção de especificar o cabeçalho IPv6 na frente do datagrama de saída para o pacote. Se a opção de soquete IPV6_HDRINCL estiver definida como true para um soquete IPv6 (família de endereços de AF_INET6), o aplicativo deverá fornecer o cabeçalho IPv6 nos dados de saída para operações de envio. A configuração padrão para essa opção é false. Se essa opção de soquete for false (a configuração padrão), o cabeçalho IPv6 não deverá ser incluído nos dados de saída para operações de envio. Para IPv6, não deve haver necessidade de incluir o cabeçalho IPv6. Se as informações estiverem disponíveis usando funções de soquete, o cabeçalho IPv6 não deverá ser incluído para evitar problemas de compatibilidade no futuro. Esses problemas são discutidos no RFC 3542 publicado pelo IETF. O uso da opção de soquete IPV6_HDRINCL não é recomendado e pode ser preterido no futuro.

  • A função recvfrom ou WSARecvFrom normalmente é usada para receber dados em um soquete do tipo SOCK_RAW. Ambas as funções têm a opção de retornar o endereço IP de origem de onde o pacote foi enviado. Os dados recebidos são um datagrama de um soquete não conectado.

  • Para IPv4 (família de endereços de AF_INET), um aplicativo recebe o cabeçalho IP na frente de cada datagrama recebido, independentemente da opção de soquete IP_HDRINCL .

  • Para IPv6 (família de endereços de AF_INET6), um aplicativo recebe tudo após o último cabeçalho IPv6 em cada datagrama recebido, independentemente da opção de soquete IPV6_HDRINCL . O aplicativo não recebe nenhum cabeçalho IPv6 usando um soquete bruto.

  • Os datagramas recebidos são copiados em todos os soquetes SOCK_RAW que atendem às seguintes condições:

    • O número do protocolo especificado no parâmetro de protocolo quando o soquete foi criado deve corresponder ao número do protocolo no cabeçalho IP do datagrama recebido.
    • Se um endereço IP local for definido para o soquete, ele deverá corresponder ao endereço de destino, conforme especificado no cabeçalho IP do datagrama recebido. Um aplicativo pode especificar o endereço IP local chamando a função bind . Se nenhum endereço IP local for especificado para o soquete, os datagramas serão copiados para o soquete, independentemente do endereço IP de destino no cabeçalho IP do datagrama recebido.
    • Se um endereço estrangeiro for definido para o soquete, ele deverá corresponder ao endereço de origem, conforme especificado no cabeçalho IP do datagrama recebido. Um aplicativo pode especificar o endereço IP estrangeiro chamando a função connect ou WSAConnect . Se nenhum endereço IP estrangeiro for especificado para o soquete, os datagramas serão copiados para o soquete, independentemente do endereço IP de origem no cabeçalho IP do datagrama recebido.

É importante entender que alguns soquetes do tipo SOCK_RAW podem receber muitos datagramas inesperados. Por exemplo, um programa PING pode criar um soquete do tipo SOCK_RAW para enviar solicitações de eco ICMP e receber respostas. Embora o aplicativo esteja esperando respostas de eco ICMP, todas as outras mensagens ICMP (como ICMP HOST_UNREACHABLE) também podem ser entregues a esse aplicativo. Além disso, se vários soquetes SOCK_RAW estiverem abertos em um computador ao mesmo tempo, os mesmos datagramas poderão ser entregues a todos os soquetes abertos. Um aplicativo deve ter um mecanismo para reconhecer os datagramas de interesse e ignorar todos os outros. Para um programa PING, esse mecanismo pode incluir a inspeção do cabeçalho IP recebido para identificadores exclusivos no cabeçalho ICMP (a ID do processo do aplicativo, por exemplo).

Observação

Para usar um soquete do tipo SOCK_RAW requer privilégios administrativos. Os usuários que executam aplicativos Winsock que usam soquetes brutos devem ser membros do grupo Administradores no computador local, caso contrário, as chamadas de soquete brutas falharão com um código de erro WSAEACCES. No Windows Vista e posteriores, o acesso para soquetes brutos é imposto na criação do soquete. Em versões anteriores do Windows, o acesso para soquetes brutos é imposto durante outras operações de soquete.

 

Usos comuns de soquetes brutos

Um uso comum de soquetes brutos são a solução de problemas de aplicativos que precisam examinar pacotes IP e cabeçalhos em detalhes. Por exemplo, um soquete bruto pode ser usado com a SIO_RCVALL IOCTL para permitir que um soquete receba todos os pacotes IPv4 ou IPv6 que passam por um adaptador de rede. Para obter mais informações, consulte a referência de SIO_RCVALL .

Limitações em soquetes brutos

No Windows 7, Windows Vista, Windows XP com Service Pack 2 (SP2) e Windows XP com Service Pack 3 (SP3), a capacidade de enviar tráfego por meio de soquetes brutos foi restrita de várias maneiras:

  • Os dados TCP não podem ser enviados por meio de soquetes brutos.

  • Os datagramas UDP com um endereço de origem inválido não podem ser enviados por meio de soquetes brutos. O endereço de origem IP para qualquer datagrama UDP de saída deve existir em um adaptador de rede ou o datagrama é descartado. Essa alteração foi feita para limitar a capacidade do código mal-intencionado de criar ataques de negação de serviço distribuídos e limita a capacidade de enviar pacotes falsificados (pacotes TCP/IP com um endereço IP de origem forjado).

  • Uma chamada para a função de associação com um soquete bruto para o protocolo IPPROTO_TCP não é permitida.

    Observação

    A função bind com um soquete bruto é permitida para outros protocolos (IPPROTO_IP, IPPROTO_UDP ou IPPROTO_SCTP, por exemplo).

     

Essas restrições acima não se aplicam ao Windows Server 2008 R2, Windows Server 2008 , Windows Server 2003 ou a versões do sistema operacional anteriores ao Windows XP com SP2.

Observação

A implementação da Microsoft de TCP/IP no Windows é capaz de abrir um soquete UDP ou TCP bruto com base nas restrições acima. Outros provedores Winsock podem não dar suporte ao uso de soquetes brutos.

 

Há outras limitações para aplicativos que usam um soquete do tipo SOCK_RAW. Por exemplo, todos os aplicativos que escutam um protocolo específico receberão todos os pacotes recebidos para esse protocolo. Isso pode não ser o desejado para vários aplicativos usando um protocolo. Isso também não é adequado para aplicativos de alto desempenho. Para contornar esses problemas, pode ser necessário gravar um driver de protocolo de rede do Windows (driver de dispositivo) para o protocolo de rede específico. No Windows Vista e posteriores, o WSK (Winsock Kernel), um novo modo de kernel independente de transporte Interface de Programação de Rede pode ser usado para gravar um driver de protocolo de rede. No Windows Server 2003 e anteriores, um provedor de TDI (Interface do Driver de Transporte) e uma DLL auxiliar do Winsock podem ser gravados para dar suporte ao protocolo de rede. Em seguida, o protocolo de rede seria adicionado ao catálogo winsock como um protocolo com suporte. Isso permite que vários aplicativos abram soquetes para esse protocolo específico e o driver do dispositivo pode acompanhar qual soquete recebe pacotes e erros específicos. Para obter informações sobre como escrever um provedor de protocolo de rede, consulte as seções sobre WSK e TDI no WDK (Windows Driver Kit).

Os aplicativos também precisam estar cientes do impacto que as configurações de firewall podem ter ao enviar e receber pacotes usando soquetes brutos.