Provided by:
manpages-pt_20040726-4_all 
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).
FORMATO DO ENDEREÇO
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)