NOME¶
raw, SOCK_RAW - Sockets IPv4 raw
SINOPSE¶
#include <sys/socket.h>
 
#include <netinet/in.h>
 
raw_socket = socket(PF_INET, SOCK_RAW, int protocol);
 
DESCRIÇÃO¶
Sockets raw (não processados) permitem a implementação de novos
  protocolos sob o IPv4. Um socket raw recebe ou envia o datagrama bruto, sem
  incluir cabeçalhos de link.
 
A camada IPv4 gera um cabeçalho IP ao enviar um pacote a menos que se ative
  a opção 
IP_HDRINCL do socket. Quando ela está
  habilitada, o pacote deve conter um cabeçalho IP. Um pacote IP que seja
  recebido terá sempre o cabeçalho IP.
 
Apenas processos com user id efetivo de 0 ou com capacidade 
CAP_NET_RAW
  podem abrir sockets raw.
 
Todos os pacotes ou erros relacionados ao número de 
protocolo
  especificado para o socket raw são passados para este socket. Para uma
  lista dos protocolos permitidos consulte o RFC 1700 e
  
getprotobyname(3).
 
Um protocolo 
IPPROTO_RAW implica que o 
IP_HDRINCL está
  habilitado e recebe todos os protocolos IP. transmitir não é
  permitido.
 
  
    
    
  
  
    | Cabeçalhos IP são midificados quando enviados pelo
      IP_HDRINCL | 
     | 
  
  
    | IP Checksum | 
    Sempre preenchido. | 
  
  
    | Source Address | 
    Preenchido quando zero. | 
  
  
    | Packet Id | 
    Preenchido quando zero. | 
  
  
    | Total Length | 
    Sempre preenchido. | 
  
 
Se for especificado 
IP_HDRINCL e o cabeçalho IP tiver um
  endereço de destino diferente de zero, este endereço é usado
  para rotear o pacote. Quando for especificado ,B MSG_DONTROUTE o endereço
  de destino deve apontar para uma interface local, caso contrário é
  feita uma consulta à tabela de roteamento, mas as rotas com gateways
  são ignoradas.
 
Se não for especificado 
IP_HDRINCL as opções do
  cabeçalho IP podem ser ajustadas nos socker raw com 
setsockopt(2);
  Ver 
ip(7) para mais informações.
 
No linux 2.2, todos as opções e campos de cabeçalho IP podem ser
  configuradas usando as opções para sockets IP. Isto significa que os
  sockets raw normalmente só são necessários para protocolos
  novos ou protocolos sem interface de usuário como o ICMP.
 
Um pacote recebido é passado para quaisquer sockets raw que tenham sido
  atrelados ao seu protocolo antes de ser passado para outros handlers deste
  protocolo (ex. módulos de protocolo do kernel).
 
Sockets raw usam a estrutura de endereço padrão 
sockaddr_in
  definida em 
ip(7).
 
O campo 
sin_port pode ser usado para especificar o número do
  protocolo IP, mas é ignorado pelo linux 2.2 e deve ser sempre ajustado
  para zero. (ver PROBLEMAS) O campo 
sin_port contém o número
  do protocolo de pacotes recebidos. Ver a lista de protocolos IP válidos
  em 
<netinet/in.h>
 
OPÇÕES DE SOCKET¶
As opções de sockets raw podem ser ajustadas com 
setsockopt(2)
  ou lidas com 
getsockopt(2) passando-se o flag designador de
  família 
SOL_RAW
 
  - ICMP_FILTER
 
  - Habilita um filtro especial para sockets raw ligados ao
      protocolo IPPROTO_ICMP Cada bit deste campo designa um tipo de
      mensagem ICMP a ser excluída. O default é não filtrar
      nenhuma mensagem ICMP.
    
 
   
Além disso, todas as opções de socket 
SOL_IP ip(7)
  válidas para sockets de datagrama são suportadas.
 
NOTAS¶
Sockets raw fragmentam um pacote cujo tamanho total exceda o MTU da interface
  (veja, no entanto, a seção PROBLEMAS). Uma alternativa mais
  rápida e em sintonia com a rede é implementar a pesquisa do MTU do
  caminho na seção 
IP_PMTU_DISCOVER do 
ip(7).
 
Um socket raw pode ser ligado a um endereço local específico usando a
  chamada 
