Provided by:
manpages-es_1.55-7_all 
NOMBRE
raw, SOCK_RAW - Conectores directos (raw) IPv4 de Linux
SINOPSIS
#include <sys/socket.h>
#include <netinet/in.h>
raw_socket = socket(PF_INET, SOCK_RAW, int protocol);
DESCRIPCIÓN
Los conectores directos permiten implementar nuevos protocolos IPv4 en
el espacio de usuario. Un conector directo recibe o envía el datagrama
crudo sin incluir cabeceras del nivel de enlace.
La capa IPv4 genera una cabecera IP cuando se envía un paquete, a menos
que se active la opción IP_HDRINCL en el conector. Cuando se activa,
el paquete debe contener una cabecera IP. En la recepción, la cabecera
IP siempre está incluida en el paquete.
Sólo los procesos con un identificador de usuario efectivo de 0 o la
capacidad CAP_NET_RAW pueden abrir conectores directos.
Todos los paquetes o errores cuyo protocolo coinciden con el número
protocol especificado por el conector directo, se pasan a este
conector. Para una lista de los protocolos permitidos vea los números
asignados en RFC1700 y getprotobyname(3).
Un protocolo IPPROTO_RAW implica que IP_HDRINCL está activa y preparada
para enviar cualquier protocolo IP especificado en la cabecera pasada.
Recibir todos los protocolos IP via IPPROTO_RAW no es posible con
conectores directos.
+-------------------------------------------------------------+
|Campos de cabecera IP modificados en el envío por IP_HDRINCL |
+-----------------------------+-------------------------------+
|Suma de comprobación IP | Siempre se rellena. |
+-----------------------------+-------------------------------+
|Dirección fuente | Se rellena cuando es cero. |
+-----------------------------+-------------------------------+
|Identificador del paquete | Se rellena cuando es cero. |
+-----------------------------+-------------------------------+
|Longitud total | Siempre se rellena. |
+-----------------------------+-------------------------------+
Si se especifica IP_HDRINCL y la cabecera IP tiene una dirección de
destino distinta de cero, la dirección de destino del conector se
utiliza para enrutar el paquete. Cuando se especifica MSG_DONTROUTE,
la dirección de destino debe referirse a una interfaz local, de lo
contrario, se realiza una búsqueda en la tabla de enrutamiento, aunque
se ignoran las rutas que se dirigen a enrutadores.
Si no se activa IP_HDRINCL, se pueden configurar las opciones de la
cabecera IP de los conectores directos con setsockopt(2). Vea ip(7)
para más información.
En Linux 2.2 todas las opciones y campos de las cabeceras IP se pueden
configurar usando las opciones de los conectores IP. Esto significa que
los conectores directos son usualmente necesarios sólo para protocolos
nuevos o protocolos que no tienen una interfaz de usuario (como ICMP).
Cuando se recibe un paquete, se pasa a cualquier conector directo que
haya sido asociado a su protocolo antes de que sea pasado al manejador
de cualquier otro protocolo (por ejemplo, los módulos de protocolo del
núcleo).
FORMATO DE LAS DIRECCIONES
Los conectores directos usan la estructura de direcciones estándar
sockaddr_in definida en ip(7). El campo sin_port se podría usar para
especificar el número de protocolo IP, pero en Linux 2.2 se ignora al
enviar y siempre debería valer 0 (vea FALLOS). Para los paquetes de
entrada, a sin_port se le asigna el protocolo del paquete. Vea el
fichero cabecera <netinet/in.h> para protocolos IP válidos.
OPCIONES DE LOS CONECTORES
Las opciones de los conectores directos se pueden configurar con
setsockopt(2) y leer con getsockopt(2), pasando la opción de familia
SOL_RAW.
ICMP_FILTER
Activa un filtro especial para los conectores directos asociados
al protocolo IPPROTO_ICMP. El valor tiene un bit activo para
cada tipo de mensaje ICMP que debe filtrarse. Por defecto, no se
filtra ningún mensaje ICMP.
Además, se soportan todas las opciones SOL_IP de ip(7) válidas.
OBSERVACIONES
Los conectores directos fragmentan un paquete cuando su longitud total
excede la MTU de la interfaz (no obstante, vea FALLOS). Una alternativa
más rápida y favorable para la red es implementar el descubrimiento del
MTU de la ruta como se describe en la sección IP_PMTU_DISCOVER de
ip(7).
Se puede asociar un conector directo a una dirección local específica
usando la llamada bind(2). Si no está asociado, se reciben todos los
paquetes con el protocolo IP especificado. Además, se puede asociar un
conector directo a un dispositivo de red específico usando
SO_BINDTODEVICE. Vea socket(7).
Un conector IPPROTO_RAW es sólo de envío. Si verdaderamente quiere
recibir todos los paquetes IP, use un conector packet(7) con el
protocolo ETH_P_IP. Dése cuenta que, a diferencia de los conectores
directos, los conectores de paquete no reensamblan fragmentos IP.
Si quiere recibir todos los paquetes ICMP para un conector de
datagramas, normalmente es mejor usar IP_RECVERR en ese conector
particular. Vea ip(7).
Los conectores directos pueden interceptar todos los protocolos IP de
Linux, incluso protocolos como ICMP o TCP que poseen un módulo de
protocolo dentro del núcleo. En este caso, los paquetes se pasan tanto
al módulo del núcleo como al conector (o conectores) directo. No se
debería confiar en esto en programas transportables ya que muchas otras
implementaciones de conectores BSD tienen limitaciones aquí.
Linux nunca cambia las cabeceras pasadas por el usuario (salvo para
rellenar algunos campos de valor 0 como se ha descrito en IP_HDRINCL).
Esto es diferente de muchas otras implementaciones de conectores
directos.
Generalmente, los conectores directos son poco transportables y
deberían evitarse en programas destinados a ser transportables.
En el envío a través de conectores directos se debería tomar el
protocolo IP de sin_port. Esta capacidad se perdió en Linux 2.2. La
forma de solucionar esto es usar IP_HDRINCL.
MANEJO DE ERRORES
Sólo se pasan al usuario los errores generados por la red cuando el
conector está conectado o está activa la opción IP_RECVERR. Para
conectores conectados, sólo se pasan EMSGSIZE y EPROTO por
compatibilidad. Con IP_RECVERR todos los errores de red se guardan en
la cola de errores.
ERRORES
EMSGSIZE
Paquete demasiado grande. O bien el descubrimiento del MTU de la
ruta está activo (la opción IP_PMTU_DISCOVER de los conectores)
o bien el tamaño del paquete excede el máximo tamaño de 64KB
permitido por IPv4.
EACCES El usuario ha intentado enviar a una dirección de difusión sin
tener activa la opción de difusión en el conector.
EPROTO Ha llegado un error ICMP informando de un problema de
parámetros.
EFAULT Se ha pasado una dirección de memoria inválida.
EOPNOTSUPP
Se ha pasado a la llamada socket una opción inválida (como
MSG_OOB).
EINVAL Argumento inválido.
EPERM El usuario no tiene permiso para abrir conectores directos. Sólo
los procesos con un identificador de usuario efectivo de 0 o el
atributo CAP_NET_RAW pueden hacerlo.
VERSIONES
IP_RECVERR y ICMP_FILTER son nuevos en la versión 2.2 de Linux. Ambos
son extensiones de Linux y no deberían usarse en programas
transportables.
La versión 2.0 de Linux activaba cierta compatibilidad fallo a fallo
con BSD en el código de los conectores directos cuando se activaba la
opción SO_BSDCOMPAT. Ésto se ha eliminado en la versión 2.2.
FALLOS
No se han descrito las extensiones de proxy transparente.
Cuando se activa la opción IP_HDRINCL, los datagramas no se fragmentan
y están limitados por la MTU de la interfaz. Ésta es una limitación de
la versión 2.2 de Linux.
La posibilidad de especificar el protocolo IP en sin_port durante el
envío desapareció en Linux 2.2. Siempre se usa el protocolo al que se
enlazó el conector o el que se especificó en la llamada inicial a
socket(2).
AUTOR
Esta página de manual fue escrita por Andi Kleen.
VÉASE TAMBIÉN
ip(7), socket(7), recvmsg(2), sendmsg(2)
RFC1191 para el descubrimiento del MTU de la ruta.
RFC791 y el fichero cabecera <linux/ip.h> para el protocolo IP.