ip - Implementación del protocolo IPv4 en Linux
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* contiene a los anteriores */
tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
raw_socket = socket(AF_INET, SOCK_RAW, protocolo);
Linux implementa el Protocolo de Internet (Internet Protocol, IP),
version 4, descrito en RFC 791 y RFC 1122. ip contiene
una implementación de multidestino del Nivel 2 según el
RFC 1112. También contiene un enrutador IP incluyendo un
filtro de paquetes.
La interfaz del programador es compatible con la de los conectores
BSD. Consulte socket(7) para más información sobre
conectores.
Los conectores IP se generan mediante socket(2):
socket(AF_INET, socket_type, protocolo);
Los tipos de conector válidos serían
SOCK_STREAM para un conector de flujo, SOCK_DGRAM para abrir
un conector de datagrama y SOCK_RAW para abrir un conector
raw(7) que accede al protocolo IP directamente.
protocol representa el protocolo IP en el encabezado IP que
se envía o recibe. Valores validos para protocol
serían:
- •
- 0 y IPPROTO_TCP para conectores de flujo tcp(7);
- •
- 0 y IPPROTO_UDP para conectores de datagrama udp(7);
- •
- IPPROTO_SCTP para conectores de flujo sctp(7); y
- •
- IPPROTO_UDPLITE para conectores de datagrama
udplite(7).
Para SOCK_RAW puede definir un protocolo IP válido
según el IANA tal como se define en el RFC 1700.
Cuando un proceso quiere recibir nuevos paquetes de entrada o
conexiones, debe enlazar un conector a una dirección de la interfaz
local usando bind(2). Sólo se puede ligar un conector IP a un
par (dirección, puerto) dado. Cuando en la llamada a bind se
especifica INADDR_ANY, el conector será ligado a todas
las interfaces locales. Cuando se llama a connect(2) con un conector
no enlazado, el conector será automáticamente ligado a un
puerto aleatorio libre cuya dirección local sea
INADDR_ANY.
Una dirección local de conector TCP que haya sido enlazada,
no estará disponible durante un cierto tiempo después de que
se cierre, a menos que se haya activado la opción
SO_REUSEADDR. Se debe tener cuidado al usar esta opción ya que
hace que TCP sea menos fiable.
Una dirección de conector IP se define como una
combinación de una dirección de interfaz IP y un número
de puerto 16-bit. El protocolo IP básico no proporciona
números de puerto. Estos son implementados por protocolos de un nivel
más alto como udp(7) y tcp(7). En los conectores
directos, a sin_port se le asigna el protocolo IP.
struct sockaddr_in {
sa_family_t sin_family; /* familia de direcciones: AF_INET */
in_port_t sin_port; /* puerto en el orden de bytes de la red */
struct in_addr sin_addr; /* dirección de internet */
};
/* Irección de internet */
struct in_addr {
uint32_t s_addr; /* Dirección de red en bytes */
};
A sin_family siempre se le asigna el valor AF_INET.
Este valor es necesario. En Linux 2.2, la mayoría de las funciones de
red devuelven EINVAL cuando se ha omitido este valor. sin_port
contiene el puerto con los bytes en orden de red. Los números de
puerto por debajo de 1024 se llaman puertos privilegiados (algunas
veces puertos reservados). Sólo los procesos privilegiados o
con la capacidad CAP_NET_BIND_SERVICE pueden realizar enlaces
mediante bind(2) a estos conectores. Observer que el protocolo IPv4
puro no posee como tal el concepto de puerto. Estos son implementados por
protocolos de capas superiores como tcp(7) y udp(7).
sin_addr es la dirección IP del equipo. El miembro
s_addr de struct in_addr contiene la dirección de la
interfaz del equipo con los bytes en orden de red. Sólo se
debería acceder a in_addr usando las funciones de biblioteca
inet_aton(3), inet_addr(3) y inet_makeaddr(3), o
directamente mediante el mecanismo de resolución de nombres (vea
gethostbyname(3)).
Las direcciones IPv4 se dividen en direcciones unidestino, de
difusión y multidestino. Las direcciones unidestino especifican una
única interfaz de un anfitrión, las direcciones de
difusión especifican todos los anfitriones de una red y las
direcciones multidestino identifican a todos los anfitriones de un grupo
multidestino. Sólo se pueden enviar datagramas a o recibir datagramas
de direcciones de difusión cuando está activa la opción
de conector SO_BROADCAST. En la implementación actual, los
conectores orientados a conexión sólo pueden usar direcciones
unidestino.
Dese cuenta que la dirección y el puerto se almacenan
siempre en orden de red. En particular, esto significa que necesita llamar a
htons(3) con el número que se ha asignado al puerto. Todas las
funciones de manipulación de dirección/puerto en la biblioteca
estándar trabajan en orden de red.
Hay varias direcciones especiales:
- INADDR_LOOPBACK
(127.0.0.1)
- siempre hace referencia al equipo local a través del dispositivo
loopback;
- INADDR_ANY
(0.0.0.0)
- representa dirección para vinculación de sockets;
- INADDR_BROADCAST
(255.255.255.255)
- Por razones históricas, tiene el mismo efecto en bind(2) que
INADDR_ANY. Un paquete dirigido a INADDR_BROADCAST a
través de un socket con SO_BROADCAST configurado se
transmitirá a todos los equipos en el segmento de la red local,
siempre que el enlace sea apto para esta transmisión.
- Dirección con el
número más alto
- Dirección con
el número más bajo
- En cualquier subred IP conectada localmente no punto a punto con un tipo
de enlace que admita transmisiones, la dirección con el
número más alto (por ejemplo, la dirección .255 en
una subred con máscara de red 255.255.255.0) se designará
como dirección de transmisión. No es práctica
asignarla a una interfaz individual y solo se podrá direccionar con
un socket en el que se haya configurado la opción
SO_BROADCAST. Históricamente, los estándares de
Internet también han reservado la dirección con el
número más bajo (por ejemplo, la dirección .0 en una
subred con máscara de red 255.255.255.0) para transmisión,
aunque suele considerarse 'obsoleta' para este propósito. Algunas
fuentes también se refieren a esto como 'dirección de red'.
A partir de la versión 5.14 de Linux , se trata como una
dirección de unidifusión ordinaria y se puede asignar a una
interfaz.
Los estándares de Internet tradicionalmente también
han reservado varias direcciones para usos particulares, aunque Linux ya no
las trata de manera especial.
- [0.0.0.1, 0.255.255.255]
- [240.0.0.0, 255.255.255.254]
- Las direcciones en estos intervalos (0/8 y 240/4) están reservadas
globalmente. Desde Linux 5.3 y Linux 2.6.25, respectivamente, las
direcciones 0/8 y 240/4, distintas de INADDR_ANY y
INADDR_BROADCAST, se tratan como direcciones de unidifusión
ordinarias. Estas direcciones se consideraron siempre reservadas y,
tradicionalmente, los equipos no pueden interoperar con ellas.
- [127.0.0.1, 127.255.255.254]
- Las direcciones en este intervalo (127/8) se tratan como direcciones de
loopback similares a la dirección loopback local estandarizada
INADDR_LOOPBACK (127.0.0.1);
- [224.0.0.0, 239.255.255.255]
- Las direcciones en este rango (224/4) están dedicadas al uso de
multidifusión.
IP soporta algunas opciones de conector específicas del
protocolo que se pueden configurar con setsockopt(2) y leer con
getsockopt(2). El nivel de opciones de conector para IP es
IPPROTO_IP. Una opción entera booleana es cero cuando es falsa
y cualquier otra cosa cuando es cierta.
Si se define una opción no válida,
getsockopt(2) y setsockopt(2) emiten el error
ENOPROTOOPT.
- IP_ADD_MEMBERSHIP
(desde Linux 1.2)
- Unirse a un grupo multidestino. El argumento es una estructura
ip_mreqn.
-
struct ip_mreqn {
struct in_addr imr_multiaddr; /* Dirección IP del grupo
multidestino */
struct in_addr imr_address; /* Dirección IP de la
interfaz local */
int imr_ifindex; /* Índice de la interfaz */
};
- imr_multiaddr contiene la dirección del grupo multidestino
al que la aplicación se quiere unir o quiere dejar
(setsockopt(2) falla con un error EINVAL). Debe ser una
dirección multidestino válida. imr_address es la
dirección de la interfaz local con la que el sistema debe unirse al
grupo multidestino. Si es igual a INADDR_ANY el sistema elige una
interfaz adecuada. imr_ifindex es el índice de la interfaz
que debe unirse a o dejar el grupo imr_multiaddr, o 0 para indicar
cualquier interfaz.
- La estructura ip_mreqn está disponible desde la
versión 2.2 de Linux. Para preservar la compatibilidad, la antigua
estructura ip_mreq (existente desde la versión 1.2) sigue
teniendo soporte. Sólo difiere de ip_mreqn en que no incluye
el campo imr_ifindex. El núcleo identifica qué
estructura se está empleando en base al tamaño de
optlen.
- IP_ADD_MEMBERSHIP sólo es válido para
setsockopt(2).
- IP_ADD_SOURCE_MEMBERSHIP
(desde Linux 2.4.22 hasta Linux 2.5.68)
- Se une a un grupo multidestino permitiendo recibir datos de una
única fuente. El argumento es una estructura
ip_mreq_source.
-
struct ip_mreq_source {
struct in_addr imr_multiaddr; /* Dirección IP del
grupo de multidifusión
struct in_addr imr_interface; /* Dirección IP de la
interfaz local */
struct in_addr imr_sourceaddr; /* Dirección IP
multidifusión del origen */
};
- La estructura ip_mreq_source es similar a ip_mreqn descrita
en IP_ADD_MEMBERSHIP. El campo imr_multiaddr contiene la
dirección del grupo de multidifusión al que la
aplicación se desea unir o abandonar. El campo imr_interface
es la dirección de la interfaz local con la que el sistema debe
unirse al grupo de multidifusión. Finalmente, el campo
imr_sourceaddr contiene la dirección de la fuente de la que
la aplicación desea recibir datos.
- Es posible emplear esta opción varias veces para recibir datos de
varias fuentes.
- IP_BIND_ADDRESS_NO_PORT
(desde Linux 4.2)
- Indica al núcleo que no se reserve brevemente un puerto al usar
bind(2) con el cero como número de puerto. Dicho puerto se
seleccionará posteriormente durante connect(2) de forma que
se puede compartir un puerto origen mientras la tupla de 4 sea
única.
- IP_BLOCK_SOURCE
(desde Linux 2.4.22 / 2.5.68)
- Dejar de recibir datos de multidifusión de una fuente
específica en un grupo determinado. Esto es válido solo
después de que la aplicación se haya suscrito al grupo de
multidifusión utilizando IP_ADD_MEMBERSHIP o
IP_ADD_SOURCE_MEMBERSHIP.
- El argumento es una estructura ip_mreq_source tal como se describe
en IP_ADD_MEMBERSHIP.
- IP_DROP_MEMBERSHIP
(desde Linux 1.2)
- Dejar un grupo multidestino. El argumento es una estructura
ip_mreqn o ip_mreq similar a la de
IP_ADD_MEMBERSHIP.
- IP_DROP_SOURCE_MEMBERSHIP
(desde Linux 2.4.22 / 2.5.68)
- Abandona un grupo de fuente específica—es decir, dejar de
recibir datos de un grupo de multidifusión determinado que provenga
de una fuente concreta. Si la aplicación se ha suscrito a varias
fuentes dentro del mismo grupo, se seguirán entregando datos de las
fuentes restantes. Para dejar de recibir datos de todas las fuentes a la
vez, use IP_DROP_MEMBERSHIP.
- El argumento es una estructura ip_mreq_source tal como se describe
en IP_ADD_MEMBERSHIP.
- IP_FREEBIND
(desde Linux 2.4)
- Si está habilitada, esta opción booleana permite vincularse
a una dirección IP no local o que (todavía) no existe. Esto
permite estar a la escucha en un socket, sin necesidad de que la interfaz
de red subyacente o la dirección IP dinámica especificada
estén activas en el momento en que la aplicación intenta
conectarse a ella. Esta opción es la equivalente por socket de la
interfaz ip_nonlocal_bind /proc que se describe a
continuación.
- IP_HDRINCL
(desde Linux 2.0)
- Cuando está activa, el usuario proporciona una cabecera IP delante
de los datos de usuario. Sólo válida para conectores
SOCK_RAW; vea raw(7) para más información.
Cuando esta opción está activa los valores configurados
mediante IP_OPTIONS, IP_TTL y IP_TOS se ignoran.
- IP_LOCAL_PORT_RANGE
(desde Linux 6.31)
- Establezca u obtenga el rango de puertos locales predeterminado por
socket. Esta opción se puede utilizar para limitar el intervalo de
puertos locales globales, definido por la interfaz
ip_local_port_range /proc descrita a continuación,
para un socket determinado.
- La opción toma un valor uint32_t con los 16 bits superiores
establecidos en el límite superior del intervalo y los 16 bits
inferiores establecidos en el límite inferior. Los límites
de intervalo son inclusivos. Los valores de 16 bits deben estar en orden
de bytes del equipo.
- El límite inferior tiene que ser menor que el límite
superior cuando ambos límites son distintos de cero. De lo
contrario, la configuración de la opción falla con
EINVAL.
- Si alguno de los límites está fuera del intervalo de puertos
locales globales o es cero, no tendrá efecto.
- Para resetear la configuración, defina los límites superior
e inferior a cero.
- IP_MSFILTER
(desde Linux 2.4.22 / 2.5.68)
- Esta opción proporciona acceso a la API de filtrado avanzado de
estado. El argumento es una estructura ip_msfilter.
-
struct ip_msfilter {
struct in_addr imsf_multiaddr; /* Dirección IP del grupo
multidestino */
struct in_addr imsf_interface; /* Dirección IP de la interfaz
local */
uint32_t imsf_fmode; /* Modo de filtrado */
uint32_t imsf_numsrc; /* Cantidad de fuentes en el
siguiente vector */
struct in_addr imsf_slist[1]; /* Vector de direcciones de
fuente */
};
- Hay dos macros, MCAST_INCLUDE y MCAST_EXCLUDE, que se pueden
utilizar para especificar el modo de filtrado. Además, la macro
IP_MSFILTER_SIZE(n) existe para determinar cuánta memoria se
necesita para almacenar la estructura ip_msfilter con n
fuentes en la lista de fuentes.
- Para completa descripción del filtrado de fuentes de
multidifusión, consulte el RFC 3376.
- IP_MTU (desde Linux
2.2)
- Obtiene la MTU de la ruta conocida actualmente para el conector actual.
Devuelve un entero.
- IP_MTU sólo es válido para getsockopt(2) y
sólo puede emplearse cuando el conector se ha conectado.
- IP_MTU_DISCOVER
(desde Linux 2.2)
- Establece o recibe la configuración del descubrimiento de la MTU de
la rutapara el conector. Cuando se activa, Linux realizará el
descubrimiento de la MTU de la ruta en este conector tal y como se define
en RFC 1191 para los conectores SOCK_STREAM. Para los
conectores SOCK_STREAM, IP_PMTUDISC_DO fuerza la
opción de no fragmentar en todos los datagramas de salida. Es
responsabilidad del usuario enpaquetar los datos en fragmentos de
tamaño MTU y realizar la retransmisión si es necesario. El
núcleo rechazará aquellos paquetes que sean más
grandes que la MTU de ruta conocida si esta opción está
activa (con EMSGSIZE). IP_PMTUDISC_WANT fragmentará
un datagrama si necesario, en base al MTU, o activará la
opción de no fragmentar.
- El valor predeterminado en todo el sistema se puede alternar entre
IP_PMTUDISC_WANT y IP_PMTUDISC_DONT escribiendo
(respectivamente, cero y distintos de cero) en el archivo
/proc/sys/net/ipv4/ip_no_pmtu_disc.
| Opciones del descubrimiento del MTU de
la ruta |
Significado |
| IP_PMTUDISC_WANT |
Usar configuraciones por ruta. |
| IP_PMTUDISC_DONT |
Nunca realizar el descubrimiento de la MTU de la ruta. |
| IP_PMTUDISC_DO |
Realizar siempre el descubrimiento de la MTU de la ruta. |
| IP_PMTUDISC_PROBE |
Define DF pero ignora el MTU de la ruta. |
- Cuando se activa el descubrimiento de la MTU de la ruta, el núcleo
automáticamente memoriza la MTU de la ruta por anfitrión de
destino. Cuando se está conectado a un extremo específico
mediante connect(2), se puede obtener convenientemente la MTU de la
ruta conocida actualmente usando la opción de conector
IP_MTU (por ejemplo, después de que haya ocurrido un error
EMSGSIZE). La MTU puede cambiar con el tiempo. Para conectores no
orientados a conexión con muchos destinos, también se puede
acceder a la nueva MTU usando la cola de errores (vea IP_RECVERR).
Se encolará un nuevo error para cada actualización que
llegue de la MTU.
- Mientras se está realizando el descubrimiento de la MTU, se pueden
perder paquetes iniciales de los conectores de datagramas. Las
aplicaciones que usan UDP deben se conscientes de esto y no tenerlo en
cuenta para sus estrategias de retransmisión de paquetes.
- Para iniciar el proceso de descubrimiento de la MTU de la ruta en
conectores no orientados a conexión, es posible comenzar con un
tamaño grande de datagramas (con longitudes de bytes de hasta 64KB
en las cabeceras) y dejar que se reduzca mediante actualizaciones de la
MTU de la ruta.
- Para obtener una estimación inicial de la MTU de la ruta, conecte
un conector de datagramas a una dirección de destino usando
connect(2) y obtenga la MTU llamando a getsockopt(2) con la
opción IP_MTU.
- Es posible implementar el sondeo MTU RFC 4821 con sockets
SOCK_DGRAM o SOCK_RAW estableciendo un valor de
IP_PMTUDISC_PROBE (disponible desde Linux 2.6.22). Esto
también es particularmente útil para herramientas de
diagnóstico como tracepath(8) que envían
deliberadamente paquetes de sondeo más grandes que la MTU de ruta
observada.
- IP_MULTICAST_ALL
(desde Linux 2.6.31)
- Esta opción se puede utilizar para modificar la normativa de
entrega de mensajes de multidifusión. El argumento es un
número entero booleano (el valor predeterminado es 1). Si se
establece en 1, el socket recibirá mensajes de todos los grupos que
se hayan unido globalmente en todo el sistema, sino entregará
mensajes solo de los grupos a los que se haya unido explícitamente
(por ejemplo, mediante la opción IP_ADD_MEMBERSHIP) en este
socket en particular.
- IP_MULTICAST_IF
(desde Linux 1.2)
- Configura el dispositivo local para un socket de multidifusión. El
argumento para setsockopt(2) es una estructura ip_mreqn o
(desde Linux 3.5) ip_mreq similar a IP_ADD_MEMBERSHIP, o una
estructura in_addr. El núcleo determinará qué
estructura se pasa según el tamaño pasado en optlen.)
Para getsockopt(2), el argumento es una estructura
in_addr.
- IP_MULTICAST_LOOP
(desde Linux 1.2)
- Establece o lee un argumento entero booleano que indica si los paquetes
multidestino enviados deben o no ser devueltos a los conectores
locales.
- IP_MULTICAST_TTL
(desde Linux 1.2)
- Establece o lee el valor "tiempo de vida" (time-to-live, TTL) de
los paquetes multidestino de salida para este conector. Es muy importante
para los paquetes multidestino utilizar el TTL más pequeño
posible. El valor por defecto es 1 lo que significa que los paquetes
multidestino no abandonarán la red local a menos que el programa de
usuario lo solicite explícitamente. El argumento es un entero.
- IP_NODEFRAG
(desde Linux 2.6.36)
- si está activo (el argumento es distinto de cero), el reensamblado
de los paquetes salientes está desactivado en la capa de netfilter.
El argumento es un número entero.
- Esta opción sólo es válida para los conectores
SOCK_RAW
- IP_OPTIONS
(desde Linux 2.0)
- Establece u obtiene las opciones IP a enviar con cada paquete desde este
conector. Los argumentos son punteros a un buffer de memoria que contiene
las opciones y la longitud de las opciones. La llamada
setsockopt(2) establece las opciones IP asociadas a un conector. El
tamaño máximo de opción para IPv4 es de 40 bytes. Vea
RFC 791 para las opciones permitidas. Cuando el paquete inicial de
petición de conexión para un conector SOCK_STREAM
contiene opciones IP, las opciones IP se configurarán
automáticamente al valor de las opciónes del paquete inicial
con las cabeceras de enrutamiento invertidas. No se permite que los
paquetes de entrada cambien las opciones después de que la
conexión se haya establecido. El procesamiento de todas las
opciones de enrutamiento de la fuente de entrada está desactivado
por defecto y se puede activar mediante la interfaz en /proc
accept_source_route. Otras opciones, como las marcas de tiempo,
todavía se siguen manejando. Para los conectores de datagramas, las
opciones IP sólo pueden ser configuradas por el usuario local.
Llamar a getsockopt(2) con IP_OPTIONS coloca en el buffer
proporcionado las opciones IP actuales usadas para enviar.
- IP_PASSSEC
(desde Linux 2.6.17)
- Si se configura IPSEC o NetLabel con etiqueta en los equipos de
envío y recepción, esta opción permite recibir el
contexto de seguridad del socket del mismo nivel en un mensaje auxiliar de
tipo SCM_SECURITY recuperado mediante recvmsg(2). Esta
opción sólo se admite para sockets UDP; para sockets TCP o
SCTP, consulte la descripción de la opción SO_PEERSEC
a continuación.
- El valor dado como argumento para setsockopt(2) y devuelto como
resultado de getsockopt(2) es un indicador booleano entero.
- El contexto de seguridad devuelto en el mensaje auxiliar
SCM_SECURITY tiene el mismo formato que el que se describe a
continuación en la opción SO_PEERSEC.
- Obervación: seguramente haya sido un error la reutilización
del tipo de mensaje SCM_SECURITY para la opción de socket
IP_PASSSEC. Otros mensajes de control de IP usan su propio esquema
de numeración en el espacio de nombres de IP y a menudo usan el
valor de la opción de socket como tipo de mensaje. Actualmente no
hay ningún conflicto ya que la opción IP con el mismo valor
que SCM_SECURITY es IP_HDRINCL y nunca se usa para un tipo
de mensaje de control.
- IP_PKTINFO
(desde Linux 2.2)
- Pasa un mensaje auxiliar IP_PKTINFO que contiene una estructura
pktinfo que proporciona alguna información sobre los
paquetes de entrada. Esto sólo funciona para conectores orientados
a datagramas. El argumento es un indicador que le dice al conector si
debería pasar el mensaje IP_PKTINFO. El mensaje en sí
mismo sólo puede ser enviado/obtenido como un mensaje de control
con un paquete usando recvmsg(2) o sendmsg(2).
-
struct in_pktinfo {
unsigned int ipi_ifindex; /* Índice de la interfaz */
struct in_addr ipi_spec_dst; /* Dirección local */
struct in_addr ipi_addr; /* Dirección de destino
en la cabecera */
};
- ipi_ifindex es el índice único de la interfaz en la
que se recibió el paquete. ipi_spec_dst es la
dirección local del paquete y ipi_addr es la
dirección de destino en el encabezado del paquete. Si
IP_PKTINFO se pasa a sendmsg(2) y ipi_spec_dst no es
cero, entonces se utiliza como dirección de origen local para la
búsqueda de la tabla de enrutamiento y para configurar las opciones
de ruta de origen IP. Cuando ipi_ifindex no es cero, la
dirección local principal de la interfaz especificada por el
índice sobrescribe ipi_spec_dst para la búsqueda de
la tabla de enrutamiento.
- No compatible con sockets SOCK_STREAM.
- IP_RECVERR
(desde Linux 2.2)
- Habilita el paso adicional fiable de mensajes de error. Cuando se activa
en un conector de datagramas todos los errores generados se
encolarán en una cola de errores por conector. Cuando el usuario
recibe un errore procedente de una operación con un conector, se
pueden recibir el errore llamando a recvmsg(2) con la opción
MSG_ERRQUEUE activa. La estructura sock_extended_err que
describe el error se pasará en un mensaje auxiliar con el tipo
IP_RECVERR y el nivel IPPROTO_IP. Esto es útil para
el manejo fiable de errores en conectores no conectados. La parte de datos
recibida de la cola de errores contiene el paquete de error.
- El mensaje de control IP_RECVERR contiene una estructura
sock_extended_err:
-
#define SO_EE_ORIGIN_NONE 0
#define SO_EE_ORIGIN_LOCAL 1
#define SO_EE_ORIGIN_ICMP 2
#define SO_EE_ORIGIN_ICMP6 3
struct sock_extended_err {
uint32_t ee_errno; /* número de error */
uint8_t ee_origin; /* dónde sucedió */
uint8_t ee_type; /* tipo */
uint8_t ee_code; /* código */
uint8_t ee_pad;
uint32_t ee_info; /* información adicional */
uint32_t ee_data; /* otros datos */
/* Puede haber más info a continuación */
};
struct sockaddr *SO_EE_OFFENDER(struct sock_extended_err *);
- ee_errno contiene el número de errno del error puesto
en cola. ee_origin es el código de origen que identifica al
origen del error. Los otros campos son específicos del protocolo.
La macro SO_EE_OFFENDER devuelve un puntero a la dirección
del objeto de red dónde se originó el error dado un puntero
al mensaje auxiliar. Si la dirección no es conocida, el miembro
sa_family de sockaddr valdrá AF_UNSPEC y los
otros campos de sockaddr serán indefinidos.
- IP usa la estructura sock_extended_err como sigue: a
ee_origin se le asigna el valor SO_EE_ORIGIN_ICMP para
errores recibidos en un paquete ICMP o SO_EE_ORIGIN_LOCAL para
errores generados localmente. Los valores desconocidos deben ser
ignorados. A ee_type y ee_code se les asignan los campos
tipo y código de la cabecera ICMP. ee_info contiene la MTU
descubierta para errores EMSGSIZE. El mensaje contiene
también la estructura sockaddr_in del nodo que
provocó el error, a la cual se puede acceder con la macro
SO_EE_OFFENDER. El campo sin_family de la dirección
devuelta por SO_EE_OFFENDER valdrá AF_UNSPEC cuando la
fuente sea desconocida. Cuando el error se originó en la red, todas
las opciones IP(IP_OPTIONS, IP_TTL etc.) activas en el
conector y contenidas en el paquete de error, se pasan como mensajes de
control. El contenido útil del paquete que ha provocado el error se
devuelve como datos normales. Observe que TCP no posee una cola de
errores. MSG_ERRQUEUE es ilegal en conectores SOCK_STREAM.
IP_RECERR sí es válido en TCP pero todos los errores
son devueltos únicamente mediante funciones de conector o a
través de SO_ERROR.
- Para conectores directos (raw), IP_RECVERR activa el paso de todos
los errores ICMP recibidos a la aplicación. En cualquier otro caso,
sólo se informa de los errores que se producen en conectores
conectados.
- Esta opción establece u obtiene un valor booleano entero. Por
defecto, IP_RECVERR está desactivada.
- IP_RECVOPTS
(desde Linux 2.2)
- Pasa todas las opciones IP de entrada al usuario en un mensaje de control
IP_OPTIONS. La cabecera de enrutamiento y otras opciones ya las
completa el anfitrión local. No soportada para conectores
SOCK_STREAM.
- IP_RECVORIGDSTADDR
(desde Linux 2.6.29)
- Esta opción booleana habilita el mensaje auxiliar
IP_ORIGDSTADDR en recvmsg(2), en el que el núcleo
retorna la dirección de destino original del datagrama que se
recibe. El mensaje auxiliar contiene una struct sockaddr_in. No es
compatible con sockets SOCK_STREAM.
- IP_RECVTOS
(desde Linux 2.2)
- Si está habilitado, el mensaje auxiliar IP_TOS se pasa con
los paquetes entrantes. Contiene un byte que especifica el campo Tipo de
servicio/precedencia del encabezado del paquete. Espera un indicador de
número entero booleano. No es compatible con sockets
SOCK_STREAM.
- IP_RECVTTL
(desde Linux 2.2)
- Cuando esta opción está activa, pasa un mensaje de control
IP_TTL con el campo "tiempo de vida" (time to live) del
paquete recibido en forma de entero de 32 bits. Los conectores
SOCK_STREAM no lo implementan.
- IP_RETOPTS
(desde Linux 2.2)
- Idéntico a IP_RECVOPTS, pero devuelve opciones sin procesar
con opciones de marca temporal y registro de ruta no completadas para este
tránsito. No compatible con sockets SOCK_STREAM.
- IP_ROUTER_ALERT
(desde Linux 2.2)
- Pasar a este conector todos los paquetes a reenviar que tengan activa la
opción alarma del enrutador IP (IP Router Alert). Sólo
válida para conectores directos. Esto es útil, por ejemplo,
para demonios RSVP en el espacio de usuario. Los paquetes interceptados no
son reenviados por el núcleo, es responsabilidad de los usuarios
envilarlos de nuevo. Se ignora el enlace del conector, tales paquetes
sólo son filtrados por el protocolo. Espera una opción
entera.
- IP_TOS (desde Linux
1.0)
- Establece o devuelve el campo Tipo de Servicio (Type-Of-Service, TOS) a
enviar con cada paquete IP creado desde este conector. Se usa para
priorizar los paquetes en la red. TOS es un byte. Existen algunas opciones
TOS estándares definidas: IPTOS_LOWDELAY para minizar los
retrasos en el caso de tráfico interactivo, IPTOS_THROUGHPUT
para optimizar el rendimiento, IPTOS_RELIABILITY para optimizar la
fiabilidad e IPTOS_MINCOST, que se debería usar para
"datos de relleno" donde no tenga sentido una transmisión
lenta. Como mucho, se puede especificar uno de estos valores TOS. Los
otros bits son inválidos y se limpiarán. Por defecto, Linux
envía primero datagramas IPTOS_LOWDELAY pero el
comportamiento exacto depende de la configuración de la cola.
Algunos niveles de prioridad alta pueden necesitar privilegios de
administrador (consulte la capacidad CAP_NET_ADMIN.
- IP_TRANSPARENT
(desde Linux 2.6.24)
- Establecer esta opción booleana permite el proxy transparente en
este socket. Esta opción de socket permite que la aplicación
que realiza la llamada se vincule a una dirección IP no local y
funcione como cliente y servidor con la dirección externa como
punto final local. OBSERVACIÓN: esto requiere que el enrutamiento
se configure de manera que los paquetes que van a la dirección
externa se enruten a través del cuadro TProxy (es decir, el sistema
que aloja la aplicación que emplea la opción de socket
IP_TRANSPARENT). Habilitar esta opción de socket requiere
privilegios de administrador (la capacidad CAP_NET_ADMIN).
- La redirección de TProxy con el destino TPROXY de iptables
también requiere que esta opción esté configurada en
el socket redirigido.
- IP_TTL (desde Linux
1.0)
- Establece u obtiene el campo "tiempo de vida" actual que se
envía en cada paquete enviado desde este conector.
- IP_UNBLOCK_SOURCE
(desde Linux 2.4.22 / 2.5.68)
- Desbloquea fuentes multidifusión bloqueadas con anterioridad.
Devuelve EADDRNOTAVAIL cuando no se está bloqueando la
fuente.
- El argumento es una estructura ip_mreq_source tal como se describe
en IP_ADD_MEMBERSHIP.
- SO_PEERSEC
(desde Linux 2.6.17)
- Si IPSEC o NetLabel están configurados en los equipos de
envío y recepción, esta opción de socket de solo
lectura devuelve el contexto de seguridad del socket del mismo nivel
conectado a él. Por defecto, será el mismo que el contexto
de seguridad del proceso que creó el socket del mismo nivel, salvo
que sea anulado por normativa o por un proceso con los permisos
necesarios.
- El argumento de getsockopt(2) es un puntero a un búfer de la
longitud especificada en bytes en el que se copiará la cadena
contextual de seguridad. Si la longitud del búfer es menor que la
longitud de la cadena de contexto de seguridad, entonces
getsockopt(2) devuelve -1, establece errno en ERANGE
y devuelve la longitud requerida mediante optlen. El invocante debe
asignar al menos NAME_MAX bytes para el búfer inicialmente,
aunque no se garantiza que esto sea suficiente. Es posible que sea
necesario cambiar el tamaño del búfer a la longitud devuelta
y volver a intentarlo.
- La cadena contextual de seguridad puede incluir un carácter nulo de
terminación en la longitud devuelta, pero no se garantiza que
así sea: un contexto de seguridad 'foo'podría representarse
como {'f','o','o'} de longitud 3 o {'f','o','o','\0'} de longitud 4, que
se consideran intercambiables. La cadena es imprimible, no contiene
caracteres nulos no terminantes y tiene una codificación no
especificada (no se garantiza que sea ASCII o UTF-8).
- El empleo de esta opción para conectores de la familia
AF_INET está implementado desde la versión 2.6.17
para conectores TCP y desde la 4.17 para los SCTP.
- Para SELinux, NetLabel transmite solo la parte MLS del contexto de
seguridad a través del cable, y establece de forma predeterminada
el resto del contexto de seguridad en los valores definidos en la
normativa para el identificador de seguridad inicial (SID) de netmsg. Sin
embargo, NetLabel se puede configurar para pasar contextos de seguridad
completos a través de loopback. IPSEC siempre pasa contextos de
seguridad completos como parte del establecimiento de la asociación
de seguridad (SA) y los busca en función de la asociación
para cada paquete.
El protocolo IP admite un conjunto de interfaces /proc para
configurar algunos parámetros globales. Se puede acceder a los
parámetros leyendo o escribiendo archivos en el directorio
/proc/sys/net/ipv4/. Las interfaces descritas como Boolean
toman un valor entero, con un valor distinto de cero ('true') que significa
que la opción correspondiente está habilitada y un valor cero
('false') que significa que la opción está deshabilitada.
- ip_always_defrag
(Booleano; desde Linux 2.2.13)
- [Nueva con la versión 2.2.13 del núcleo. En anteriores
versiones del núcleo esta característica se activaba durante
la compilación del núcleo mediante la opción
CONFIG_IP_ALWAYS_DEFRAG] que ya no está presente en
versiones 2.4.x y posteriores.
- Cuanda esta opción booleana se habilita (es distinta de 0) los
fragmentos de entrada (partes de paquetes IP que aparecen cuando
algún anfitrión entre el origen y el destino decidió
que los paquetes eran demasiado grandes y los dividió en pedazos)
se reensamblarán (desfragmentarán) antes de ser procesados,
incluso aunque vayan a ser reenviados.
- Habilítelo sólo cuando tenga en funcionamiento un
cortafuegos que sea el único enlace de su red o un proxy
transparente. Nunca lo active para un router o un equipo. Podría
perturbarse la comunicación fragmentada cuando los fragmentos
viajen a través de diferentes enlaces. La desfragmentación
también tiene un alto coste de tiempo de CPU y de memoria.
- Esto se activa 'automágicamente' cuando se configura un
enmascaramiento o un proxy transparente.
- ip_autoconfig
(desde Linux 2.2 hasta Linux 2.6.17)
- No documentado.
- ip_default_ttl
(entero; por defecto: 64; a partir de la versión 2.2)
- Establece el valor "tiempo de vida" (TTL) por defecto de los
paquetes de salida. Éste se puede cambiar para cada conector con la
opción IP_TTL.
- ip_dynaddr
(Booleano; por defecto: deshabilitado; a partir de Linux 2.0.31)
- Activa la reescritura dinámica de la dirección del conector
y de las entradas de enmascaramiento (masquerading) para cuando cambie la
dirección de la interfaz. Esto es útil para interfaces
dialup (como las telefónicas) con direcciones IP cambiantes. 0
significa no reescritura, 1 la activa y 2 activa el modo verboso.
- ip_forward
(Booleano; por defecto: dehabilitado; a partir de la versión
1.2)
- Activa el reenvío IP con una opción booleana. También
se puede configurar el reenvío IP interfaz a interfaz.
- ip_local_port_range
(desde Linux 2.2)
- Este archivo contiene dos números enteros que definen el intervalo
de puertos locales predeterminado asignado a sockets que no están
vinculados explícitamente a un número de puerto—es
decir, el intervalo utilizado para puertos efímeros. Se
asignará un puerto efímero a un socket en las siguientes
circunstancias:
- •
- el número de puerto aparece como 0 en una dirección de
conector al invocar bind(2);
- •
- se invoca listen(2) en un conector de flujo sin enlzar
previamente;
- •
- Se ha invocado connect(2) en un conector no conectado
previamente.
- •
- se invoca sendto(2) en un conector de datagrama no conectado
previamente.
- La asignación de puertos efímeros comienza con el primer
número en ip_local_port_range y termina con el segundo
número. Si se agota el intervalo de puertos efímeros, la
llamada al sistema correspondiente devuelve un error (pero consulte
ERRORES).
- Debe tenerse en cuenta que el intervalo de puertos en
ip_local_port_range no debe entrar en conflicto con los puertos
utilizados por el enmascaramiento (aunque a veces se maneje).
Además, las elecciones arbitrarias pueden causar problemas con
filtros de paquetes del firewall que hacen suposiciones sobre los puertos
locales en uso. El primer número debería ser al menos mayor
que 1024, o mejor, mayor que 4096, para evitar conflictos con puertos
conocidos y minimizar los problemas del firewall.
- ip_no_pmtu_disc
(booleano; predeterminado: deshabilitado; desde Linux 2.2)
- Si está activa, por defecto no realiza el descubrimiento de la MTU
de la ruta para los conectores TCP. El descubrimiento de la MTU de la ruta
puede fallar si se encuentran en la ruta cortafuegos mal configurados
(como los que pierden todos los paquetes ICMP) o interfaces mal
configuradas (por ejemplo, un enlace punto a punto en donde ambos extremos
no se ponen de acuerdo en la MTU). Es mejor arreglar los enrutadores
defectuosos de la ruta que desactivar globalmente el descubrimiento de la
MTU de la ruta ya que el no realizarlo incurre en un alto coste para la
red.
- ip_nonlocal_bind
(booleano; predeterminado: deshabilitado; desde Linux 2.4)
- Si se establece, permite que los procesos bind(2) (se enlacen) a
direcciones IP no locales, lo que puede ser bastante útil, pero
puede dañar algunas aplicaciones.
- ip6frag_time
(entero; predeterminado: 30)
- Tiempo en segundos para mantener un fragmento de IPv6 en memoria.
- ip6frag_secret_interval
(entero; predeterminado: 600)
- Intervalo de regeneración (en segundos) del secreto hash (o vida
útil del secreto hash) para fragmentos de IPv6.
- ipfrag_high_thresh
(entero)
- ipfrag_low_thresh
(entero)
- Si el número de fragmentos IP encolados alcanza el valor
ipfrag_high_thresh, la cola se recorta al valor
ipfrag_low_thresh. Contiene un entero con el número de
bytes.
- neigh/*
- Vea arp(7).
Todas las ioctls descritas en socket(7) se aplican a
ip.
Las ioctls para configurar los parámetros de los
dispositivos genéricos se describen en netdevice(7).
- EACCES
- El usuario intentó ejecutar una operación sin los permisos
necesarios. Estos incluyen: enviar un paquete a una dirección de
transmisión sin tener configurado el indicador SO_BROADCAST;
enviar un paquete a través de una ruta prohibida; modificar
la configuración del firewall sin privilegios de administrador (la
capacidad CAP_NET_ADMIN); enlazar a un puerto privilegiado sin
privilegios de administrador (la capacidad
CAP_NET_BIND_SERVICE).
- EADDRINUSE
- Se ha intentado el enlace a una dirección ya en uso.
- EADDRNOTAVAIL
- Se ha solicitado una interfaz inexistente o la dirección fuente
solicitada no es local.
- EAGAIN
- La operación se bloquearía sobre un conector
bloqueante.
- EALREADY
- Ya se está realizando una operación de conexión sobre
un conector no bloqueante.
- ECONNABORTED
- Se ha cerrado la conexión durante un accept(2).
- EHOSTUNREACH
- Ninguna entrada válida de la tabla de enrutamiento coincide con la
dirección de destino. Este error puede ser provocado por un mensaje
ICMP procedente de un enrutador remoto o por la tabla local de
enrutamiento.
- EINVAL
- Se ha pasado un argumento inválido. Para las operaciones de
envío, éste se puede producir al enviar a una ruta
blackhole.
- EISCONN
- Se ha llamado a connect(2) sobre un conector ya conectado.
- EMSGSIZE
- El datagrama es mayor que una MTU de la ruta y no puede ser
fragmentado.
- ENOBUFS
- ENOMEM
- No hay suficiente memoria libre. Esto a menudo significa que la reserva de
memoria está limitada por los límites del búfer de
conectores, no por la memoria del sistema, aunque esto no es coherente al
100%.
- ENOENT
- Se ha llamado a SIOCGSTAMP sobre un conector en donde no han
llegado paquetes.
- ENOPKG
- No se ha configurado un subsistema del núcleo.
- ENOPROTOOPT
y EOPNOTSUPP
- Se han pasado opciones de conector inválidas.
- ENOTCONN
- La operación solo está definida en un conector conectado
pero el conector no está conectado.
- EPERM
- El usuario no tiene permiso para establecer una prioridad alta, cambiar la
configuración o enviar señales al proceso o grupo
solicitado.
- EPIPE
- La conexión ha sido cerrada o cancelada por el otro extremo.
- ESOCKTNOSUPPORT
- El conector no está configurado o se ha solicitado un tipo de
conector desconocido.
Los protocolos superpuestos pueden generar otros errores. Vea
tcp(7), raw(7), udp(7) y socket(7).
IP_FREEBIND, IP_MSFILTER, IP_MTU,
IP_MTU_DISCOVER, IP_RECVORIGDSTADDR, IP_PASSSEC,
IP_PKTINFO, IP_RECVERR, IP_ROUTER_ALERT y
IP_TRANSPARENT son específicas de Linux.
Debe tenerse especial precaución con la opción
SO_BROADCAST: no tiene privilegios en Linux y es fácil
sobrecargar la red con transmisiones descuidadas. Para nuevos protocolos de
aplicación, es preferible utilizar un grupo de multidifusión
en lugar de transmisión. Se desaconseja la radiodifusión.
Consulte RFC 6762 para ver un ejemplo de un protocolo (mDNS) que utiliza el
enfoque de multidifusión más moderno para comunicarse con un
grupo abierto de hosts en la red local.
Otras implementaciones de conectores BSD proporcionan las opciones
de conector IP_RCVDSTADDR y IP_RECVIF para obtener la
dirección de destino y la interfaz de los datagramas recibidos. Linux
posee la opción más general IP_PKTINFO para la misma
tarea.
Algunas implementaciones de conectores de BSD también
proporcionan una opción IP_RECVTTL, pasando un mensaje
auxiliar con el tipo IP_RECVTTL en el paquete entrante. Esta
opción es diferente de IP_TTL empleada en Linux.
El empleo de la opción de nivel SOL_IP en conectores
no es portable. Las pilas basadas en BSD emplean el nivel
IPPROTO_IP
INADDR_ANY (0.0.0.0) y INADDR_BROADCAST
(255.255.255.255) son neutrales en el orden de bytes. Esto hace que
htonl(3) no tenga ningún efecto sobre ellos.
Por compatibilidad con Linux 2.0, todavía se soporta la
sintáxis obsoleta socket(AF_INET, SOCK_PACKET,
protocol) para abrir un conector de paquetes
(packet(7)). Se recomienda no usar esta sintaxis y debería
reemplazarse por socket(AF_PACKET, SOCK_RAW, protocol).
La principal diferencia es la nueva estructura de direcciones
sockaddr_ll para la información genérica de la capa de
enlace en lugar de la antigua sockaddr_pkt.
Hay demasiados valores de error inconsistentes.
El error utilizado para diagnosticar el agotamiento del intervalo
de puertos efímeros difiere entre las distintas llamadas al sistema
que pueden asignar puertos efímeros (connect(2),
bind(2), listen(2), sendto(2).
No se han descrito las ioctls para configurar las opciones de
interfaz específicas de IP y las tablas ARP.
Recibir la dirección de destino original con
MSG_ERRQUEUE en msg_name mediante recvmsg(2) no
funciona en algunos núcleos de Linux 2.2.
recvmsg(2), sendmsg(2), byteorder(3),
capabilities(7), icmp(7), ipv6(7), netdevice(7),
netlink(7), raw(7), socket(7), tcp(7),
udp(7), ip(8)
Documentación del código fuente del núcleo
Documentation/networking/ip-sysctl.txt.
RFC 791 para la especificación IP original. RFC1122
para los requerimientos IPv4 para lo anfitriones. RFC 1812 para los
requeremientos IPv4 para los enrutadores.
La traducción al español de esta página del
manual fue creada por Juan Piernas <piernas@ditec.um.es>, Miguel
Pérez Ibars <mpi79470@alu.um.es> y Marcos Fouces
<marcos@debian.org>
Esta traducción es documentación libre; lea la
GNU General
Public License Version 3 o posterior con respecto a las condiciones de
copyright. No existe NINGUNA RESPONSABILIDAD.
Si encuentra algún error en la traducción de esta
página del manual, envíe un correo electrónico a
debian-l10n-spanish@lists.debian.org.