bind(2) Caso contrário, todos os pacotes com o protocolo
  IP especificado são recebidos. Além disso, um socket RAW pode ser
  associado a um dispositivo de rede específico usando
  
SO_BINDTODEVICE; Ver 
socket(7).
 
Um socket 
IPPROTO_RAW é transmissor apenas. Se você realmente
  quiser receber todos os pacotes IP use um socket 
packet(7) com o
  protocolo 
ETH_P_IP
 
Se você quiser receber todos os pacotes ICMP de um socket de datagrama,
  é muitas vezes melhor usar 
IP_RECVERR neste socket. Ver
  
ip(7).
 
Os sockets raw podem ler todos os protocolos IP no linux, mesmo protocolos como
  ICMP ou TCP, que têm um módulo de protocolo no kernel. Neste caso,
  os pacotes são passados tanto para o módulo do kernel e para o(s)
  socket(s) raw. Não se deve contar com isso em programas portáveis,
  porque muitas implementações de sockets em BSD têm
  limitações aqui.
 
O linux nunca modifica cabeçalhos enviados pelo usuário, exceto para
  preencher alguns campos zerados conforme descrito em 
IP_HDRINCL. Muitas
  implementações de sockets raw não se comportam assim.
 
Os sockets RAW geralmente são pouco portáveis, devendo ser evitados em
  programas que se deseje portar.
 
Os sockets raw enviados lêem o protocolo de 
sin_port; Esta
  capacidade foi perdida no linux 2.2. A solução é usar
  
IP_HDRINCL.
 
MANUSEIO DE ERROS¶
Erros originários da rede só são passados para o usuário
  quando o socket está conectado ou o flag 
IP_RECVERR está
  habilitado. Sockets conectados recebem apenas 
EMSGSIZE e 
EPROTO
  para manter a compatibilidade. Com 
IP_RECVERR todos os erros de rede
  são enviados para a fila de erros.
ERROS¶
  - EMSGSIZE
 
  - O pacote é grande demais. Ou a pesquisa de MTU do
      caminho está habilitada (com o sinalizador IP_PMTU_DISCOVER )
      ou o tamanho do pacote excede o máximo de 64KB permitido pelo
    IPv4.
 
  - EACCES
 
  - O usuário tentou transmitir para um endereço de
      broadcast sem que o socket tivesse um flag de broadcast.
 
  - EPROTO
 
  - Um mensagem ICMP chegou reportando um erro de
      parâmetros.
 
  - EFAULT
 
  - Foi fornecido um endereço de memória
      inválido.
 
  - EOPNOTSUPP
 
  - Um flag inválido foi passado para uma chamada de
      socket (como MSG_OOB).
 
  - EINVAL
 
  - Argumetno inválido.
 
  - EPERM
 
  - O usuário não tem permissão para abrir
      sockets raw. Apenas processos com user if efetivo de 0 ou o atributo
      CAP_NET_RAW podem fazer isto.
    
 
   
VERSÕES¶
IP_RECVERR e 
ICMP_FILTER surgiram no linux 2.2. São
  extensões linux e não devem ser usadas em programas portáveis.
 
O linux 2.0 criou alguma compatibilidade 'bug a bug' com o BSD no código
  dos sockets raw, que é habilitada com o flag SO_BSDCOMPAT. Isto foi
  retirado do 2.2.
 
PROBLEMAS¶
Extensões transparentes de proxy não estão incluídas.
 
Quando a opção 
IP_HDRINCL está habilitada os datagramas
  não serão fragmentados, e ficam limitados à interface MTU. Isto
  é uma limitação do linux 2.2.
 
O ajuste do protocolo IP para envio no campo 
sin_port foi perdido no
  linux 2.2. O protocolo que foi atrelado a este socket ou que foi especificado
  na chamada inicial à 
socket(2) é usado sempre.
 
AUTORES¶
Esta página foi escrita por Andi Kleen.
 
VEJA TAMBÉM¶
ip(7), 
socket(7), 
recvmsg(2), 
sendmsg(2).
RFC1191 para pesquisa do MTU do caminho.
 
RFC791 e o arquivo 
<linux/ip.h> para o protocolo IP.
TRADUZIDO POR LDP-BR em 21/08/2000.¶
Paulo César Mendes <drps@ism.com.br> (tradução) André
  L. Fassone Canova <lonelywolf@blv.com.br> (revisão)