Últimos Cambios |
||
Blog personal: El hilo del laberinto |
Última Actualización:
30 de Junio de 1.996 - Domingo
El módulo IP (Internet Protocol) es el equivalente a la capa de RED (nivel 3) del modelo OSI de ISO. Gracias a este nivel se logra ofrecer una visión homogenea y coherente de la "red", independientemente de que ésta esté constituida por un sinnúmero de tecnologías hardware, topologías, protocolos de enlace, etc., diferentes. El objetivo último de este módulo consiste en hacer llegar datagramas de una capa IP de una máquina origen a la capa IP de la máquina destino, abstrayéndonos de los detalles subyacentes. Sus características más destacables son:
El protocolo IP [RFC791] es el resultado de diversos proyectos de investigación de DARPA (Defense Advanced Research Projects Agency), y aunque inicialmente su ámbito de actuación era, sobre todo, militar y universitario, en los últimos años se ha producido una explosión comercial y el número de empresas proveedoras de servicios y de máquinas conectadas a la red crece rápidamente. Ello está ocasionando que el protocolo IP original (conocido como "Versión 4") empiece a tener problemas de escala, seguridad, encaminamiento y congestión, lo que ha llevado a definir, recientemente, una ampliación conocida como "IP Versión 6" o, más popularmente, "IP Next Generation" [RFC1883] [RFC1884].
Dado que la estandarización del nuevo protocolo es muy reciente,
apenas cinco meses en el momento de escribir estas líneas, hemos
decidido implantar, en este Proyecto Fin de Carrera, el protocolo
original. Se vaticina, además, un período de larga coexistencia
mientras se produce la migración a la nueva arquitectura, siendo
los sistemas personales -precisamente donde se enmarca este
Proyecto- los que probablemente tarden más en completar la
evolución.
Interfaz
La interfaz de este módulo se compone tanto de procesos como de rutinas que se ejecutan en el contexto del llamante.
PROC_IP_BC
Este proceso se encarga de inicializar y finalizar el módulo IP. Los mensajes admitidos son MSG_INIT y MSG_QUIT. Los campos de información son ignorados.
Una vez que este módulo ha sido inicializado, este proceso se "recicla" para gestionar las temporizaciones de los reensamblajes: cuando se recibe un datagrama fragmentado se inicia una temporización de 30 segundos y si ésta vence antes de que llegue el resto del datagrama, se descarta.
PROC_IP_SUP
Este proceso es invocado cuando alguna tarea quiere enviar un datagrama. Los mensajes que espera recibir son "MSG_MBUF", y la interpretación de los campos es como sigue:
campo1 contiene una cadena de MBUFs cuyo primer elemento consiste en una estructura IP interfaz definida como:
typedef struct { uint32 ip_fuente; uint32 ip_destino; uint8 dummy; uint8 protocolo; uint16 longitud; } ip_header;
"ip_fuente" debe ser una de nuestras direcciones IP, mientras que "ip_destino" indica la dirección del destinatario. "dummy" es un campo ignorado y que debe ser cero. "protocolo" identifica el protocolo que debe gestionar el datagrama en el destino, mientras que "longitud" contiene el número de bytes del datagrama en sí, que aparece a continuación en la cadena MBUFs.
El datagrama puede estar constituido por varios MBUFs, pero es necesario que la cabecera IP interfaz y el datagrama en sí estén en MBUFs diferentes y que la primera esté contenida en un único MBUF.
Todos los valores multibyte de la cabecera IP interfaz deben estar en formato de red. Es decir, el byte de mayor peso es el que aparece primero (la dirección de memoria más baja).
campo2 contiene, en sus 16 bits de menor peso, un valor que no debe repetirse -en un tiempo de varios minutos- entre datagramas diferentes enviados al mismo destino y con el mismo protocolo. Este valor se utiliza en el reensamblaje IP para poder diferenciar los distintos fragmentos de un datagrama. Es posible, incluso recomendable, utilizar el mismo valor en las retransmisiones de un mismo datagrama.
campo3 contiene, normalmente, el valor cero. En ese caso se indica a la capa IP local, y a todas las que el datagrama tenga que atravesar hasta llegar a su destino, que se admite la fragmentación. Si este parámetro contiene el valor uno implicará que no se permite fragmentar el datagrama. En este caso el datagrama será descartado si es mayor que el MTU de alguna de las redes a lo largo del camino. Ello, normalmente, genera una respuesta ICMP.
PROC_IP_INF
Este proceso es el que recibe los datagramas de la capa física. Los mensajes que recibe son "MSG_MBUF". En campo1 se almacena el MBUF al datagrama (compuesto por un sólo MBUF), y campo2 y campo3 contienen valores indefinidos.
Si el datagrama es para nosotros, y tras un posible reensamblaje, se envía al proceso correspondiente según el campo "protocolo" original. El mensaje enviado es, también, "MSG_MBUF". campo1 consiste en una cadena de tres MBUFs:
En cuanto a rutinas en sí, tenemos:
estado ip_alta_canal(uint32 canal,uint16 MTU);
Esta rutina permite dar de alta un canal, que es una interfaz de entrada/salida de datagramas IP. Un canal, normalmente, corresponde a una interfaz física, si bien algunos sistemas permiten multiplexar diversos canales a través del mismo enlace hardware (por ejemplo, el protocolo PPP). "canal" contiene el nombre del canal que estamos creando.
"MTU" informa a la capa IP de cual es la MTU (Maximum Transfer Unit) del canal. El protocolo IP permite enviar datagramas, en teoría, de hasta 64Kb. En la práctica se ha definido un tamaño mínimo que cualquier capa IP debe gestionar: 576 bytes. El Proyecto desarrollado permite intercambiar datagramas de hasta 1024 bytes. Si se intenta enviar un datagrama con un tamaño mayor que la MTU del canal por el cual va a viajar, éste se fragmentará en porciones más manejables, que se enviarán por separado y que serán reensambladas en el destino.
void ip_baja_canal(uint32 canal);
Esta función da de baja un canal.
estado ip_alta_ip(uint32 ip,uint32 mask,uint32 canal);
Esta rutina permite asignar un número IP a un canal dado. "mask" contiene la máscara de red de esa dirección. Cualquier dirección IP cuya dirección de red, según esa máscara, coincida con la dirección de red de "ip" según esa misma máscara, se considera "alcanzable" directamente a través de ese canal. Todos los valores están en formato RED.
Por ejemplo:
ip=193.216.57.165
mask=255.255.255.128
canal=CHN1
Nuestra dirección IP asociada al canal "CHN1" es 193.216.57.165, y todas las direcciones entre 193.216.57.128 y 193.216.57.255 son "alcanzables" a través de él (pertenecen a nuestra red).
Un canal está capacitado para poseer varias direcciones IP asociadas, que pueden pertenecer a redes diferentes.
void ip_baja_ip(uint32 ip);
Esta rutina da de baja una dirección IP, en formato RED.
uint16 ip_mtu(uint32 ip);
Esta rutina devuelve el MTU del canal asociado a una dirección IP. "ip" es una de nuestras direcciones, en formato RED. La función retorna el MTU del canal, o cero si no existe.
estado ip_alta_gateway(uint32 ip,uint32 mask,uint32 gateway);
Esta rutina permite crear tablas de encaminamiento mediante la inclusión de pasarelas y redes asociadas. "ip" y "mask", juntos, definen la dirección de red alcanzable a través de la pasarela propuesta. Las pasarelas deben ser "alcanzables" a través de alguno de nuestros canales.
void ip_baja_gateway(uint32 gateway);
Como su nombre indica, esta rutina da de baja una pasarela.
estado ip_alta_protocolo(uint8 protocolo,proc_id id);
Todos los datagramas tienen un protocolo asociado (ver la definición de la cabecera IP interfaz definida con anterioridad). Esta rutina permite especificar qué proceso se encarga de gestionar los datagramas recibidos para un protocolo dado: ICMP, IGMP, UDP, TCP, RTP, etc.
void ip_baja_protocolo(uint8 protocolo);
Da de baja un protocolo. Los datagramas que se reciban para ese protocolo serán descartados y se generará un error ICMP.
proc_id ip_proc_protocolo(uint8 protocolo);
Esta rutina indica qué proceso es el responsable de un protocolo. Si el protocolo especificado no tiene un proceso asociado se devuelve PROC_INDEF.
uint32 ip_calcula_destino(uint32 ip_destino,puint32 ip_nuevo_dest);
Esta rutina proporciona información de encaminamiento. "ip_destino" contiene la dirección que queremos alcanzar. La rutina devuelve la dirección IP del interfaz que debemos utilizar para llegar a la máquina deseada, mientras que "ip_nuevo_dest" nos dará la nueva dirección destino. Será la misma que la inicial si la dirección indicada pertenece a una de nuestras redes locales (es "alcanzable"). En caso contrario "ip_nuevo_dest" contendrá la dirección de la pasarela que tendremos que usar para alcanzar el objetivo.
Un valor devuelto de 0.0.0.0 indica que nuestras tablas de encaminamiento no permiten llegar a esa localización.
Todos los valores están en formato RED.
estado ip_flujo(uint32 ip,uint16 tamanho);
Dado que la capa IP proporciona un servicio de datagramas sin control de flujo implícito y este Proyecto Fin de Carrera ha sido diseñado para trabajar con interfaces serie de baja velocidad, resulta necesario implementar algún mecanismo de control de flujo para evitar el desbordamiento de las colas de transmisión. Esta rutina nos da acceso a dicho mecanismo. A través de ella se pide permiso para enviar un datagrama de "tamanho" bytes a través de la dirección local "ip" (este último valor en formato RED). Si se nos deniega podemos reintentarlo de nuevo tras una espera prudencial (una décima de segundo, por ejemplo).
Este sistema es completamente diferente al implementado en el Laboratorio de Comunicación de Datos [LABCD], basado en el intercambio de testigos, debido a que ahora pueden existir diversas fuentes de datagramas y diversas vías de salida (canales).
estado ip_trace(uint32 canal,tip_trace POINTER trace);
Esta rutina devuelve una estructura "tip_trace" conteniendo diversa información sobre un canal dado. Se declara como:
typedef struct { uint32 rx; uint32 tx; uint32 vers_error; uint32 ihl_error; uint32 df_error; uint32 tl_error; uint32 ttl_excedido; uint32 prot_error; uint32 hc_error; } tip_trace;
Los dos primeros campos indican el número de datagramas
transmitidos y recibidos. Los siguientes campos informan del
número de datagramas recibidos con diversos errores: versión,
tamaño de la cabecera, fragmentación y longitud.
"ttl_excedido"
indica el número de datagramas cuyo tiempo de vida se excedió
mientras los estábamos reencaminando. "prot_error"
contabiliza
el número de datagramas recibidos que iban destinados a un
protocolo desconocido. Por último, "hc_error" cuenta el número
de errores de suma de control detectados.
Implementación
Este módulo implanta una capa IP fiel al modelo definido en [RFC791]. Se han eliminado, no obstante, algunas funcionalidades por considerarlas superfluas y que no son utilizadas en Internet: opciones de seguridad, "source routing", "record route", "stream ID" e "Internet timestamp".
Adicionalmente se han fijado los siguientes valores de operación:
Cuando se envía un datagrama se comprueba que la dirección IP fuente especificada se corresponda con alguna de las nuestras. Lo siguiente que se hace es comprobar si el destino pertenece a alguna de nuestras redes locales. Si es así, se le envía directamente. En caso contrario se busca alguna pasarela que lo cubra, y en cuanto se encuentre una válida se le enviará a ella.
Las tablas de encaminamiento, por tanto, deben declararse de redes pequeñas a grandes. En particular, resulta útil definir una pasarela última con máscara 0.0.0.0 que se haga responsable de todos los datagramas que no sabemos enrutar. Las pasarelas en sí, como ya se ha indicado, deben ser alcanzables directamente.
Cualquier error detectado en la gestión de datagramas provoca la generación de respuestas ICMP. Ello incluye también la incapacidad de llegar a una dirección dada ("Destination Unreachable"), el vencimiento del tiempo de vida de los datagramas reencaminados y del tiempo de reensamblaje ("Time Exceded") y el desbordamiento de las colas de transmisión durante el reenrutado ("Source Quench").
Para dar de alta una nueva dirección IP es necesario haber
declarado antes su canal. Igualmente, cuando se elimina un canal
se borran de forma automática todas sus direcciones IP
asociadas.
Bibliografía
[LABCD] Laboratorio de Comunicación de Datos Curso 94-95. Vigo, 16 de Marzo de 1.995 Alvaro Manuel Gómez Vieites Carlos Gabieiro Martínez Jose Cadavid Jáuregui Jesús Cea Avión [RFC791] RFC 791: "Internet Protocol" Jon Postel Septiembre 1.981 [RFC815] RFC 815: "IP Datagram Reassembly Algorithms" David D. Clark Julio 1.982 [RFC966] RFC966: "Host Groups: A Multicast Extension to the Internet Protocol" S. E. Deering D. R. Cheriton Diciembre 1.985 [RFC988] RFC988: "Host Extensions for IP Multicasting" S. E. Deering Julio 1.986 [RFC1112] RFC1112: "Host Extensions for IP Multicasting" Steve Deering Agosto 1.989 [RFC1122] RFC1122: "Requirements for Internet Hosts -- Communication Layers" Robert Braden Octubre 1.989 [RFC1349] RFC1349: "Type of Service in the Internet Protocol Suite" Philip Almquist Julio 1.992 [RFC1455] RFC1455: "Physical Link Security Type of Service" Donald E. Eastlake, III Mayo 1.993 [RFC1546] RFC1546: "Host Anycasting Service" Walter Milliken Trevor Mendez Craig Partridge Noviembre 1.993 [RFC1812] RFC1812: "Requirements for IP Version 4 Routers" Fred Baker Junio 1.995 [RFC1883] RFC1883: "Internet Protocol, Version (IPv6) Specification" S. Deering R. Hinden Diciembre 1.995 [RFC1884] RFC1884: "IP Version 6 Addressing Architecture" S. Deering R. Hinden Diciembre 1.995
Más información sobre los OpenBadges
Donación BitCoin: 19niBN42ac2pqDQFx6GJZxry2JQSFvwAfS