Archivo de la categoría ‘Proyectos’

Seguridad: Sniffing. Capítulo Tercero -> Introducción a Routers, Switch, Hubs y Bridges

ATENCION: Los ejemplos que se van a mostrar y “tutoriales” tan solo tienen carácter educativo. En ningún aspecto comparto filosofías de invasión a la intimidad, ataques contra un sistema informático o cuestiones similares. En la medida que sea posible siempre se usarán ejemplos y formas que puedan ser usados por cualquier persona, de forma que pueda verificar los contenidos escritos. No obstante, por motivos más que obvios, materiales como contraseñas, nombres de usuarios o de hosts, serán omitidos o modificado en las capturas de pantallas realizadas (o las lineas escritas). Es decir, los ejemplos serán completamente reales, los datos mostrados a vosotros necesarios para poder pertrechar estos ejemplos no siempre lo serán (Sí lo serán los resultados). Para que esto conste de forma clara, todo material sensible modificado o falso estará resaltado en ROJO. Por motivos de seguridad, todo el material que sea expuesto aquí (exceptuando software propietario o libre, citaciones expresas o código de terceros) tanto texto, imágenes y código son propiedad del autor y está completamente prohibido su reproducción completa o parcial en otros lugares, espero que se comprenda.


Introducción a Routers, Switch, Hubs y Bridges

El último punto necesario a ver antes de poder entrar en el Sniffing, son los dispositivos de red más comunes que podemos tener a nuestro alcance. Muchos de estos han sido más o menos explicados a lo largo de toda esta la literatura, aunque ahora será necesario comprender un poquito mejor su funcionamiento. Aunque parezca lo contrario, es necesario conocer como funcionan estos para poder comprender y poder realizar si es necesario alguna técnica de Sniffing. Nosotros veremos estos dispositivos de red atendiendo a la complejidad de estos, de menor a mayor, aunque al final veremos otros dispositivos de red, para terminar con la “totalidad” de dispositivos de red que podemos encontrar.

  • Hubs
  • Bridges
  • Switches
  • Routers
  • Otros: Modems, APs, Gateways

Como veremos, algunos de ellos están prácticamente en desuso por el empleo masivo de otros (como es en el caso de los Hubs y los Bridges), pero en cambio son los mejores ejemplos para comprender tanto el Sniffing como los otros dispositivos de red.

 

 

Hubs

El nombre castellano es Concentrador, si bien es cierto que incluso en nuestro idioma incluso es más normal referirnos a ellos como Hubs. El término Hubs o concentrador en cambio es usado en otros puntos de la informática, por ejemplo los Hubs USB, esos pequeños aparatitos que proveen a nuestros equipos con más USBs. Pues bien, aquí nos referiremos a un Hub como los Hub Ethernet. Sus funciones principales siempre han sido dos: La interconexión de diferentes equipos entre sí para formar normalmente redes locales y para regenerar las señales.

Los Hubs se vieron en el capítulo anterior en su gran mayoría, o al menos en su funcionamiento básico. Básicamente es un elemento hardware con un número determinado de “puertos” en los cuales se pueden conectar diferentes equipos por medio de Ethernet o FastEthernet. Su funcionamiento es simple, simplemente redirige (o más correctamente repite) las señales que llegan a cada puerto al resto. Es decir, son meros repetidores de señales. Esto hace que nos preguntemos en que nivel del modelo OSI ó TCP/IP funcionan los Hubs, a lo que la respuesta más lógica (y cierta) es por ende el nivel físico, es decir la capa 1.

Como elemento hardware, lo único que hace es conectar las líneas de transmisión de datos de cada puerto con las líneas de recepción de todos los otros. Los Hub por tanto no realizan ninguna modificación de los datos, ni a nivel lógico (IP, datos…) ni a nivel de enlace de datos (MAC, control de errores…). Los Hub simplemente repiten lo que reciben en un puerto a TODOS los otros puertos. Algunos, quizás aun recuerden la necesidad en aquellos tiempos de usar o cables Ethernet directos (pin a pin) o cables Ethernet cruzados (Los pins de transmisión a los de recepción y viceversa). Por aquel entonces, los cables que se conectaban a los hub debían de ser cables directos, pero los cables necesarios para conectar directamente dos PCs o un hub a otro hub, o el router al hub, debían de ser cruzados. ¿Por qué? Por lo que estamos diciendo precisamente. A día de hoy esto no es necesario, primero porque los hub han desaparecido prácticamente y segundo porque los dispositivos modernos detectan que tipo de cable se está usando, y si es necesario cruza las líneas.

Los equipos conectados a un Hub simplemente pueden conocer si un frame es o no para ellos por la dirección MAC a la que están siendo enviados, pero es muy importante anotar que cualquier adaptador ethernet conectado a dicho hub recibirá siempre la totalidad de los frame que son enviados a través del hub. Que el adaptador ethernet procese o no dichos frames es secundario, la cuestión es que dichos frames son colocados a la entrada del adaptador, lo cual será de suma importancia a la hora de la seguridad y del Sniffing.

Otro inconveniente de los Hubs, es que al estar conectados todos los equipos de este modo, se produce un número muy elevado de colisiones. Es decir, es muy común que dos o más equipos estén transmitiendo datos simultáneamente. Dado que un hub lo que realiza es repetir la transmisión al resto de los puertos, se da que el mismo medio se está usando de forma simultanea, lo que origina colisiones de datos, lo que origina en un decremento importante de rendimiento, lo que hace además necesario un mecanismo de control de colisiones por parte del hub, para poder enviar a los adaptadores ethernet conectados a él una señal de colisión de datos.

El diseño propio de un Hub produce que la velocidad máxima de dicho hub quede definida por el adaptador ethernet más lento. Es decir, si tenemos una red compuesta tanto por adaptadores Ethernet (10Mb/s) como adaptadores FastEthernet (100Ms/s), el hub funcionará tan solo a una velocidad de 10Mb/s. La explicación es obvia, al actuar como mero repetidor y tener conectadas de forma interna las líneas de transmisión con las de recepción entre los propios puertos, si un equipo intentase enviar datos a 100Mb/s estos no podrían jamás ser recibidos por los adaptadores Ethernet, con lo que los adaptadores FastEthernet en una red mixta Ethernet/FastEthernet, funcionarían tan solo en modo Ethernet 10Mb/s.

En cambio, pese a todas las deficiencias hay que recordar y tener en cuenta que son un dispositivo tremendamente sencillo en comparación con los Switches, y hay que tener en cuenta también que no es lo mismo hablar de la tecnología de hace 20 años con la de hoy en día. Incluso los propios hubs FastEthernet cuando aparecieron eran treméndamente costosos!! Poco a poco, estos comenzaron a ver como se iba reduciendo su precio y comenzaban a aparecer los primeros Switches. Por aquel entonces los Switches estaban limitados tan solo a entornos que se necesitase una alta seguridad y gran rendimiento, dejando los Hubs como dispositivos de red con un precio bastante asequible y ya presentes en prácticamente la totalidad de las redes, e incluso su incorporación en routers. El tiempo de nuevo y gracias a las tecnologías de integración de hoy en día, los nuevos materiales y otros han hecho posible que los Hubs sean poco más o menos un recuerdo, un hermano pequeño de los actuales Switches que tan solo es posible encontrarlos en redes antiguas. Hoy por hoy, incluso los routers más económicos del mercado incorporan Switches en lugar de hubs.Eso sí, una vez más hacer hincapié en que un hub de a lo mejor 40 puertos podía tener un precio casi inexistente en comparación de un Switch de 8 de puertos.

Otra función que tenían los Hubs eran la de regeneración de las señales. Las redes Ethernet (Estandar, Fast, Giga…) tienen una limitación aproximada de 100 metros de cableado punto a punto para garantizar la estabilidad de las señales. Es decir, cada 100 metros de cableado se debería de regenerar la señal. Dado que los Hubs son meros repetidores, una forma sencilla sin tener que recurrir a dispositivos regeneradores sería aprovechar los mismos Hubs de la red. No obstante, la necesidad de detección de colisiones entre los diferentes hosts hace que tan solo sea posible la interconexión de un máximo de 4 hubs entre sí. Es decir, un hub con 20 puertos y la entrada de uplink conectado a un segundo hub, conectado a un tercero conectado a un cuarto.

No obstante, de cara al Sniffing, el uso de Hubs es una gran ventaja. Los hub reenvían todos los datos que son recibidos al resto de dispositivos, es decir, no debería de ser por tanto complicado configurar un adaptador de red para que en vez de descartar todas las tramas que no coincidan con su dirección MAC, recogerlas TODAS (aunque no se interprete ni se use dicha información), independientemente de quien iba a ser el receptor de dicha información (Router, otro host, una impresora de red…). A este modo de operación se le conoce como “modo promiscuo”. En las redes WIFI ocurre algo similar y lo denominamos “modo monitor”, ya que al igual que un hub envía los datos a todos los demás dispositivos conectados, los datos en una red inalámbrica se transmiten al aire, y es posible configurar los adaptadores WIFI para poder monitorizar todo el ambiente en busca de señales WIFI, con independencia de si iban o no dirigidos a ellos. Esto es lo que hace que tanto hubs como los AP (puntos de acceso) sean inseguros de base, dado que la información que circula por ellos está realmente a disposición de cualquiera que sepa poner la oreja en el lugar adecuado.

 

 

Bridges

Bridge o puente, y es otro elemento de red que a día de hoy ha desaparecido como elemento propio. No obstante los propios Switchs están basados en los bridges, y tampoco es raro ver por ejemplo puentes WIFI. ¿Pero que es un bridge? Básicamente es un elemento de red que une segmentos de red diferentes. Por ejemplo, si tenemos 2 hubs de 4 puertos cada uno, si interconectamos los hub tendríamos una LAN (una red local) de 8 posible equipos, los 8 pertenecientes todos al mismo segmento de red y todo tratados de igual modo. En cambio, podemos tener esos dos hub conectados por medio de un bridge. En este caso, tendríamos dos segmentos de red de 4 equipos cada uno,  y aun así los 4 equipos de un lado podrían comunicarse perfectamente con los otros 4 equipos. La diferencia es que a la vez que el bridge hace de unión entre ellos, también filtra los frames que no pertenecen a dicho segmento. Es decir, podemos decir que en realidad los bridges son una forma eficaz de dividir/segmentar una red a nivel casi de hardware (nivel 2 del modelo OSI), sin ser necesario una división a nivel de red, como haría por ejemplo un router.

Los bridges no son meros repetidores como es el caso de los Hubs. Estos, trabajan en el nivel 2 del modelo OSI, es decir, en el nivel de enlace de datos, luego podemos decir que los bridges trabajan sobre los frames enviados/recibidos. Aun así, comprender el funcionamiento de un bridge es muy fácil. Imaginar el esquema citado anteriormente, dos segmentos de red diferentes conectados por un puente, donde el puente sería un dispositivo con dos puertos de red (en los cuales se conectarían cada uno de los segmentos) y una memoria interna donde se va creando con el tiempo la tabla de direcciones del puente (MAC/Puerto). Lo interesante en el funcionamiento de los bridges es precisamente dicha tabla.

 

La tabla de un bridge se va generando de forma automática con el tiempo. Además, estos (los bridge) no requieren de ninguna configuración inicial, las propias tablas son las que configuran el dispositivo. Si pensamos en un arranque en frío, la tabla de un bridge se encontraría completamente vacía. La idea es simplemente ir examinando las direcciones origen/destino de los frames e ir almacenando en su memoria, en su tabla una asociación MAC-Puerto del Bridge. La mejor forma de ver esto es con un ejemplo. Imaginemos que disponemos de una red igual a la imagen mostrada anteriormente, dos segmentos de red conectados ambos por un puente de dos puertos, el puerto 1 y el puerto 2 (el primer segmento conectado al puerto 1 y el segundo segmento conectado al puerto 2). El primer segmento posee dos equipos y el segundo segmento posee 3 equipos. Dichos equipos podrían estar conectados entre ellos por ejemplo a través de un hub, aunque eso ahora mismo es completamente indiferente. Llamemos por tanto a los equipos del primer segmento A y B, y a los equipos del segundo segmento X, Y y Z. Imaginemos ahora que partimos de un arranque en frío del puente y que la tabla del puente está completamente vacía. Imaginemos que el equipo A quiere enviar un mensaje al equipo Y del segundo segmento. Veamos que es lo que sucedería en dicha red, omitiendo por simplificar direcciones IP o protocolos ARP:

  1. El host A envía un frame al host Y. ¿Como lo hace? crea un frame Ethernet con la dirección MAC Origen (que será la dirección MAC de A) y con la dirección MAC destino (que será la dirección MAC de Y).
  2. Dado que tanto el primer segmento como el segundo tienen sus equipos conectados gracias a un hub, el frame sale de A hacia el hub del primer segmento. Una vez el frame llega al hub del primer segmento, este repite el frame a todos los demás puertos, en este caso al host B y al puente, ambos dispositivos conectados al hub.
  3. El host B recibe un frame gracias al hub (los hub son completamente transparentes para los host, para ellos es como si no existiese un elemento de red en medio) cuyo origen es la MAC de A y destino es la MAC de Y. Dado que no es un frame destinado a él, el host B descarta el frame de A (a menos que el adaptador de red de B estuviese configurado en modo promiscuo).
  4. El puente recibe en el puerto 1 exactamente el mismo frame que ha recibido B, pero el puente no es u mero repetidor. Lo primero que realizará el Puente será inspeccionar la dirección Origen de dicho frame y la buscará en la tabla. Si en su tabla posee dicha entrada no la añadirá, si no la posee la añadirá. Dado que hemos partido de un arranque en frío, tenemos la certeza de que el puente no encontrará la entrada en la tabla, así que añadirá en la tabla lo expuesto a continuación:

    Host A -> Puerto 1

  5. Una vez que se ha inspeccionado la MAC de origen y realizado o no la inclusión de la tabla, se inspeccionará la MAC destino y se buscará si existe alguna correspondencia en la tabla. En este punto la tabla tan solo posee una entrada que especifica el puerto al que está conectado el Host A, pero nada sobre el puerto Y. Dado que no conoce el puerto al que está conectado el host Y, el puente reenviará el frame a TODOS sus puertos, en este caso tna solo al puerto 2 (tan solo es un puente con dos puertos).
  6. El frame saldrá del puente por el puerto 2 y llegará al hub del segundo segmento, el cual, reenviará a todos sus puertos el mismo frame, es decir, enviará el frame tanto a X, a Y y a Z.
  7. Tanto X y como Z descartarán el frame dado que la MAC destino no es la de ellos, en cambio el host Y aceptará y recibirá el frame originario de A
  8. El host Y envía la contestación a A, para ello construye un frame con la dirección origen (la MAC de Y) y la dirección destino (la MAC de A). El frame alcanzará el hub y de aquí al puerto 2 del puente.
  9. El puente inspeccionará la dirección origen del frame, y dado que no la encuentra en la tabla la añadirá a la tabla, de este modo esta quedaría ya de este modo:

    Hot A -> Puerto 1
    Host Y -> Puerto 2

  10. El puente inspeccionaría la dirección MAC destino y la buscaría en su tabla. En este caso el puente SI encuentra en la tabla la dirección del host A, y sabe que debe de reenviar el frame por el puerto 1.
  11. El frame sale por el puerto 1, llega hasta el hub del primer segmento y de ahí al host A y al host B, rechazando el host B el frame porque no es para él.

Todo esto puede parecer un pobo absurdo, porque no parece que se haya logrado gran casa, el camino de ida del frame es exactamente el mismo camino de vuelta del segundo frame. Pero de echo no lo es. Si partimos ahora con la tabla del puente tal y como ha quedado después de la transmisión anterior, veamos que sucede cuando ahora el Host B quiere enviar un dato al Host A:

  1. El host B construye un frame con la dirección origen (la de B) y la dirección destino (la de A). El frame alcanza el hub y este repite el frame a todos sus puertos: El Host A y el puerto 1 del puente.
  2. El host A recibe el frame, y dado que su MAC coincide con la MAC destino del frame, acepta y recibe el frame.
  3. ¿Que pasa con el puente? El puente examinaría la dirección origen del frame y al no encontrarla en su tabla la añadiría, como ha hecho siempre, dejando la tabla de la siguiente forma:

    Hot A -> Puerto 1
    Host Y -> Puerto 2
    Host B -> Puerto 1

    Y después de analizar el origen del frame inspeccionaría la MAC destino. En su tabla encontraría que el host A ya está incluido y que este está conectado al puerto 1, que es por donde el frame le está llegando. ¿Que hace el puente? Simplemente descarta el frame (sería un poco absurdo reenviar de nuevo el frame por el puerto 1, dado que proviene de él)

¿Que se ha logrado hacer por tanto con el puente? Poco a poco la tabla del puente separa la red en lo que se denomina dos dominios de colisión diferentes. Sin el puente, todos los frames enviados de cualquiea de los 5 hosts alcanzarían TODOS los host. Con el puente (y la tabla del puente completa) los frames enviados por hosts dentro del mismo segmento jamás cruzarán el puente. Esto dota a estos dispositivos de red de algunas interesantes cualidades:

  1. Los puentes pueden segmentar/dividir redes sin necesidad de configurar nada, y lo hacen a nivel de enlace de datos (nivel 2). Ojo!! no separa el 100% del tráfico, como veremos más adelante.
  2. Gracias a las tablas de reenvío de estos, los frames dejarán de circular por segmentos de red en los que el host destino no pertenece, lo que se traduce en la ausencia de colisiones entre segmentos de red diferentes. Ningún host de un segmento tendrá una colisión con un host de otro segmento.
  3. Al separar los dominios de colisión, hace que el rendimiento de los diferentes segmentos de red sea mucho mayor y dota además de muchísima más seguridad a cada segmento, ya que se puede tener la certeza de que un frame de un segmento jamás circulará por el otro segmento (excepto el inicial cuando la tabla del puente no posee aun la entrada y por supuesto los frames broadcast)
  4. Son dispositivos muy simples de implementar y extremadamente baratos

Evidentemente no es oro todo lo que reluce, y posee algunas desventajas, como por ejemplo que no separa dominios de broadcast, y posíblemente y más importante aun sea que para los puentes es muy complicado la interconexión de dos segmentos que usen tecnologías diferentes.

A día de hoy, al igual que los Hub, los puentes como tales han desaparecido casi en su totalidad. No obstante, su principio de funcionamiento es el que inspira el funcionamiento básico del siguiente dispositivo de red que vamos a ver: Los Switches. ¿De cara al sniffing? Los puentes como los hub son dispositivos completamente transparentes para los equipos, no obstante los puentes no reenviarán frames de un segmento a otro, lo que producirá que un sniffer no podrá (en principi0) capturar ningún frame del otro segmento de red, aun cuando el adaptador de red del equipo esté en modo promiscuo.



Switches

La evolución de la tecnología, procesadores, microcontroladores, integración… han echo posible que los Switches estén presente casi en la totalidad de todas las redes del mundo. Al igual que los hubs o los bridges, nosotros tan solo veremos los Switches Ethernet. El nombre español es Conmutador, lo cual tiene bastante sentido ya que podríamos ver un Switch como una máquina que interconecta en el momento adecuado los dos hosts que quieren hablar entre ellos, con completo aislamiento del resto.

En realidad, el funcionamiento del Switch es simple si se ha comprendido el funcionamiento de un hub y de un bridge. El más simple de todos los Switchs podríamos verlo/simplificarlo como un bridge multipuerto. Fusionar por un lado la idea simplista de un hub con las ventajas que brindan los puentes. Un puente segmenta una red  en dominios de colisión, pero es posible aplicar el mismo concepto a cada host en particular, de forma que cada host tendría por así decirlo un dominio de colisión propio. Dicho de otro modo, cada host queda de este modo completamente aislado del resto. Imaginar un puente de 4 puertos que une 4 segmentos de red diferentes, segmentos de red que poseen tan solo un host. Recordemos que el funcionamiento de un hub era meramente el de repetir los frames en cada uno de los puertos, pero en los Switch no se realizará dicha repetición, cada frame será entregado UNICAMENTE al host concreto. ¿Como? Gracias a la tabla de reenvío, exactamente del mismo modo que el puente conoce el puerto al que pertenece cada host. Además de esta peculiaridad, en un Switch es posible trabajar en FullDuplex y simultáneamente, mientras que el host A mantienen una comunicación con el host B, el host C y el host D pueden estar teniendo otra comunicación entre ellos a la máxima velocidad. Por supuesto no podemos limitarnos a pensar que en un puerto de un Switch tan solo es posible conectar un host, es posible conectar desde otro Switch, un hub, un router…

Si la función que realiza es realmente la de un puente multipuerto sería correcto decir que los Switches también son dispositivos de red de nivel 2, que trabajan enviando el frame recibido por un puerto al puerto destino gracias a una tabla interna. Y es cierto en parte, dado que los Switchs han evolucionado mucho más allá de un mero puente multipuerto. Aun así, el Switch base (por así decirlo) es un dispositivo de red de nivel 2. Por otro lado, como hemos dichos los Switches han evolucionado más allá del nivel 2, y aquí comienza realmente la complejidad de estos, dado que las funcionalidades y niveles en los que operan un Switch pueden ser muy diferentes, dependiendo de los fabricantes o incluso del márketing. ¿No está entonces estandarizado? Bueno, dependiendo de la literatura a la que se acuda podemos leer una cosa u otra, y realmente no siempre es errónea, a veces es simplemente puntos de vistas diferentes. Por regla general no obstante se conoce como Switchs inteligentes a aquellos Switchs que operan al menos también a nivel 3 (nivel de red), aunque es más normal el uso del término “multilayer Switch”, es decir, Switch (o conmutador) multi-capa (que opera en múltiples niveles diferentes). El problema de usar el término “Layer-3 Switch” (Switch de nivel 3) o incluso “Multilayer Switch”, es que la definición puede hacer referencia directamente a un Router, dado que en sentido estricto, podemos decir que un Routers es también un Switch multi-capa.

Históricamente, los dispositivos de red de nivel 1 fueron los Hub, los dispositivos de red de nivel 2 los bridges y Switches y los Routers dispositivos de red de nivel 3 y superiores. Desde mi punto de vista por tanto, no llamaría (por confusión más que nada) a un router un “Multilayer Switch”, ya que para mi estos últimos no poseen la finalidad ni las funciones que identifican quizás más inequívocamente a un Router. Para mi, un Switch multi-capa o un Switch de nivel 3 es un Switch avanzado que posee o puede poseer algunas funciones de nivel 3 que pueden ser interesantes a la hora de desempeñar su labor principal, que no es la del rutado de datos, sino la de la interconexión de hosts de una misma red. Aunque repito una vez más que esto es simplemente una apreciación personal. Por ejemplo, CISCO (la mayor compañía del mundo dedicada a redes) tiene un interesante artículo que nos habla poco más o menos de todo esto. Para ellos un Switch de nivel 3 no es más que un router que realiza las funciones de rutado por hardware y no por software:

Artículo de CISCO sobre Switchs de nivel 2 y nivel 3

 

Una función interesante de los Switchs (no todos) es solucionar el “problema” del broadcast y poder crear diferentes redes dentro del mismo Switch. Con un router podemos crear de forma fácil subredes, pero esta cualidad puede realizarse también en nivel 2 gracias a las VLAN: Virtual Local Area Network. Consiste simplemente en poder configurar el Switch para tener diferentes “agrupaciones” de puertos. Por ejemplo, asignar el puerto 1 y el puerto 2 como una VLAN, el puerto 3 y el puerto 4 como otra VLAN y el puerto 1 y el puerto 4 como una tercera VLAN. Efectivamente, no hay que pensar en las VLAN como algo estricto. Cada una de las VLAN serán tratadas como redes independientes de las otras, con un dominio broadcast diferente para cada una de ellas. Esto es una técnica usada de forma muy habitual. Actualmente esto se logra sobre todo con el estandar 802.1Q, el marcado de frames, en el que el Switch añade a los frame ethernet un campo de marcado que especifica la VLAN a la que será enviado el frame. Imginar por ejemplo que disponemos de un Switch de 5 puertos (Puert 1, 2 3 y 4 para hosts  y el puerto 5 para la conexión al router). Podríamos por ejemplo querer que los puertos 1 y 2 formasen junto al puerto 5 una VLAN, con lo que los puertos 1 y 2 tendrían acceso a internet y podrían verse entre ellos. Pero por otro lado podríamos crear una VLAN con los puertos 3 y 4, con lo que estos dos equipos tan solo podrían verse uno al otro y sin conexión a internet.

Pero hablemos un poco más de los Switchs. Una cuestión que no contempla los Switchs es por ejemplo la gestión de los mensajes multicast, ya que estos son enviados a todos los host conectados a este, con independencia de si los hosts conectados a él pertenecen al mismo grupo multicast o no. ¿Por qué sucede esto? Bueno, porque los grupos y las direcciones de multicast se realizan a nivel de red. He aquí un ejemplo de la necesidad de los Switches de nivel 3. Una solución a este “problema” es por ejemplo una técnica conocida como IGMP snooping, en la que el Switch monitoriza también los mensajes IP multicast, almacenando en una caché/tabla del propio Switchs cuando un host se une a un grupo multicast o lo abandona. Conociendo los hosts que pertenecen a cada grupo multicast, los mensajes multicast que traspasen por tanto el Switch ya no serían enviados a todos los hosts, sino a aquellos que realmente pertenecen al grupo multicast al cual están dirigidos. Esto que parece un pequeño añadido produce que en redes que hacen un uso intenso de tráfico multicast (como por ejemplo videoconferencias o transmisiones de audio/video a grupos multicast concretos) obtengan un rendimiento muy superior, ya que los hosts que no pertenecen al grupo multicast no recibirán tráfico alguno. En una red con 4 hosts esto parece un poco absurdo, pero pensar en una red con 200 hosts conectados, y que por ejemplo tienen dos grupos multicast de 100 hosts cada uno. Con este sistema 100 hosts no tendrían tráfico alguno, sin IGMP snooping toda la red estaría recibiendo los datos. Dado que el sistema de IGMP Snooping requiere examinar las IPs, el Switch estaría trabajando por tanto en nivel 3, pero para mi, un Switch con IGMP Snooping no es un router. Aquí se ve por tanto la problemática. Todos los Routers son Layer-3 Switchs, pero no todos los Layer-3 Switchs son Routers.

Otra función que es relativamente fácil encontrar en algunos Switchs de nivel 3 son los sistemas QoS (Calidad de Servicio), para evitar la saturación de la red. Es cierto que QoS suele ser implementado a nivel de Router, pero sin mucho trabajo puede ser bastante útil que los Switchs puedan manipular los bits de la cabecera IP para QoS.

 

Para encontrar Switchs más allá del nivel 3,  deberíamos de acudir a redes más complejas o empresas que pueden beneficiarse de estos dispositivos. Por ejemplo, se pueden encontrar Switchs que proporcionan ellos mismos sistemas NAT sobre todo para balancear la carga de los servidores. Imaginar que disponemos de 4 servidores Web que tienen la información sincronizada, y un Switch que envía a los usuarios a un servidor o a otro en función de la saturación/carga de cada uno de los 4 servidores, sin necesidad de interponer un router que se encargue de dicha tarea, que evidentemente podría realizarla. Quizás, aquí comprendemos más que es lo que CISCO quiere decir cuando habla de Routers = Swichs de nivel 3 por software. A fin de cuenta un router a día de hoy suele tener todo un OS instalado en él, y es el OS que tiene instalado quien gestiona cada uno de los servicios que este posee…. es decir, un procesador que ejecuta programas. Un Switch en cambio, posiblemente el balanceo de la carga de los servidores lo haría íntegramente por hardware, una electrónica que es capaz de conocer la carga que circula por cada uno de los servidores y según esta información redirigir a un usuario a uno u a otro. Mientras que el propósito es el mismo, el medio es muy diferente.

En realidad, no hay un límite en cuanto a funcionalidades de un Switch, basta con implementarle por hardware alguna función de cualquier nivel del modelo OSI que pueda ser interesante para un escenario concreto. Si bien es cierto que los Routers suelen encargarse de la mayoría de estas cuestiones, también lo es que para tareas concretas el rendimiento y facilidad que otorgará un switch siempre será mucho mayor.

 

¿Que podemos decir de los Switches de cara al Sniffin? Lo mismo que podíamos decir sobre los bridges. En principio, un host conectado a un Swicth tan solo podría capturar tráfico de sí mismo, dado que en los Switches cada frame se envía tan solo al puerto concreto. Es decir, los Switches son infinitamente más seguros a priori que los Hub. A día de hoy los Hub han desaparecido y sustituidos casi en su totalidad por los Switches modernos, entre los cuales podemos encontrar desde dispositivos asequibles para casi cualquier persona del mundo y que no requieren ningún tipo de configuración, a dispositivos profesionales de los cuales mejor no preguntar siquiera el precio:

Para hacernos una idea solo del tamaño de dichos dispositivos, si miramos el Switch de la derecha de la imagen, cada uno del los agujeros que se pueden apreciar en la mitad superior son conexiones RJ45, es decir, un puerto Ethernet, en este caso son 10GigaEthernet. Es evidente que este tipo de Switchs es un poco el extremo más extremo que podemos encontrar, hablamos de Switchs que realizan funciones de rutado, QoS, VLAN, VPN, Firewall… Tampoco hay que dejarse engañar, ojo!! la mayoría de los Switchs y Rotuers de este tipo son modulares, es decir, se pueden añadir a lo mejor 200 puertos para Ethernet sobre fibra óptica de golpe con un módulo extra para ello.

 

 

Routers

Son el alma máter de Internet. Originalmente su función era simple: Un dispositivo capaz de poder conectar dos o más redes independientes entre ellas, de modo que se puedan intercambiar entre ellas paquetes de datos, generalmente de manera selectiva. Es decir, si tenemos la red A y la red B, un dispositivo que pueda permitir a la red A comunicarse con la red B. Esto puede parecer que es exactamente lo que hacía un Switch, pero nada más lejos. Es cierto que un Switch común puede interconectar dos redes diferentes a nivel físico, pero el papel principal de un router es completamente diferente.

Un router posee dos aspectos fundamentales de operación: El plano de control y el plano de reenvío.

Si un router puede conectar dos o más redes independientes entre ellas, lo primero que debe de conocer es, por así decirlo, el mapa de red que existe a su alrededor, e incluso que se extiende más allá de esta. ¿Y que interpretamos como mapa de red? Pues ni más ni menos que la arquitectura de esta, las interfaces de acceso de dichas redes, los protocolos que van a usarse en cada una de ellas, las direcciones de estas… En definitiva crear, modificar, adaptar, mantener… lo que se conoce como la tabla de enrutamiento. Esta función será la que realice el plano de control.

Pero aunque se dispongan de un plano de control perfecto, es necesario poder cumplir con su funcionalidad principal: Enviar los, generalmente, paquetes de una red a otra, siguiendo unas determinadas reglas o filtros. Podríamos ver que el plano de control es algo así como la oficina de correos y el plano de reenvío los carteros. Una vez más esto puede asemejarse a la función que desempeñaría un Switch, solo que este realiza dichas funciones en nivel 2 dele modelo OSI, mientras que un router realizaría esta función a nivel 3 (nivel de red), manejando IPs (generalmente).

Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.153.1 * 255.255.255.255 UH 0 0 0 ppp0
192.168.153.1 * 255.255.255.255 UH 0 0 0 ppp0
192.168.2.0 * 255.255.255.0 U 0 0 0 br0
192.168.1.0 * 255.255.255.0 U 0 0 0 vlan2
169.254.0.0 * 255.255.0.0 U 0 0 0 br0
127.0.0.0 * 255.0.0.0 U 0 0 0 lo
default 192.168.153.1 0.0.0.0 UG 0 0 0 ppp0

Evidentemente esta es una tabla de rutado muy sencilla, nada comparable a lo que podría ser una tabla de rutado de un router conectado a una gran red, pero el funcionamiento y comprensión es sencillo. La tabla de rutado no se preocupa de saber el origen de nada, simplemente el destino de todo.

Ejemplo 1:

Si cualquier paquete llegase a este router, por ejemplo con intención de alcanzar la IP 192.168.2.100, el router miraría primero la tabla de rutado para saber la “ubicación” de dicha red, en este caso la red 192.168.2.0 para la máscara de subred 255.255.255.0. Según se muestra en la tabla de rutado, la interfaz asociada a dicha red sería la interfaz “br0”, es decir que dicha interfaz sería por la que saldría el paquete para poder alcanzar el host destino. Esto podría darse por ejemplo en un paquete entrante desde Internet a la red interna 192.168.2.0

Ejemplo 2:

Imaginemos que ahora es un equipo perteneciente a la red 192.168.1.0 el que desea acceder a google.es (66.249.92.104). El router no posee en este caso ninguna ruta definida para dicho host, con lo que usará la ruta por defecto (default). La ruta por defecto se hará cargo de TODOS los destinos que no hayan coincidido con alguna ruta anterior. De echo, el destino “default” en realidad es la ip destino 0.0.0.0, que como ya se dijo en su momento es lo mismo que decir “Todas las IPs”. A diferencia del resto de rutas, esta define además una puerta de enlace a la que se deben de reenviar los paquetes, que no es el propio router. Siguiendo con el ejemplo anterior, cuando el router recibiese la petición para enviar el paquete a la dirección 66.249.92.104, este reenviaría dicho paquete a la puerta de enlace 192.168.153.1, y lo haría por medio de la interfaz ppp0e.

 

Por supuesto, como veremos más adelante las funcionalidades de un router han ido incrementándose con los años de tal forma que hoy por hoy parece que aquella función principal para la que se concibieron es la más desconocida para la mayoría, mientras que aquellas funcionalidades que podríamos llamar “secundarias” son mucho más conocidas. Pero antes de verlas, es importante tener una visión de los routers mucho más amplia de aquellos routers residenciales que tenemos en nuestras casas. De echo, si fuésemos completamente estrictos hablando, es posible que el término “router” tuviésemos que eliminarlo de los “routers caseros” que posee la gran mayoría en sus hogares, y llamarse estos simplemente “Puertas de enlace”, ya que la gran mayoría de estos aunque conectan nuestra propia red a la red del ISP, no intercambian ningún tipo de información de enrutado, de ahí el nombre de “Puerta de Enlace” o “Router residencial”. Pero dejando esta matización a un lado, continuaremos llamando a nuestras puertas de enlace routers, y es por ello por lo que los veremos definidos aquí, aunque más adelante.

  • Edge/Border Routers

    Literalmente sería algo así como Routers de bordes, aunque personalmente prefiero usar el término de “Routers Exteriores”, interpretando exteriores como los routers que se encuentran en el punto más extremo  de la red del ISP al que pertenecen, las fronteras de ella. Si recordamos más o menos lo que es Internet, Internet no es más que un cúmulo enorme de dispositivos interconectados entre ellos, redes dentro de redes dentro de redes…. ¿A fin de cuenta no tenemos la mayoría de nosotros una red LAN constituida en casa? Pero del mismo modo esta red LAN doméstica se encuentra conectada a la Red o subred de nuestro ISP, y esta a su vez puede pertenecer a la red de otro ISP o directamente conectada a las demás redes. Pues bien, los Routers exteriores son los routers que conectan directamente la red del ISP (como telefónica) con otros ISP, o incluso con grandes organizaciones y/o empresas.

    La necesidad de los Routers exteriores no solo puede encontrarse en los ISP, es psoible como hemos dicho encontrarlos en empresas con unas infraestructuras de red grandes, u organizaciones de cualquier índole: Universidades, Multinacionales, Gobiernos… Y su importancia es evidente, son estos Routers los que enviarán/recibirán nuestros paquetes de datos cuando el destino se encuentre fuera de, normalmente, nuestro ISP.

    ¿Como? Bueno, la función principal de los routers ya se han tratado. Gracias a protocolos específicos para ello como BGP, estos routers intercambian entre ellos toda la información de enrutado necesaria para garantizar que todos ellos conocen perfectamente el destino de cada nueva red. Dicho de otro modo, si queremos acceder a la página de google, no nos gustaría que nuestro paquete de datos en vez de llegar en último término a las redes de google se enviasen a las redes de yahoo (por ejemplo). Si los servidores de DNS (como explicamos) eran esas bases de datos enormes que asociaban a un determinado nombre de dominio una IP (simplificando mucho), los Routers exteriores serían los encargados de asociar cada red a un destino físico determinado, en este caso sería lo que se denomina un AS (Sistema autónomo). Definir un AS puede ser un poco complicado. La definición oficial sería algo como: “Un AS es un grupo interconectado de uno o varios prefijos IP que son usados por una o más ISP, que tiene un política de enrutado simple y claramente definida”. Dicho de otro modo, un dispositivo (un router externo posiblemente) perteneciente al propio ISP de la red en la que se encuentra que posee los prefijos IP de dicha red. Cada ISP por tanto poseerá un AS principal registrado y conocido por todos, que será al que estará conectado los routers exteriores.

  • Core Routers

    Si a los Edge Routers los llamamos Routers exteriores, los Core Routers podríamos definirlos como Routers interiores. Serían básicamente el resto de los Routers. Dentro de la red de un ISP, serían la infraestructura principal sobre la que se asienta toda ella, un compendio de decenas, centenas, millares… de routers conectados entre sí, que permiten que los paquetes de datos circulen perfectamente por dicha red, desde un extremo hasta otro si hace falta, y por supuesto en caso de que sea necesario enviar los paquetes de datos a los routers exteriores si estos tienen que salir de la red propia.


Para poder realizar las tareas que se han descrito, los routers actuales son prácticamente computadores en sí mismos, normalmente con un OS propio que administra los recursos de este. Esto cada vez tiene mayor importancia, así como el hardware usado, si tenemos en cuenta que las funciones que se van implementando en los routers son cada vez mayores. Y es que a pesar de su principal finalidad, ha ido siendo cada vez más frecuente el ir añadiendo funcionalidades propias de otros dispositivos dedicados, dotando a los routers de una mayor versatilidad, a la vez que se va prescindiendo de otros equipos dedicados, lo cual suele ser costoso. Esto tiene aun más importancia cuando abandonamos las grandes empresas y nos centramos en PYMES y particulares, donde no es viable disponer de equipo específico para funciones especializadas. Vamos a ver cuales de estas funciones son las más usuales que podemos encontrar en la actualidad:

  • Servidor DHCP

    DHCP es un protocolo para la auto-configuración de dispositivos. Para que cualquier dispositivo de red IP pueda acceder a esta necesita estar configurado para ello, cuanto menos necesita tener una IP asignada y una máscara de subred, aunque lo habitual es una configuración completa: puerta de enlace, servidores dns, ip asignada y el tiempo de vida de la asignación de dicha IP. DHCP como la mayoría de protocolos que nacieron originalmente, no se basaban en la seguridad, sino en la versatilidad y facilidad de uso. Lo cierto es que es un sistema simple y eficaz para la configuración automática de dispositivos de red que no necesitan de una configuración específica, lo cual es el caso del 90% de los hosts de cualquier red.  aparte de los ajustes de configuración básicos, es corriente que tanto clientes y servidores DHCP puedan ser configurados para solicitar/asignar parámetros de configuración extra, incluyendo ajustes específicos para sistemas operativos concretos. La lista completa de los parámetros puede encontrarse en la documentación oficial: Parámetros DHCP

    El funcionamiento es simple. El dispositivo se conecta a la red, y dado que no dispone de ninguna dirección IP o parámetros de configuración, lanza un mensaje broadcast tanto a nivel de MAC como de IP, solicitando auto-configuración por medio de DHCP (presuponiendo que el cliente dispone de un cliente DHCP que permite realizar dicha tarea). Dicha solicitud puede incluir no solo el deseo simple de obtener sus parámetros básicos, sino que puede solicitar también unos ajustes concretos, como una dirección IP concreta, el nombre NetBios que tendrá, el tipo de nodo… cualquier ajuste que el sistema operativo del dispositivo (o el cliente DHCP del dispositivo) crea pertinente que necesita o que podría ser útil. Si existe un servidor DHCP en dicha red, recogerá la petición DHCP del cliente con los ajustes solicitados, y será este quien procese la información y conteste al cliente de forma específica, con los ajustes que el cliente solicitó u otros completamente diferentes, o incluso ignorando la petición de dicho cliente. Es decir, siempre será el servidor DHCP quien una vez tomada la petición de un cliente configurará (o no) al cliente como él (el servidor) desee. Vamos a ver un ejemplo de una petición DHCP (ambos usando IPv4, recordar que al igual que existe el protocolo DHCPv4, existe también el protocolo DHCPv6 para redes IPv6):

    Como se puede apreciar, además de solicitar una IP y nombre de host concretos, el host (con OS Windows 7) solicita además algunos parámetros de configuración, como por ejemplo el nombre de dominio, ajustes netbios… lo cual no quiere decir de nuevo que el servidor conteste a todo ello, el cliente tendrá que conformarse por regla general con los parámetros de configuración que le asigne el servidor DHCP, es más, el servidor DHCP puede modificar algunas funciones del propio cliente por medio de DHCP, tales como por ejemplo deshabilitar para dicho adaptador Netbios dentro de su propio OS (Windows 7 en este caso)

    Estos servidores DHCP podrían constituirse perfectamente con la mayoría de versiones servidores de los OS que conocemos a día de hoy, aunque era muy frecuente tener un equipo con Linux que se encargase de ciertas funciones similares. A día de hoy, esto es una función típica que se ha incluido en ¿todos? los routers actuales.


  • Clientes de conexión

    En realidad es complicado buscar un nombre adecuado a este tipo de funciones. La mayoría de los routers podríamos verlos como un dispositivo con al menos 2 entradas/salidas (2 puertos Ethernet por ejemplo). En cambio, estamos acostumbrados a pensar automáticamente en nuestras puertas de enlace residenciales (routers residenciales), los cuales los vemos más bien como un dispositivo con una entrada y una o más salidas (Un puerto de “entrada” para WAN y otros de “salida” para LAN, no estoy hablando de Modems). En realidad los puertos de un router son evidentemente tanto de entrada de salida, pero es algo común el verlos como puertos independientes. En este tipo de routers, el puerto WAN suele tener una función muy concreta: La conexión del router a Internet. Si la conexión se realiza por medio de un modem, sería el modem el que se encontraría conectado a dicho puerto, si fuese un modem/router ADSL lo normal es encontrar un puerto para la línea de teléfono, sin que sea visible la existencia de un puerto WAN, aunque internamente exista. Con todo esto en la cabeza… ¿a que nos referimos entonces con que un router puede funcionar como diferentes clientes de conexion?

    Imaginar por ejemplo que nuestro router residencial está conectado a un modem ADSL por el puerto WAN. DSL es una tecnología que por regla general usa ATM como transportador, y se basa en protocolos como PPPoE y PPPoA para conectarnos con nuestro ISP. Para que esto sea posible, el router o el modem tienen que actuar como clientes PPPoE/PPPoA para poder realizar dicha conexión. En modems DSL antiguos, era bastante habitual que el cliente PPPoE fuese un programa a descargar en su OS, después fue una función incorporada al router del modem/router residencial.

    Otro escenario típico es por ejemplo la necesidad de poder conectar entre sí dos o más redes a través de Internet, pudiendo de este modo que ambas redes puedan interactuar entre ellas como si de una sola red se tratase. Esto suele realizarse por protocolos de túneles o VPN, como PPTP, L2TP o IPSec, Para que este escenario sea posible, lo ideal es contar con un router que actúe de servidor del túnel y tantos otros que actúen como clientes del túnel. Pero incluso el mismo acceso a internet podría venir dado igualmente por dicho túnel.

    Son muchos los sistemas de conexión que puede conectarse un router, además de los nombrados tendríamos por supuesto el actuar como cliente DHCP, en el que el router obtendría sus parámetros de configuración por medio de otro servidor DHCP, o como cliente WIFI, cliente 3G… las posibilidades son muchas.


  • Network Address Translation (NAT)

    Esta es sin duda una de esas funcionalidades estrella para todos los routers residenciales, y en cambio me atrevería a decir que completamente inservible fuera del ámbito de los hogares y las PYMES. Uno de los principales problemas que tenemos a día de hoy es como ya dijimos el agotamiento del espacio de direcciones IPv4. La mayoría de los hogar (y evidentemente cualquier empresa, organización…) dispone de al menos más de un dispositivo que desean conectar a Internet. Al margen de que dispongamos de más líneas contratadas, IPs dinámicas o estáticas… si no existiese NAT se requeriría una IPv4 unicast (y por IPv4 unicast me refiero a una IPv4 direccionable en Internet) por cada dispositivo que deseásemos conectar a la red!! es decir, si tenemos 4 portátiles necesitaríamos 4 IPv4 unicast. Esto es impensable. Es NAT quien hace posible que todos y cada uno de los host de una LAN pueda acceder simultáneamente a Internet, compartiendo TODOS ellos la misma IPv4 unicast asignada por su ISP.

    Es de aquí de donde aparecen los términos de IP privada e IP pública. Al contrario de lo que la mayoría de las personas cree, la IP privada es la IP menos importante de cara al exterior, siendo realmente la IP pública la que obtiene todo el protagonismo. La IP privada de un host es la IP que le ha sido asignada en su LAN, con la que puede comunicarse con todos y cada uno de los dispositivos de esta. La IP pública de dicho host es la IP con la que se comunica al exterior para poder alcanzar cualquier destino de Internet. La IP privada es por tanto asignada por el mismo Host o por algún servidor DHCP de la red al que pertenece, mientras que la IP pública será asignada por el ISP, y será usada por todos los Host de la red que estén detrás de un dispositivo NAT. De este modo se comienza a ver la verdadera utilidad de NAT, mientras que todos los hosts dentro de la misma red pueden comunicarse con una IPv4 que pertenece a un rango IP para uso privado, todos usan la misma IP para Internet, siendo el ahorro de direcciones IPv4 unicast evidente.

    ¿Como es esto posible? La función de NAT es simple, NAT es ni más ni menos que un traductor (quizás sería más correcto usar conversor) de direcciones IP. Según hacia que lado se realice dicha conversión o traducción, podremos hablar de SNAT o de DNAT. Si NAT modifica una IP destino hablaríamos entonces de DNAT, si la IP modificada es la IP de origen del paquete hablaríamos de SNAT. Independientemente de esto, la idea de NAT es que cuando un host envía un paquete IP hacia Internet, su IP privada es convertida por SNAT a la IP pública de este antes de lanzar dicho paquete a Internet. El destino de dicho paquete responderá a la IP pública que envió dicho paquete, este será recogido de nuevo por el router, y por medio de DNAT convertirá la IP destino de dicho paquete (que actualmente es la IP pública de los hosts de la red) a la IP privada de quien envió dicho paquete, para acabar enviando el paquete de vuelta al host que comenzó la comunicación. Son dos las cuestión realmente interesante con NAT: Como hace el router para saber a quien enviar de nuevo el paquete destino y la necesidad/beneficio de lo que llamamos redirección de puertos (Port Forwarding). Un dispositivo NAT puro, al igual que puede realizar conversiones de direcciones IP debería de ser capaz de realizar PAT (Port Address Translation), es decir, ser capaz de modificar también los puertos TCP/UDP de origen/destino. Esto es a tener en cuenta, dado que muchos routers disponen tan solo de un soporte NAT parcial, incapaz de realizar PAT. Menos usado tal vez sean los esquemas de NAT dinámicos, en los que en vez de tener una sola IP externa (aka pública) se disponen de varias, y el dispositivo NAT puede realizar SNAT a una u otra IP.

    El cómo se realiza el proceso SNAT es simple. Dado que el router conoce tanto la IP pública como la IP privada de quien realiza el envío del paquete IP, SNAT “sólo” tiene que modificar al vuelo la IP privada por la IP pública. En realidad esto no es del todo correcto dado que al modificar la IP del paquete sería necesario modificar modificar también otros campos del paquete IP (CRC o incluso las cabeceras TCP/UDP), y esto no es algo tan simple en protocolos dependiente de IP como ICMP. Pero de un modo simplista podríamos ver que SNAT simplemente cambia una IP por otra. El problema es  DNAT. Cuando el paquete externo llega al router es porque algún servidor (por ejemplo) envió a nuestra IP pública dicho paquete. Dicho servidor no tiene siquiera que saber ningún tipo de información relativa a algún host de nuestra red, en todo caso podrá saber alguna información del único dispositivo de nuestra red expuesto a Internet, nuestro router. La pregunta del millón es por tanto ¿cómo se reenvía desde el router dicho paquete IP al interior de nuestra LAN? ¿Cómo sabe el router siquiera si dicho paquete fue o no solicitado? Bueno, todo ello depende de que tipo de NAT tenga implementando nuestro dispositivo, o el tipo de NAT que necesitemos.

    • NAT de Cono completo (Full-Cone NAT):

      Es la implementación NAT menos segura. NAT mapeará la dirección IP del host junto con su puerto (llamados internos) a una dirección y puerto diferentes (llamados externos, el puerto externo puede ser el mismo al puerto interno) . Una vez se ha realizado dicho mapeo, CUALQUIER host externo PUEDE comunicarse con el host interno enviando los paquetes a UNA dirección:puerto externo que haya sido mapeado.


    • NAT de cono restringido (Restricted Cone NAT)

      Una vez una dirección:puerto interno se ha mapeado a una dirección:puerto externo, SOLO PODRÁ comunicarse con el host interno un host externo sí el host interno en cuestión se ha conectado previamente al host que desea comunicarse con el host interno. En tal caso, dicho host externo PODRÁ comunicarse con el host interno usando CUALQUIER puerto propio, enviando los paquetes a la IP y puertos externos que han sido mapeados.


    • NAT de cono restringido de puertos (Port-Restricted Cone NAT)

      El modo de funcionamiento es exactamente igual a NAT de cono restringido, salvo que se le impone la restricción al host externo de usar el MISMO puerto propio al que previamente se conectó el host interno. En tal caso podrá usar UNA dirección:puerto externa del host interno para comunicarse con él


    • NAT Simétrico (Symmetric NAT)

      Es la implementación NAT más segura. Básicamente a Nat de cono restringido de puertos se le añade una nueva restricción, obligando que el host externo SOLO pueda comunicarse con el host interno a través del puerto externo concreto que realizó la conexión previa, además de tener que hacerlo por el puerto propio al que estaba destinada la comunicación previa.

    La mejor forma de ilustrar esto es sin duda alguno ejemplificándolo. Vamos a ver unos pequeños ejemplos de esto. Para todos ellos vamos a suponer que disponemos 1 host interno (Host A) y 2 host externos (Host Y y Z):


    Full Cone

    Host A: 192.168.0.100 : 50000 -> SNAT -> 80.25.213.2 : 51000 | El puerto Interno del host A es 50000, mapeado al puerto externo 51000.
    Host Y : 212.251.23.5 : XXXXX
    Host Z: 120.21.0.25 :  WWWWW

    Siendo XXXXX y WWWWW un puerto cualquiera, tanto el Host Y como el Host Z podran enviar en cualquier momento un paquete al puerto 50000 del Host A enviándolo a la IP pública de este 80.25.213.2 y a su puerto exterior 51000

    La principal ventaja de este sistema es que no se requiere de ninguna conexión previa por parte del Host A para que este pueda recibir una conexión entrante a dicho puerto. Esto es algo abstante habitual, por eejmplo es el comportamiento que deseamos cuando usamos programas P2P, Messenger, Juegos Online, Accesos remotos… aplicaciones que pueden recibir en cualquier momento datos de algún host al cual previamente no hemos conectado. En cierto modo, cuando en un Router hacemos uso de ese típico “abrir puerto”, realmente lo que se hace es hacer que para dicho puerto NAT se comporte como Full Cone. La desventaja de este sistema es evidente, el Host A en este caso siempre tendrá expuesto su puerto 50000 al exterior por medio del puerto mapeado externo 51000, lo cual es un problema muy grande de seguridad.

    Restricted Cone

    Host A: 192.168.0.100 : 50000 -> SNAT -> 80.25.213.2 : 51000 | El puerto Interno del host A es 50000, mapeado al puerto externo 51000.
    Host Y : 212.251.23.5 : XXXXX
    Host Z: 120.21.0.25 : WWWWW

    El Host A envía un paquete IP al puerto XXXXX del Host Y a través de su puerto interno 50000.

    Siendo XXXXX y WWWWWW un puerto cualquiera, en este caso solo el Host Y podrá enviar un paquete al puerto 50000 del Host A enviándolo a la IP pública de este 80.25.213.2 y a su puerto exterior 51000. El Host Z en contrapartida no podrá enviar ningún paquete IP al Host A por medio de su puerto externo, ya que la tabla NAT del router del Host A no posee tiene registrada ninguna conexión previa al host Z. Para que el Host Z puda comunicarse con el Host A del mismo modo que lo hace el Host Y, el Host A deberá de iniciar una conexión al Host Z.

    La ventaja de este sistema es una de las principales barreras de seguridad de un router, es en sí mismo un poderoso Firewall. Solo con esta función, ningún Host externo podrá comunicarse con ningún Host de nuestra red salvo que se haya iniciado previamente la comunicación por parte de nuestra red. Es decir, el 90% de todos los posibles ataques a nuestra red serán inmediatamente cortados. ¿Por qué? Porque en el mejor de los casos los host externos tan solo podrán alcanzar el router, los paquetes nunca pasarán más allá de este. Cualquier malware que requiera de una conexión activa externa, automáticamente será anulado, puesto que no será nuestros dispositivos los que inicien la comunicación. Pero la seguridad trae consigo que podamos necesitar para nuestros propios fines precisamente el comportamiento que NAT nos está protegiendo, como se ha visto en Full-Cone.

    Hay que tener en cuenta que el Host Y podrá realizar dicha comunicación por cualquiera de sus puertos.

    Restricted-Port Cone

    Host A: 192.168.0.100 : 50000 -> SNAT -> 80.25.213.2 : 51000 | El puerto Interno del host A es 50000, mapeado al puerto externo 51000.
    Host Y : 212.251.23.5 : 1234
    Host Z: 120.21.0.25 : WWWWW

    El Host A envía un paquete IP al puerto 1234 del Host Y a través de su puerto interno 50000.

    El Host Y podrá enviar un paquete al puerto 50000 del Host A enviándolo a la IP pública de este 80.25.213.2 y a su puerto exterior 51000, siempre y cuando lo haga por su puerto 1234, que fue el puerto al que el Host A se conectó. El Host Z en contrapartida no podrá enviar ningún paquete IP al Host A de ninguna de las formas.

    Además de añadir la funcionalidad de Restricted Cone, se añade una capa de seguridad adicional, y es que el puerto usado por el host externo con nuestro hsot interno tendrá que ser el mismo al que se conectó el host interno. Esto es importante. Generalmente los puertos de los host externos suelen estar asociados a servicios concretos. Por ejemplo el puerto 80 suele estar asociado a servidores Web. En un esquema de Restricted Cone, el Host A podría realizar la conexión inicial al puerto 80 del host Y con la intención de recuperar una página web, y el Host Y aprovechando dicha conexión podría en vez de devolver por el mismo puerto 80 la página web usar un puerto al que tenga asociado algún programa o finalidad maligna. El dispositivo NAT no verificaría en ningún momento si el puerto del host Y es el mismo, le sería completamente indiferente. En un esquema de Restricted-Port Cone, si el puerto no coincide el dispositivo NAT no permitiría el reenvío de los paquetes al host A.

    Hay que tener en cuenta que no se soluciona el problema que plantearemos en el siguiente método.

    Symmetric Cone

    Host A: 192.168.0.100 : 50000 -> SNAT -> 80.25.213.2 : 51000 | El puerto Interno del host A es 50000, mapeado al puerto externo 51000.
    Host A: 192.168.0.100 : 50001 -> SNAT -> 80.25.213.2 : 51001 | El puerto Interno del host A es 50001, mapeado al puerto externo 51001.

    Host Y : 212.251.23.5 : 80
    Host Z: 120.21.0.25 : 80

    El Host A envía un paquete IP al puerto 80 del Host Y por su puerto 50000 y otro al puerto 80 del Host Z a través de su puerto interno 50001.

    En este caso, incluso en un esquema de Restricted-Port Cone NAT, el host Z podría realizar una conexión al puerto 50000 del Host A, aunque dicha conexión se usase para conectarse al host Y y no al Host Z. Se cumpliría la restricción de puerto, dado que tanto el host Y como el Z se comunican por el puerto 80, y se cumpliría la premisa de una comunicación previa. Con Symmetric Cone, el dispositivo NAT registraría un seguimiento integral de las comunicaciones de entrada/salida de este. En este caso, el Host Y solo podría comunicarse con el Host A por el puerto externo 51000, y el Host Z solo podría hacerlo por el puerto externo 51001.

    No obstante, NAT plantea diversos problemas reales que puede hacer que ciertas aplicaciones sean inviables de usar. El caso más típico es por ejemplo los clientes FTP. El protocolo FTP tiene dos métodos de funcionamiento fundamentales: Modo Pasivo y Modo Activo. En Modo activo, una vez que el cliente FTP realiza la conexión al servidor FTP externo, el servidor FTP externo se conectará a un puerto DIFERENTE del cliente. Esto no es posible hacerlo con NAT, ya que NAT esperará que la única conexión entrante se realice por el mismo puerto que cursó la conexión. El modo Pasivo por otro lado usa el puerto 21 para todo, con lo que el cliente FTP funcionaría perfectamente.

    Este tipo de problemas se han ido solucionando con diferentes aproximaciones. Para ello la mayoría de routers permiten el mapeo de puertos indiscriminado, es decir, abrir de forma permanente un cierto número de puertos al exterior que estarán siempre mapeados a ciertos puertos de un host específico de la red. Otros por ejemplo permiten sistemas como el disparo de puertos, que es un mapeo de puertos similar, pero de forma dinámica, es decir cuando el cliente realiza la conexión al exterior por un puerto concreto, el router mapearía en ese justo momento y no antes una serie de puertos que podrían ser usados por el host remoto para la comunicación. No obstante el problema de estos métodos es el mismo, en ambos casos se necesita saber con antelación que puertos son los que los hosts remotos pueden necesitar, con la idea de poder tenerlos abiertos antes de realizar la conexión. Cuando son aplicaciones concretas conocidas o son pocos puertos, no es un problema demasiado grande (aunque bastante inseguro). Pero este tipo de soluciones se hacen imposibles si no conocemos los puerto que puede necesitar el host remoto. Es aquí donde se requiere de tecnologías que hagan NAT transversal, es decir que puedan saltarse el dispositivo NAT. NAT transversal no es algo tan simple de realizar, y los routers que disponemos deben de ser capaces de realizar ciertas funciones un tanto más avanzadas. Generalmente basadas en túneles u otros protocolos.


  • Servidor DNS

    Ya sabemos que son los servidores DNS, así que no vamos a describirlos ahora. ES cierto que los servidores DNS requieren generalmente una gran capacidad de procesamiento para funcionar correctamente, pero podemos encontrar entornos en los que no necesitemos de servidores específicos de DNS, y podamos descargar dicha tarea en un router. Si bien es cierto que a día de hoy el software más extendido para los servidores DNS es BIND, DNSmasq es más común encontrarlo en dispositivos integrados como los routers, que no quiere decir que no podamos encontrar routers con BIND. Lo cierto es que para redes relativamente pequeñas puede ser suficiente un servidor DNS integrado en el mismo router que sea capaz de resolver cualquier nombre de host de cualquier equipo de la propia red interna.


  • Firewall

    Aunque me gustaría tratar todo lo referente a Firewalls en otro tema, lo cierto es que prácticamente cualquier router a día de hoy implementa funciones de Firewall, de cortafuegos. Como ya vimos, NAT es en sí mismo un pequeño cortafuegos, pero este se suele extender para dotar a una red de mayor seguridad.

    A día de hoy lo normal es contar con Firewalls tipo SPI. SPI (stateful packet inspections) sería algo así como Firewalls de inspección intensiva de paquetes, y su funcionamiento es similar al que realiza NAT. La idea de SPI es mantener un rastreo constante de todos los paquetes que entran y salen de la red, construyendo tablas de seguimiento de paquetes y permitiendo o denegando su paso a través de él en función de unas reglas. Como digo en esencia es similar a NAT, el cual mantiene unas tablas que realizan igualmente un seguimiento de las conexiones realizadas. En cambio, auque puedan tener funciones similares no tiene nada que ver uno con el otro. La finalidad de NAT es la de traducir direcciones, no actuar de cortafuegos (aunque sirva para ello).

    Gracias a Firewallos tipo SPI, podemos por ejemplo definir reglas no solo basadas en el origen o destino de los paquetes que se envían o se reciben, sino que podemos crear reglas mucho más complejas, como por ejemplo permitir tan solo un determinado número de conexiones por minuto, permitir tan solo paquetes con determinados flag activados, crear protecciones para ataques de denegación de servicio (DoS)… Con un buen firewall SPI se puede crear prácticamente cualquier filtro que necesitemos.

    Las implementaciones en routers van desde implementar un NAT simple con ellos hasta crear verdaderas puertas seguras a nuestras redes. Quizás la implementación más usada en los routers es el uso de la suite Netfilter (aka iptables) para dicho propósito.


  • VPN

    Virtual Private Network, o red privada virtual es una tecnología usada ampliamente sobre todo en grandes redes, aunque cada vez más se está viendo su uso en redes domésticas y PYMES. Básicamente una VPN es una infraestructura que permite conectar entre sí dos redes a priori independientes separadas generalmente por Internet. Es decir, una tecnología que nos permite conectarnos a la red interna de otro lugar, sin estar conectados físicamente a ella, tan solo a través de internet. Es evidente que puede usarse para muchas otras cosas, como por ejemplo para cifrar el tráfico en una red local o usar VPN para crear túneles entre diferentes ubicaciones.

    La función de VPN correspondía casi siempre a equipos configurados como clientes o servidores de este, o dispositivos integrados específicos para ello. No obstante está siendo cada vez más habitual encontrar routers incluso de segmento medio incorporar funciones de VPN. La mayoría de ellos tan solo para actuar como clientes, otros poseen capacidades de actuar de servidores. Esto tiene mucha más utilidad de la que uno puede pensar. Veamos la utilidad de que un router posea características de cliente o servidor VPN:

    Imaginar que tenemos una pequeña empresa de centros educativos por toda la comunidad andaluza. Cada centro posee una red propia conectada a Internet, y en uno de ellos está un servidor de bases de datos que es donde se almacenan todos los datos de los usuarios matriculados. Cada una de las redes locales de cada centro evidentemente se encuentran separadas incluso por cientos de kilómetros. En este tipo de empresas es normal la actualización de contenidos entre profesores o entre alumnos, no solo en cada centro sino también entre centros. Una solución sería estar enviando constantemente dichos archivos o documentos por correo, o enviar una vez al mes los nuevos datos de matrículas al servidor central. Pero si tenemso creada una infraestructura de VPN podríamos hacer que las 10 o 20 redes de todas las academias se encontrasen todas ellas entre sí en una red local virtual. Cada router de cada academia estaría configurado como cliente de un servidor VPN, que podría ser precisamente otro router. Dado que todos los equipos de cada academia están conectados a su router, esto significaría que todos los equipos de todas las academias estarían a efectos prácticos en una red local propia, todos serían visibles entre ellos, y todos los servicios de red estarían disponibles. Cualquier profesor podría acceder en cualquier momento a la base de datos centra, o compartir un archivo con otro profesor o alumno.

    Existe no obstante otro ejemplo de VPN muy extendido, que es en los juegos Online. Casi todos permite siempre dos tipos de acceso a multijugador, partidas LAN y partidas en Internet. Pues bien, configurando una VPN sería posible realizar partidas en LAN, aun cuando nuestros compañeros estuviesen a miles de kilómetros de nosotros, sin necesidad de publicar las partidas en Internet.

    El como se hace posible este tipo de conexiones a través de Internet, es simple: Túneles. Cuando hablamos de Túneles en redes, generalmente nos referimos al envío de datos encapsulados dentro de otros protocolos. Es decir, enviamos datos de un protocolo por medio de otro protocolo. Un ejemplo simple sería intentar comprender como es posible crear una VPN. Sabemos que las redes locales generalmente usan frames Ethernet, y también sabemos que los frames Ethernet no son jamás transmitidos por Internet. Pero entonces, como es posible que podamos comunicarnos en red local si estamos en la otra parte del mundo? Internet usa paquetes IP para transmitir datos, y generalmente TCP o UDP como protocolos de transporte de estos, pero ninguna especificación dice que tipo de datos puedo enviar por TCP o UDP u otros protocolos de transporte. Es decir, que podría coger un frame Ethernet, meterlo dentro de un paquete IP y enviarlo al otro lado del mundo. Si el otro extremo está preparado para ello podría leer dicho paquete IP, extraer de él el frame Ethernet y enviar dicho frame Ethernet al equpo de su red local. Eso es un Tunel, en este caso se estaría encapsulando un frame Ethernet en un paquete IP, es decir un protocolo de nivel 3 (de red) como IP encapsula o lleva consigo un protocolo de nivel 1 y 2 como Ethernet.

    Existen varios protocolos estándares para VPN, quizás uno de los más antiguos e inseguro (y aun muy extendido) sea PPTP, del cual es fácil encontrar routers con soporte de cliente para él. Un paso más adelante sería L2TP, aunque es menos común que PPTP suele ser más seguro cuando se combina con protocolos de seguridad como IPsec. IPSec es un protocolo de encriptación que fue designado en principio como requerimiento para IPv6, pero su uso está muy extendido por la gran seguridad que brinda no solo a los túneles que pueden crearse, sino para el cifrado de paquetes IP. Quizás, la suite más usada en todo el mundo sea sin duda los clientes/servidores VPN de CISCO o la implementación gratuita OpenVPN, ambas altamente seguras.

    No obstante alguno de estos protocolos presentan dificultades para operar cuando la red se encuentra detrás de un dispositivo NAT. Es por ello que la mayoría de los routers, soporte o no VPN, suelen soportar opciones especiales para permitir el paso de paquetes que usen estos protocolos. Esto es necesario si tenemos en cuenta q los protocolos comentados pueden tener encriptado en sus datos el puerto o el destino de dichos paquetes, con lo que el dispositivo NAT los filtraría de inmediato.Esto suele denominarse Passthrough, en cierto modo es algo similar a lo que se pretende cuando se realiza NAT transversal.


  • QoS

    Lo ideal sería vivir en un mundo en el que no existiesen límites físicos, en el que la información pudiese fluir a velocidades infinitas en caudales infinitos. Pero esto no es la realidad. Es por ello que cualquier red, sea grande o pequeña puede en un momento dado saturarse. Lo normal sería aplicar una política de balanceo, es decir si dispongo de un enlace a Internet de 10Mb/s y 10 clientes conectados a él descargando al mismo tiempo, por ley salomónica cada host tendría aproximadamente 1Mb/s del ancho de banda disponible. Este sistema en realidad es justo, pero nada efectivo en multitud de escenarios. Imaginar que de los 10 clientes que están haciendo uso de dicho ancho de banda, 5 lo están usando para ver páginas web, 3 para descargar archivos y 2 para realizar videoconferencias. Ya no solo son diferentes las necesidades de cada uno en cuanto a ancho de banda se refiere, sino que también poseen diferentes necesidades de fiabilidad de datos o la latencia de estos. Veamos 4 ejemplos típicos en las que las necesidades son completamente diferentes:

    Descarga de Archivos: Cuando descargamos cualquier archivo, generalmente no nos preocupa demasiado si hay muchos errores de transmisión o una latencia alta. Recordar que la latencia no tiene nada que ver con la velocidad de descarga, sino que mide el retraso de la información, es decir podemos tener un flujo constante de 10Mb/s y a la vez tener una latencia de 10 segundos. En realidad cuando descargamos un archivo lo que solemos desear es velocidad pura y dura de descarga. Incluso cuando la transferencia se abortase, tampoco nos supone un gran problema la mayoría de las veces.

    Videconferencias: A diferencia de la descarga de archivos, aquí no necesitamos una gran capacidad de la red, de los 10Mb a lo mejor tendríamos suficiente con 64KB/s. Del mismo modo que con la descarga de archivos, en la videoconferencia la tasa de errores no es importante, no nos importa demasiado que de cuando en cuando el sonido no sea muy claro o el video se pixele o muestre bloques. Pero a diferencia de la descarga de archivos sí tendremos una exigencia muy alta de latencia, necesitamos que la videoconferencia sea en la medida de lo posible en tiempo real, sería imposible mantener una videoconferencia con una latencia ya no de 10 segundos, con 3 segundos sería suficiente para arruinar toda la conversación. Es decir, decimos algo y hasta 3 segundos despues el otro no escucha lo que decimos, tiempo en el que dicha persona ha podido estar hablando. Es evidente que lo fundamental aquí son tiempos de retraso mínimos.

    Cirugía Remota: Esto no es ciencia ficción, es una realidad. Imaginar una operación a distancia con las nuevas tecnologías de las que disponemos. Tecnologías que no requieren en realidad de anchos de banda enormes, en este caso quizás con 100KB/s sería más que suficiente. En cambio, la latencia sería aquí bastante importante. Pero más importante en este caso sería la fidelidad de los datos. Que en un video aparezca de cuando en cuando un error en los colores o e la imagen puede ser un poco molesto, pero que un robot manejado de forma remota corte con un bisturí un centímetro más o un centímetro menos, sí es la diferencia entre la vida o la muerte.

    Descarga de archivos P2P: Normalmente las pretensiones suelen ser similares a las descargas de archivo, salvo con la salvedad de que generalmente deseamos que sean aplicaciones con la menor prioridad de todas. Es decir, el último en solicitar ancho de banda. Generalmente deseamos que el navegador u otras aplicaciones tengan mayor prioridad sobre el ancho de banda que las redes P2P, que generalmente tenemos ejecutas de fondo. Esto no quiere decir que dichas descargas no puedan hacer uso del máximo de la red, solo que si tenemos otras aplicaciones, estas tengan preferencia.

    Esto es lo que hace QoS (Quality Of Service). Las tecnologías QoS se basan ni más ni menos en estos principios , sistemas de control de tráfico para evitar no solo saturaciones en la red, sino aplicar diferentes reglas a diferentes tipos de tráfico. Gracias a los mecanismos QoS, un usuario doméstico podría por ejemplo tener abierto algún programa tipo eMule o Torrent, mientras que a la par descarga archivos por el navegador, mientras que ve otras páginas y mientras que su mujer está hablando por un teléfono VOIP, sin que ninguna de dichas tareas degrade en absoluto el rendimiento de cada una de las demás. No obstante estos mecanismos son bastante complejos, y una mala configuración de ellos puede tener consecuencias bastante impredecibles. Por regla general se suelen combinar diferentes métodos:

    Limitación de ancho de banda: Quizás sea el sistema más simple, limitar a cada cliente o servicio directamente su capacidad a usar. Por ejemplo, podríamos limitar el PC que tenemos abandonado en nuestro hogar y que tan solo tenemos para el eMule, a usar tan solo un 10% de la red. o usar sistemas más complejos, que ajustan de forma dinámica estas limitaciones en función de los demás dispositivos de red.

    Programación: Sistemas que controlan y supervisan las peticiones de los clientes, y según estas las sirve o no en función de ciertas reglas

    Control de la congestión: Si la red llega a su límite, que sucede? La idea es evitar que la red pueda saturarse. El ejemplo más fácil de este tipo de tecnologías es simplemente el descartar (tirar) aquellos paquetes de datos que tengan menos prioridad, con lo que los paquetes con mayor prioridad continuarán llegando correctamente a sus destinos.

    Un buen sistema QoS usará todos los sistemas de control que esté a su alcance para obtener en la medida de lo posible el mejor manejo de los paquetes. Posiblemente el mejor sistema QoS en la actualidad sea DiffServ (Differentiated Services), aunque no es común verlo implementado o usado en redes domésticas (por desgracia). Ya es relativamente habitual encontrar routers con soporte QoS, aunque suelen usar sistemas poco eficientes en su mayoría, aunque fáciles de configurar. Implementar y configurar correctamente QoS en un router doméstico, puede implicar tener una red mucho más ágil  y eficaz, por no decir los beneficios en una red empresarial.



Otros: Puertas de Enlace Residenciales, Modems y Puntos de Accesos

La última serie de dispositivos que vamos a ver, son posiblemente los más usados en la actualidad en el hogar. Como ya he dicho, es muy diferente la estructura/arquitectura de red que puede tener o necesitar un hogar a la que puede tener o necesitar una empresa. Las tecnologías son diferentes, los accesos a la red son diferentes, el número de equipos, la seguridad necesaria… es precisamente por estos motivos por los cuales un usuario normal no tendría que saber nunca que es un puente o un Switch, que es un punto de acceso o que es en realidad un router. Si escogiésemos al azar a un transeúnte y le preguntásemos que es un Router o un Modem, indistintamente te dirían con bastante probabilidad que es “algo de Internet” o el aparato que pone el ISP para Internet. Si le preguntamos que sabe de puentes, nos responderá casi con toda seguridad que es una construcción generalmente de metal/hormigón para alcanzar un terreno no accesible de otro modo.

  • Modems

    La gran mayoría de dispositivos de red que manejamos, trabajan siempre de puertas para dentro, en nuestra propia red. Es cierto que tanto estas redes locales nuestras como toda Internet se basan en lo que denominamos la pila de protocolos TCP/IP, pero sin embargo el método y los medios de transmisión de estos datos es muy diferente según cada escenario. Por ejemplo, en una red doméstica lo normal será que los datos sean trasmitidos por cables de par trenzado Categoría 5e+ o WIFI, mientras que los datos viajarán por estos cables como frames Ethernet traducidos a señales eléctricas. En cambio, eso no significa que nuestros datos viajen del mismo modo por todas las infraestructuras de nuestro ISP, y de echo no lo hacen. Por ejemplo en líneas DSL nuestros datos son enviados por el par de cobres de teléfono de toda la vida hasta unas estaciones llamadas DSLAM, allí se multiplexan (combinan) los datos de este usuario con los de otros muchos y se envían todos ellos (juntos) a un Servidor BRAS. Hasta este servidor, todos los datos que se están manipulando se hacen en bloques, no son redes IP en las que se manipulan los paquetes independientes de cada usuario. Una vez llegan a estos servidores, los datos de los diferentes usuarios se separan y ahora sí se comienzan a rutar por la red IP del propio ISP, y de ahí a cualquier parte del mundo. Pero incluso cuando los datos son enviados al otro lado del mundo, sería una locura pensar que nuestros datos vayan a viajar solos por los enlaces troncales, es decir, nuestros datos se multiplexan continuamente con los de otros cientos/miles de usuarios.

    Dado el funcionamiento explicado, es necesario dispositivos intermedios que puedan transferir esos datos entre diferentes partes de estas infraestructuras. Los Routers dirigen el tráfico, pero los Modems son por así decirlo los que cambian el contexto de los datos. De echo, MODEM son las siglas de MOdulador DEModulador, es decir, su función es la de modular señales, trabajando en el nivel 2 y nivel 1 del modelo OSI. Es por eso que en prácticamente cualquier hogar, se disponga de un Cable-Modem o un Modem xDSL. Estos serán los traductores de nuestros frames Ethernet/ATM a las señales moduladas que se enviarán o recibirán de nuestro ISP. Los Modems por tanto son completamente dependientes de la tecnología para la cual fueron usados, es decir un Modem ADSL no tiene por qué funcionar para una línea ADSL2+, y seguro que no lo hace para líneas VDSL. Del mismo modo un Modem DOCSIS 1.0 (una tecnología de cable) no funcionará para redes DOCSIS 3.0, y evidentemente menos aun para líneas DSL.


  • Puntos de Acceso

    Con puntos de acceso nos referimos intrínsecamente a puntos de acceso WIFI. WIFI ha sido una tecnología inalámbrica de gran éxito en los últimos años, aunque no es la única (BlueTooth). Una vez que desarrollas una tecnología que tenga una aplicación directa en las redes actuales, es interesante integrarla a esta de algún modo. ¿Cómo se hace? Si recordamos, una de las funciones de un Router es precisamente su facilidad para interconectar diferentes tecnologías entre sí. Esto es posible a que del mismo modo que un Router puede hacer uso de Interfaces generalmente Ethernet, puede hacer uso de cualquier otra, si se fabrican con ellas (o se les añade). Si fabricamos un Router con una Interfaz de salida Ethernet y otra WIFI, nuestro Router será capaz de comunicarse a redes Ethernet y Redes WIFI indistíntamente.

    Por lo general, hay 3 formas básicas de hacer esto. La primera es por medio de chips integrados en los mismos dispositivos, tales serían los casos de la gran mayoría de los dispositivos. Evidentemente todos los adaptadores de red en última instancia son chips integrados, pero nos referimos al sistema por el cual se dota de WIFI a un dispositivo. El segundo caso más extendido sería por expansión del hardware por medio de algún conector/puerto/interface, como pueda serlo vía Ethernet, lo que permite dotar con capacidades inalámbricas prácticamente cualquier dispositivo que posea una interfaz de este tipo, aunque otro sistema puede ser el uso de USB. El tener caso sería un poco más complejo de verlo, sería un poco combinación de ambos, en el que se integra directamente un adaptador (chip) inalámbrico, pero usando internamente una interfaz conocida, como Ethernet o USB.

    La gran mayoría de los routers domésticos que se comercializan tienen capacidades inalámbricas integradas. No obstante, es muy habitual la necesidad de disponer de un dispositivo independiente WIFI que permita desde dotar con tales capacidades a un Router o cualquier dispositivo Ethernet, hasta expandir el rango de otros dispositivos inalámbricos. También es cierto que el, cada vez más, bajo precio de los routers WIFI, los puntos de acceso van viendo como su uso como dispositivos propios va disminuyendo cada vez más.


  • Puertas de Enlace Residenciales

    Los podemos llamar también Routers domésticos/residenciales, modem-router… en realidad son la inmensa mayoría de todos los dispositivos que tienen los usuarios domésticos en sus domicilios, la gran mayoría de ellos incluso cedidos o regalados por su propio ISP. De echo, como ya dijimos técnicamente la mayoría de ellos no son Routers, sino que poseen ciertas capacidades de estos. Su uso es una cuestión meramente económica, de espacio y de estética.

    Si enumeramos el equipo que necesitamos para poder conectar un solo dispositivo por medio de una línea ADSL a Internet, necesitaríamos tan solo un Modem DSL que pudiésemos conectar a nuestro PC. Si quisiésemos poder conectar más de un dispositivo de forma simultanea se necesitaría además del Modem DSL un dispositivo NAT que permita conectar todos los dispositivos de la red a Internet, funciones de routers que puedan redirigir el tráfico de un lado a otro… y por supuesto un Switch que permita la conexión de múltiples dispositivos entre ellos. Pero si además queremos conectividad WIFI tendríamso que disponer de un punto de acceso. Eso hace un total de 4 dispositivos!!: Modem, Router, Switch y Punto de acceso. Evidentemente a nadie le gusta tener en su casa 4 dispositivos diferentes para poder tener acceso a Internet en todos sus dispositivos, y la solución por tanto se llama Puerta de Enlace Residencial, o Modem-Router doméstico. ¿Que son? Pues visto desde un punto de vista electrónico es una placa con diferentes chips, pistas de cobre… pero si se aísla cada parte de esta (de la placa), tendríamos que en realidad es una caja negra en la que se han interconectado en la fábrica los 4 dispositivos entre sí. Esto evidentemente no es del todo correcto, pero funcionalmente tanto a nivel práctico como teórico, es exactamente eso:

    La imagen mostrada podría ser perfectamente una puerta de enlace residencial común. Por un lado tendríamos el MODEM DSL, el cual tendría un puerto de entrada tipo RJ11 (donde se conectaría el cable de teléfono). Por otro lado dispondríamos de un Switch de 5 puertos RJ45, 4 de los cuales se encontrarían expuestos al exterior para poder conectar a ellos 4 dispositivos diferentes, ya fuesen equipos, otros Switchs… lo que se desease. Por otro lado dispondríamos de un pequeño adaptador WIFI que dotaría a la puerta de enlace con tales capacidades. ¿Cual sería el nexo de todos ellos? El Router. Este Router en cuestión dispondría de 4 Interfaces físicas diferentes, llamadas PPP, Eth0, Eth1 y Lo, y una Interfaz adicional virtual llamada Br0:

    PPP: Esta sería la Interfaz del Router encargada de realizar el acceso/conexión al MODEM DSL para poder realizar una conexión PPPoE al ISP. Todo lo que envíe por dicha Interfaz irá directamente a nuestro ISP, para después alcanzar cualquier parte del mundo. Del mismo modo todo lo que llegue por dicha interfaz, se procesará en el Router y se determinará su destino.

    Que todas las Interfaces (Y su homólogo en el módulo respectivo) tengan el símbolo de un Conector RJ45 no es un capricho, y es que podríamos verlo como si realmente estuviesen interconectados  ambos por un cable Ethernet. Evidentemente todo estos dispositivos son integrados, ¿pero que diferencia existe realmente entre un conector RJ45 externo (que tiene 8 pins) a 8 pistas de cobre en la baquelita? En realidad un conector no es más que una pieza que nos ayuda sacar fuera dichas pistas para poder conectar algo de forma externa. Si lo que se quiere conectar es un dispositivo interno, no tiene sentido conector alguno. Es decir, que exista o no un conector físico, no significa que el Router se comunique o se deje de comunicar con las demás partes por medio de Ethernet.

    Eth0: Sería la Interfaz del Router conectada al Switch. A través de ella, el router procesaría todas las solicitudes realizadas al exterior de la red formada por el Switch. Esto es a tener en cuenta, ojo, todos los equipos conectados al Switch no requieren de un Router para hablar entre ellos, el router para ellos es la puerta de enlace, el destino de sus paquetes cuando el host a alcanzar no se encuentra dentro de su red. El Router por tanto tomará las peticiones de entrada (de entrada para él, es decir de salida para los dispositivos conectados al Switch) y las procesará, mediante la tabla de rutado determinará por qué interfaz debe de enviar dichos datos para que puedan llegar a su destino. Del mismo modo cuando el Router tiene que enviar un paquete entrante por su Interfaz PPP hacia el Switch, lo realizará por la Interfaz Eth0

    Eth1: La interfaz Wifi, o la Interfaz a la que está conectado el adaptador WIFI del propio Router. Todos los datos que se envíen o reciban a través de WIFI cruzarán dicha Interfaz. Pero cuidado!! A diferencia de como sucedía con el Switch, aunque el paquete sea enviado a otro host de la misma red (ya sea el otro conectado por WIFI o Ethernet), este cruzará siempre por la Interfaz Eth1

    Br0: Bro es una Interfaz Virtual que se crea en el router para crear un puente entre la Interfaz Eth0 y Eth0. Si recordamos los puentes, es una forma de crear redes. Cuando se realiza un puente de dos Interfaces como ya vimos, todos los dispositivos a ambas partes del puente pasarán a constituir una única red entre ellos, aunque constituyesen dos segmentos de red diferente. Dicho de otro modo, es la forma más simple de la que disponemos para unificar de forma más o menos completa todos los equipos conectados al router, ya sean de forma inalámbrica o por medio de cable, para que formen entre ellos una única red. Así, si el Router tiene que enviar un paquete a la red local, no tiene que saber si debe de enviarlo por la Interfaz Eth1 o a la interfaz Eth0, cada una de ellas dos redes independientes, sino que sabe que lo tiene que enviar a la Interfaz Br0, es decir al puente. Por regla general, cualquier puerta de enlace residencial utiliza este procedimiento si dispone tanto de alguna interfaz inalámbrica.

    Lo: Lo (Loopback) podríamos verla como otra interfaz virtual, la dirección de loopback del propio router, que ya ha sido explicada en más de una ocasión su utilidad.

    Con todo eso, solo hay que establecer una tabla de rutado para que los paquetes puedan circular de forma correcta por el router hacia cada uno de los dispositivos anexos. Por ejemplo, si el destino es el propio router se usará la Interfaz Lo, mientras que si el destino es Internet se usará la Interfaz PPP. Si se quiere, se puede volver a la tabla de rutado de ejemplo del comienzo de la sección de “Routers”, y se comprenderá esto mucho mejor. Esto por supuesto es un poco más complejo dado que nuestro router tendrá funciones NAT o un Firewall implementando, o será a lo mejor el mismo Firewall el que está implementando NAT. Todo eso, en conjunción con otras funciones extras es el papel fundamental que realiza aquí dicho Router. De este modo, se logra tener un solo dispositivo que posee todas las cualidades básicas de cada una de las partes que lo forman internamente. Evidentemente este tipo de dispositivos tan solo existe en el mundo doméstico, y los Switchs o Routers decentes que existen se aleja muchas veces enormemente de las funciones tan específicas de nuestros Routers domésticos

Proyecto. Towner: Destrozando otro juego Flash (Facebook y Tuenti)

No tenía pensado embarcarme en este mini proyecto, cuando la verdad tengo unos cuantos pendientes a los cuales no logro sacarles tiempo. Dejémoslo simplemente en que era algo que tenía que hacer, así mataba un par de pájaros de un tiro. Por el contrario que sucedió con Hammerfest, no tengo absolutamente nada en contra de MetroGames, que si bien creo es la compañía que desarrolló el juego en Flash, por encargo de Facebook y posteriormente de Tuenti. Tampoco es mi intención animar a los Cheaters (tramposos) a hacer trampas en el juego, que aunque existan muchos que su único fin es simplemente ser el mejor de todos (independientemente de como se alcanzó la meta), os recuerdo que esto mata la diversión, y a la larga creo que también lo hace con el espíritu humano.

Es evidente que habrá lectores que no sepa que es “Towner”. Este no es más que un juego realizado en Flash para los usuarios de Tuente y Facebook. El juego trata de construir tu ciudad, para la cual comienzas desde el nivel 1 con muy pocos recursos, y a medida que vas subiendo de nivel con los días/semanas/meses vas pudiendo acceder a más terreno para edificar, nuevos edificios que dan más ventajas y dinero… los nostálgicos recordaremos cierta similitud a Sim City. Con el tiempo puedes realizar también logros que te dan tanto dinero como experiencia. La verdad es que a pesar de que está muy limitado, y sinceramente, y muy mal equilibrado, puede tener cierta adicción, sobre todo quizás por que tiene gran importancia los propios contactos de estas redes sociales que tengas que también juegan, estos te dan dinero, experiencia o logros, y por supuesto poder acceder a la ciudad de tus amigos. El juego implementa también un sistema de pago con dinero real para poder comprar monedas que pueden ser intercambiadas en el juego por dinero de juego, edificios mejores…

Dicho esto podemos ponernos a trabajar. ¿Cual es la intención de este “proyecto”? Al igual que con Hammerfest, poner quizás un poco en evidencia cuestiones que se toman a la ligera en la programación o en la seguridad de los sistemas que se implementan. Así mismo, es una forma perfecta de aprender y tener cada vez una mayor comprensión de las tecnologías de las que disponemos en informática, que no todo es jugar, internet y los videos/fotos XXX. De paso aprovechar para criticar a todos esos Lammers que abundan por Internet que se hacen llamar Hackers o expertos en la materia cuando lo único que saben hacer es ejecutar un programa que hacen otros, sin saber que hay debajo de ello la mayoría de las veces.

Aunque parezca un poco paradójico, aun cuando los chicos de MetroGames han sido relativamente concienzudos para evitar este tipo de  situaciones o chetas, destrozar el juego ha sido quizás más sencillo que con Hammerfest. De todos modos hay que defender el trabajo de los programadores que hay detrás, es su trabajo, y las compañías que están detrás evidentemente lo que intentan es sacar dinero con ellos, con lo que es lógico que quieran proteger sus creaciones. Este tipo de artículos sin duda alguna pone en entredicho su nombre a fin de cuenta. Y aunque sea yo quien lo dice, es una pena que el trabajo de un grupo de programadores, vean como el tiempo en destrozas su criatura es mucho menor al tiempo que se tarda en crearla o hacerla crecer. Pero no divaguemos más y veamos lo que vamos a hacer:

  • Conociendo a tu enemigo: Google, Sniffers y encriptación/desencriptación XOR
  • El enemigo de mi enemigo es mi amigo: Descompiladores, XOR  y RAM. El primer número mágico es 0x66
  • Apretando el gatillo para matar a tu Enemigo: Una de C-al y otra de RAM.


Cuando terminemos podremos controlar entre otras cosas:

  • Los puntos de experiencia
  • El dinero
  • El tiempo de construcción de los edificios
  • El acceso a los edificios de pago
  • La consecución de logros que nos queden



Conociendo a tu Enemigo

Hay muchas formas con las que se puede atacar un sistema, ya sea un equipo físico o un programa informático. El tópico que dice “la imaginación pone el límite” aquí se cumple a la perfección. Siempre que estoy con algún trabajo/proyecto similar, siempre lo planteo del mismo, y lo primero es siempre conocer, cuanto mejor posible, la labor que quieres llevar a cabo. Esto parece una tontería, pero es gracias a esto a que es posible desarrollar lo demás.

Por poco que pensemos, podemos sacar muchas conclusiones:

Es un juego/aplicación Flash incrustada en el navegador, usa nuestros datos de Tuenti/Facebook para acceder y configurar nuestra partida, el juego guarda los datos de la partida a priori cada X tiempo. Esto que parece trivial sirve y para mucho. Por ejemplo, que sea una aplicación Flash ya nos está diciendo que podemos intentar atacar al sistema de 2 formas diferentes!! ya sea modificando el propio contenido Flash o manipulando nuestro propio PC que es quien está ejecutando dicha aplicación. Por otro lado, que use nuestros datos de las redes sociales nos dice casi con toda seguridad que la aplicación Flash deba de tener algún cargador que pase ciertos parámetros de nuestra cuenta de Facebook/Tuenti al juego. Y para terminar, que el juego guarde datos cada X nos abre de nuevo una tercera vía para atacar al sistema, a fin de cuenta son datos que envía nuestro PC al servidor de ellos, y dichos datos pueden modificarse.

En realidad solo es tiempo para que cualquiera de los 3 sistemas posibles para atacar el sistema tenga éxito, pero es evidente que si podemos obtener lo mismo por una vía mucho más rapida, será la que vamos a usar. Antes de comenzar por tanto, vamos a lo más simple del mundo, usar Google para ver si alguien ha hecho el trabajo ya por nosotros, aunque por supuesto, copiar el trabajo de otro no es que sea muy gratificante ni nos ayuda demasiado, pero a veces puede ilustrarnos en nuestro camino. Efectivamente, no son pocos sitios en Internet donde hablan de posibles trampas que pueden hacerse en este juego, que yo haya visto todas usando CheatEngine, y por lo que veo quizás solo fuese efectivo realizarlas hace ya mucho tiempo, antes que actualizasen el juego y le añadiesen ciertas capas de seguridad. CheatEngine es un gran programa en la medida que puede ahorrarnos mucho trabajo, pero una vez más lo divertido no es abrir un programa y seguir un tutorial, sino saber que hace realmente el programa y por qué nos ahorra realmente tiempo. De todos modos, no he visto por la web ningun ataque a “Towner” que sea real… hasta hoy claro.

Una vez que San Google no nos da nada de información sobre Towner que pueda ser de interés, hay que empezar a trabajar, empezando por intentar seleccionar el mejor de los 3 ataques, a priori,  a realizar. Es decir, analizar cada uno de los casos:

  • Atacando al juego modificando los datos que son enviados al servidor cuando la partida se guarda

    La ventaja de este sistema es que es muy fácil llevarlo a cabo, tan solo hace falta colocar un Sniffer y ver que datos son los que nuestro PC está enviando a sus servidores. El problema es que no suele ser efectivo casi nunca, dado que los datos enviados suelen estar codificados/encriptados para evitar que un ojo audaz lea de forma fácil el contenido de dichos datos, y pueda modificarlos sin problema alguno. Aun así, no requiere prácticamente nada para comprobarlo, ni tiempo ni complejidad, con lo que nunca está de comprobarlo. Además, nunca está de más ver si podemos sacar algo en claro de ello, aun cuando los datos vayan protegidos. Con un simple sniffer o proxy podemos interceptar la información, dado que es información que envía nuestro PC a su servidor lo más probable es que sea por medio de un método POST, mirando un Sniffer Tendríamos:

    POST http://social.tuenti.metrogames.com/thetowner-tuenti/ HTTP/1.1
    Host: social.tuenti.metrogames.com
    User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b7pre) Gecko/20101002 Firefox/4.0b7pre
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-us,en;q=0.8,es-es;q=0.5,es;q=0.3
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Keep-Alive: 115
    Proxy-Connection: keep-alive
    Cookie: PHPSESSID=xxxxxxxxxxxxxxxxxxxxxxxxxxxx
    Referer: http://content.ak.metrogames.com/social/thetowner-tuenti/cargadorf788d4aeab3c04950be07c6f4141bd38.swf/[[DYNAMIC]]/1
    Content-type: application/x-www-form-urlencoded
    Content-length: 769

    [bloque de datos]

    Bueno, para empezar podemos sacar algunas cosas en claro. Por la etiqueta Referer podemos inferir que efectivamente todo el juego obedece a una pequeña aplicación cargador que casi con toda seguridad es invocada con anterioridad, el mismo nombre cargadorxxxxxxxxxx.swf deja esto bastante claro. En realidad ese numero largo lo que representa exactamente es el Hash MD5 del propio archivo, un buen sistema para que luego dicho cargador pueda hacer una verificación interna de si dicho archivo ha sido modificado o no: El cargador calcula su propio hash, y si esta coincide con el del nombre del archivo, interpreta que el archivo no ha sido modificado, con lo que es legitimo.

    La intención aquí era ver lo que he simplificado tan solo como [bloque de datos]. Es un chorizo un poco grande y sin mucho interés sinceramente, por eso lo he omitido. Las etiquetas de dicho bloque de datos que son enviados son meta1, amount, meta0, mg_sid y meta2, los datos asignados a cada campo como digo son ilegible, con lo que sería improbable atacar al sistema simplemente modificando sus datos. mg_sid parece ser un ID de usuario, mientras que meta1, meta2 y meta3 probablemente sean campos para verificar que la información es correcta y no se ha modificado y para enviar al servidor nuestros datos. Bueno, dado que tenemos otros métodos de ataque viables, no vamos a buscar más por esta vía, aunque se podría seguir investigando y probando.


  • Atacando al juego modificando la RAM del sistema

    Esta quizás sea la técnica más utilizada en este tipo de aplicaciones. Es simple, al ser una aplicación Flash, esta se ejecuta y procesa en nuestro propio PC, es decir que tanto las instrucciones que se ejecutan de la aplicación como los datos de esta están casi con toda seguridad en la memoria RAM de nuestro equipo, y es algo a lo que podemos acceder sin mucha complicación. Esto es básicamente lo que hace CheatEngine, monitorizar las páginas de RAM que son usadas por una aplicación concreta.

    Este método suele ser muy efectivo, el problema que tiene es que casi todos los programadores del mundo usan diferentes técnicas para evitar que el usuario pueda obtener de la RAM algún dato de utilidad, ya sea escondiéndose lo mejor posible en la RAM para que dichos datos no sean encontrados, ya sea encriptando/codificando dichos datos o ya sea usando algún sistema de checksum para intentar evitar que se puedan introducir datos incorrectos.

    Para ver la viabilidad de este sistema de forma simple, podríamos intentar usar CheatEngine o cualquier edidor/visualizador de RAM para buscar en la memoria reservada al navegador algún valor concreto del juego, por ejemplo el dinero. No obstante, si hiciésemos esto no lograríamos en este caso ningún resultado. El siguiente paso sería usar CheatEngine para intentar averiguar la ubicación de la RAM en la cual se encuentra dicho valor, ya que aunque estuviese encriptado quizás podríamos deducirlo de algún modo. Para esto podríamos ir buscando conjuntos de bytes en la memoria que fuesen cambiando a medida que nuestro dinero (por ejemplo) cambiase, y cada vez reducir más la posible ubicación en memoria. En el mejor de los casos y con mucha mucha paciencia, en este caso concreto, encontraríamos el lugar exacto, aunque por desgracia los datos serían completamente in-interpretables para nosotros:

    Address: 075E11B4 Value: 3254212197
    Address: 075E11B0 Value: -1933194698

    A lo más que llegaríamos sería obtener esas dos direcciones de memoria, cada una conteniendo un dato de 4 Bytes, lo que harían un total de 8 Bytes, teniendo en cuenta que las dos posiciones de memoria son contiguas. Esto podría significar que quizás el valor sea almacenado en 8 Bytes, o por el contrario que cada una de las posiciones almacenase una parte del dinero, o que fuesen dos posiciones independientes siendo una un dato de control de la otra. Las posibilidades son infinitas. De todos modos aun cuando pudiésemos obtener dichas direcciones (que son diferentes en cada ejecución, con lo que esas posiciones mías no le sirven a nadie), sería imposible inferir un valor de ellas. Podemos por tanto suponer que el dinero al menos posee algún tipo de codificación/cifrado que nos impide usar este sistema.


  • Atacando al juego modificando el contenido Flash

    Este sistema suele ser el más complejo, pero el que más información nos puede brindar sobre nuestro objetivo. Dado que es una aplicación Flash, en teoría podríamos ser capaces de descargar dicha aplicación como tal (archivos .swf) y por medio de descompiladores y desensambladores lograr el acceso al código de la aplicación. Modificar lo que deseásemos y volver a montarlo todo sin que el servidor de ellos pueda darse cuenta de que hemos modificado algún contenido de este.

    Hacer esto ya no es tan simple. Principalmente porque las primeras capas de seguridad que se implementan en aplicaciones Flash son precisamente para evitar estos escenarios. No obstante la teoría es correcta, y los resultados suelen ser sorprendentes.

    Como ya hemos dicho, el primer problema al que nos encontramos es que antes de la aplicación tenemos un cargador que controla muchos aspectos de esta, el cargador entre otras cosas vigila que la aplicación en sí sea legítima, lo cual es muy simple de hacer usado algún tipo de CRC. No obstante el cargador mismo es otra aplicación Flash, con lo que aplicando el mismo principio podrámos descargar el cargador, descompilarlo/desensamblarlo, modificarlo para evitar ciertas capas de seguridad y montarlo de nuevo. Tiempo, tiempo y más tiempo. De todos modos hay que intentarlo, así que lo primero que podríamos hacer sería descargar tanto el Cargador como el Juego. ¿Como? A fin de cuenta no deberían de ser más que archivos Flash .swf, con lo que sin complicación alguna un Sniffer podría interceptar las peticiones a ellos y obtener las rutas a dichos archivos de forma manual. Es más, si aun guardamos las peticiones del primer apartado, en teoría deberían de aparecer allí. Mirando los registros anteriores tenemos que en este momento para mí las direcciones serían:

    http://content.ak.metrogames.com/social/thetowner-tuenti/cargadorcargadorf788d4aeab3c04950be07c6f4141bd38.swf
    http://content.ak.metrogames.com/social/thetowner-tuenti/juego648bcec512718feb2868a727888933cb.swf

    Como he supuesto que eran esas? Es cierto que en los registros tengo muchas otras peticiones a archivos swf, pero es evidente que puedo empezar por estas dos, para empezar porque el nombre del archivo comienza por Cargador en el primer caso y Juego en el segundo. Luego con eso ya puedo descargar ambos archivos.

    Los chicos de MetroGames son listos, y si intentamos ondar un pocon en dichos archivos, veremos que efectivamente la estructura del archivo cargador.swf corresponde a un archivo Flash, no es así para el archivo Juego.swf que hemos descargado. Esto podemos verlo si examinamos los primeros 8 Bytes (la cabecera) de sendos archivos:

    Cargador.swf: 43 57 53 0A 82 AF 02 00 | CWS.‚¯..
    Juego.swf:       25 31 35 6C 1A 02 75 66 | %15l..uf

    Los 8 primeros bytes de un archivo flash son siempre los mismos. Los 3 primeros son el ID de los arcivos Flas, serán (en ASCII) CWS para archivos Flash comprimidos y FWS los que no. El byte 4º especifica la versión Flash usada para crearlo y los 4 bytes restantes la longitud de archivo Flash sin comprimir. En el caso del archivo Cargador.swf vemos que coincide perfectamente con lo que sería un archivo Flash, su cabecera CWS (Bytes 46 57 53), Versión 10 (Bye 0A) y un tamaño de 176002 Bytes (Bytes 82 AF 02 00). ¿Pero que sucede con el archivo Juego.swf? Es evidente que algo sucede. Podríamos pensar que no es un archivo swf, pero si examinásemos el resto de arcivo swf que se descargan veríamos que todos tendrían una cabecera igual/similar a este. Lo más seguro por lo tanto que por protección, los archivos Flash del juego sean transmitido al PC de forma encriptada y que sea el mismo Loader (el cargador) quien los desencripta. Esto es un sistema bastante inteligente, ya que el acceso y/o modificación de dichos archivos sería prácticamente imposible, a priori, con lo que todo el código del juego queda protegido.

    No obstante, es evidente que el primer eslabón en la cadena, en este caso el Loader no puede estar encriptado, dado que tiene que poder ser interpretado y procesado directamente por el PC, y es la razón de que este si es enviado de forma “estandar”. Para poder solucionar esto podríamos continuar con el desensamblado/descompilado del cargador, aprender (si es posible) el sistema que usa para desencriptar los archivos y crear un programita o sistema para de este modo poder por fin tener acceso al archivo Flash original del juego. Pero aun cuando esto fuese posible, hay sistemas mucho más rapidos para lograr la misma tarea. No obstante, dado el cifrado tan simple que se ha usado vamos a ver los dos sistemas


Antes de comenzar a despedazar trozo a trozo cada parte, vamos a terminar con este bloque. De los 3 posibles ataques a realizar el primero quedaría descartado. De los otros dos, vamos a usar el primero (modificaciones internas de la RAM) aplicando lo que aprenderemos del segundo (desensamblando el código original. Con lo que a priori nos vamos a encontrar con dos problemas a resolver:

El primero, lograr obtener los archivos desencriptados para poder trabajar con ellos.
El segundo, encontrar en los archivos desencriptados el santo grial, el sistema que están usando los amigos de MetroGames para evitar el Tampering (la modificación en RAM de los aspectos del juego)

 

El Enemigo de mi Enemigo es mi Amigo

 

  • Desencriptación de Juego.swf (y otros archivos)
  • Búsqueda de los sistemas de protección de MetroGames

 

Llegados a este punto debemos de tener en el disco duro una copia de los archivos originales cargador.swf (que como hemos dicho es completamente válido) y un archivo Juego.swf (que como hemos dicho tiene algún tipo de encriptación).

En este aspecto los programadores de MetroGames no han sido muy listos, y aunque la idea era buena no han sabido ponerla en práctica de forma decente. Lo primero que vamos a hacer es realizar la desencriptación del archivo Juego.swf, y lo vamos a hacer de 2 formas diferente: Desencriptándolo nosotros y dejando que dicha labor la haga el cargador

 

  • Desencriptando

    Si queremos poder manejar el archivo Juegos.swf para poder pasarlo por algún descompilador o desensamblador necesitamos tenerlo desencritpado. Vamos a ver como hemos dicho 2 métodos: Dsencriptado manual y desencriptado automático (por asi decirlo). Normalmente ni pensaría en realizar un desencriptado “manual”, sería muy complicado saber cuestiones como el tipo de cifrado, el algoritmo usado, la key… y eso sin contar que el sistema podría ser completamente creado para tal afecto, con lo que la única forma sería desensablar el cargador e intentar encontrar las rutinas de desencriptado, implementarlas en C (u otro lenguaje) y procesar los archivos, y eso en el caso de encontrar en el cargador.swf desensamblado todos los datos que necesitásemos. Pero la verdad es que nos lo han puesto tan fácil que ya sea el desencriptado manual o automático nos va a llevar poco mas o menos el mismo tiempo (y eso que el desencriptado automático es bastante simple).

    Desencriptado Manual

    Lo primero es como siempre suponer. No todas las suposiciones son siempre correctas, y muchas veces hace falta probar varias veces antes de dar con la tecla correcta. Veamos, la encriptación/desencriptación que hayan empleado debería de ser bastante rápida de realizarse, nadie quiere que por un simple juego Flash el procesador comenzase a trabajar sin parar. Por otro lado lo ideal sería emplear un sistema de cifrado que en la medida de lo posible no incrementase el tamaño del archivo, puesto que supondría una mayor carga ya no solo para el usuario final, sino para sus propios servidores. A poder ser, si fuese yo intentaría usar algún sistema de cifrado que fuese simple de implementar, recordemos que Flash (ActionScript) no es el lenguaje C. En cuanto al tipo de cifrado lo normal sería implementar un cifrado de tipo simétrico, en la que la misma key fuese la que encriptase y desencriptase, sobre todo para evitar tamaños de Keys kilométricos. Tambien tenemos una gran ventaja!! Tenemos acceso primero al archivo cifrado, pero también tenemos acceso a parte del contenido no cifrado de este!! Recordemos que conocemos de antemano parte de la cabecera del archivo Flash (Al menos los 4 primeros Bytes sabemos que con casi total seguridad serán 46 57 53 0A)

    Aun con todo esto, suponer el sistema que están usando puede ser algo azaroso. No obstante, para quienes leyeron uno de los capítulos de encriptación, recordará que existe un método de cifrado usado casi universalmente, por no decir que es la base de la gran mayoría de todos los cifrados simétricos que existen a día de hoy: XOR. XOR es una operación lógica entre dos números binarios, cuyo resultado será 1 si ambos dígitos binarios son diferentes (uno es cero y el otro es uno) o cero si ambos dígitos son iguales. Es decir, 0000 XOR 1111 = 1111, 0011 XOR 1010 = 1001. Este sistema tiene la peculiaridad que puedes conocer cualquiera de los 3 miembros sabiendo tan solo dos de ellos y realizando entre ellos la operación XOR. Este tipo de cifrado generalmente toma los datos de Byte en Byte y va realizando XOR a cada uno de ellos con una key. Dicha Key no hace falta que sea dele mismo tamaño que los datos originales, normalmente lo que se hace con ella es o un flujo de Key (en el caso de los cifrados de flujos) o simplemente se repite una y otra vez la key para aplicarla a todos los datos de entrada. Es decir supongamos que tenemos los Bytes: 46 57 53 0A y nuestra key fuese 05. El resultado de dicho cifrado sería tomando cada Byte y aplicando a cada uno la operación XOR con el byte de la clave (05 en este caso).

    Dejando la teoría a un lado, por suerte para nosotros y mala suerte para MetroGames, ellos no hacen otra cosa que realizar precisamente un cifrado XOR, usando como Key únicamente un Byte, el cual se repite para cada Byte del archivo cifrado. Así obtienen un cifrado que no aumenta el tamaño del archivo, que lo hace aparentemente seguro para ojos indiscretos y que es muy rápido y simple de implementar. Es decir:

    Primeros Bytes Cifrados del archivo Juego.swf:
    25 31 35 6C 1A 02 75 66

    Clave XOR (aun desconocida)
    XY XY XY XY XY XY XY XY

    A priori desconzco la clave XOR, aunque ya he adelantado que es una key de un solo Byte que se repite, con lo que a cada Byte del archivo cifrado se le aplicará la misma operación con la mismo valor. Como podemos inferir dicha Key? Bueno, en este caso no hace falta profundizar. Si recordamos la breve teoría que expuse anteriormente, es muy facil obtener el tercer operando de una operación XOR si tenemos 2 de ellos. En este caso no tenemos el segundo operando, la key, (Enc XOR Key = Desenc) pero si dispongo del primero y de parte del resultado!!:

    25 31 35 6C 1A 02 75 66 <- 8 primeros Bytes del archivo encriptado
    43 57 53 0A xx xx xx xx <- 4 primeros Bytes Conocidos que tendrá el archivo desencriptado

    66 66 66 66 xx xx xx xx <- Resultado obtenido al realizar la operación XOR Byte a Byte.

    Curiosamente vemos que los 4 primeros Bytes devuelven el mismo valor hexadecimal: 0x66. Es decir, que la clave Xor para esos 4 primeros Bytes es 0x66. Evidentemente si se repite la misma para los 4 primeros Bytes, podemos suponer que la clave XOR que se ha usado para encriptar TODOS los datos no es otra que 0x66. Si esto es cierto, bastaría con aplicar XOR a todo el archivo encriptado con el valor 0x66 para cada uno de los bytes de este. El resultado debería de ser el archivo Juegos.swf desencriptado. Realizar el proceso a mano evidentemente no es viable. O se hace uso de algún programita o se implementa uno en un momento, lo cual no tendría mayor dificultad. Personalmente dado que tengo ya instalado (y hago buen uso de él) WinHex, voy a realizarlo con él. No tengo más que abrir el archivo Juego.swf encriptado con Winhex, Edición -> Modificar datos. Llegados a este punto solo tengo que seleccionar XOR e introducir 66. Y listo, el archivo desencriptado al instante. No podemos ver ningún dato de interés porque recordemos que los archivos flash con cabecera CWS están comprimidos. Pero puedo garantizar que el resultado es un archivo swf que podemos guardar como Juego_des.swf.

    De todos modos hemos llegado ha este punto suponiendo muchas cosas. Podríamos a ver dado muchos palos de ciego o incluso no lograr absolutamente nada. Tampoco estaría nada perdido. Dado que tenemos acceso al archivo Cargador.swf, podríamos descompilarlo/desensamblarlo y buscar en su código algún indicio del sistema de cifrado usado, así como la key. En este caso tampoco habría sido uan cuestión complicada si se sabe donde mirar. Por motivos legales no puedo copiar evidentemente código desensamblado de otros sin autorización (y dudo mucho que me la den). Si os puedo decir sin duda alguna que encontrar el tipo de cifrado es muy fácil, sobre todo si se han usado nombres descriptivos. En C, el código necesario no sería otra cosa que:

    while (indice < sizeof(Buffer))
    {
    Buffer [indice] = Buffer [indice] ^ clave;
    }

    En C la operación XOR se realiza mediante el operador ^, el reto es más que evidente. Básicamente en el buffer estaría almacenado el archivo encriptado, simplemente a cada byte de este se le iría aplicando XOR con la clave, y almacenando el resultado en la msima posición. Por otro lado, encontrar la key tampoco debería de ser un problema, y cuando lo fuese, sabiendo que el sistema usado es un cifrado XOR byte a Byte, podríamos aplicar lo anteriormente explicado.

    Desencriptado Automático

    Y por supuesto, tenemos el método de siempre. Si es un archivo Flash, esté encriptado o no, en algún momento este se deberá de desencriptar para que pueda ser usado. Si se desencripta, quedará almacenado en algún lugar. ¿Donde? En la RAM por supuesto. Esto quiere decir, que cuando la aplicación esté en ejecución, tendremos la certeza de que en algún lugar de la RAM dicho archivo encriptado Juego.swf se encontrará desencriptado. Solo hay que buscarlo y hacer un volcado de dicha sección de la RAM a un archivo, que nombraríamos Juego_des.swf. ¿Como? Tenemos en la red multitud de programas para tener acceso a la RAM. En mi caso de nuevo uso WinHex (un gran programa sin duda). Solo tengo que abrir la sección de RAM que está usando mi navegador para la aplicación Flash que se está ejecutando. Dado que estoy usando Firefox 4.0 beta, todo el contenido Flash no se ejecuta en el espacio de Firefox, sino de un proceso llamado plugin-container.exe. Tan solo tengo que acceder al espacio reservado para tal efecto con Winhex. Una vez abierto habría que buscar el contenido desencriptado. ¿Como?. Bueno, es fácil. Sabemos como es la cabecera de un archivo Flash. Con ello, si tenemos cerrado todas las demas pestaás de nuestro navegador, no nos costará nada encontrar el inicio del bloque que buscamos. OJO!! Las aplicaciones Flash recordemos que suelen estar comprimidas, pero una vez procesadas, en RAM se encuentran DESCOMPRIMIDAS!! Esto quiere decir que la cabecera a buscar no serían los Bytes 43 57 53 0A (correspondientes a un archivo flash CWS), sino que tendríamos q buscar por los Bytes 46 57 53 0A, correspondiente a la cabecera FWS, es decir sin comprimir. Lo más seguro es que al 5 intento como mucho demos con el inicio de bloque:


    La imagen no ha podido salir peor… lo importante es que en mi caso en la primera iteración ya apareció el bloque buscado. Como se puede saber si es realmente el buscado u otro? Hombre, con un poquito de sentido común. Por ejemplo, si se mira un poquito más abajo se puede leer perfectamente “Juego”, demasiadas casualidades. Teniendo el inicio de bloque tan solo habría  que extraer el bloque comprendido de su inicio a su fin. Esto también es tremendamente sencillo. Recordemos que los Bytes 5-8 indican el tamaño en Byte. En este caso tenemos que el tamaño en Bytes = 7C 64 13 00. WinHex automáticamente nos dice que si interpretamos todo ello como un valor de 32 bits en LittleEndian, el resultado es 1270908 Bytes. Si se quiere calcular tan solo hay que introducir el número al reves en cualquier calculadora (LittleEndian). Es decir 0x13647C = 1270908 (en Bytes). Si marcamos el inicio de bloque, nos desplazamos a un offset relativo al inicio de bloque de 1270908 Bytes, marcamos el fin de bloque y copiamos/extraemos/cortamos dicho bloque a otro archivo, habremos obtenido de otra forma el archivo Juegos_desc.swf

    La única diferencia entre el desencriptado automático y manual es que en RAM se encuentra también descomprimido. El tenerlo descomprimido o no, es indiferente. Si necesitamos tenerlo descomprimido para intentar dilucidar algo de este, bastaría con procesador cno cwstofws o con Flasm para realizar tal tarea. La cuestión es que al finalizar, tendremos un archivo Juegos.swf completamente desencriptado y listo para asaltar.


  • Buscando los sistemas de protección

    Si logramos atacar directamente el archivo Juegos.swf y comprender sus secretos, no nos hará falta tener que lidiar con las protecciones dele cargador ni con volver a compilar los originales una vez modificados. Aquí por tanto entraría la fase pura y dura de Descompilación/Desensamblado del archivo Juegos.swf.

    Esto es sumamente simple con los programas adecuados, pero tenemos aquí el mismo problema, no puedo copiar/pegar código desensamblado/descompilado, puesto que no sería legal. Es legal hacerlo en casa y usarlo como mejor me venga, pero no distribuirlo, lo siento. No obstante si puedo ir diciendo a groso modo cuales fueron los pasos que realicé.

    En mi caso me bastó con usar un desemsablador como el de sothink, que en su versión Trial es más que suficiente, tan solo queremos echar un ojo. Podríamos haber usado otras herramientas como Flasm, pero por desgracia hace tiempo que no se actualiza y no es capaz de procesar los archivos Flash 10. Si descompilamos el archivo original con este programa, podremos tener acceso a todo el código original AS (ActionScript) de la gran mayoría del juego. AS no es muy complicado de entender, y cualquier programador amateurs debería ser más que capaz de interpretar casi todo lo que ve.

    Aun así hay que aplicar un poco la lógica. ¿Que estamos buscando? No se trata de leer el código de inicio a fin, no estamos tan locos, solo necesitamos información que nos pueda resultar útil para llevar a cabo nuestra tarea, como en el pasado pudo serlo en buscar la key o el sistema de cifrado del cargador. Lo primero es buscar la tabla o estructura donde se almacena cada uno de los objetos que hay en el juego: Casas, edificios, elementos de decoración… Dado que cada elemento tiene una serie de propiedades, lo más normal es pensar que en algún lugar del código se especifica dicha estructura. Con prueba error es fácil encontrarlo. Podemos comenzar buscando por ejemplo la palabra “house” (de Red House, o casa roja). Al primero o segundo intento nos toparemos de lleno con lo que parece sin duda alguna una estructura. No hace falta ser un Einstein para ver más o menos la estrcutura que están usando. Parece que usan un objeto estructurado en el que van almacenando uno a uno todos los datos relativos a dicho objeto, como el dinero que cuestan, el tiempo (en segundos) de fabricación, el “tuenti-Crédito” que cuesta en los objetos que son de pago… etc etc. Siguiendo la misma lógica vemos que la aplicación en ese punto del código está preparando lo que será la estructura que se mantendrá en memoria con todos los objetos del juego, lo cual es muy importante. Ya no solo porque de un plumazo tengamos acceso a TODOS los objetos del juego y sus parámetros, sino porque si somos un poco cuidadosos podremos ver el motivo por el cual no podemos usar el método de búsqueda en RAM de los valores del juego (dado que están protegidos). Si nos fijamos bien, muchos de los parámetros son pasados a la estructura por una función especial, llamada protectint o algo así. Es decir, una función que curiosamente se llama Proteger Enteros (números enteros). Es decir, algunos valores antes de copiarse a la estructura que quedará en RAM se pasan por una función extraña, que casi con toda seguridad modificará los datos de algún modo y devolverá unos datos diferentes, que serán los que serán almacenados y usados en toda la aplicación. Esta función es la responsable que nos sea imposible localizar valores en RAM relativos al juego.

    En realidad una vez que veamos esto, el resto es coser y cantar. Con un poco de suerte dicha función se encontrará definida e implementada en el mismo código del archivo Juego.swf. Si es así podemos comprender que está realizando exactamente, y una vez que lo comprendamos replicar dicho comportamiento, ya sea a mano si es simple o en C si es laborioso. Si rastreamos la función, veremos que en realidad la tarea que lleva a cabo es muy simple. Llegado a este punto sí puedo pegar el código que podemos encontrar en AS. Más que nada porque la función que han usado los amigos de MetroGames no la han desarrollado ellos, sino que prácticamente la han calcado a una usada en otro proyecto (que no es de ellos). El código de unos no es exactamente el mismo al código que voy a pegar aquí, pero vamos… lo que nos interesa es exactamente igual. El orignal lo podemos encontrar AQUI, en Google Code. Voy a pegar las funciones que nos interesan:

    private const ENCRYPT_CONST:int=286331153;
    private static const CONSTANT:int=1716716216;
    private static const ROUNDS:int=10;
    private static const POLY:uint=3172090000;

    public function ProtectedInt(arg1:int=0)
    {
    super();
    _value = encode(arg1);
    checksum = getChecksum(_value);
    var loc2:*;
    var loc3:*;
    var loc1:*;
    loc1 = protectIntCount++;
    protectDict[loc1] = this;
    return;
    }

    private function encode(arg1:int):int
    {
    var loc1:*;
    loc1 = undefined;
    loc1 = 0;
    arg1 = arg1 + CONSTANT;
    loc1 = 0;
    while (loc1 < ROUNDS)
    {
    if ((arg1 & 1) != 0)
    {
    arg1 = arg1 >>> 1 ^ POLY;
    }
    else
    {
    arg1 = arg1 >>> 1;
    }
    loc1 = (loc1 + 1);
    }
    return arg1;
    }

    private function getChecksum(arg1:int):int
    {
    var loc1:*;
    loc1 = undefined;
    loc1 = undefined;
    arg1 = arg1 + ENCRYPT_CONST;
    loc1 = 0;
    while (loc1 < 10)
    {
    arg1 = arg1 >> 1 ^ (arg1 & 1) * 2567483615;
    loc1 = loc1 + 1;
    }
    return arg1;
    }

    En realidad lo que realiza la función ProtectedInt() es simple. Según su implementación genera dos valores que serán los que finalmente serán almacenados. El valor real que será convertido por medio de la función encode (), y otro llamado CheckSum que será calculado respecto al valor ya convertido a través de la función getChecksum. Aunque no expongo el resto de las funciones que toman parte en ello, si indicar que cuando se lee o se establece un nuevo valor, la aplicación comprueba si este es válido o no por su CheckSum. Esto es muy facil de comprobar, la aplicación calcula con la misma función el checksum del valor introducido/leido y lo compara con el que tiene almacenado. Si coincide da por bueno el valor, si no coincide nos obliga a refrescar el navegador, e internamente computa un aviso con “Eres un tramposo” o algo similar.

Con esto ya tenemos todo, ya podríamos estar perfilando el final de todo esto. Tenemos lo fundamental, el código de protección usado para enmascarar la RAM y hacer inviable la modificación directa sobre ella. Esto lo realiza como hemos visto de dos formas. Primero codifica el valor por medio de una función, con el fin de que sea imposible su localización en la RAM a priori, además de evitar que el valor crezca o decrezca de forma predecible. Por otro lado, cada vez que se lee o se escribe un valor protegido se le comprueba el checksum para asegurar que el valor introducido/leido es válido. De este modo aun cuando supiésemos el lugar exacto en memoria que ocupa por ejemplo el dinero, tampoco nos serviría de nada poner números aleatorios con la esperanza de que uno de ellos al pasar por la función de codificación diese como resultado un número alto, ya que aun cuando se diese dicha casualidad, al comprobarse dicho valor contra el checksum almacenado, se invalidaría inmediatamente. Es decir, vamos a tener que jugar siempre con dos valores: El valor codificado y el checksum de dicho valor.


Apretando el Gatillo

Ya solo queda poner en práctica todo lo que se ha logrado, y aunque parezca mentira todos y cada uno de los pasos tenían un fin, completamente necesario para el siguiente paso.

Dado que tenemos acceso a las funciones de encriptación y checksum, siempre podríamos coger papel y lapiz, pero es evidente que sería muy poco práctico. Ya que hemos comenzando, no nos cuesta demasiado escribir unas líneas en C para implementar el comportamiento antes visto, es decir, algo así como traducir ese pequeño código de AS a C/C++. Podría terminar todo esto simplemente pegando el código de la mini aplicación que he creado para calcular dichos valores, o mucho mejor, subir la aplicación ya compilada para que cualquiera pudiese darle a ejecutar y entretenerse en hacer trampas. No obstante este no es el objetivo de este artículo. La experiencia nos dice que si le das un caramelo a un niño se lo va a comer, cuando a lo mejor solo querías enseñarle las personas que han trabajado en él. Así que si no publico ni lo uno ni lo otro, al menos estoy obligando a quien realmente quiera hacer trampas a convertir el código en C, compilarlo por él mismo y terminar él solo, no obstante si cualquiera tiene cualquier duda relativa al código en C a escribir o realmente quiere aprender con todo esto y se queda trabado en algún sitio, es libre de preguntar lo que desee. Espero que se comprenda.

Cuando todo se ha terminado, tendremos disponible una pequeña aplicación llamada Towner.exe que al ejecutarla nos pediría por pantalla un número. Al darle a enter nos calcularía tanto el valor codificado como el Checksum asociado a dicho valor. Esos dos valores son los que nos servirán para buscar en la RAM. Por ejemplo, si tengo 10 millones de monedas y quiero saber donde y como está almacenado en RAM dicho valor, tendré que pasar por el programa el número 10 millones. Será el nuevo valor obtenido el que busque en RAM. Es por eso que en realidad no es necesario realizar el proceso de desencriptado del valor, solo el de encriptado. Del mismo modo si quisiese modificar el lugar en el cual se almacena mi dinero, una vez que tengo el lugar localizado, buscando previamente por el valor almacenado en RAM, calcularía un nuevo valor (por ejemplo 500 millones). Ya solo tendría que sustituir en RAM los valores viejos (el valor y el checksum) por los valores nuevos. Veamos todo esto con algunas pantallas, supongamos que deseamos cambiar el tiempo de construcción de TODOS los elementos de 24 horas a 1 segundo:

  • Necesitamos conocer el valor real y el checksum que el juego guarda en su estructura interna, que está RAM

    queremos cambiar de golpe TODOS los tiempos de fabricación de 1 día a 1 segundo. Los tiempos, como vimos en el código, se expresan en segundos, luego 24 horas = 86400 segundos. Lo primero por tanto será calcular el valor codificado y el checksum de 86400:

  • Una vez conocido los valores, encontrar sus posiciones en la RAM

    Podemos utilizar por ejemplo CheatEngine o WinHex para encontrar la posición de dichos valores. Una gran ventaja de que los valores estén codificados, es que es muy poco probable que en la zona de memoria que vamos a buscar se encuentren otros valores iguales que no pertenezcan a la estructura de objetos. De decir, si buscásemos por ejemplo el valor 86400 es posible que apareciese cientos de veces en toda la RAM asignada a plugins-container.exe, incluso aun cuando dicho valor fuese el real guardado por la estructura de datos!! lo que significaría tener que filtrar todos aquellos que no perteneciesen a la misma estructura de datos. Una cosa es modificar una estructura de datos en la que sabemos que estamos haciendo, y otra muy diferente modificar posiciones de memoria que no sabemos a que se están usando!! Aviso, modificar la RAM puede tener resultados fulminantes e inmediatos si modificamos lo que no debemos, es de suma importancia saber siempre que estamos modificando con seguridad. En cambio, el valor 4014934722 es mucho menos probable que sea encontrado sin que pertenezca a dicha estructura. De todos modos una de las medidas de protección es también una ventaja, el Checksum. Dado que existe un CheckSum por cada valor protegido, si encontramos 100 instancias de un valor y solo 50 de su CheckSum pareja, podremos filtrar sin problema alguno los 50 que NO SON nuestro objetivo y que pertenecen simplemente a otro proceso o es memoria sin uso.

    Con esto, debería de ser muy simple encontrar las posiciones. Para el valor = 4014934722, obtenemos 131 instancias, para el CheckSum = 794834924 otras tantas, luego podemos estar más o menos seguros que son todas instancias o valores que usa el juego para un valor de 86400 segundos (24 horas). Ojo!! No estamos filtrando más, eso quiere decir que en esas 131 entradas estarían no solo los tiempos de construcción de todos los objetos de 24 horas, sino también por ejemplo aquellos tiempos de reparación que son también 24 horas. Es decir, cualquier parámetro con un valor de 24 horas que el juego pueda usar, entre ellos por supuesto los tiempos de fabricación:


  • Una vez tenemos las 131 x 2 posiciones, calculamos el nuevo valor para 1 segundo y los introducimos.

    Queremos modificar los tiempos a 1 segundo, eso implica que debemos calcular con nuestra pequeña aplicación los valores para 1 segundo. Por motivos más que obvios no voy a poner los valores tanto de 24 horas como de 1 segundo, o algún listillo tendría todo lo necesario para al menos realizar dicha modificación.

    Una vez tenemos los valores correcto, tan solo tenemos que modificar las 131 primeras entradas por el nuevo valor, y las 131 siguientes con el Checksum correcto.



Conclusión

¿Cual es el resultado a todo esto? Bueno, del ejemplo anterior sería este:


Y por supuesto dichos edificios pasarían a tardar tan solo 1 segundo en construirse. Podría haber optado por mostrar que sucede al modificar la experiencia o el dinero, pero este cambio tan solo tendrá efecto mientras no vuelva a cargar el juego, dado que no son datos que se guardan en el servidor. Repito que esto tiene tan solo fines teóricos y didácticos, no queremos tramposos entre nosotros.

Una vez que tenemos la “formula de oro” el resto es solo la imaginación. Por ejemplo si estableciésemos un cero al precio de las tuentimonedas del cohete, podríamos crear tantos cohetes quisiésemos sin pagar nada, o tener acceso a objetos de otros niveles, o completar aquellos logros que aun nos faltan, como por ejemplo el de la fabricación de 10.000 casas.

 

El objetivo de este tipo de artículos continúa siendo el mismo, el darles un tirón de oreja a los programadores despistados que trabajan con este tipo de tecnologías. Ya no solo a los amigos de MetroGames, sino a cualquier otro que esté embarcado en proyectos similares. De echo hay que decir que los amigos de MetroGames no han hecho un trabajo demasiado malo protegiendo sus intereses. Quizás el usar un cifrado XOR simple sea demasiado cutre, aunque es verdad que simplemente con ello te quitas de un plumazo a todo aquel listillo que intenta descargar manualmente la aplicación Flash Juego.swf, y se lleva la sorpresa de que aparenta ser un archivo corrupto, cuando en realidad está cifrado. Sobre las protecciones que implementan para enmascarar la RAM en realidad es que no pueden hacer mucho más. Se podría intentar complicar, por ejemplo usando funciones propias de AS que fuesen muy difíciles de implementar en otros lenguajes como en C, lo que añadiría mayor complejidad al asunto. Pero bueno, no voy ahora a pensar posibles mejoras del juegecito, primero porque no me pagan para ello y segundo porque creo que ya he invetido suficiente tiempo en ello.

Un saludo a todos, y en especial para mis… “sobrinos”, sin los que sin duda no habría tenido interés alguno en destrozar este juego de Facebook y Tuenti.

Seguridad: Sniffing. Capítulo Segundo-> Protocolos IP, DNS, TCP/UDP y Ethernet/ARP

ATENCION: Los ejemplos que se van a mostrar y “tutoriales” tan solo tienen carácter educativo. En ningún aspecto comparto filosofías de invasión a la intimidad, ataques contra un sistema informático o cuestiones similares. En la medida que sea posible siempre se usarán ejemplos y formas que puedan ser usados por cualquier persona, de forma que pueda verificar los contenidos escritos. No obstante, por motivos más que obvios, materiales como contraseñas, nombres de usuarios o de hosts, serán omitidos o modificado en las capturas de pantallas realizadas (o las lineas escritas). Es decir, los ejemplos serán completamente reales, los datos mostrados a vosotros necesarios para poder pertrechar estos ejemplos no siempre lo serán (Sí lo serán los resultados). Para que esto conste de forma clara, todo material sensible modificado o falso estará resaltado en ROJO. Por motivos de seguridad, todo el material que sea expuesto aquí (exceptuando software propietario o libre, citaciones expresas o código de terceros) tanto texto, imágenes y código son propiedad del autor y está completamente prohibido su reproducción completa o parcial en otros lugares, espero que se comprenda.

 

Protocolos ARP, IP, DNS y TCP/UDP

Internet como estructura básica está muy bien, pero es necesario así mismo una serie de protocolos que haga posible la comunicación entre distintos dispositivos interconectados por todo el mundo. Imaginemos dos personas, una en España y otra en Francia, una habla español y la otra francés. Para comunicarse hacen uso del teléfono ordinario, lo cual hace que puedan hablar de forma simultánea, en tiempo real y de forma eficaz. Pero si habla cada uno en un idioma diferente será imposible que se entiendan. Es decir, es necesario una serie de protocolos, de normas, de… para que todos entiendan correctamente todo. Vamos a tratar quizás los más importantes de ellos de cara a nosotros, no significa que no existan otros protocolos igualmente importantes o imprescindibles, pero estos son los que para nuestra tarea es importante conocer bien:

  • IP
  • DNS
  • TCP/UDP
  • Ethernet/ARP

Hay que tener presente que estos protocolos no nacen de la nada, nacen de la necesidad de crear comunicaciones fiables, que perduren en el tiempo, que sean eficaces y simples en la medida que sea posible. Comencemos entonces.

 

 

Protocolo IP

Las siglas IP provienen de “Internet Protocol” (Protocolo de Internet), no obstante esto puede ser confuso, dado que el término IP puede hacer referencia a la suite de protocolos IP que hacen posible el modelo TCP/IP, o incluso podemos referirnos muchas veces a IP para designar una “Dirección IP”. Pero detrás de todo ello, IP en sí no es más que un protocolo más que hace posible el modelo TCP/IP, aunque por supuesto pueda ser uno de los más importantes en todos ellos.

El objetivo del protocolo IP es poder entregar/recibir paquetes (recordemos que en el nivel 3 del modelo OSI, nivel de red, la unidad de información se denominaba paquete) a/desde diferentes orígenes y destinos, de modo que cada paquete tenga un origen y un destino claro. Dicho de otro modo, es el protocolo que indica el host al que se debe de enviar el paquete o el host que lo está enviando. Aunque la referencia más inmediata que solemos tener del protocolo IP es el aspecto de una dirección IP, no podemos olvidar como se hace esto posible o que significa eso que se conoce como dirección IP. Actualmente, existen dos especificaciones diferentes para el protocolo IP, aunque sería más correcto hablar de versiones diferentes. Una es la que aún se encuentra como uso mayoritario, posiblemente copando el 98% de todo Internet a día de hoy y conocida como IPv4. La segunda aun en expansión y de implantación muy lenta desde hace ya muchos años su sucesora, IPv6.

 

IPv4

Quizás la diferencia más señalada de estas dos versiones tiene relación directa con el espacio de direcciones que soporta cada una de estas. De este modo, el protocolo IPv4 permite tan solo direcciones IP de 32 bits, lo que quiere decir que aun si se pudiese asignar una a una todas las direcciones de forma independiente (aunque esto no funciona así), “tan solo” se tendrían disponibles un total de 4.294.967.296 direcciones diferentes. 4 Mil millones de direcciones pueden parecer suficientes si tenemos en cuenta que el planeta cuenta con una población aproximada de unos 6 mil millones de habitantes. No obstante el crecimiento de los dispositivos a la red ha tenido en los últimos años un aumento exponencial. Ni siquiera las tecnologías de traducción de direcciones como NAT, el uso por parte de los ISP de direcciones IP dinámicas o los espacios IP reservados para redes privadas son suficientes para evitar el agotamiento de direcciones IPv4, lo que ha producido que a día de hoy el espacio de direcciones IPv4 esté literalmente agotado. Si los datos son ciertos, y parece que lo son, a día de hoy la ICANN habría ya entregado el último paquete de direcciones IPv4, estando por tanto disponibles tan solo los paquetes de direcciones IP gestionados por los propios gobiernos regionales. Estamos en el año 2010, y parece que con toda seguridad en uno o dos años todo el espacio de direcciones esté completamente agotado.

¿Qué es una dirección IPv4?

Casi con toda seguridad, cualquier lector que pueda estar leyendo estas letras habrá visto alguna vez una dirección IPv4, la cual no es otra que un número dividido en 4 octetos. En realidad, la división de ese número de 32 bits en 4 octetos es meramente una cuestión de comodidad a la hora de poder trabajar con ellos, es por ello que no se suele usar la notación hexadecimal siquiera, la cual tendría más sentido dado que acortaría la dirección a la hora de recordarla y/o escribirla:

11000000

10101000

00000000

00000001

C0

A8

00

01

192

168

000

001

La representación clásica de estas direcciones es por tanto la separación de cada octeto con un punto: 192.168.0.1

Hemos dicho anteriormente que no era cierto que en un espacio de direcciones IP de 32 bits se pudiesen tener otorgar 2^32 direcciones diferentes. El sistema de dirección IPv4 reduce considerablemente este número debido a su propio funcionamiento, como por ejemplo direcciones reservadas, subredes, direcciones broadcast…

En realidad, una dirección IP no identifica tan solo el host origen/destino, sino también la subred a la que pertenece. Históricamente se utilizó la misma división de los octetos como divisiones entre redes y host, de este modo se podía usar el primer, segundo y tercer octeto para la identificación de las redes, y el segundo, tercero y cuarto octeto para la identificación de los host. De este modo por ejemplo, si pudiésemos disponer de todo el espacio IPv4 para nosotros podíamos utilizar tan solo el primer octeto para identificar una red concreta y el resto de los 3 octetos para identificar los host. Es decir, podríamos constituir un máximo de 256 redes diferentes, cada una de ella con 2^24 hosts. Recordemos que un octeto son 8 bits, 256 valores diferentes. Pero si lo que necesitásemos sería tener muchas redes y pocos host podríamos del mismo modo hacerlo al revés, tener 2^24 redes diferentes y cada una de ella con 256 hosts.

A día de hoy esta práctica es normal encontrarla en redes simples, pero esto no es en modo alguno una norma, y es posible usar el número de bits que se desee tanto para el número de las redes como el número de los hosts, es decir… podemos poner un punto de separación virtual en cualquier lugar de los 32 bits de una dirección IPv4. Es por ello que se requiere de un sistema o de algún identificador que diga que parte será la usada para una tarea y para la otra. Y es cuando aparece la “Máscara de subred”. Se llama máscara porque realmente lo que hace es enmascarar los bits que se usarán para cada tarea. Básicamente se realiza una operación AND lógica entre la dirección IP origen/destino y la máscara de subred. Aquellos bits que son cero serán los que identifican el host, y el resto estará indicando exactamente la subred. La única restricción es que los bits usados para una cosa o la otra deben ser consecutivos, no se pueden intercalar bits para ser usados como subred/host. Visto esto, supongamos que tenemos la misma IP ejemplo anterior:

11000000 10101000 00000000 00000001 -> Dirección IP binaria del host, correspondiente a su notación decimal: 192.168.0.1
11111111 11111111 11111111 00000000 -> Máscara de Subred, correspondiente a su notación decimal: 255.255.255.0
—————————————————- -> Operación Lógica AND
11000000 10101000 00000000 00000000 -> Red: 192.168.0 Host: .1 (192.168.0.1)

Otra forma común de expresar la máscara de subred es utilizando una barra inclinada después de la dirección IP especificando el número de bits que se han otorgado para la identificación de la subred. Por ejemplo, continuando con el ejemplo anterior:

IP: 192.168.0.1
Máscara: 255.255.255.0

Podríamos expresarlo como:

192.168.0.1/24 dado que en realidad son 24 bits los que han sido usados para la subred. En este caso el esquema coincidirá con la separación de la subred/host por los octetos, pero como hemos dicho, la máscara podría haber sido perfectamente 255.255.255.240.0 -> 192.168.0.1/20 lo que significaría que la parte de la red es identificada por 20 bits.

¿Por qué es tan importante tener configurado correctamente esta máscara? Los nodos de red como los routers necesitan conocer a quien enviar cada paquete. Para hacer esto el router tiene que mirar en sus tablas de rutado, de este modo puede identificar la subred al que pertenece el destino y enviárselo. Si la máscara de subred no es correcta, el router no dispondrá en sus tablas de rutado dicha red, y no podrá entregar el paquete.

Aunque cualquier sistema interno podría hacer uso cualesquiera del protocolo IP y de sus direcciones, este no es empleado de forma arbitraria. En teoría se podría usar cualquier máscara de subred para cualquier IP, pero la ICANN ya desde el principio (como máximo organismo que mantiene u otorga las IP) tiene perfectamente definido diferentes clases de IP y su finalidad. Podemos decir que todo el espacio de direcciones IP se encuentra perfectamente organizado en 5 diferentes clases:

Clases

Bits Primer Octeto

Rango IP

Máscara de Red

Número de Redes

Hosts/red

Direc. Broadcast

Clase A

0xxxxxxxx

1.0.0.0-126.255.255.255

255.0.0.0

126

16777214

x.255.255.255

Clase B

10xxxxxx

128.0.0.0-191.255.255.255

255.255.0.0

16382

65534

x.x.255.255

Clase C

110xxxxx

192.0.0.0-223.255.255.255

255.255.255.0

2097150

254

x.x.x.255

Clase D (Multicast)

1110xxxx

224.0.0.0-239.255.255.255

Clase E (I+D)

11110xxxx

240.0.0.0-255.255.255.255

 

Propósito

Rangos IP Reservadas

Máscara de Red

Número de Redes

Hosts/red

Direc. Broadcast

IP “Comodín”

0.0.0.0-0.255.255.255

255.0.0.0

1

16777214

0.255.255.255

Loopback

127.0.0.0-127.255.255.255

255.0.0.0

1

16777214

127.255.255.255

Enlace Local

169.254.0.0-169.254.255.255

255.255.0.0

1

65534

169.254.255.255

Sin Uso

192.0.0.0-192.0.0.255

255.255.255.0

1

254

192.0.0.255

TEST-NET-1

192.0.2.0-192.0.2.255

255.255.255.0

1

254

192.0.2.255

6TO4

192.88.99.0-192.88.99.255

255.255.255.0

1

254

192.88.99.255

Pruebas

198.18.0.0-192.19.255.255

255.128.0.0

2

131070

198.19.255.255

TEST-NET-2

198.51.100.0-198.51.100.255

255.255.255.0

1

254

198.51.100.255

TEST-NET-3

203.0.113.0-203.0.113.255

255.255.255.0

1

254

203.0.113.255

Broadcast

255.255.255

1

1

255.255.255.255

 

Antes de explicar algunas peculiaridades de este sistema, se hace necesario hablar ya de IP Privada Vs IP Pública

Del esquema anterior se podría inferir que la ICANN podría asignar cualquier IP o rango de estas a cualquier entidad/organización/persona que desease, pero esto no es así. No solo ya de por sí podemos ver que algunos de los rangos mostrados ya de por sí se encuentran reservados para propósitos específicos (los cuales hablaremos más adelante) y que podemos llamar como IPs Reservadas. Pero aún hay más. Con el fin de poder expandir enormemente el número de dispositivos que pudiesen conectarse a la Red de Redes y con el fin de poder crear Redes sin necesidad de estar conectadas a Internet, surgió la necesidad de usar rangos IP reservados exclusivamente para el uso privado. A estas IPs son las que conocemos como IPs Privadas. Es evidente que por el otro lado tendríamos lo que llamamos IPs Públicas. Al contrario de los rangos IP públicas, las IPs privadas y reservadas son usadas de forma simultánea en todas partes del mundo sin constituir esto un problema, ya que dichas IPs se usan tan solo dentro del marco de una Red Privada. Dicho de otro modo, cada usuario puede si desea hacer uso de los rangos de IP Privada para crear la red que mejor se ajuste a sus necesidades. El caso de las IPs reservadas es un poco más peculiar, dado que su uso generalmente no está orientado a identificar un host concreto, sino más bien son usadas por otros servicios, los cuales como ya hemos dicho se tratará más adelante.

El uso de IPs privadas para la creación de una Red Privada es muy ventajoso, pero si se desea usar conectar dicha red privada a Internet es necesario un dispositivo (generalmente hardware) que pueda convertir de algún modo nuestras direcciones IP privadas en públicas. Y esto lo conocemos como Network Address Traslation (NAT) o traductor de direcciones de red.

Se estableció así los 3 rangos diferentes de IPs privadas dentro de todo el espacio IPv4. Es evidente que al estar reservadas estas para dicho fin, no podrán ser usados para otro. Cada rango cae dentro precisamente de cada una de las 3 clases de IP principales, de este modo cada usuario/empresa/organización puede usar aquellas que más se ajuste a sus necesidades.

 

Clases

Rango IP

Máscara de Red

Direc. Broadcast

Clase A

10.0.0.0-10.255.255.255

255.0.0.0

10.255.255.255

Clase B

172.16.0.0-172.31.255.255

255.255.0.0

172.x.255.255

Clase C

192.168.0.0-192.168.255.255

255.255.255.0

192.168.255.255

 

Es muy común por tanto hablar tanto de IP privada como IP pública. Al contrario de lo que pueda pensarse, la IP privada es la que menos importancia podría tener nuestro sistema de puertas para fuera, dado que lo que realmente identifica nuestra red desde el exterior es nuestra IP pública. Son los dispositivos de red como los routers los que hacen posible el intercambio de información entre las redes privadas e Internet.

Vamos a explicar algunas cuestiones de las clasificaciones anterior a la par que vamos a aprovechar para añadir algunos términos más:

  • IP Privada: Ya hemos hablado de ella, son rangos específicos dentro del espacio de direcciones, de uso exclusivamente propio, no tiene valor más allá de nuestra red.
  • IP 0.0.0.0: Este será la primera IP reservada que nos encontremos. La IP 0.0.0.0 es digamos la IP comodín, es decir, hace referencia a cualquier IP, ya que es necesario en multitud de tareas poder usar una IP que signifique “Todas”. Pensar en cuando se desea aplicar una regla en un firewall para permitir todas las IPs, o denegar todas. La dirección 0.0.0.0 es ese “Todas”.
  • IP 127.0.0.0: También se conoce como IP de retroalimentación, de Loopback, IP del propio host. Si la IP 0.0.0.0 hace referencia a Todas, la IP de Loopback hace referencia siempre a sí mismo. Es decir, para un equipo, sea cual sea la IP que tenga asignada él se podrá siempre identificar a sí mismo para tareas locales como 127.0.0.1. Esto es tremendamente útil, dado que no depende de la IP que pueda tener asignada para poder hacer uso de sus propios recursos de red.
  • Enlace Local: Rango de IP usado tan solo en ámbitos locales por ciertos servicios, por ejemplo por APIPA, un sistema usado para configuración automática de IP cuando otros sistemas como DHCP no están disponibles.
  • Test-NET-X: Son rangos reservados para ser usados en documentación y/o ejemplos didácticos, así como en código fuente ejemplo.
  • 6TO4: Con la inminente salida de IPv6, se ha reservado un espacio por el cual podrá circular contenido IPv6 hacia direcciones IPv4 y viceversa. Esto es necesario dado que no se puede implementar un sistema que sea diferente de la noche a la mañana, y durante un tiempo (posiblemente largo) ambos estándares deberán de convivir uno con el otro, ya que el soporte hardware de los dispositivos personales, así como dispositivos de red, es completamente necesario. Este rango será usado para facilitar esta tarea.
  • ID de Red: Si uno es cuidadoso y realiza las multiplicaciones por sí mismo, se dará cuenta que siempre desaparecen dos posibles direcciones que podrían usarse para hosts. Es decir, por ejemplo para el rango de clase C 192.168.10.0, decimos que tenemos disponibles un total de 254 hosts para dicha red. ¿De dónde sale este número? Dado que la máscara de Red es 255.255.255.0, tan solo podríamos tener un total de 256 hosts, el último octeto es el que estaría reservado para ello. Lo que sucede es que dos de ellas podemos decir que se encuentran reservadas. En el ejemplo puesto, la dirección IP 192.168.10.0 no podría ser usada jamás para identificar un hosts, dado que dicha dirección en dicho ejemplo sería la red misma, es decir el ID de red.
  • Dirección de Broadcast: Continuando con el punto anterior, para la red 192.168.10.0 y la máscara de subred 255.255.255.0, existe otra dirección reservada conocida como dirección de broadcast. Esta dirección es muy importante, dado que es por así decirlo el canal de comunicación común de toda nuestra red. Esta dirección es siempre el último host de la red, en este caso sería 192.168.10.255. Pero que es ¿Broadcast?

    Existen diferentes modos de comunicación entre diferentes dispositivos. Quizás el método más simple sería aquel en el que un host mantiene una comunicación directa con otro hosts. En este caso hablaríamos de Unicast. Pero es posible que el hosts con el que queremos entablar una comunicación no sea siempre el mismo, sea tan solo uno pero dependiendo de ciertas circunstancias pueda ser uno u otro, por ejemplo en función de la distancia entre ambos. La comunicación sería de nuevo tan solo entre dos hosts, aunque el destino no tendría que estar específicamente tipificado. En este caso estaríamos hablando de Anycast. Unicast y Anycast es posiblemente los dos sistemas de comunicación más usados, pero muchas veces se puede tener la necesidad de tener que enviar un mensaje a más de un hosts. Así, por Multicast entendemos un sistema de comunicación de uno a muchos, en el que esos muchos forman entre ellos un colectivo propio dentro de la misma red por supuesto. Por último, podemos desear poder enviar o comunicarnos con todos los hosts de nuestra red, en un esquema de “Uno a Todos”, y es lo que llamamos Broadcast. Un ejemplo sencillo de broadcast es la televisión, sale de un emisor pero el receptor somos todos, no va dirigida a nadie en particular, y el ejemplo más común de multicast podría ser los servicios de televisión por internet.

    Visto esto, comprendemos el significado de la dirección broadcast de nuestra red, dado que muchos mensajes son necesarios emitirlos a todos los miembros de nuestra red, ya sean informativos o con simples fines distributivos. Podemos decir por tanto que el último host de una red, queda también reservado y no puede ser usado como un host concreto.

  • Subred: En realidad el término “Máscara de Red” sería tan solo aplicable a la máscara por defecto de una IP según su clase. Por ejemplo, la máscara de red para una IP de clase C será 255.255.255.0. Esto es importante, dado que no se debe de confundir con una Subred o una Máscara de Subred. Según la clasificación anterior, se podría pensar que no hay necesidad de subredes, dado que el espacio ya está dividido en diferentes clases que se amoldan a la gran mayoría de todos los interesados. Es cierto que la ICANN jamás otorgaría una IP de clase A a un particular, dado que sería una pérdida absurda de direcciones IP, ningún usuario particular tendría la necesidad de crear una red de 16777214 dispositivos. Al contrario, la ICANN tiene (solía asignar, dado el agotamiento de estas) asignado tan solo IPs de clase A a los propios gobiernos de cada país o a grandes empresas/organizaciones, la mayoría de ellas por razones históricas, como Intel, MIT… Hay que tener en cuenta que la ICANN tan solo disponía de 126 paquetes de direcciones de clase A. Por el contrario la ICANN asignaba IPs de clase B a grandes empresas y organizaciones de forma común, pensar que en este caso ya no disponía de tan solo 126 paquetes, sino 16380. Y por último los paquetes de clase C que serían los que podrían ser otorgados a particulares.

    Aunque este reparto pueda parecer suficiente, lo cierto es que no lo es. Según esto, si un particular recibiese por parte de la ICANN un red de clase C con sus 256 IPs, por ejemplo la red 193.125.222.0, el usuario tan solo podría tener una red con 256 hosts. Pero qué pasa si el usuario quiere tener 2 redes diferentes en vez de tan solo una? No podría. En cambio, podría tener un router en la entrada de su red, con una máscara de subred de 255.255.255.192, lo cual me daría la posibilidad de tener 4 subredes distintas, cada una de ella con 62 (64 menos el ID de red y la dirección de broadcast). Así, la dirección IP 193.125.222.2 pertenecería a la subred 1, mientras que la IP 193.125.222.130 pertenecería a un host en la subred 3.

    De este modo, la creación de subredes es el método más eficiente para la gestión de las propias IPs. Es evidente que nunca podremos trabajar con máscaras más pequeñas que la máscara por defecto que tenemos, pero si podemos trabajar con máscaras más grandes para seccionar y optimizar la red.

  • Clase D: Las direcciones de clase D están reservadas para usarse de manera interna para propósitos de multicast. Ya hemos explicado esta técnica, pero como saben los dispositivos que dirección multicast escuchar? Lo normal es que antes de que esto sea posible, un host tiene que realizar una petición de unión a un grupo multicast, petición que realizará a través de una dirección multicast. Después de esto, el dispositivo de red (generalmente un router) reenviará el mensaje de él o para él al resto, dado que el conoce quienes son todos los miembros del grupo multicast.
  • Clase E: Tan solo se puede decir que es un rango de IP reservado para poder hacer pruebas, experimentos…. o simplemente para futuros usos.
  • IP 255.255.255.255: Esta IP sería algo así como la dirección de Broadcast para redes no constituidas. Si comprendemos que la dirección 0.0.0.0 es la dirección IP que hace referencia a cualquier hosts, la dirección IP 255.255.255.255 sería su IP de broadcast, siempre por supuesto hablando dentro de una red local, una red privada.

 

A pesar del uso de direcciones IP privadas con dispositivos NAT y al excelente trabajo de gestión de la ICANN para aprovechar al máximo las direcciones IPv4, ha sido muy normal el uso de direcciones IP dinámicas. Esto no es más que una práctica de los ISP para asignarnos IPs que podríamos llamar de “sesión”. Es evidente que jamás todos los clientes de un mismo ISP estarán conectados a la red de manera simultánea, luego sería un desperdicio de IPs. Imaginar que un ISP tiene arrendado un paquete de un millón de IPs y tiene un millón de clientes, luego asigna una a cada uno de ellos y problema resuelto. Pero como hemos dicho es evidente que esto no será jamás así, y a lo mejor las estadísticas dicen que en el mejor de los casos se forman picos de 700.000 usuarios conectados. Dicho ISP podría por lo tanto tener un paquete IPs de tan solo 700.000 direcciones, lo que le costaría sensiblemente menos. Como se gestionan estas IPs? En realidad igual que las IPs estáticas. Cuando conectamos a nuestro ISP este nos asigna una IP temporal. Dicho tiempo puede venir dado en función de la sesión o de un tiempo concreto. Una vez se da dicha circunstancia, la IP es liberada y la próxima conexión/sesión usará otra IP. De este modo si apagamos por las noches el router por ejemplo, nuestro ISP podrá reasignar dicha IP a otro cliente que quiera establecer una conexión. Por tanto, consideramos una IP dinámica aquella que varía de forma habitual con el tiempo o por conexión, e IP estática aquella que persiste. Por supuesto, el concepto aplicado a un ISP es exactamente igual que aplicado a una red local (LAN), donde la IP puede ser asignada de forma estática (por ejemplo estableciéndola en el mismo adaptador) o dinámica (por ejemplo usando servidores DHCP).

El uso de una IP dinámica o estática tiene pros y contras. Por un lado el uso de IPs dinámicas por parte de los ISP les ahorra dinero en cuanto a número de IPs necesarias, así como aumenta la seguridad y privacidad de cara al usuario, dado que su IP nunca será fija y por ende un difícil objetivo de amenazas externas. Pero por otro lado el uso de IP estáticas permite tener acceso a una serie de servicios mayores, como cualquier servicio que sea IP dirigido. Al ser la IP estática nuestro equipo/red estará siempre identificada desde el exterior, haciendo muy sencillo el uso de servidores Web/eMail o cualquier otro que nos imaginemos.

Para terminar completamente con IPv4, y dado que a estas alturas deberíamos de conocer a menos a groso modo el funcionamiento del modelo OSI/TCPIP, es interesante conocer como es un paquete IP. Recordemos que en cada nivel se encapsulará el contenido de nivel superior con el contenido añadido del nivel propio. En el caso del protocolo IP, es un protocolo de nivel 3, el cual tomará el mensaje del nivel de transporte como SDU, y le añadirá una cabecera propia, para poder así conformar el PDU del nivel 3, es decir, un paquete IP, tal y como lo encontramos en las especificaciones de 1981.

Versión

IHL

DiffServ

Longitud

Identificación

Flag

Desplazamiento de Fragmentos

TTL

Protocolo

CheckSum

IP Origen

IP Destino

Opciones (Variable)

Padding (Variable)

  • Versión (4 bits): Contendrá la versión del protocolo. Para la versión IPv4 el valor de dichos bits será 0100 (4).
  • IHL (4 bits): Es la longitud de la cabecera expresada en grupos de 32 bits. Es decir, si la cabecera tiene un total de 160 bits, 160/32 => IHL = 5.
  • DiffServ (8 bits): Originalmente usado para TOS (Type Of Service), fue sustituido en un RFC de 1998 para su uso como “Differenced Services” (Servicios Diferenciados), un sistema para QoS
  • Longitud (16 bits): Especifica el tamaño en Bytes del paquete IP completo. Al tener un campo de 16 bits podemos inferior directamente que el tamaño del paquete IP mayor que podemos tener es de 65535 Bytes (64KB)
  • Flag (3 bits): El bit de mayor peso se fuerza a cero y no es usado. El segundo bit especifica si el paquete se podrá o no fragmentar, de estar marcado como no fragmentar y es necesaria su fragmentación para enviarlo, este paquete se descartará. El bit de menor peso especifica si hay más fragmentos o no los hay.
  • Desplazamiento de Fragmentos (13 bits): A groso modo especifica el byte al que pertenece dicho fragmento. si es el primer fragmento tendrá un offset (desplazamiento) de 0, si fuese el segundo pues dependiendo ya de la fragmentación necesaria. ¿Por qué es la fragmentación necesaria? Podemos asimilarlo a la segmentación en el modelo OSI. Cada red tiene una unidad máxima de transmisión llamada MTU que precisamente especifica el tamaño máximo de un paquete. Esta es una limitación de la red, no del protocolo, esto es importante. La longitud máxima de un paquete IP es de 64KB, en cambio los enlaces Ethernet estándar suelen ser de 1500 Bytes, luego la fragmentación se puede convertir en algo “normal”. Esto significa que si se desea enviar por ejemplo una cantidad de datos de 5000 Bytes y tenemos una conexión ADSL con un MTU de 1492 bytes (cosa habitual), dicha información se deberá de fragmentar en paquetes IP más pequeños, cada paquete con un tamaño máximo (cabecera IP + datos) de 1492.

    Si atendemos a la cabecera IP expuesta arriba, cada fila corresponde a un total de 32 bits. Por tanto, la cabecera IP más corta que podríamos tener sería aquella que no se tiene el campo “Opciones”, lo que sería por tanto: 32 bits * 5 (filas) = 160 bits / 8 = 20 Bytes. La cabecera IP más larga que se puede estipular por otro lado serían 60 Bytes. Supongamos que disponemos por tanto de una Cabecera IP de un tamaño de 20 Bytes (la cabecera más simple). Si nuestra conexión ADSL tan solo puede manejar paquetes IP de 1492 Bytes significa que la cantidad de datos que pueden añadirse a nuestro paquete IP sería de 1492 – 20 = 1472 Bytes. Si deseamos enviar esos 5000 Bytes, será necesario crear paquetes IP más pequeños, en este caso un total de 4 paquetes:

    Cabecera IP 1 (20 Bytes)

    1º Cuarto SDU (Offset 0, tamaño = 1472 Bytes

    Cabecera IP 2 (20 Bytes)

    2º Cuarto SDU (Offset 1472, tamaño = 1472 Bytes

    Cabecera IP 3 (20 Bytes)

    3º Cuarto SDU (Offset 2944, tamaño = 1472 Bytes

    Cabecera IP 4 (20 Bytes)

    4º Cuarto SDU (Offset 4416, tamaño = 583 Bytes

  • TTL (8 bits): Tiempo de vida, es un contador que se establece a un número dado. Cada salto que de nuestro paquete, el dispositivo de red pertinente que procese el paquete decrecerá en uno su valor. Si el TTL llega a Cero, el paquete será descartado por la red (por cualquier dispositivo de red que lo esté procesando en ese momento). Esto es una medida de seguridad para evitar que paquetes perdidos puedan circular de forma indefinida por la red.
  • Protocolo (8 Bits): Estos 8 bytes representan un número que identifica el protocolo de nivel superior que está contenido en los datos que porta el paquete IP. El protocolo IP trabaja en el nivel 3 (nivel de red), pero los datos que maneja proceden del nivel superior 4, nivel de transporte. No obstante un paquete IP puede enviar como datos un protocolo de nivel 3 adjunto como datos, como es el caso de ICMP por ejemplo. Poner la lista completa es un poco absurdo, dado que casi con toda seguridad la mayoría de ellos jamás lleguemos a verlos en la vida. Quien lo desee puede acudir al RCF 790 para conocer la lista completa. Pero si cabe destacar los protocolos más usados:

    Protocolo = 1 -> ICMP; Protocolo = 6 -> TCP; Protocolo = 17 -> UDP;

  • CheckSum (16 bits): El protocolo IPv4 realiza una operación de checksum en la cabecera para garantizar la integridad NO EL PAQUETE COMPLETO, sino de la cabecera IP. Para ello se van sumando en complemento a uno cada 16 bits de la cabecera. Una vez terminada la suma se le realiza el complemento a uno al resultado y es este el que se inscribe en este campo. A la hora de verificarlo es igual, si el resultado obtenido (omitiendo el campo checksum) es el mismo que el que está en el cabecera, el paquete es válido.
  • IP Origen/IP Destino (32 bits cada campo) : Pues no es más que eso, la IP del sistema que envía el paquete y la IP del destino. Cabe decir que en teoría es posible modificar este dato a voluntad, lo cual deja ver lo relativamente vulnerable que es el protocolo ante el IP Spoofing (al menos en teoría)
  • Opciones y Padding (Variable, de 0 a 40 bytes): Este campo es de obligada implementación en el stack TCP/IP, pero dependerá de cada protocolo y cada paquete que sea necesario su uso o no. Es por ello la importancia del campo IHL. Si este campo tiene un valor de 5 significará que el campo Opciones no estará presente, y la cabecera tendrá una longitud fija de 20 Bytes. En cambio, el IHL pude tener un valor de entre 6-13, lo que implicará que el campo de opciones se está usando y tiene una longitud también conocida, entre 0-40 Bytes, gracias al padding final que se le añade.

    Este campo se utiliza en algunas redes por temas de seguridad por ejemplo, en el que en estos campos se indica que el contenido es considerado desde sensible a alta seguridad, o también se puede usar para indicar la fecha del paquete mismo o especifique una ruta concreta que deba de seguir el paquete.

    El Padding es simplemente un relleno que se le añade al campo de opciones para que este concluya en múltiplo de 32 bits, luego puede tener un tamaño de entre 1-31 bits, de esta forma no se rompe la estructura de la cabecera y simplemente conociendo el IHL es posible conocer exactamente el tamaño de la cabecera.



IPv6

Como se ha dicho, posiblemente la causa más urgente a solucionar es el agotamiento del espacio de direcciones IPv4. Esto es algo que era previsible no ahora, sino hace ya unos años. En 1998 se terminaron las especificaciones IPv6, y evidentemente como característica más marcada fue ampliar a 128 bits los 32 bits de las direcciones IPv4, lo que permitiría un número virtualmente infinito de direcciones. En realidad no es que sea infinito, pero de unos 4 mil millones pasaríamos a unos 3.4 x 10^38, es decir, 34 con 37 ceros a su derecha. Dicho de otro modo, se podría entregar a cada persona del mundo un espacio de direcciones miles millones… de veces superior que todo el espacio de direcciones IPv4, y eso solo para cada habitante!! Es evidente que esta será la diferencia más significativa entre IPv4, pero como veremos tampoco es la única.

Hay que tener en cuenta el por qué se clasificaron las direcciones IPv4 del modo que se hizo, y no fue otro que el de la buena gestión del espacio de este. Pero en IPv6 este problema desaparece, ya que podemos disfrutar prácticamente de un espacio ilimitado de direcciones, luego el esquema que conocemos a día de hoy se parte completamente y muchos de los conceptos y tecnologías usadas a día de hoy desaparecen… y desaparecerán en los próximos años. Como organizaríamos el espacio de direcciones IP si pudiésemos disponer de forma ilimitada de estas?

En realidad la única complejidad que tiene IPv6 frente a IPv4 es que posee unas reglas mucho más específicas de direcciones, de este modo también es más fácil tener un reparto de direcciones de forma mucho más lógico y ordenado. La idea básica que se tendrá siempre presente es que si una interfaz de red tiene asignada de fábrica un ID único llamado comúnmente dirección MAC (de 48 bits), se podría usar dicha MAC como extremo último de una dirección IPv6.

¿Qué es una dirección IPv6?

Si bien a día de hoy la penetración de IPv6 es mínima, estas direcciones comenzarán a formar parte de nuestra vida de forma bastante habitual dentro de muy pocos años. En este caso hablamos de un espacio de direcciones inicial de 128 bits, es decir, 2128 direcciones posibles. Con IPv4 la forma más habitual de representarla era por medio de 4 octetos: 4*8= 32bits en notación decimal. El problema es que si se usase el mismo esquema para las direcciones IPv6 se necesitarían 16 octetos, lo que resultaría en una dirección realmente grande de expresar:

125.223.0.25.158.231.45.0.0.0.0.0.98.250.115.23

Es evidente que no es una forma eficiente de representación. En lugar de la representación clásica IPv4, se usan 8 agrupaciones de dos octetos y en formato hexadecimal, no decimal. De este modo la dirección antes expresada podría simplificarse como:

7DDF:0019:9EE7:2D00:0000:0000:62FA:7317

A priori puede parecer que se tiene la misma complejidad, pero no es así. Para empezar 1 byte en decimal tiene una representación de hasta 3 dígitos, mientras que en hexadecimal jamás pasará de 2 valores. Además, es más cómodo la agrupación en bloques de 16 bits que de 8. Aun así, las reglas de notación se expanden precisamente para evitar la complejidad de representación, permitiendo la simplificación de estas direcciones. Por ejemplo, cuando un grupo de 16 bits posee tan solo ceros, es posible acotar los 4 en uno solo. Por otro lado, se puede si se desea omitir incluso todas las palabras (16 bits) siempre y cuando estas tengan un valor de “cero” y se encuentren contiguas entre sí. Dicho esto, de la dirección anterior podríamos simplificarla como:

7DDF:0019:9EE7:2D00:0:0:62FA:7317

Pero también podríamos representarla como:

7DDF:0019:9EE7:2D00::62FA:7317 (nótese los :: contiguos)

De este forma es posible acotar bastante la representación de estas. Pero en realidad esto tan solo es un efecto secundario de tener que manejar bloques de direcciones tan enormes. Y del mismo modo que el espacio de direcciones IPv4 se encuentra clasificado, con IPv6 sucede exactamente lo mismo, salvo con matices, dado que aquí desaparece la necesidad y los conceptos de Clases de IP, y prácticamente todas las IPs IPv6 pueden clasificarse como reservadas, de enlace local y Unicast. Pero veamos que sucede con la máscara de red/subred.

A pesar de tener un número de IPs virtualmente ilimitado, la necesidad de constituir redes independientes es evidente. El concepto de máscara de red/subred será usado prácticamente del mismo modo, aunque es cierto que de forma un tanto diferente. IPv6 pretende ser completamente jerárquico, lo que hará que sea también más eficiente a la hora de conocer el destino de un paquete (de cara a los router). Esta es la clasificación actual del espacio IPv6 según la IANA:

Prefijo

Uso

0000::/8

Reservada por IETF

0100::/8

Reservada por IETF

0200::/7

Reservada por IETF

0400::/6

Reservada por IETF

0800::/5

Reservada por IETF

1000::/4

Reservada por IETF

2000::/3

Unicast Global

4000::/3

Reservada por IETF

6000::/3

Reservada por IETF

8000::/3

Reservada por IETF

A000::/3

Reservada por IETF

C000::/3

Reservada por IETF

E000::/4

Reservada por IETF

F000::/5

Reservada por IETF

F800::/6

Reservada por IETF

FC00::/7

Unicast Única Local

FE00::/9

Reservada por IETF

FE80::/10

Unicast de Enlace Local

FEC0::/10

Reservada por IETF

FF00::/8

Multicast

  • Reservada por la IETF:

    La IETF es un organismo que gestiona el funcionamiento de todo esto. Son rangos de IPs que simplemente no están asignados a ninguna tarea.

  • Unicast Global:

    Aquí encontraríamos el espacio IPv6 que sería usado de manera global para especificar cualquier dispositivo de red, lo que en IPv4 podríamos conocer como IPs Públicas. Estas IPs tienen una estructura en común:

    Prefijo de Red

    Subred

    ID de interface

    n bits

    m bits

    128-n-m bits

El prefijo de red tiene la función del rutado principal dentro de todo Internet, podemos ver este como los bloques principales de IPs que se entregarían a los ISP o las grandes multinacionales por parte de los administradores de zona como RIPE, ARIN y otros.

La Subred sería administrada de manera local por los administradores de dichos bloques con la finalidad de configurar sus propias redes.

El ID de interface sería la punta de la flecha que señalaría cada host en concreto, de forma única dentro de cada subred y a su vez dentro de cada red principal. Este ID de interface vendrá a ser de forma similar a lo que hoy en día entendemos como dirección MAC de un dispositivo de red. Dicho de otro modo, cada IPv6 señalará directamente a cada adaptador de red en Internet.

Aun así, el mismo rango de direcciones posibles dentro de las direcciones Unicast Globales, se encuentra dividido y asignado de forma diferente:

Rango IP

Asignado a

2001:0000::/29 – 2001:01F8::/29

IANA

2001:0200::/29 – 2001:03F8::/29

APNIC

2001:0400::/29 – 2001:05F8::/29

ARIN

2001:0600::/29 – 2001:07F8::/29

RIPE NCC

2001:0800::/29 – 2001:09F8::/29

No asignado aun

2001:0A00::/29 – 2001:0BF8::/29

No asignado aun

2001:0C00::/29 – 2001:0DF8::/29

No asignado aun

2001:0E00::/29 – 2001:0FF8::/29

No asignado aun

2001:1000::/29 – 2001:11F8::/29

No asignado aun

No asignado aun

2001:FE00::/29 – 2001:FFF8::/29

No asignado aun


Una vez se vaya agotando cada bloque asignado a cada RIR, se le reasignaría un nuevo bloque.

  • Unicast Única Local:

    Este rango sería el equivalente al usado para las direcciones privadas en la actual IPv4. Su estructura no obstante sería exactamente igual que las direcciones IPv6 Unicast globales. Al igual que las direcciones privadas IPv4, las direcciones Unicast Únicas Locales tan solo tienen un ámbito de uso interno, y no serán (no deberían al menos) ser enrutadas fuera de la red local. De todos modos y por seguridad, el prefijo de red en este caso se establece en 40 bits, el cual será generado de forma aleatoria con el objetivo de que si en algún momento un paquete IPv6 con IPv6 única Local fuese enrutado al exterior y del exterior inyectado a otra red local, tener la garantía de que no correspondería a ningún hosts de esta. Dicho de otro modo, la probabilidad de que el host externo existiese sería a todos los efectos prácticamente nula, dado que teóricamente la IP generada para uso local sería única en toda Internet. Todo el resto del rango pasaría a ser administrado por la persona a cargo de la red a voluntad, del mismo modo que configuramos nuestras redes privadas. De este modo tendremos la posibilidad si así lo deseamos de conectar nuestra red directamente a Internet o aislarla de esta. Si fuese este último caso, es evidente que sería necesario hacer uso de dispositivos NAT para traducir las direcciones locales a una dirección IPv6 Unicast Global en caso de querer conectar dicha red al exterior, del mismo modo que se realiza a día de hoy con IPv4

  • Unicast de Enlace Local:

    A diferencia de Unicast única local, en este caso la IPv6 no solo no tendría un ámbito local, sino que esta no sería única. Es decir… esa misma IP podría ser encontrada en otros puntos del planeta, todo lo contrario que lo que sucede con el apartado anterior, que pese a ser de ámbito local pueden considerarse IPs únicas. Estas IPs corresponderían a las que en IPv4 podríamos llamarlas IPs APIPA, es decir, IPs de autoconfiguración propia sin necesidad siquiera de un enlace a un nodo de red:


    Prefijo de Red (10 bits)

    Subred (54 bits)

    ID de interface (64 bits)

    1111111011

    0

    Host


  • Multicast:

    En IPv6 el término IP Broadcast desaparece, y tan solo permanece el de Multicast. A fin de cuenta para enviar un paquete a toda una misma red no hace falta una dirección específica, ya que todos estos hosts pueden formar parte de un mismo grupo Multicast. Es decir, en IPv6 las direcciones de punto final :FF señalarían a hosts concretos.

    Por ello se reserva un rango específico para direcciones Multicast. Estas, si poseen una estructura algo diferente a las direcciones Unicast vistas hasta el momento, y tiene su lógica. Estas direcciones Multicast pueden tener tanto un ámbito local como global, por lo tanto se requerirán de ciertos bits específicos para esta diferenciación:


    Prefijo de Red (8 bits)

    Flag (4 bits)

    Ámbito ( 4 bits)

    ID de grupo (112 bits)

    11111111

    0 | R | P | T

    Ver tabla

    ID

Flag: Especifican algunas opciones de la IP multicast, como por ejemplo si la IP es permanente (T) o si es una IP que pertenece al propio prefijo de red (P).
Ámbito: Según el valor que tome, especificará el alcance de la dirección Multicast. Así por ejemplo, para un ámbito 1110 la IP multicast sería escuchada de manera global, mientras que si es 0010 el ámbito sería local. Las especificaciones completas las podemos encontrar si lo deseamos en el RFC 4291.

En adición de esto, existen ya preestablecidos grupos estándares, así como especificaciones mucho más amplias de cómo usar estas IPsv6 Multicast, pero tampoco es demasiado importante para nosotros.

  • IP no especificada e IP de Loopback:

    Del mismo modo que en IPv4 existen las IPs especiales 0.0.0.0 como IP comodín e IP 127.0.0.1 conocida como IP de retroalimentación o Loopback, en IPv6 existe exactamente lo mismo. Así la IP no especificada será la correspondiente a ::/128, mientras que la IP de Loopback corresponderá a ::1/128.

 

Además del ingente espacio de direcciones IP, IPv6 posee principalmente tres grandes mejoras frente a IPv4. La primera es que IPv6 está creado de base para ser usado con IPSec, protocolo punto a punto para el cifrado de las conexiones. Esto no significa que IPSec será usado en todo internet, sino que su implementación es obligada y cualquier sistema preparado para ello. La segunda característica es que los propios hosts y nodos extremos podrán auto negociar su propia IP, sin necesidad de un servidor DHCP. El proceso se realiza gracias al nuevo protocolo ICMPv6. El host enviará así un paquete ICMPv6 de descubrimiento a la dirección multicast de enlace local y si existe un router configurado para ello en un extremo, este le responderá directamente con los ajustes de configuración de este, según la estructura actual de su red. La tercera mejora son los conocidos como los paquetes Jumbo. Estos no son desconocidos, ya que actualmente son usados en redes GigaEthernet para mejorar la transmisión de los datos, ya que es posible exceder el MTU de la red, enviando paquetes con un mayor tamaño.

De cara a como es en sí un paquete IPv6 (su cabecera) hay que destacar la simplificación que se ha realizado de la actual IPv4:

Versión

Clase de Tráfico

Etiqueta de Flujo

Longitud

Cabecera Siguiente

Límite de saltos

IP Origen

IP Destino



  • Versión (4 bits): Corresponde exactamente igual al valor de IPv4, es decir, específica la versión del protocolo. Para IPv6 tomará por tanto un valor de 0110
  • Clase de Tráfico (8 bits): Similar a al campo DiffServ de IPv4. Su objetivo es proveer al protocolo capacidades QoS, es decir, capacidades para priorización del tráfico, dado que por desgracia el ancho de banda siempre será limitado.
  • Etiqueta de Flujo (20 bits): Aun se encuentra en experimentación. La idea original consistía en la posibilidad de poder etiquetar los paquetes de forma que fuese adecuado para aplicaciones en tiempo real como VoIP, o para sistemas QoS no estándares. No es un requerimiento actual, y puede establecerse todo a ceros si no es usado. Recordemos que IPv6 es aún un protocolo experimental que está en sus primeras fases. Hasta que no pase X tiempo en el entorno real y a gran escala, no se podrá con casi toda seguridad retocarlo para obtener las mejores prestaciones.
  • Longitud (16 bits): Especifica ni más ni menos la longitud en bytes de los datos que serán enviados por el paquete sin contar la propia cabecera. Es decir, si el SDU de la capa superior ocupa 60KB, la longitud será 60KB. A esto hay que añadir que IPv6 permite extensiones de la cabecera para añadir funcionalidades opcionales. Estas extensiones de la cabecera NO forman parte de la cabecera en sí, e irían justo antes del SDU. Esto quiere decir que el tamaño de las extensiones de la cabecera sí será contabilizado en este campo. Al ser un campo de 16 bits permitirá de nuevo un tamaño máximo de paquete de unos 64KB.
  • Cabecera Siguiente (8 Bits): Tiene la misma funcionalidad que el campo “protocolo” de IPv4. Especifica la cabecera que se encontrará después de la cabecera actual. En IPv4 hacía referencia prácticamente tan solo al protocolo usado en el SDU superior, pero aquí puede especificar también las extensiones de cabecera, como por ejemplo extensión de cabecera para fragmentos.
  • Límite de Saltos (8 bits): Es el campo TTL (Time To Live) de IPv4. Cada salto que dé el paquete, este contador será decrementado en 1. Si llegase a cero, el paquete se descarta de la red.
  • IP Origen/Destino (128 bits cada campo): Cada dirección IPv6 de 128 bits, primero la IP de origen y después la IP destino.

Es interesante ver como por ejemplo se ha eliminado de la cabecera IPv6 el checksum, dejando la comprobación de integridad directamente sobre los niveles superiores e inferiores. Aunque las ideas en papel son buenas, hay que tener en cuenta que las estadísticas y la realidad son otras. A lo mejor en un principio se estimó que la comprobación de la integridad de una cabecera IP era adecuado a principios de Internet dado la poca fiabilidad de las redes antiguas. A día de hoy se ha demostrado que la comprobación de la cabecera en IPv4 quizás tan solo era útil (es decir, existía un error y este era detectado) en un porcentaje tan ínfimo que su uso ha dejado de ser necesario, máxime cuando niveles superior e inferiores ya poseen controles de integridad adecuados (los cuales antes también existían)

Las extensiones de cabecera son igualmente parte imprescindible de IPv6. Si bien es cierto que la cabecera base ha sido completamente reducida, parte de las opciones que existían en IPv4 ahora las podremos encontrar como extensiones. Estas extensiones serán indicadas en el campo “cabecera siguiente” antes descrito, que nos dirá que cabecera será la que encontraremos justo después de la cabecera base, es decir, antes de los datos superiores. Estas cabeceras no obstante jamás serán procesadas por un nodo de red, esto quiere decir que todos los nodos de los saltos intermedios que de un paquete desde el origen al destino, tan solo se procesará la cabecera base. Las extensiones de cabecera serán por tanto tan solo procesadas cuando el paquete alcance su destino final. La única excepción se dará cuando exista la extensión de cabecera Hop-By-Hop. La cual será siempre añadida como primera extensión de cabecera e identificada por “Cabecera siguiente” como un cero.

Las extensiones especificadas actualmente en IPv6, así como su orden (en caso de que exista más de una extensión de cabecera) es el siguiente:

Cabecera IPv6 Base
Cabecera Hop-By-Hop
Cabecera de Opciones de destino (Para ser procesada tan solo por el primer destino/salto)
Cabecera de Rutado
Cabecera de Fragmentos
Cabecera de encapsulación de seguridad de los datos
Cabecera de Opciones del destino (Para ser procesada tan solo por el destino final)
Cabecera de nivel superior

Cada cabecera tiene sus campos y opciones concretos, que podríamos especificar pero sería rizar más el rizo. De todos modos se puede acudir a las especificaciones para obtener las especificaciones detalladas en el RFC 2460. Lo que es evidente es que cada cabecera de extensión tendrá un campo que será también “Siguiente Cabecera”, puesto que en IPv6 puede existir más de una extensión de cabecera. No obstante, el tamaño de estas extensiones será siempre un número múltiplo de 64 bits, con la idea de que en ningún momento se pierda la alineación de los 64 bits (La cabecera completa de un paquete IPv6 será por tanto siempre múltiple de 64)

Para terminar con IPv6, hay que tener en cuenta que algunos protocolos asociados a IPv4 son modificados ligeramente para poder soportar IPv6, como es el caso por ejemplo de ICMPv6 o DCHPv6. Es evidente que por ello IPv4 e IPv6 son completamente incompatibles entre ellos. No obstante, durante algunos años viviremos posiblemente una utilización de ambos. Esto será posible no porque ambos protocolos sean compatibles, sino porque se usarán técnicas de túneles para poder lograr esta interoperabilidad. Es decir, cuando un router obtenga una petición IPv6 y quiera enviarla por una red IPv4 tendrá que encapsular el paquete IPv6 como un paquete IPv4 estándar. El paquete podrá viajar así a través de toda la red IPv4 hasta el nodo destino, en el cual el paquete IPv4 se abriría para dar origen al paquete IPv6 que sería rutado a través de la red IPv6. Este mismo concepto puede ser usado a la inversa. El problema principal al que uno se encuentra es el soporte hardware de IPv6, así como de técnicas de túneles descrita.

Para que un usuario a día de hoy pueda realizar una conexión a redes IPv6 de forma directa, necesitará primero que su ISP tenga una infraestructura IPv6 ya creada (cosa que actualmente es muy raro que tengan), por no hablar de que el router de cada particular sea compatible con IPv6. De cara a los PCs de los usuarios esto no es problema en Windows ni en Linux desde hace tiempo. El soporte para IPv6 existe desde hace tiempo y los equipos estarían perfectamente preparados para recibir direcciones IPv6 y conectarse a las redes pertinentes. Microsoft implementó además del soporte nativo IPv6 técnicas de túneles como Teredo para permitir la interoperabilidad, aunque como he dicho actualmente la penetración de IPv6 es mínima. Poco a poco las pruebas van terminándose, y además urge un nuevo espacio de Direcciones, IPv6 como hemos dicho está acabado. El principal problema por tanto recae tan solo en los routers y otros dispositivos de red, si no tenemos soporte en ellos, así como en las redes de nuestro ISP, no podremos hacer mucho. Veamos un ejemplo de conexión a una red IPv6:

Interfaz en Windows 7 para IPv6:

Adaptador de Ethernet Local Area Connection:
Sufijo DNS específico para la conexión. . :
Descripción . . . . . . . . . . . . . . . : Marvell Yukon PCI-E

Gigabit Ethernet Controller #2
Dirección física. . . . . . . . . . . . . : xx-xx-x-xx-xx-xx
DHCP habilitado . . . . . . . . . . . . . : sí
Configuración automática habilitada . . . : sí
Dirección IPv6 . . . . . . . . . . . . . :2002:xxxx:xxxx:x:xxxx:xxxx:xxxx:xxxx(Preferido)
Dirección IPv6 temporal. . . . . :2002:xxxx:xxxx:x:xxxx:xxxx:xxxx:xxxx(Preferido)
Vínculo: dirección IPv6 local. . . : xxxx::xxxx:xxxx:xxxx:xxxx%12 (Preferido)

Dirección IPv4. . . . . . . . . . . . . . : 192.168.x.x(Preferido)
Máscara de subred . . . . . . . . . . . . : 255.255.255.0
Concesión obtenida. . . . . . . . . . . . : sábado, 05 de junio de 2010 21:05:12
La concesión expira . . . . . . . . . . . : miércoles, 13 de julio de 2146 3:39:47
Puerta de enlace predeterminada . . . . . : xxxx::xxx:xxxx:xxxx:xxxx%12
192.168.x.x
Servidor DHCP . . . . . . . . . . . . . . : 192.168.x.x
Servidores DNS. . . . . . . . . . . . . . : 192.168.x.x
NetBIOS sobre TCP/IP. . . . . . . . . . . : habilitado

 

Petición DNS IPv6:

ipv6.l.google.com: type AAAA, class IN, addr 2a00:1450:8002::68
Name: ipv6.l.google.com
Type: AAAA (IPv6 address)
Class: IN (0x0001)
Time to Live: 5 minutes
Data length: 16
Addr: 2a00:1450:8002::6a

 

Paquete TCP/IPv6:


 

 

Protocolo DNS

Domain Name System (o Sistema de Nombres de Dominio en español) es la segunda piedra angular en la que se sustenta no solo Internet, sino todas las rede en general. Al igual que IP, DNS no es más que un espacio de direcciones por así decirlo, aunque sería más correcto usar el término de espacio de nombres. Es curioso el hecho de que incluso los menos instruidos en la materia en algún momento ha escuchado o ha tenido que tratar con IPs, pero en cambio los términos DNS parecen mucho más difusos y raramente tenidos en cuenta, quizás tan solo cuando el ISP nos da la configuración de nuestra línea. No obstante, gracias al sistema DNS conocemos internet como la conocemos. ¿Es realmente necesario el sistema DNS? No, su existencia no nace de una “necesidad” propiamente dicha, sino de ser un recurso de increíble valor para cualquier persona, dada las limitaciones mentales que todo el mundo tenemos: Siempre conoceremos el nombre de una persona, pero solo algunos de sus números de teléfono.

El sistema DNS puede verse por tanto como un sistema de mapeo de direcciones IP a nombres. Es simple, cualquier persona del mundo será capaz de recordar nombres como google.es, microsoft.com, intel.com o theliel.es con infinita más facilidad que recordar (en el mismo orden): 216.239.59.104, 207.46.197.32, 198.175.96.33, 188.121.46.128. Y eso por supuesto si tenemos en cuenta el sistema actual IPv4, si tenemos en cuenta la proximidad de IPv6 el problema sería infinitamente mayor. Es evidente por tanto que aun cuando técnicamente no es imprescindible, de cara a las capacidades limitadas del ser humano podemos decir que sí lo es.

Cada vez que hacemos mención en alguna red (ya sea local o externa) de un nombre de domino, el sistema DNS hace posible la comunicación con dicho host, lo que sucede es que este sistema trabaja aparentemente siempre de forma transparente para nosotros, del mismo modo que para un usuario que navega por internet no entiende de IPs ni las necesita, lo cual no significa que sin saberlo las esté empleando de forma continuada.

Hay que tener presente como se vio en el capítulo anterior, que al igual que se gestiona el espacio de direcciones IP, se gestiona el espacio de nombres. Esto quiere decir que no existirán dos nombres iguales para el mismo dominio. ¿Dominio? Esto es algo que también se explicó. El sistema DNS es jerárquico, dividido por así decirlo en dominios, de forma que cada dominio superior gestiona sus dominios secundarios, y estos secundarios los dominios terciarios y así sucesivamente. Ya vimos el papel de la ICANN a la hora de gestionar los dominios de primer nivel y como se delegan los dominios de segundo o tercer nivel a cada autoridad. También se habló de los servidores raíces y de función, pero aquí veremos realmente la importancia de estos, así como el funcionamiento real del sistema DNS. En esta ocasión vamos a suponer un ejemplo, y de este todo el funcionamiento DNS, comenzando por el ejemplo más simple y aumentando su complejidad:

 

  • Caso 1: No necesaria resolución DNS, especificación de IP de forma directa

    El caso más sencillo que podemos ver es cuando realizamos una solicitud directamente sobre una IP. Por ejemplo si deseamos obtener acceso a un recurso de red interna y conocemos de antemano la IP de dicho servidor. Si en el explorador de archivos de Windows tecleamos la ruta \\192.168.5.23 (por supuesto damos por hecho una correcta configuración de puerta de enlace, máscara de subred e IP), el PC se comunicará directamente con el host especificado, en este caso sin siquiera necesidad de acceder a la puerta de enlace del router, ya que la tabla ARP del sistema ya contiene la dirección de este (más adelante se verá el protocolo ARP), con lo que se hace la petición sobre la propia dirección MAC:

    Interfaz: 192.168.5.2 — 0xc
    Dirección de Internet Dirección física Tipo
    192.168.5.1 00-xx-xx-xx-xx-xx dinámico
    192.168.5.23 00-xx-xx-xx-xx-xx dinámico

    En el caso que la petición sea realizada en el navegador, por ejemplo especificando de forma directa la IP del servidor de google en España: “216.239.59.104”, el proceso será exactamente igual, la petición saldrá por nuestro router e irá directamente hacia dicha IP (nuestro paquete irá saltando de router en router hasta alcanzar el host indicado, pero sin ninguna necesidad de uso del sistema DNS:

    tracert 216.239.59.104

    1 <1 ms <1 ms <1 ms Alpha5 [192.168.x.1]
    2 35 ms 35 ms 36 ms 192.168.153.1
    3 35 ms 35 ms 32 ms 209.Red-81-46-42.staticIP.rima-tde.net [81.46.42.209]
    4 80 ms 42 ms 42 ms So6-0-0-0-grtmadno1.red.telefonica-wholesale.net.10.16.84.in-addr.arpa [84.16.10.65]
    5 43 ms 64 ms 64 ms Xe9-1-0-0-grtpartv2.red.telefonica-wholesale.net [84.16.15.174]
    6 65 ms 65 ms 63 ms Xe0-3-0-0-grtpartv1.red.telefonica-wholesale.net [84.16.12.213]
    7 * * * Tiempo de espera agotado para esta solicitud.
    8 77 ms 72 ms 104 ms 209.85.251.40
    9 76 ms 74 ms 72 ms 209.85.248.95
    10 75 ms 78 ms 75 ms gv-in-f104.1e100.net [216.239.59.104]

     

  • Caso 2: Resolución DNS en archivo local

    En este caso no se hace uso del sistema DNS como tal, sino de archivos de texto existentes en cada equipo que contienen precisamente este mapeo de nombres-IPs. Históricamente era el sistema usado para esta tarea, y aun cuando a día de hoy el sistema DNS es usado de forma global, este sistema se continúa usando de forma relativamente extendida, aunque generalmente por propósitos un tanto diferentes. Ya hemos hablado alguna vez de ello: El archivo “Hosts”. Este archivo presente en la gran mayoría de todos los sistemas operativos es el que mantiene esta lista, puesto que no es más que una lista. En Windows por ejemplo podemos encontrarlo en “C:\Windows\System32\Drivers\etc\Hosts”, mientras que en Linux lo encontramos en “/etc/hosts”. Veamos un ejemplo de este fichero:

    192.168.x.52 alpha
    192.168.x.52 beta.com
    209.85.229.104 google.es
    127.0.0.1 webpeligrosa.com

    Dado este fichero LOCAL de nuestro sistema, nuestro sistema estaría en condiciones de aceptar los primeros nombres en lugar de las direcciones IPs. Así, para acceder al hosts con la IP 192.168.x.52 se puede realizar conociendo su IP o su nombre de dominio, en este caso “alpha”. El segundo caso, beta.com es exactamente igual, solo recordar que el sistema jerárquico actual de dominios de primer nivel, segundo nivel… es una cuestión de eficiencia, organización y acuerdos, para una resolución local no es necesario tener el hombre de host asociado a un dominio TLD (de primer nivel).

    Más interesante es el tercer caso. Los dos primeros hacen referencia a direcciones locales, mientras que la tercera es una dirección global. Pero el proceso es el mismo. Sin la existencia de un sistema DNS como el actual, el archivo hosts de cada PC debería de tener dicha entrada si se quisiese poder acceder al servidor de google.es sin necesidad de conocer la IP de este. En este caso la IP mostrada es la IP real de google.es, esto es muy importante saberlo, puesto ¿qué sucedería si la IP que hemos añadido a dicho archivo realmente no perteneciese al servidor de google.es? El archivo hosts es un archivo de mapeo, sean las direcciones mapeadas legítimas o no. Esto quiere decir que si sustituimos dicha entrada del archivo hosts por ejemplo esta otra:

    217.146.186.221 google.es

    tendríamos algo tan gracioso como acceder a la web de Yahoo cuando en el navegador introducimos google.es. El mapeo del archivo hosts prevalece sobre cualquier resolución de nombres externa. ¿Qué utilidad puede tener esto? A día de hoy muchos tipos de malware modifican el archivo de hosts para enviar a los afectados a sitios donde realizar pishing o webs con código maligno para lanzar exploits o ataques XSS (entre otros) contra el usuario.

    El último caso, y posiblemente el más usado a día de hoy, es la redirección de ciertas páginas a la dirección IP de Loopback. Esta simple práctica abre la posibilidad a un sin fin de posibilidades, como por ejemplo el filtrado de hosts, ya que cualquier hosts redirigido a la dirección de Loopback será anulado por así decirlo (siempre que en el equipo local no tenga levantado ningún servidor web, claro está. Así por ejemplo en el caso mostrado, si redirigimos la URL webpeligrosa.com, que por ejemplo conocemos es altamente dañina, a nuestra dirección de Loopback, en cualquier momento que el PC intente una conexión a dicho host, ya sea premeditado o por la intervención de un malware, nuestro equipo la enviará a la dirección de Loopback, y con ello la web no será válida.

    Estos archivos hosts, este sistema tiene una gran serie de ventajas, pero tienen tres características que lo hacen completamente inviable de cara a una red extensa: La primera de ella es que un archivo local de estas características es fácil de administrar cuando los hosts a filtrar son pocos, en cambio si el número es elevado tendríamos desde problemas de rendimientos (cientos de miles de direcciones supondría tamaños de archivos considerables) hasta entradas duplicadas. El segundo problema es aún peor. Si poseemos un archivo de hosts con la resolución de 10 equipos, y uno de ellos cambia de IP es fácil localizarlo y cambiarlo. Si manejamos archivos de hosts de cientos o miles de equipos, se hace imposible la actualización de estos archivos. La tercera es que no dispone de ningún sistema centralizado, esto significa que cada archivo hosts debería de ser almacenado en principio de forma local, y cualquier actualización de cualquier hosts tendría que ser modificada en todos los equipos.

  • Caso 3: Resolución DNS en caché local

    Sin un archivo de hosts ni especificación de la dirección IP de forma directa, el equipo necesita de un sistema “superior” que permita darle a conocer dicha IP, y es por ello que el sistema DNS es necesario. Pero si se realizase una petición DNS por cada nombre de dominio introducido, sería una práctica enormemente ineficiente. Es cierto que la actualización en el caso 2 de la IP de un hosts es algo más que inviable en grandes magnitudes, pero igualmente es cierto que tampoco es algo que suceda constantemente. Si la IP de un hosts se mantiene relativamente “estable” con el tiempo, sería una tontería estar realizando peticiones DNS constantemente para resolver la dirección del hosts. Más aun, cada petición DNS que se realiza, tiene un coste en el ancho de banda y en la sobrecarga de los servidores de resolución DNS (estos los veremos más adelante)

    Por todo ello, no es rara la existencia de una caché a nivel local que almacene las peticiones más realizadas o más recientes. Imaginar por ejemplo que se desea acceder a la web de google.es y que 5 segundos más tarde deseamos realizar otro acceso a la misma web. Esto implicaría dos peticiones DNS. Con una caché de DNS local, con un tiempo de vida limitado evidentemente, sería el equipo local quien respondería la petición DNS de nuestro navegador, sin necesidad de enviar una petición DNS a nuestra puerta de enlace o directamente a nuestros servidores DNS:

    C:\Users\Theliel>ipconfig /displaydns >> dns.txt
    zxlinks.com
    —————————————-
    Nombre de registro . : zxlinks.com
    Tipo de registro . . : 1
    Período de vida . . . : 86400
    Longitud de datos . . : 4
    Sección . . . . . . . : respuesta
    Un registro (host). . : 127.0.0.1

    zxlinks.com
    —————————————-
    No hay registros de tipo AAAA

    arstechnica.com
    —————————————-
    Nombre de registro . : arstechnica.com
    Tipo de registro . . : 1
    Período de vida . . . : 2091
    Longitud de datos . . : 4
    Sección . . . . . . . : respuesta
    Un registro (host). . : 75.102.3.15

    Con ipconfig /displaydns mostramos el contenido de la caché DNS de Windows. En este caso vemos dos entradas en ella, una de ellas apunta a la dirección de Loopback, la otra la IP de dicho hosts. Esto es debido a que Windows introduce los host del archivo hosts en su caché DNS, con un tiempo de vida de 24 horas (86400 seg). Por otro lado registrará cualquier petición DNS reciente que sea realizada, de este modo si el sistema requiere la resolución de otro host en un tiempo en el que la caché aun tenga dicho registro, será esta quien devuelva el resultado en vez de realizar una petición. El lado negativo en cambio es que si un host modifica su IP en el tiempo que nuestro sistema está cacheando la IP, la IP no será actualizada para nuestro sistema, y posiblemente nos toparemos con una URL no disponible. Es decir, el uso de caché aumenta el rendimiento considerablemente, pero de cuando en cuando puede existir un problema de coherencia. Es por ello que casi cualquier sistema permite el vaciado de la caché DNS, en Linux suele ir asociado simplemente a reiniciar el servicio (dependiendo del servicio usado), en Windows se realiza mediante: “ipconfig /flushdns”

    Por encima de esta caché local, podríamos situar un caché aún más cercana al usuario que se resolvería antes que enviar la petición al sistema. Algunos navegadores como Firefox poseen una pequeña caché interna de resolución de DNS que realiza una función igual. Esta caché suele ser más pequeña y suele ser mucho más eficiente, dado que esta caché tan solo es usada para peticiones realizadas mediante el navegador. Esto quiere decir que cualquier otro tipo de peticiones producidas por gestores de correo, clientes FTP, conexiones de juegos/aplicaciones… ninguna de estas estarán registradas en dicha caché. En Firefox, para poder acceder a las opciones de caché de DNS es necesario acceder a la página de configuración avanzada mediante la dirección en la barra de direcciones: about:config, y dentro de esta buscar la clave “network.dnsCacheEntries” y “network.dnsCacheExpiration”, siendo ambos nombres bastante descriptivos sobre su función.

  • Caso 4: Resolución DNS en caché de nuestro router

    Del mismo modo que nuestro sistema cuenta con una pequeña caché para almacenar las peticiones DNS más recientes o más comunes, no es extraño pensar en que un sistema similar podría ser incluido por ejemplo a nivel de nuestro propio router, de modo que el router serviría a todos sus clientes conectados como servidor de DNS. Sería por tanto este quien resolvería por los clientes las peticiones pertinentes y devolvería a estos el resultado. Pero por el mismo motivo, podría mantener una caché interna de DNS con las peticiones no de un solo cliente, sino de todos los clientes conectados. Es decir, si el cliente 1 necesita acceder por vez primera al servidor google.es y segundos más tardes el cliente 2 quiere acceder al mismo servidor, es más que probable que el router no vuelva a realizar una petición DNS para conocer la IP del servidor google.es, sino que ya tendrá almacenada dicha entrada debido a la petición anterior del cliente 1, con lo que todo el sistema se agiliza de forma considerable, optimizando además el ancho de banda. De lo contrario el router tendría que esperar la contestación de los servidores DNS configurados en él, estos a su vez o devolver la petición o realizarla a un servidor superior… y tan solo cuando se obtiene la IP destino devolverla al hosts que la pidió, y una vez el hosts tiene la IP dele servidor poder realizar ahora sí la petición http (por ejemplo) pertinente. Esta función no obstante depende del router en cuestión, y al igual que la resolución de DNS en caché local, posee de pros y contras (en el 90% de las situaciones es una práctica que merece bastante la pena)

    Hay que tener en cuenta y no hay que confundir una caché DNS con un servidor DNS, el cual evidentemente mantiene una caché DNS. Existen routers en la actualidad que poseen funciones de servidor DNS y por tanto cachea las peticiones DNS. Por ejemplo podemos ver esto en las firmware del equipo de DD-WRT.

Resolución DNS por medio de los servidores DNS (caso 5)

Aunque sería el caso 5, vamos a verlo independientemente de los otros 4 casos, dado que es aquí donde se pone en marcha en realidad el sistema DNS. Todos los casos anteriores lo que impiden de un modo u otro es tener que hacer uso de este sistema, no porque sea ineficaz, sino para evitar la sobrecarga en este. Además, es evidente que cualquier petición realizada al exterior consumirá un tiempo superior a cualquier petición respondida de forma local. Veamos algunos tiempos de resolución gracias a la herramienta de resolución DNS Dig, disponible tanto para Linux (suele venir incluida) como para Windows (se debe de descargar):

theliel@Anarchy:~$ dig theliel.es
; <<>> DiG 9.7.0-P1 <<>> theliel.es
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 58146
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;theliel.es. IN A

;; ANSWER SECTION:
theliel.es. 2362 IN A 188.121.46.128

;; Query time: 2 msec
;; SERVER: 192.168.3.1#53(192.168.3.1)
;; WHEN: Fri Jun 11 17:34:21 2010
;; MSG SIZE rcvd: 44

theliel@Anarchy:~$ dig @80.58.61.250 theliel.es

; <<>> DiG 9.7.0-P1 <<>> @80.58.61.250 theliel.es
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3856
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;theliel.es. IN A

;; ANSWER SECTION:
theliel.es. 2361 IN A 188.121.46.128

;; Query time: 66 msec
;; SERVER: 80.58.61.250#53(80.58.61.250)

;; WHEN: Fri Jun 11 17:34:22 2010
;; MSG SIZE rcvd: 44

Como podemos ver, la resolución DNS realizada por mi router en este momento es de tan solo 2 msec, es más que probable que tenga en su caché la resolución ya realizada. En cambio, si especifico que la resolución se lleve a cabo por medio de mi ISP, el tiempo se eleva a 66 msec, en este caso es el servidor DNS primario de telefónica España. Esta utilidad puede ser usada también para comprobar que servidores DNS son más óptimos para nuestra red. Por ejemplo, podemos ver el tiempo que tardaría los servidores de DNS de google, y si son mejores que los de nuestro ISP:

theliel@Anarchy:~$ dig @8.8.8.8 theliel.es
; <<>> DiG 9.7.0-P1 <<>> @8.8.8.8 theliel.es
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 49868
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;theliel.es. IN A

;; ANSWER SECTION:
theliel.es. 3594 IN A 188.121.46.128

;; Query time: 97 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)

;; WHEN: Fri Jun 11 17:43:00 2010
;; MSG SIZE rcvd: 44

En este caso, el servidor de DNS de Google (8.8.8.8) tiene unos tiempos de resolución peores a los servidores de mi ISP. Esto también tiene su explicación. Por un lado la cercanía de los servidores, por otro lado la necesidad de dichos servidores de recurrir a servidores DNS superiores.

Cuando ningún sistema “local” puede resolvernos un nombre de dominio, es necesario realizar una petición DNS a un servidor DNS para que este nos devuelva la IP del host al que deseamos acceder. Cuanto antes sea respondida dicha petición, antes será alcanzado el hosts. La mejor forma de ilustrar esto es poner dos ejemplos: El mejor de los casos y el peor de los casos. De este modo se puede ver perfectamente el funcionamiento jerárquico de DNS y la importancia última de los servidores DNS raíces.

En el mejor de los casos, el servidor DNS de nuestro ISP tiene directamente la respuesta de nuestra petición. Es decir, imaginar que deseamos conocer la IP del servidor donde está alojado el dominio theliel.es. Si nuestro ISP posee esta entrada directamente en su servidor DNS, este no tendrá que acudir a un servidor de DNS superior y de forma inmediata devolverá la IP de este host. Pero si dicha entrada no se encuentra presente en el servidor de DNS de nuestro ISP, este a su vez debe de realizar una petición DNS a un servidor DNS superior a él, De este modo se realiza lo que se conoce como peticiones DNS recursivas, en la que nuestra petición DNS va saltando entre los diferentes servidores DNS hasta que alguno de estos servidores devuelve la IP deseada. Veamos el peor de los casos de este ejemplo cuando se desea conocer la IP del host earth.google.es:

theliel@Anarchy:~$ dig +trace @80.58.61.250 earth.google.es

; <<>> DiG 9.7.0-P1 <<>> +trace @80.58.61.250 earth.google.es
; (1 server found)
;; global options: +cmd
. 472319 IN NS f.root-servers.net.
. 472319 IN NS g.root-servers.net.
. 472319 IN NS h.root-servers.net.
. 472319 IN NS i.root-servers.net.
. 472319 IN NS j.root-servers.net.
. 472319 IN NS k.root-servers.net.
. 472319 IN NS l.root-servers.net.
. 472319 IN NS m.root-servers.net.
. 472319 IN NS a.root-servers.net.
. 472319 IN NS b.root-servers.net.
. 472319 IN NS c.root-servers.net.
. 472319 IN NS d.root-servers.net.
. 472319 IN NS e.root-servers.net.
;; Received 228 bytes from 80.58.61.250#53(80.58.61.250) in 400 ms

es. 172800 IN NS ns1.crn.nic.es.
es. 172800 IN NS ns1.nic.es.
es. 172800 IN NS ns1.cesca.es.
es. 172800 IN NS ns3.nic.fr.
es. 172800 IN NS sun.rediris.es.
es. 172800 IN NS ns-ext.nic.cl.
es. 172800 IN NS sns-pb.isc.org.
;; Received 376 bytes from 202.12.27.33#53(m.root-servers.net) in 99 ms

google.es. 7200 IN NS ns2.google.com.
google.es. 7200 IN NS ns1.google.com.
;; Received 79 bytes from 130.206.1.2#53(sun.rediris.es) in 66 ms

earth.google.es. 345600 IN CNAME earth.google.com.
earth.google.com. 86400 IN CNAME www3.l.google.com.
www3.l.google.com. 300 IN A 209.85.229.102
www3.l.google.com. 300 IN A 209.85.229.100
www3.l.google.com. 300 IN A 209.85.229.101

;; Received 132 bytes from 216.239.34.10#53(ns2.google.com) in 116 ms

En este caso, el servidor DNS de nuestro ISP (80.58.61.250) es incapaz de resolver la IP del host earth.google.es. Dado que no es capaz de resolver dicha dirección, no tiene otro remedio que realizar una petición DNS a un servidor que pueda conocer algo más de ese host. Aquí es donde cobra gran importancia la jerarquía de los dominios. En el host earth.google.es, el dominio de primer nivel es “es”. El servidor de DNS de telefónica no conoce cuales son los servidores de resolución DNS para los ccTLD .es, pero sí conoce la dirección de los servidores DNS raíces. El servidor DNS de telefónica consulta la lista de los servidores raíces y opta por enviar la petición al servidor raíz m (m.root-servers.net). El servidor raíz m recibe por parte del servidor DNS de telefónica una petición de resolución para el servidor DNS .es. El servidor raíz m SI CONOCE y si tiene en su base de datos la dirección de los servidores DNS que gestionan las direcciones ccTLD .es, y de entre todas ellas escoge el servidor sun.rediris.es, con lo que envía esta IP al servidor DNS de telefónica. Este conoce ya la IP del servidor de DNS que le podrá resolver la IP del dominio google.es, con lo que envía al servidor DNS anteriormente devuelto por el servidor raíz una petición de resolución para el dominio de segundo nivel google.es. El servidor sun.rediris.es recibe la petición por parte del servidor raíz M para resolver la dirección del host google.es (ya dentro del dominio de primer nivel .es). Esta consta en su base de datos, con lo que le responde de nuevo con la IP de la de la resolución del host del servidor de DNS de google, concretamente ns2.google.com. Dado que este es el último servidor de DNS que necesita, el servidor de telefónica que está realizando la recursividad solicita la resolución de earth.google.es a dicho hosts, dicho servidor recibe la petición de resolución para earth (ya dentro del dominio google.es), y dado que la posee envía la contestación al ISP y este a nosotros.

Lo normal es que todo este proceso se realice de forma completamente transparente por parte de nuestro ISP, y nuestro sistema tan solo realice una petición DNS, mientras que nuestro ISP puede realizar la petición recursiva DNS (es quien va enviando las diferentes peticiones según las respuestas que va recibiendo por parte de los servidores DNS) y es él quien al final nos envía a nosotros la dirección IP final. Aquí podemos ver la gran importancia de los servidores raíces, podemos decir que estos son los que poseen acceso directo a los servidores de DNS TLD. Si estos servidores raíces fallan, Internet falla, de ahí a ser objetivo de hackers desde que Internet nació y de ahí a que estén repartidos por todo el mundo y con numerosas réplicas en él.

Esta es la mejor imagen que he encontrado que ilustra todo el proceso: caché del navegador, caché del PC, caché del ISP y de cómo este envía la petición recursiva:


 

Tipo de Registros DNS:

Hasta ahora hemos hablado sobre cómo funciona el sistema DNS, pero está incompleto. Hasta ahora podríamos hacernos la idea de que un servidor DNS es a groso modo un sistema que procesa las peticiones DNS recibidas con una gran base de datos en la que asocia una IP a un nombre de dominio. Pero esto no es cierto. Esta base de datos no está constituida por una asociación IP -> Nombre de dominio, sino por un conjunto de registros asociados a cada dominio. Esto otorga al sistema DNS de funcionalidades mucho más extendidas, que no simplemente el mero hecho de conocer la IP de un host. Estos registros almacenan cierta información sobre el dominio en cuestión, por ejemplo el registro A lo que contiene es precisamente la IP de dicho dominio.

Aun cuando en la actualidad la lista de posibles registros DNS es mucho mayor, la inmensa mayoría de toda la red continúa usando tan solo algunos de los registros DNS que se crearon originalmente, aquellos especificados en el RFC 1035. De este primer abanico de registros, algunos son experimentales como los registros MB o MR, mientras que otros como MD y MF fueron sustituidos por otros más usados y con la misma finalidad. Veamos los registros DNS que podríamos considerar “útiles” de esta primera especificación:

 

  • A: Almacena la IPv4 del host, es decir, el mapeo de nombre de dominio – dirección IP de host.
  • NS: Especifica un servidor DNS para dicho dominio, es decir, el servidor DNS autorizado para dicho host.
  • CNAME: Más comúnmente conocido quizás como un alias. Es decir, especifica el nombre de otro nombre. Podría verse quizás como una redirección a nivel de DNS de un dominio a otro. Por ejemplo una entrada de este tipo: “correo.theliel.es CNAME gl2.gmail.com” significa que cada vez que se debe de resolver la IP para “correo.theliel.es”, se devolverá en su lugar la IP de gl2.gmail.com. En este caso, decimos que correo.theliel.es (o solamente correo, si damos por hecho que estamos en el dominio theliel.es) es un alias del host de google dado. Esto es usado constantemente. Hay que tener en cuenta que por su propia definición no es posible solicitar a un servidor DNS que nos respondan los alias de dicho dominio, pero sí podemos saber si un dominio/subdominio… dado es un alias de otro simplemente haciendo un ping. Veamos la diferencia entre hacer un ping a un alias o hacer ping a un host directamente:

    Ping a un alias:

    C:\Users\Theliel>ping earth.google.com
    Haciendo ping a www3.l.google.com [209.85.227.100] con 32 bytes de datos:

    Ping al host real anterior:

    C:\Users\Theliel>ping www3.l.google.com
    Haciendo ping a www3.l.google.com [209.85.227.139] con 32 bytes de datos:

    Al hacer un ping a un alias, este automáticamente nos “redirige” al host al que apunta el alias. Es decir, en los servidores de nombres de Google en algún lugar existirá una entrada de este tipo: earth.google.com CNAME www3.l.google.com. Para terminar indicar que aunque se puede hacer, no es recomendable anidar alias, es decir, un alias que apunta a otro alias que apunta al host.

  • SOA: Marca el comienzo de una zona DNS, entendiendo por zona DNS algo así como el ámbito de acción de dicha red. Es decir, los servidores DNS de google forman una zona DNS que casi con toda seguridad englobaría todos los servicios de google, todas sus redes, etc… pero es evidente que los servidores DNS de google casi con toda seguridad no poseen registros de otras zonas DNS como las de Yahoo, Microsoft…

    El registro SOA por tanto contiene en primer lugar el servidor DNS principal de la zona, así como datos administrativos: correo del administrador, número de serie, temporizadores de refresco… datos concretos sobre la propia zona DNS.

  • PTR: Puntero a un nombre de dominio. Su función principal es hacer resoluciones DNS inversas, es decir, en vez de obtener la IP por el host obtener el host por la IP. Un ejemplo de esto:

    C:\Users\Theliel>dig -x 74.125.77.104
    ; <<>> DiG 9.7.1rc1 <<>> -x 74.125.77.104
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1981
    ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

    ;; QUESTION SECTION:
    ;104.77.125.74.in-addr.arpa. IN PTR

    ;; ANSWER SECTION:
    104.77.125.74.in-addr.arpa. 86400 IN PTR ew-in-f104.1e100.net.

    Es decir si realizamos una resolución inversa de la IP 74.125.77.104 nos devuelve que es el host ew-in-f104.1e100.net, host de google.es

  • MX: Registro de intercambio de correo. Este registro es fundamental para el uso del correo electrónico, mapea un dominio a un servidor de correo (o una lista de posibles candidatos). Cada vez que enviamos un correo electrónico a una dirección, es necesario conocer el servidor de correo de dicho dominio. ¿Cómo? A través de la consulta de sus registros MX. Una vez obtenemos el host de dicho servidor podemos conectarnos a él para entregar el correo. En realidad el funcionamiento del correo electrónico es muy simple. Si enviamos desde Gmail por ejemplo (interfaz web) un correo a una dirección @live.com, aunque no sea nuestro navegador quien haga la consulta, el servidor de google por nosotros para poder entregar dicho mensaje primero tiene que conocer la IP o el destino de dicho realm (el realm es el @live.com). Por ciencia infusa Google no puede conocer la IP del host al que debe de entregar el correo. Realizaría algo similar a lo siguiente:

    theliel@Anarchy:~$ dig live.com MX
    .

    ;; QUESTION SECTION:
    ;live.com. IN MX

    ;; ANSWER SECTION:
    live.com. 2426 IN MX 5 mx1.hotmail.com.
    live.com. 2426 IN MX 5 mx2.hotmail.com.
    live.com. 2426 IN MX 5 mx3.hotmail.com.
    live.com. 2426 IN MX 5 mx4.hotmail.com.

    theliel@Anarchy:~$ ncat -C mx1.hotmail.com 25
    Connected to mx1.hotmail.com.
    Escape character is ‘^]’.
    220 col0-mc2-f34.Col0.hotmail.com Sending unsolicited commercial or bulk e-mail (bla bla bla)
    ehlo test
    250-col0-mc2-f34.Col0.hotmail.com (3.10.0.73) Hello [81.34.161.58]
    250-SIZE 29696000
    250-PIPELINING
    250-8bitmime
    250-BINARYMIME
    250-CHUNKING
    250-AUTH LOGIN
    250-AUTH=LOGIN
    250 OK
    mail from: <test@gmail.com>
    550 DY-001 Mail rejected by Windows Live Hotmail for policy reasons. We generally do not accept email from dynamic IP’s as they are not typically used to deliver unauthenticated SMTP e-mail to an Internet mail server. http://www.spamhaus.org maintains lists of dynamic and residential IP addresses. If you are not an email/network admin please contact your E-mail/Internet Service Provider for help. Email/network admins, please visit http://postmaster.live.com for email delivery information and support
    Connection closed by foreign host.

    Es decir, primero hay que conocer el servidor de correo, que es posible gracias a una consulta DNS de su registro MX. Este servidor nos responde con una lista de hosts disponibles, TODAS en esta ocasión con la misma prioridad (el número 5 que las precede, a menor número mayor prioridad a la hora de conectarse a uno u otro). Una vez que disponemos ya del host (mx1.hotmail.com en este caso) podemos conectarnos a él. OJO!! aunque se da ya por sabido en realidad cuando intentamos conectarnos al host citado, nuestro sistema deberá realizar otra petición DNS para conocer la IP del host mx1.hotmail.com, consultando el registro A de dicho dominio. Una vez que se realiza la conexión (en mi caso de ejemplo con ncat) el servidor de Gmail intentaría algo como lo expresado, mail from: <test@gmail.com>. En este caso el servidor de correos de live.com no nos permite continuar dado que detecta que la IP origen es dinámica (cuestiones de seguridad de los servidores de correo). En el caso de Gmail permitiría la conexión. Evidentemente es solo un ejemplo.

  • TXT: Es un registro reservado para cualquier tipo de información que se quiera añadir. A día de hoy se usa para una gran multitud de propósitos, ninguno específico.


No obstante, con el paso de los años se han ido haciendo necesario algunos registros adicionales, y a esta lista inicial deberíamos de añadir algunos más para poder dar la lista como “completa”, aunque evidentemente existan muchos otros registros, aunque también mucho menos usados:

  • AAA: Si el registro A mapeaba hosts a direcciones IPv4, es necesario disponer de un registro DNS que permite devolver del mismo modo direcciones IPv6. Su función es exactamente la misma, salvo que en vez devolver los 32bits de una IPv4 nos devolverá los 128 bits de la dirección IPv6.
  • SRV: Registro de servicios, otorga información sobre ciertos servicios. A día de hoy su uso es fundamental en aplicaciones tipo VoIP o muchos otros servicios modernos que dependen de una forma u otra de servidores más o menos específicos.


Paquete DNS:

Las peticiones DNS a fin de cuentas son datos que se envían, y al igual que una petición HTTP, este tiene su estructura por así decirlo. No obstante, DNS opera en el nivel de aplicación, por tanto hace uso de otros protocolos inferiores como UDP o IP para transmitirse. DNS usa el protocolo UDP para enviarse, usando el puerto 53 para tal efecto:

1 0.000000000 192.168.x.124 192.168.x.1 DNS Standard query A theliel.es
2 0.117633000 192.168.x.1 192.168.x.124 DNS Standard query response A 188.121.46.128


 

Problemas y soluciones a DNS:

Existen ciertas limitaciones en cuanto al sistema DNS. En realidad no son limitaciones en sí, sino problemas que surgen con los años. Para empezar y el más importante quizás es que DNS como tantos otros protocolos no se crearon para ser seguros, sino eficientes. Pensar por ejemplo que cualquiera podría construir un servidor DNS e intentar suplantar unas peticiones por otras malignas. O realizar ataques de envenenamiento DNS (que se verá en otro momento).

A todo esto se añade el problema de los actuales hosting virtuales, que permiten albergar en el mismo host diferentes servidores web funcionando al mismo tiempo. Con esto nos topamos cada día y nadie se pregunta en realidad cómo es posible, dado que un registro A tan solo devolverá la IP de un host, no la web que se quiere acceder a él. Es decir imaginar que deseamos acceder a una web http://ejemplo.com. Para poder realizarse la conexión es necesaria conocer la IP e imaginemos que la IP es 2.2.2.2. Ahora bien, en teoría solo bastaría una conexión a dicha IP por el puerto 80 y mediante el protocolo http para recibir dicha web. El problema aparece cuando en dicho host hay múltiples servidores web funcionando todos en el mismo puerto y al mismo tiempo. Es por eso que si en el navegador intentamos acceder a estos servidores por IP no podremos. Como saben estor servidores que web devolver? Gracias a las cabeceras HTTP que sirven de referencia al servidor para conocer la web que debe de devolver.

Por último y no menos importante son los conocidos como DDNS, o DNS dinámicos. Ya hemos visto la importancia de un dominio, y que los servidores DNS se van actualizando con el tiempo para tener siempre actualizada la IP a la que apuntan dichos nombres de dominio. No obstante la IP de un host no debería de variar demasiado, pero que sucede si tenemos un dominio que queremos que apunte a un host que posee una IP dinámica? Pues bien, existen servicios tanto gratuitos o de pago para sofocar esto. El sistema funciona de forma muy simple:

  1. Se nos otorga un dominio, normalmente un subdominio de segundo nivel, tipo “pepito.dyndns.org”
  2. Dado que nuestra IP puede variar incluso con cada conexión a la red, se crea una aplicación cliente que envía los datos de la nueva conexión cada vez que la conexión se debe de actualizar, y estos datos los envía precisamente a este proveedor de servicios, en este caso dyndns. Esta aplicación cliente enviaría nuestra IP actual, nombre de usuario y contraseña y con esos datos ellos actualizarían sus servidores DNS para actualizar así la IP asociada a dicho dominio.
  3. Nuestro host, aun teniendo una IP dinámica siempre sería accesible por medio del servicio de DDNS proporcionado por dyndns.

Para que esto sea posible SIEMPRE debe de existir una aplicación cliente que sea la que se encargue siempre de enviar los datos de la nueva conexión al servidor del proveedor. Lo que se hace a día de hoy para facilitar esto es añadir soporte en los propios routers para esto, es decir, muchos routers poseen internamente clientes DDNS, de modo que en realidad todo el proceso queda completamente transparente al usuario, este tan solo tiene que configurar el router y una vez realizado, cada vez que la IP cambia el router conecta con el servidor del servicio y actualiza la IP. Como digo es un servicio muy importante a día de hoy, sobre todo para aquellos que necesitan acceder a servicios de su red de forma remota sin importar la IP de esta.

 

 

Protocolos TCP y UDP

En conjunto con el protocolo IP conforman el núcleo principal de prácticamente todas las redes existentes a día de hoy, recordemos que estamos usando el modelo TCP/IP, luego el protocolo TCP seguro que jugará un papel importante.

Estos dos protocolos serán básicamente los dos únicos protocolos a nivel de transporte que vamos a tener. Podríamos añadir en todo caso SCTP usado para streaming, pero vamos… el 99% de todo el tráfico se gestiona por uno de estos dos protocolos. Recordemos que el nivel de transporte será quien establezca una comunicación entre aplicación origen- aplicación destino (en los niveles inferiores en realidad las comunicaciones son entre nodos). La idea es proveer a la comunicación con ciertos mecanismos como el control de flujo, detección de errores y otras cuestiones que iremos viendo.

Como hemos dicho veremos dos protocolos tan solo:

  • UDP (User Datagram Protocol)
  • TCP (Transmission Control Protocol)

Vamos a ver primero UDP por su gran sencillez, sería prácticamente la mínima expresión. A partir de este no obstante es mucho más simple comprender un protocolo bastante más complejo como TCP. Pero antes de entrar en los protocolos en sí hay que hablar de los puntos de accesos a estos, dado que será algo primordial para estos: Los puertos.

 

Puertos:

De cara al modelo TCP/IP o modelo OSI, los puertos serían los SAP del nivel de transporte, los puntos de acceso. Visto de forma más práctica los puertos permiten conexiones múltiples simultáneas entre distintos o iguales hosts sin que ninguna conexión interfiera en la otra. Visto de un modo más simple aun, los puertos serían las diferentes entradas/salidas en las comunicaciones.

Cuando un host desea enviar un mensaje a otro por medio de TCP o UDP primero debe de solicitar al OS un puerto de salida por el cual poder realizar la comunicación. Del mismo modo que necesita de un puerto de salida, dicho mensaje deberá de especificar ya no solo el destino (la IP o el nombre de host), sino el puerto al que quiere acceder en dicho host e informar al destino de puerto de salida que está usando para la comunicación, a fin de que el destino pueda contactar del mismo modo con el emisor. La necesidad del puerto de salida es clara, por algún lado tiene que salir el mensaje. ¿Pero y el puerto de entrada? En realidad es igualmente importante, ya que tanto puertos de entrada/salida se asocian generalmente a servicios/aplicaciones concretas. Es decir, gracias a estos puertos ya no solo debemos de especificar un host destino, sino que dentro de este, a que servicio o aplicación deseamos enviarle el mensaje.

Estos puertos se identifican como un número entero sin signo de 16 bits, es decir, un número comprendido entre el 0 y el 65535. Estos números hacen de ID de puerto por así decirlo. Estos puertos no son compartidos es decir, existirán por tanto 65536 puertos para TCP enumerados de 0 a 65535 y otros tantos para UDP enumerados exactamente igual, es por ello que el número del puerto no especifica si es UDP o TCP, esto es importante.

Como he dicho el 99% de todas las comunicaciones que hacemos se basan en este concepto, aun cuando no lo sepamos porque el proceso sea transparente a nosotros. El mejor ejemplo de esto es por ejemplo la navegación web. Hemos hablado de la necesidad de la IP o de las DNS, pero nadie ha visto en ningún momento nada parecido a un puerto o a un número que no sea la IP y que podamos imaginar que es un puerto. Pero esto es porque los navegadores lo hacen de forma implícita. Cuando en un navegador especificas por ejemplo “http://” estás especificando el protocolo http que por defecto (no significa que no pueda ser otro) se le asocia el puerto 80. Es decir, si en el navegador accedemos a la web http://www.google.es se realizará una petición al host www.google.es por el puerto 80 TCP, y con puerto no me refiero al puerto de salida de nuestro host, sino el puerto destino del host remoto.

Esto de que el puerto 80 esté asociado a los servidores web es así porque la IANA estableció que el puerto 80 sería el puerto “conocido” para el servicio web. En realidad la IANA mantiene un extenso listado con todos los puertos “conocidos”, así como los puertos registrados. Pero esto no quiere decir que los servicios de dicha lista se deban de asociar a dichos puertos, dado que un administrador de sistemas tiene siempre la última palabra sobre qué puerto asociar a que servicio. De todos modos esto tiene su lógica. Si se establece que el puerto para web será el 80, cualquier aplicación estará configurada para ello y no será necesario conocer en cada ocasión el puerto, lo mismo sucede con infinidad de puertos. Otras veces en cambio lo deseable puede ser exactamente lo contrario, y por motivos de seguridad no queremos asociar un servicio a su puerto preestablecido.

Se podría decir que generalmente tan solo los puertos de destino suelen tener un servicio asociado, pero esto sería incorrecto dado que un puerto de entrada se convierte en puerto de salida cuando tiene que enviar un mensaje. Así que podríamos matizar diciendo que generalmente los puertos de salida al iniciar la comunicación no suelen estar asociados. Por ejemplo, si realizamos una petición http al servidor web de google, sabemos que debemos de enviarla al puerto 80 TCP, ¿pero por qué puerto saldrá el mensaje de nuestro equipo? podríamos pensar en primer lugar que por el mismo puerto, que por el 80, pero esto no es así, el puerto 80 lo usaríamos para enviar datos (lo normal claro) tan solo de tener instalado un servidor web. Luego… ¿qué puerto se usará de salida? En este caso lo normal es que el navegador solicite una conexión de salida al OS, y sea el propio sistema quien le asigne un puerto que en ese momento no esté en uso para realizar dicha conexión, posiblemente entre un rango de puertos ya preestablecidos. Es decir, cada comunicación que hagamos incluso para navegar, el puerto de salida de nuestro mensaje será diferente casi el 100% de las veces. Es más, ahora mismo por ejemplo mi navegador Firefox mantienen de forma simultanea 5 conexiones activas, usando los puertos de salida 44384, 44385, 44387, 44388 y 44389, pero esto es en este mismo instante!! en cuanto la conexión TCP finalice y se abra una conexión TCP nueva, se le asignará un nuevo puerto de salida, y así el navegador quedará mientras dure la conexión “a la escucha” de dicho puerto preparado para recibir cualquier información que entre por él, que es de suponer que el mismo navegador estará esperando. Evidentemente los puertos que ya no están en uso se reutilizan sin problema alguno.

Podemos decir también que un puerto tiene 2 estados fundamentales, Abierto y Cerrado. Para que un puerto pueda enviar/recibir información, debe de estar abierto, es decir, algún servicio o programa asociado a él. Cuando en el ejemplo anterior nuestro navegador tiene que comunicarse con el puerto 80 TCP de un servidor web, antes de poder realizar la conexión el OS asocia a dicha aplicación (Firefox) el puerto temporal para la comunicación, digamos que el puerto queda abierto. Al otro lado en cambio, el puerto 80 del servidor web estará permanentemente abierto a la espera de cualquier comunicación externa entrante, el puerto 80 en este caso estará asociado a por ejemplo un servidor web Apache o IIS. En cambio, el puerto temporal abierto por el OS para Firefox para dicha conexión estará abierto tan solo el tiempo que dure la comunicación, cuando esta finalice, el puerto se cerrará. Esto es muy importante de cara a la seguridad como se verá en otro momento.



UDP:

Es un protocolo no orientado a la conexión, es decir, no provee ningún mecanismo de control de flujo, ni tampoco implementa ningún sistema propio de detección de errores o de pérdida de mensajes/datagramas (en nivel 4 no se puede hablar ya de paquetes, que es propio del nivel 3). Aunque en realidad el término “orientado a conexión” hace referencia a que no es necesario una negociación previa entre los dos dispositivos para comenzar la comunicación. Cuando tratamos con UDP debemos de tener claro por tanto que a este protocolo no le importa si se pierden datos en el camino, es más, el destino puede incluso estar saturado o colgado y UDP no tendrá constancia de ello, como si el puerto de comunicación está abierto o simplemente no es válido.

Esto parece tener muchos inconvenientes, pero en cambio todo depende de la aplicación que necesite enviar los datos o qué tipo de datos sean. Por ejemplo, la corrección de errores o el control de flujo puede implementarse a nivel de aplicación, o simplemente la pérdida de datagramas podría no ser importante, cosa muy habitual por ejemplo en aplicaciones en tiempo real como juegos online, Streaming, VoIP… ¿Pasa algo si 1 de cada 1000 datagramas se pierde en una videoconferencia? Pues la verdad es que prácticamente no afecta absolutamente en nada, a lo mejor vemos en ese momento un punto de otro color en la imagen recibida de la webcam del otro usuario, o puede que la conversación tenga un poco de más ruido de fondo, pero para nosotros es mucho más importante la fluidez de la conversación a la calidad de esta. Puede que UDP tenga muchos puntos negativos, pero no hay que verlo como negativos, sino como características, que dependiendo de la situación son mucho más deseables que otras. ¿Cuál es el objetivo por tanto de UDP? es fácil, la transmisión rápida de datos, la sencillez de la comunicación, en que prácticamente no hay que ocuparse de nada.

Hay que tener en cuenta que cuanto más complejo es un protocolo más sobrecargado está, y esto tiene un impacto notable en el uso de las redes. Imaginar que solo quiero enviar la palabra “Casa” a otro host. Con UDP me vasta dos datos y medio y lo envío. En TCP como ya veremos tendríamos que negociar la conexión, enviar los datos, cerrar la conexión… y todo ello además con cabeceras mucho más grandes en fin.. que a lo mejor en vez de enviar 20 bytes tendríamos que enviar 200 bytes para la misma tarea.

Como hemos dicho UDP no requiere del establecimiento de una conexión previa, de ningún sistema de acuerdo entre los dos hosts. Si un host quiere enviar un mensaje UDP a otro, tan solo tiene que (a nivel de transporte claro está) rellenar la cabecera UDP y adjuntar los datos que quiera:

Puerto de Origen

Puerto de Destino

Longitud

Checksum

  • Puerto de Origen/Puerto de Destino (16 bits cada uno): Especifica el puerto de origen y el puerto de destino del mensaje UDP. Al ser un número de 16 bits se infiere que tendremos un máximo de 65536 puertos posibles
  • Longitud (16 bits): Es un registro ya típico, en este caso especifica la longitud en bytes de todo el mensaje UDP, incluyendo tanto cabecera como el SDU del nivel superior, es decir, los datos realmente. Hay que recordar que cada nivel normalmente añade/elimina su propia cabecera a los datos recibidos y los envía hacia abajo o hacia arriba en el modelo TCP/IP. Dado que la cabecera tiene un tamaño fijo de 64 bits, la longitud mínima para un mensaje UDP sería 8 Bytes, es decir, un mensaje UDP vacío. Por la misma razón, la máxima cantidad de datos que se pueden enviar por un mensaje UDP sería 64K menos 8 Bytes.
  • CheckSum (16 bits): La detección de errores en este caso es un poco peculiar, y además, en IPv4 es opcional (obligatoria en IPv6, recordemos que IPv6 NO tenía comprobación de checksum a nivel de protocolo IP). El algoritmo que usa es exactamente el mismo que el que se realiza en IP, se realiza el complemento a uno a la suma en complemento a uno resultante de cada palabra, pero en este caso no se hace sobre la cabecera de UDP, sino sobre la llamada pseudo cabecera UDP. Esta cabecera en realidad no existe, tan solo es una composición que se crea para crear el checksum. Esta cabecera está compuesta por la IP de origen, la IP destino, un byte de ceros, un registro que especifica el protocolo y otro registro que especifica la longitud del mensaje UDP, es decir, esta cabecera virtual toma algunos elementos de la cabecera IP. Pero repito, tan solo se “construye” esta cabecera para calcular el checksum, esta cabecera como tal no existe, no se transmite.

Eso es todo. Es la mínima expresión, una cabecera con lo mínimo, en que lo más “complejo” puede ser el checksum y que ni siquiera es obligado en IPv4. Después de la cabecera evidentemente se adjuntarían los datos del nivel superior, el SDU, que junto a la cabecera conformarían el 4PDU, el mensaje UDP completo que pasaría al nivel de red (en caso de que se esté enviando).

¿Cuál es el mejor ejemplo de mensaje UDP? Los mensajes DNS, DNS se transmite por medio de mensajes UDP. Qué pasa si se pierde un mensaje DNS? Pues posiblemente que si el navegador o el host tenga un tiempo de espera predeterminado para la petición DNS, si no recibe la respuesta casi de inmediato, enviará casi seguro una segunda o una tercera petición. Pero no es algo que requiera una integridad especial o una complejidad enorme. Además, son mensajes que se están retransmitiendo constantemente. Usar TCP para mensajes tan cortos sería hacer un uso enorme de la red tan solo para las peticiones DNS. Con UDP funcionan el 99% perfectamente, y hacen un uso muchísimo más optimizado de la red. Además, cuanto más pequeños sean los mensajes, menor probabilidad de errores existirá en su retransmisión.


TCP:

Es todo lo contrario a UDP. Para empezar, es un protocolo orientado a conexión, es decir, requiere del establecimiento previo de una conexión antes de poder comenzar a retransmitir datos. Es infinitamente más complejo que UDP, pero por otro lado TCP hace posible comunicaciones fiables, tolerantes a fallos, con una buena gestión del control de flujo… aunque todo ello requiere por ende un protocolo más complejo, una cabecera más grande y una menor cadencia a la hora de transmitir datos en definitiva.

Al igual que le pasara a UDP, no se puede ver esto como algo negativo, sino como algo necesario para poder tener una comunicación fiable para aplicaciones que así lo requieren. Posiblemente el caso más ilustrativo sería la navegación web por ejemplo. Una web puede pesar considerablemente, desde unos KBs a MBs de datos. Que importa en este caso gastar unos KBs de más si nos garantizamos que el navegador recogerá correctamente la información del servidor opuesto. Pensar cuando enviamos un formulario (al margen de que se pueda enviar o no por protocolos seguros como TLS/SSL), no podemos permitirnos en modo alguno que al servidor no le llegue un mensaje TCP correcto, dado que ese mensaje podría ser desde un número diferente en el DNI, en el nombre o en cualquier otro lugar. Recordar que protocolos como UDP no tienen siquiera ningún mecanismo para saber si los datos han llegado o no, mucho menos si lo hicieron correctamente. En la mayoría de las comunicaciones necesitamos saber que los datos se han enviado correctamente o se han recibido sin errores.

Existen pues muchas aplicaciones que hacen uso de ambos protocolos, por ejemplo la mayoría de programas P2P o juegos online. ¿Por qué? Habilitan por ejemplo un puerto UDP para maximizar el envío/recepción de datos, y se usa la misma aplicación para controlar que estos lleguen en buen estado. Pero a la par se usa un puerto TCP para aquellas cuestiones que si requieran precisión, normalmente pequeños mensajes, pero que sí necesitamos conocer que han llegado y en buen estado:

 

Puerto de Origen

Puerto de Destino

Número de Secuencia

Número de ACK

Offset

Reservado

U

A

P

R

S

F

Ventana

CheckSum

Puntero “Urgente”

Opciones

Padding

 

  • Puerto de Origen/Destino (16 Bits cada uno): Tiene exactamente el mismo uso que el citado en el protocolo UDP, especifica mediante un entero sin signo el puerto de origen que usará el mensaje TCP, así como el puerto destino al que va dirigido.
  • Número de Secuencia (32 bits): Recordemos que TCP posee funciones de control de flujo, esto significa que de algún modo cada mensaje enviado tiene que ser claramente identificable de otro. Esto quiere decir que si dos mensajes TCP llegan al destino de forma desordenada, el host receptor podría ordenarlos perfectamente dado el número de secuencia. Del mismo modo si se recibe un mensaje cuyo número de secuencia no concuerda con el esperado, el mensaje podría descartarse por interpretar que dicho mensaje es ajeno a la comunicación actual entre los dos hosts, por ejemplo un mensaje inyectado desde un tercer host que intentase manipular la conversación entre ambos. Si el flag Syn (S) no está especificado, será el número de secuencia del primer octeto (byte) de datos adjuntos en dicho mensaje (después de toda la cabecera). En cambio, si el flag Syn está habilitado, el primer octeto adjunto en dicho mensaje será el número de secuencia + 1.
  • Número de ACK (32 bits): La gran mayoría de las veces, para nosotros un ACK será un mensaje o paquete de confirmación. Este tipo de mensajes son muy comunes en gran multitud de protocolos, son como pequeñas señales de respuesta para indicar que se ha recibido la información. Gracias a estos mensajes también solucionamos el problema de conocer si un mensaje llega correctamente o no a su destino, dado que si llega, el destinatario nos responderá con un ACK (ACK proviene de Acknowledgment). Por ello, si el flag ACK (A) está activado, el número de ACK corresponderá al próximo número de secuencia del mensaje que espera recibir por parte del emisor. Es decir, en el caso de que la comunicación sea correcta, si un host envía un ACK con número de ACK “200”, significará que está esperando que el otro host le envíe un mensaje (del tipo que sea) con un número de secuencia de 200.
  • Offset (4 bits): El número de bloques de 32 bits que ocupará la cabecera, por tanto indica cuando empiezan los datos (el SDU). Como ya se viese en el protocolo IP, para que este tipo de registros sean posible es necesario que la cabecera siempre sea múltiplo de 32 bits, lo cual se hace con un padding, puesto que existen campos en la cabecera de longitud variable.
  • Reservado (6 bits): bits reservados, se deben de establecer a cero.
  • Flags (1 bit cada una): Los flag o banderas son bits que básicamente dicen cuando un flag está activado o no. Cada uno de esos bits especifican algo concreto:


    URG (U): Usado conjuntamente con el campo “Puntero Urgente” para especificar que existe un dato en el mensaje que debe de ser procesado con anterioridad.
    ACK (A): Usado conjuntamente con el número de ACK para indicar una contestación, como ya se ha explicado.
    PSH (P): Esta señal está relacionada directamente con la ventana del protocolo TCP que se verá a continuación. Si el flag PSH es especificado, el mensaje por pequeño que sea será enviado.
    RST (R): Básicamente es una bandera que de habilitarse indica al otro host que reinicie la comunicación, algo así como un reset de la sesión.
    Syn (S): Formalmente realiza la sincronización del número de secuencia. El primer mensaje enviado por cada una de las partes al otro tendrá activada el flag Syn, es decir, al inicio de la comunicación.
    FIN (F): Se usa para comenzar o forzar el cierre de la sesión. Técnica significa que no serán enviados más datos por parte del emisor.



  • Ventana (16 bits): Especifica en Bytes el tamaño de la ventana de recepción. Es decir, el tamaño máximo (comenzando desde el número de secuencia de ACK) de datos que puede recibirse en una comunicación TCP, antes de contestar con un ACK. En realidad esta ventana no es más que un buffer, cuyo tamaño queda especificado por este campo. Cuanto mayor sea el tamaño de ventana se obtendrá una mayor cadencia en los datos (el término exacto es throughput, pero creo que no existe un equivalente exacto en español). En contra partida, una ventana grande es perjudicial cuando la calidad de la red no es demasiado buena, puesto que en caso de error (por pequeño que sea), se requerirá enviar de nuevo toda la ventana completa, repercutiendo negativamente en el rendimiento. No es lo mismo a fin de cuenta enviar un mensaje de 1 byte en un byte, teniendo en cuenta que entre byte y byte hay que responder con un ACK, que enviar un mensaje en bloques de hasta 64KB, lo cual es muchísimo más eficiente… aunque menos seguro y menos fiable.


    A día de hoy cada vez se está optando por incrementar casi al máximo las ventanas de recepción, o en caso de Windows por ejemplo permitir al propio OS establecer de forma dinámica el tamaño de esta en función de la calidad de la comunicación y otros factores.



  • CheckSum (16 bits): El sistema de comprobación de errores de TCP es el mismo que el que se explicó en UDP.
  • Puntero Urgente (16 bits): Especifica un desplazamiento de Bytes (comenzando desde el número de secuencia) en el que se encuentra el primer byte que se ha tipificado como “mensaje urgente”
  • Opciones y Padding (Variable): Especifica una serie de opciones que pueden añadirse antes del SDU. Dado que se debe de conservar la divisibilidad entre 32 Bits, se usará un padding rellenando de ceros para cubrir siempre cualquier pico que pudiese existir en dichas opciones.

Es evidente que la complejidad aquí es mucho mayor que en UDP. Describir el funcionamiento de todo el protocolo sería algo inviable, y para eso están las especificaciones oficiales en el RFC 793. No obstante, aunque no se explique cada uno delos posibles casos pueden darse en una comunicación TCP, si es interesante ver a groso modo como se llevaría a cabo una comunicación modelo, sin entrar en demasiados detalles, en lo que sería el establecimiento y cierre de la comunicación. Como digo esto es tan solo una pequeña parte de todo el protocolo TCP, se pueden presentar un millón de posibilidades y de comportamientos anómalos en la conexión y la respuesta de cada host a dicho comportamiento está en algunos casos especificados y en otros no. De todos modos, esto se podrá ver en otros temas, como por ejemplo en los escáneres de puertos, donde es muy importante conocer el funcionamiento de estos protocolos:

 

Sabiendo los registros de la cabecera, se puede más o menos inferir las características de TCP. Por ejemplo, la fiabilidad en los datos enviados/recibidos queda asegurada gracias a los números de secuencia, por los cuales es posible conocer el orden incluso en el que deben de llegar los mensajes, o en caso de que un mensaje no sea recibido el host emisor puede ser informado sobre ello para reenviar de nuevo el mensaje perdido. El número de secuencia de ACK tiene un cometido similar, dado que si el emisor no recibe el ACK de un mensaje que ha enviado, puede interpretar que el mensaje no ha sido recibido y podría enviarlo de forma automática de nuevo, mientras que de cara al receptor si le llegan dos mensajes con el mismo número de secuencia (por ejemplo porque el emisor ha reenviado el mensaje y el primero no llegó por una latencia excesiva de la red) ignoraría simplemente el segundo, siempre y cuando el número de secuencia fuese correcto, si recibe un número de secuencia erroneo simplemente descartaría el mensaje.

Por otro lado, el uso de una ventana (buffer) también garantiza un correcto control de flujo, mientras que técnicas como los algoritmos de congestión de red hacen posible que la comunicación sea todo lo fluida que se pueda cuando la intensidad del tráfico amenaza la comunicaicón. Estos algoritmos se basan simplemente en los mismos flags de las conexiones TCP para ajustar ciertos parámetros como la ventana de recepción, el tamaño máximo del mensaje (especificado en las extensiones de la cabecera TCP) o la gestión de ACKs. Por ejemplo, el algoritmo de congestión que puede usar Windows Vista/7 se llama Compound TCP. Este algoritmo posee dos ventanas, las cuales aumentan en tamaño o disminuyen en función del retraso en las comunicaciones. De forma similar actáa por ejemplo el protocolo de congestión por defecto de Linux: TCP Cubic. A la par que las comunicaciones son más rápidas y fiables, es normal que los algortimos de congestión usados vayan cambiando con el tiempo, dado que el que es bueno ahora no lo será mañana.

 

 

Protocolo Ethernet y ARP

Llegados a este punto sería conveniente hablar de Ethernet, aunque sin entrar en mucho detalle sobre este. Ethernet es un protocolo… una tecnología para redes locales. Al ser un protocolo de nivel 1 y 2, tiene más componentes físicas que informáticas. Por ejemplo, Ethernet tiene sus propios estándares para cables que pueden usarse, conectores, hardware… cuestiones que podrían ser interesantes ver, pero que se escapan al alcance de este capítulo. Ahora veremos Ethernet como el protocolo de nivel más bajo que tendremos dentro del modelo TCP/IP o modelo OSI, y será la misma tecnología Ethernet y sus protocolos los que convertirán al final los datos en meras señales eléctricas que serán transmitidas por un cable.

Desde el punto de vista físico, para nosotros tan solo nos interesa conocer cuestiones como la velocidad, modo de funcionamiento y tipo de medio. Desde el punto de vista lógico nos interesa no obstante conocer la estructura de un frame ethernet.

Físicamente para nosotros podemos diferenciar 3 estándares atendiendo a la velocidad de enlace de Ethernet: Ethernet, Fast Ethernet y Gigabit Ethernet, La diferencia de ellos es por tanto el ancho de banda posible. ASí, Ethernet tiene una capacidad máxima de transmisión de datos de 10Mb/sec (ojo!! Megabits, no MegaBytes), Fast Ethernet 100Mb/s y GigaEthernet una capacidad de 1000Mb/s. Actualmente existen estándares menos usados domésticamente como 10 GigaEthernet o 100 GigaEthernet, cuyos nombres son completamente descriptivos.

De cara al medio, estamos acostumbrados a ver Ethernet siempre usado sobre el famoso cable “Categoría 5e” y conectores RJ45. Este cables son a groso modo 4 parejas de hilos trenzados. Pero esto es solo una de las especificaciones de Ethernet, ya que en realidad Ethernet puede ser usado no solo sobre estas parejas de hilos trenzadas, sino por ejemplo sobre fibra óptica también. Lo que sucede es que los cables de hilos trenzados son infinitamente más baratos que otras infraestructuras como pueda ser la de fibra óptica, por no hablar de la facilidad de crimpar (añadir un conector a un extremo de un cable) a un cable de hilos trenzados a uno de fibra, o la flexibilidad de uno y de otro. Actualmente sobre hilos de cobre trenzados es posible llegar hasta 10GigaEthernet, mientras que sobre fibra hasta los 100GigaEthernet. De todos modos, lo más común, barato y cómodo para un usuario doméstico son los estándares 100BaseT y 1000BaseT, es decir, Fast Ethernet y Giga Ethernet sobre cables de cobre trenzados. En el caso de 100BaseT se usarán 4 hilos en total de un cable de pares trenzados Categoría 5 como mínimo, mientras que en redes GigaEthernet requeriremos de los 4 pares de hilos de un cable Categoría 5e o Categoria 6. En ambos casos, el estándar asegura una longitud máxima de cable entre nodos de 100 metros, a partir de los cuales sería necesario regenerar la señal. Como nota personal, en entornos especialmente ruidosos o cuando dichos cables serán usados externamente, recomendaría que los cables fuesen apantallados para aislar mejor las interferencias, aunque esto es tan solo opcional.

Desde el punto de vista del modo de funcionamiento, tan solo decir que Ethernet puede funcionar tanto en Half-Duplex como en Full-Duplex. Esto se verá más en detalle en otro capítulo cuando se vean Hubs y Switchs.

Desde un punto de vista lógico tenemos que ver como es un frame Ethernet, y teniendo en cuenta los diferentes protocolos que hemos visto hasta ahora, Ethernet no supondrá mayor problema. Un frame Ethernet II (los frames usados a día de hoy) no poseen otra cosa que la dirección MAC origen y destino, el protocolo superior que lo usará, los datos que portará y un checksum:

Cuando se trató el protocolo IP se mencionó MTU como unidad máxima de transmisión, que es una limitación de la red y no del mismo protocolo IP, ya que el protocolo IP podía incluir paquetes de hasta 64KB. Pues bien, ese MTU proviene de los niveles inferiores, en caso de usar redes Ethernet dicha limitación procede de aquí. ¿Por qué dijimos que lo normal para conexiones ADSL es un MTU de 1492 Bytes? El 99% de las redes locales domésticas son redes Ethernet. Como podemos apreciar perfectament en la imagen superior, los frame Ethernet tienen un tamaño mínimo de 64 bytes y un tamaño máximo de 1512 Bytes. De esos 1512 Bytes, 1500 son los reservados para los datos adjuntos. Dado que nuestros equipos se comunican principalmente por cable a nuestros routers, estos enlaces son Ethernet con un MTU de 1500. Pero por otro lado, la mayoría de nuestras conexiones ADSL están apoyadas por el protocolo PPPoE (Punto a Punto sobre Ethernet), el cual (el protocolo) tiene una cabecera de 8 Bytes. Es decir, el tamaño máximo de los datos que pueden enviarse por medio de una conexión ADSL mediante PPPoE debería de ser exactamente 1492, dado que PPPoE usa frames Ethernet. Ahora bien, esto no quiere decir que un MTU de 1942 para conexiones ADSL PPPoE sea el óptimo, pero explicar esto implicaría de nuevo salirnos del ámbito de este capítulo.

Hay que tener bien presente que estos frames existen tan solo para nosotros, para nuestra red local Ethernet, y en el caso específico de las conexiones ADSL PPPoE. Siempre que usemos un Sniffer para ver que tipos de frames nos están llegando hay que comprender bien esto, dado que podemos ver solo lo que llega a nuestros equipos, no como dichos datos son transportados desde un punto del planeta a otro, hablamos por tanto en este caso de un protocolo de puertas para dentro.

De la cabecera Ethernet II anterior, EtherType especifica el protocolo inmediato contenido en los datos adjuntos. Así por ejemplo, para un paquete IPv4, EtherType tendrá un valor de 0x0800, 0x86DD para IPv6, 0x8863 y 0x8864 para PPPoE, o un valor de 0x0806 si es el protocolo ARP. Para quien quiera una lista completa puede verla en el estándar de la IEEE de los tipos de redes Ethernet


Una dirección IP es una dirección lógica asociada a un host, mientras que una dirección MAC es una dirección “física”. Quizás el término dirección física no sea realmente correcto, pero sí podemos decir que una dirección MAC especifica inequívocamente una interfaz NIC (o al menos debería). Tal y como se plantea toda la red de Internet, así como los protocolos TCP/IP y DNS, parecerá innecesario un protocolo como ARP, pero sin embargo es un protocolo crucial, sobre todo dentro de redes locales como las redes Ethernet (casi todas las redes locales).

Gracias al protocolo IP podemos encontrar en el globo un host simplemente conociendo su dirección IP. Pero esta dirección no es más que una dirección lógica. En IPv6 esto es diferente dado que la asociación IP-NIC es casi estructural, pero en IPv4 esto no es así ni mucho menos. Volviendo al tema principal, puede que una dirección IP especifique un host en internet, pero… ¿Como saben los equipos o los routers a que interfaz de red enviar dichos paquetes? Es importante conocer siempre lo que pueda ser la parte física de una comunicación a la parte lógica. Podemos pensar en la parte física aquello que podemos tocar o ver: Cables, Routers, Switchs, Bridges, Interfaces de Red (NIC)… hardware a fin de cuenta. En cambio, en la parte “lógica” tendríamos fundamentalmente los protocolos de comunicación que funcionan sobre esa parte física, y en última instancia bits de datos que circulan de un lado a otro. Pues bien, en algún punto por tanto es necesario unir esa parte física con esa parte lógica, y el protocolo ARP se encarga de ello, al menos en cuanto a conocer el origen/destino de un paquete IP.

El protocolo ARP será el encargado por tanto de conocer el host físico emisor/receptor de un paquete por medio de su IP, dicho de otro modo, el protocolo ARP se encargará de saber las direcciones MAC de las NIC. El protocolo IP trabaja en el nivel 3 del modelo OSI (nivel de red), TCP/UDP son protocolos del nivel 4 (de transporte), mientras el protocolo DNS es un mensaje concreto UDP (luego es un protocolo a nivel de aplicación). ¿A que nivel pertenece por tanto ARP?

El problema del ámbito de ARP no es nuevo. En teoría es un protocolo a nivel de enlace de datos (nivel 2), pero no obstante para que ARP pueda trabajar correctamente necesita tener acceso al nivel 3 para conocer la IP. Si vemos esto desde un modelo OSI estricto, ARP quedaría fuera de este, dado que requeriría acceder a ambos niveles, lo cual violaría los principios del modelo OSI. Pero por un lado el modelo usado actualmente es TCP/IP, y por otro podríamos ver el modelo OSI como algo más flexible. Otros expertos concluyen que aun cuando el modelo OSI fuese completamente fijo e inflexible, ARP no violaría el modelo, dado que su función es meramente de nivel de red, con la única salvedad de que porta datos pertenecientes a IP, y que por tanto ARP es un protocolo de nivel 2. Personalmente creo que las dos opciones son correctas. No se puede ver el modelo TCP/IP u OSI como algo completamente rígido, y tampoco podemos pensar en que un frame solo puede contener datos propios. Quizás el ejemplo más significativo estaría en el protocolo ICMP. Sin entrar en detalle a explicar este protocolo, ICMP depende y se apoya sobre IP, con lo que debería de ser un protocolo superior a IP, pero en realidad no presta ningún servicio de transporte o de nivel superior. ICMP es un protocolo puramente de nivel 3, aunque necesite o se apoye en IP. Bueno, de forma similar podríamos ver ARP. Para mi por tanto ARP es un protocolo de nivel de enlace de datos (nivel 2), pero quizás sería correcto decir que es un protocolo tanto de nivel 2 como de nivel 3.

 

¿El problema?

La finalidad de ARP queda clara. Un protocolo que permita extraer de algún modo de la dirección física MAC de un host. ¿Por qué es esto estrictamente necesario? La mejor forma de ver esto es intentar componer la red TCP/IP más sencilla que pueda existir, para evitar pensar en routers, hubs u otros elementos de red: Dos hosts conectados uno a otro por un cable Ethernet. Imaginar por tanto que disponemos de dos host configurados manualmente y conectados por un cable de red, formando entre ambos equipos una red muy simple. El host A se configura para tener una dirección IP 192.168.0.1 y el host B para tener la dirección 192.168.0.2. Si lo vemos de una forma completamente lógica, decimos simplemente que el host A se comunica con el host B enviando los paquetes IP a la dirección 192.168.0.2. ¿Pero como sabe el host A quien es el host B? Visto desde un punto de vista completamente físico, la tarjeta de red del host A tan solo sabe que ella tiene una dirección física por ejemplo de 00:00:00:00:00:01, a la cual hay conectada un cable por el cual enviar o recibir datos, y lo mismo para el host B, 00:00:00:00:00:02. Los adaptadores de red no tienen por qué entender de IP, recordemos que Ethernet es un protocolo de nivel 2. En última instancia, el adaptador de red simplemente pone los datos que sean en las lineas de transmisión del cable y listo. En este caso es simple, dado que tan solo hay un equipo conectado al otro extremo, los datos enviados por A llegarán siempre al equipo B. El host B cuando recibe lo que sea por su interfaz de red podría simplemente tomarlo por bueno y tomar cualquier dato que llegue por él como válido y procesarlo. En este caso no haría falta siquiera conocer direcciones físicas. Pero que sucede si creamos una red en vez de dos equipos de tres?

Imaginar que a los dos equipos antes mencionados incluimos un Host C con dirección física 00:00:00:00:00:03. ¿Como? En el caso más simple de todos esto se haría con un dispositivo de red conocido como Hub. Básicamente los Hub conectan todos los diferentes hosts conectados a él entre sí de una forma muy simple. Un cable/interfaz Ethernet o Fast-Ethernet tiene dos lineas para transmitir datos y dos para recibir, pues el hub lo que hace es conectar internamente las dos líneas de transmisión de datos de cada cable con las dos de recepción de los otros. Es decir, cuando el host A envíe un paquete, este será recibido tanto en B como en C, y exactamente lo mismo para cualquier paquete enviado por B o por C. El problema es evidente, ante esta situación ya no basta simplemente con poner el dato en el cable y dejar que los hosts tomen por bueno y procesen el dato. Por otro lado cada host puede tener una IP diferente sí, pero como hemos dicho los adaptadores de red no tiene por qué saber nada de IP, y por otro lado las aplicaciones no entienden de direcciones MAC, solo de paquetes IP.

 

¿La solución?

Si al enviar el dato que sea desde A especificamos la dirección MAC destino (es decir, el adaptador de red a quien está destinado dicho frame), esta dirección o ID si puede ser comprobada/verificada por el adaptador de red. En este caso del Hub, tanto B y C recibirán un frame de A, pero el frame de A especificará que el destino será 00:00:00:00:00:02, con lo que el host C simplemente ignorará el frame, puesto que la dirección MAC no es la suya. Con esto podría parecer que el uso de IP es innecesario, pero recordemos que la función de un protocolo de nivel de red es completamente diferente a un protocolo de nivel de enlace de datos. IP hablará con todos los protocolos superiores, mientras que Ethernet es un protocolo de bajo nivel. Visto esto vemos la necesidad de las direcciones MAC, pero no del protocolo ARP. Pues bien, se ha dado por echo que el host A conoce la dirección MAC del host B, lo cual puede ser que la conozca o puede ser que no la conozca. Si arrancamos en frió todos los dispositivos, la única forma que el host A conozca la dirección MAC de los otros host y viceversa es manteniendo un archivo local en cada equipo que especifique dichas direcciones. Esto ya vimos en DNS que no aceptable en ningún modo, hace falta un protocolo que se encargue de dicha tarea.

Cuando un host no posea la dirección mac de otro, necesitará realizar una petición ARP para conocer dicha dirección. ARP tiene tan solo dos métodos de funcionamiento: Enviar peticiones y Enviar respuestas. El procedimiento base es muy simple, si necesita conocer la MAC del host B (del cual evidentemente conoce la IP, dado que el mismo paquete IP especifica dicha IP), enviará una petición a la dirección física de broadcast de la red con la solicitud. Todos los host recibirán Y ATENDERÁN la petición puesto que la dirección física a la cual está destinado el frame son TODOS los host, pero tan solo el host B contestará a ella, dado que dicha petición especifica la IP del host B. La respuesta de B por otro lado será dirigida directamente a A, dado que en la misma solicitud se incluye la dirección MAC del host A. La respuesta llegará a todos los host (estamos usando un hub), pero estos no la procesaran porque la dirección MAC especificada en el frame será la de A. A recibirá la contestación por parte de B con un frame que contendrá la dirección física de B, y el host A podrá actualizar su caché ARP, donde almacenará la asociación IP host B -> MAC host B.

Lo primero será por tanto conocer la estructura de este frame un tanto especial, ya se ha dicho que aun siendo (a mi juicio) un protocolo de nivel 2, lleva consigo una IP:

 

Tipo de Hardware
Tipo de Protocolo
Long. Dirección Hardware Long. Dirección del Protocolo
Operación
Dirección Hardware del Origen
Dirección del Protocolo del Origen
Dirección Hardware del Destino
Dirección del Protocolo del Destino

Hay que tener en cuenta que ARP depende de dos protocolos, el superior y el inferior. Para nosotros, ARP será usado extensamente en redes IPv4 sobre Ethernet, pero esto no quiere decir que son los únicos protocolos con los que podría funcionar ARP.

  • Tipo de Hardware (16 bits): Especifica el hardware del nivel inferior que será usado. En caso de redes Ethernet, el valor de dicho campo será un 0x0001
  • Tipo de Protocolo (16 bits): Especifica el protocolo superior al que referenciará, en caso del protocolo IP el valor de dicho campo será de 0x0800
  • Long. Dirección Hardware (8 bits): Especifica el tamaño en bytes que ocupará una dirección del tipo hardware especificado en el campo “Tipo Hardware”. En caso de redes Ethernet, las direcciones MAC tienen un tamaño de 48 bits, luego este campo estará fijo en 48/8 = 6 Bytes -> 0x06
  • Long. Dirección del Protocolo (8 bits): Especifica el tamaño de la Dirección del protocolo de nivel superior, en nuestro caso una dirección IPv4 tiene una longitud de 32 bits -> 32/8 = 4 Bytes -> 0x04
  • Operación (16 bits): Especifica el modo de operación del protocolo ARP. Ya se dijo que ARP actúa o realizando una petición (Request, un valor de 1 en dicho campo) o respondiendo a una (Reply, con un valor de 2 en dicho campo)
  • Dirección Hardware/Protocolo Origen/Destino (variable): Dado que el hardware y el protocolo sobre los cuales ARP va a funcionar puede ser diferente, estos campos no tienen una longitud fija, de echo estos campos son fijados en los registros anteriores. En estos campos se almacenará la dirección MAC de origen y la dirección MAC destino en caso de los registros Dirección Hardware y la dirección IP de origen y destino en el caso de los campos de Dirección del Protocolo.


En realidad es un frame muy simple, no lleva mayores complicaciones ni sobrecargas en el protocolo. Vamos a ver un ejemplo de frame tipo ARP IP sobre Ethernet capturado por un Sniffer:

+Frame 1: 60 bytes on wire (480 bits), 60 bytes captured (480 bits)
-Ethernet II, Src: Cisco-Li_xx:xx:xx (00:xx:xx:xx:xx:xx), Dst: AsustekC_xx:xx:x (00:xx:xx:xx:xx:xx)
Destination: AsustekC_xx:xx:x (00:xx:xx:xx:xx:xx)
Source: Cisco-Li_xx:xx:xx (00:xx:xx:xx:xx:xx)
Type: ARP (0x0806)
Trailer: 00000000000000000000000000004fe127ba

-Address Resolution Protocol (request)
Hardware type: Ethernet (0x0001)
Protocol type: IP (0x0800)
Hardware size: 6
Protocol size: 4
Opcode: request (0x0001)
Is gratuitous: False
Sender MAC address: Cisco-Li_xx:xx:xx (xx:xx:xx:xx:xx:xx)
Sender IP address: 192.168.x.1 (192.168.x.1)
Target MAC address: 00:00:00_00:00:00 (00:00:00:00:00:00)
Target IP address: 192.168.X.2 (192.168.x.2)

El primer bloque pertenecería al protocolo Ethernet. Tan solo se especifica como ya se dijo la dirección MAC origen y destino, el tipo de protocolo (en este caso ARP) y el trailer. El trailer es el fin de la trama (frame), lo cual hay que explicarlo. Como hemos visto un frame Ethernet termina con una secuencia de 4 Bytes que es el checksum. No obstante por regla general no será posible acceder a estos datos del frame por un sniffe, dado que el checksum se calcula de forma automática en el propio adaptador, y para tener acceso a ello sería necesario drivers específicos que realmente no merece la pena molestarse por ello.Es decir, el trailer NO ES el checksum en modo alguno, sino un padding necesario. ¿Por qué? Un frame Ethernet debe de tener un tamaño mínimo de 64 bytes. En este caso podemos comprobar que el Frame capturado tiene curiosamente 64 Bytes (60 Bytes + 4 Bytes del Checksum que se omiten), pero se obtiene un valor exacto de 64 Bytes gracias al trailer, sin este el frame ethernet tendría un tamaño inferior. Es por ello que la propia interfaz de red añade un padding después de los datos para rellenar ese tamaño mínimo de 64 bytes (60 si no contamos el checksum), o lo que es lomismo, un tamaño mínimo de datos de 46 Bytes.

El segundo bloque corresponde al protocolo ARP. La captura muestra exactamente cada uno de los campos de este protoclo, el tipo de Hardware (Ethernet), el tipo de protocolo de red (IP), el tamaño en Bytes de las direcciones, el modo de operación y las direcciones MAC e IP. Aparece no obstante un campo llamado “Is gratuitous”. En el protocolo ARP se denomina un frame gratuito a un auto anunciamiento. Es decir, imaginar que el frame anterior ARP en vez de tener como emisor la MAC y la IP del router tuviese la MAC e IP de él mismo, pero el destino fuese igualmente la dirección indeterminada: 00:00:00:00:00:00. En este caso, es evidente que nadie contestaría al frame ARP, pero este mensaje SI actualizaría probablemente las tablas ARP locales de cada equipo.

El frame completo ARP del ejemplo lo que realmente significa es que pregunta a toda la red por la dirección MAC de la IP 192.168.x.2. ¿Como es posible? porque el frame no está siendo enviado a una dirección MAC concreta, sino a la dirección indefinida 00:00:00:00:00:00, dado que no se conoce cual es. Esto hace que todos los host en la red escuchen tal frame. Cabe esperar que inmediatamente de lanzar el route dicha peticion ARP, el host del cual se desea conocer la dirección MAC responda con un frame ARP reply a dicha petición.

¿Que sucede cuando una petición ARP se contesta?

Al igual que las caché DNS, todos los equipos poseen una caché generalmente dinámica ARP que almacena las asociaciones MAC/IP, lo que evita el uso continuo de realizar peticiones ARP para conocer dichas direcciones MAC. Estas tablas se actualizarán a medida que sean necesaria, pero al contrario de lo qeu se piense, generalmente son actualizadas al recibir cualquier ARP reply de la red, sea legítimo o no, y esto será tratado en profundidad en otro capítulo de este tema. Dado que existe esta tabla/caché ARP, es posible tanto eliminar entradas de esta como añadir entradas manualmente, como listar la tabla ARP.

En windows:

C:\Users\Theliel>arp -a

Interfaz: 192.168.x.3
Dirección de Internet Dirección física Tipo
192.168.x.1 00-xx-xx-xx-xx-xx dinámico
192.168.x.255 ff-ff-ff-ff-ff-ff estático
224.0.0.22 01-00-5e-00-00-16 estático
224.0.0.252 01-00-5e-00-00-fc estático
239.255.255.250 01-00-5e-7f-ff-fa estático
255.255.255.255 ff-ff-ff-ff-ff-ff estático

Interfaz: 192.168.x.2
Dirección de Internet Dirección física Tipo
192.168.x.1 00-xx-xx-xx-xx-xx dinámico
192.168.x.6 00-xx-xx-xx-xx-xx dinámico
192.168.x.8 00-xx-xx-xx-xx-xx dinámico
192.168.x.13 00-xx-xx-xx-xx-xx dinámico
192.168.x.255 ff-ff-ff-ff-ff-ff estático
224.0.0.22 01-00-5e-00-00-16 estático
224.0.0.252 01-00-5e-00-00-fc estático
239.255.255.250 01-00-5e-7f-ff-fa estático
255.255.255.255 ff-ff-ff-ff-ff-ff estático

En Linux:

Anarchy:/# arp -n
Address HWtype HWaddress Flags Mask Iface
192.168.x.1 ether 00:xx:xx:xx:xx:xx C eth0
192.168.x.2 ether 00:xx:xx:xx:xx:xx C eth0
192.168x.25 ether 00:xx:xx:xx:xx:xx C eth0


El protocolo ARP es simple y altamente efectivo, no obstante no está libre de problemas de seguridad. Cuanto más simples es un protocolo más efectivo es, pero también es intrínsecamente más inseguro la mayoría de las veces. Recordar que Internet no se pensó como una fortaleza en la que todo estuviese medido, sino todo lo contrario, un sistema lo más simple posible y efectivo. Y viendo los protocolos que la hacen posible, tengo que decir que lo lograron, y a día de hoy es sin duda alguna la red de redes.

Proyecto: Adrianne I

Antes de comenzar, citar posiblemente a quien me inspiró a ello, y en cierto modo me ayudó a comprender algunos conceptos y me enseñó por donde buscar, por así decirlo: Bilalt, aunque desgraciadamente no conozco su nombre real y hace ya años que “desapareció”.

Voy a ir intentando completar este “reto personal”. Entre otras cosas, siempre me sentí atriado por los gráficos 3D, aunque no quiero decir con esto los juegos, sino el diseño 3D, como crear esos mundos increibles que tanto estamos acostumbrados a ver.

Por otro lado debo de decir que no me puedo consuderar ni mucho menos un gurú en la programación. Lo suficiente quizás para ser capaz de crear el programa que sea con algo de tiempo, pero dudo mucho que este pudiese estar a la altura de un verdadero programador como los que hay, auténticos genios en su campo. Pero por el lado positivo, la informática me ha enseñado que todos los campos dentro de ella de alguna u otra forma están relacionados, lo que quiere decir es que para mi es más facil que para la gran mayoría enfrentarme a un problema concreto (claro está, informáticamente hablando), sea de programación, de diseño… hasta el punto que aunque un genio de la programación sea capaz de hacer lo mismo mucho más eficientemente y más rapido que yo (sin duda alguna), yo tengo ideas o caigo en una serie de cosas que para otro normalmente serían muy complejas o siquiera las tendría en cuenta.

Todo esto me ha ayudado a la hora de poner en marcha Adrianne. A todo esto… quien es Adrianne? Esta es Adrianne:

Con cada serie de nuevas tarjetas gráficas, nVidia ordena crear una Demo especialmente diseñada para ella, intentando poner al máximo sus prestaciones. Hace unos años, con el lanzamiento de la serie 8 de nVidia, nos deleitaba con esta Demo. Se trata de Adrianne Curry si no recuerdo mal, creo que era una PlayMate que se prestó para tal exhibición.

Evidentemente no pretendo obtener un resultado similar. Mi idea es ser capaz al menos de renderizar el cuerpo entero de ella poligonalmente con un mínimo de iluminación, y como un “imposible” dejaría abierta la posibilidad de texturizar el modelo.

En realidad el reto que me propuse pasaba simplemente por ser capaz de realizar un parser para los arcihvos nmb, que son archivos propietarios de nVidia en los que se encuentra toda la geometría de los diseños 3D de estos. Es decir, en el caso de Adrianne, el archivo “geo_model.nmb”contiene toda la información sobre el modelo 3D Adrianne. Al ser un archivo propietario, a menos que llame a la puerta de nVidia y les pida por favor la estructura interna de este, el trabajo a mano a realizar es increiblemente grande. Hay que tener en cuenta que para mis ojos, tan solo es un archivo binario de 64MB, sin aparente información usable en su interior. Luego antes de ser capaz de renderizar nada, lo que tengo q hacer es ir interpretando poco a poco cada bloque hexadecimal de tan ingente archivo. Mi proyecto principal no fue con Adrianne, sino con Dawn, una Demo más antigua. Pero a fin de cuenta la estructura de ambos es muy similar, la diferencia es que ADrianne está en 64MB, y Dawn en tan solo 13MB. Es mas, tan solo la cabeza de Adrianne es más compleja que todo el modelo de Dawn.

Antes de poder hacer nada, la primera etapa es por tanto crear un pequeño Engine gráfico, la creación de un pequeño espacio tridimensional en el que poder representar puntos, polígonos… esto no es algo complicado, sobre todo con la cantidad de información que tenemos en internet. El problema claro está es comprender los ejemplos, el código, cada instrucción… y adaptarlo todo de la mejor forma a nuestro proyecto.

En mi caso he usado OpenGL como render, y GLUT para facilitarme el jugar con las coordenadas espaciales y la perspectiva.

Una vez la plantilla principal del engine está creada, el paso siguiente es verificar si dicho archivo, “geo_model.nmb” realmente contiene la información geométrica de Adrianne, y por supuesto verificar si el engine gráfico funciona. Aquí es donde tenemos que poner a funcionar el cerebro.

Lo más simple de todo, como no tenemos idea de la estructura interna del archivo de nVidia, es intentar renderizar todo el archivo como si fuese todo él un array de puntos. Pensar en un polígono. Su esencia última es el triángulo. Un triangulo se representa por 3 vértices. En cualquier archivo de geometría, lo que más debe de abundar con diferencia son vértices. Los vertices posicionarán los polígonos (triángulos) en el espacio tridimensional, los vértices de las normales serán los que indiquen el vector normal, usado para conocer la cara poligonal que recive la luz o por ejemplo también los vertices de los vectores tangenciales. Con esto quiero decir que de dicho archivo, de ser cierto, el 90% deberían de ser coordenadas espaciales.

Un vértice en un espacio de tres dimensiones se representa por 3 coordenadas x, y z. Si es un espacio bidimensional, usado por ejemplo en el mapeo de las texturas hacen falta tan solo 2 coordenadas u, v. Pero volviendo al tema principal, mi primer parser podría consistir simplemente en leer todo el archivo e interpretarlo como he dicho como un array de vértices. Un vertice normalmente se considera un numero de tipo float (numeros en coma flotante), un tipo de representación numérica, que es usada muy comúnmente cuando se necesita una resolución muy grande o muy pequeña. Un float se representa por medio de 32bits, es decir 4 bytes. Dicho esto, la primera aproximación a realizar es interpretar todo el archivo como una hilera de bloques de 32bytes, en el que se repetirá constantemente el patrón: X, Y, Z. Es decir, los primeros 4*3bytes del archivo serían el vértice 1: la componente X la componente Y y la componente Z. Los 3 floats siguientes se interpretarían como el vértice 2 con sus tres componentes… así sucesivamente.

Renderizar esto es facil, tan solo tenemos que cargar el archivo en memoria y desde nuestro engine hacer q se se representen en pantalla los vértices contenidos en nuestro buffer o la estructura creada. En mi caso he usado una estructura de este tipo:

Typedef Struct {

float x, y,z;
}vertices;

vertices *buffer;

Es decir, creo un array buffer de tipo vértices.Una vez todo está preparado, en el mismo engine tan solo tengo que llamar a este buffer y representar todos los puntos con un bucle simple for, que recorra todo el array. Previamente se ha calculado el número de vértices que tendría el archivo. Esto es facil, si he interpretado que todo el archivo en sí es un conjunto de vértitces, tan solo tengo que conocer por medio de ifstream el tamaño del archivo. Una vez conocido el tamaño del archivo en bytes, dividirlo entre 4 bytes (1 float = 4bytes) y después dividirlo por 3 (cada vértice tiene 3 componentes). El número resultante son los vértices. Por medio de new creo un array dinámicamente.

Cuando todo ello está terminado, con un for recorro todo el array, representando en cada momento el supuesto vértice:

glVertex3f (buffer.x, buffer.y, buffer.z);

Pero para poder lograr tener más información de todo ello, hago que dependiendo del puntero de nuestro buffer (la posición de este) me represente cada punto de un color u otro. Para ello divido el numero de vértices en 4, y el resultado será la umbral de cada trozo. De esta forma si el punto representado se encuentra en el primer cuarto del archivo, se representará de color rojo, si corresponde al segundo verde. Blanco si es al tercero y azul si es al cuarto. Esto es simple con una instrucción if y glColor3f.

Por último queda pensar en algo… de funciona, hemos presupuesto que el primer vértice comienza en la posición del archivo 0, y todos los consiguientes en saltos de 4 bytes. Imaginemos por un momento que tenemos realmente un archivo tan solo con vértices, pero que el primer byte del archivo es un identificador. Quiere decir que de representarlo como digo, no tendría nada!! puesto que mi matrón se extiende por todo el archivo, y jamás tendría un solo vértice representado correctamente. Pero esto mismo sucedería no solo si los vertices comenzasen en el primer byte, sino tb con el segundo y con el tercero. Las posibilidades por tanto sería un desplazamiento de 0, 1, 2 y 3 bytes. 4 no haría falta, dado que son bloques de 4 Bytes cada float, si desplazase 4 sería igual que no desplazar. Hablo de localidad dentro del mismo archivo. Con lo que si quiero representar el archivo a pelo, tengo que hacer en realidad 4 representaciones, cada una variando el desplazamiento 1 byte.

Como si de magia se tratase, con un desplazamiento de 0, y con todo lo comentado, esto es lo que obtengo:

Si no me falla la vista, eso parece ser el bañador de Adrianne? Evidentemente no quiere decir que todo lo que vemos sea parte de la geometría, ni mucho menos. Tan solo hemos pasado a nuestro engine un buffer de 64MB interpretado todo ello como vértices y obtenemos eso. Cláramente el bañador en azul, si está en azul quire decir que el bañador se encontraría en el último cuarto del archivo.

Para un desplazamiento de 1 Byte:

Vaya… en este caso hemos acertado en la cabeza de lleno, una pierna, medio cuerpo, un brazo, el ojo izquierdo, un pendiente… La cabeza en Verde nos dice que está en el segundo cuarto.

Para un desplazamiento de 2:

Otra pierna, en azul a la derecha y girado parece que podría ser el collar y un posible ojo? Tener en cuenta que las posiciones no tiene porqué corresponderse, al menos por ahora.

Y por último para un offset de 3:

Por último tenemos otro brazo, collar, cuerpo…

Creo que la mayoría de toda la geometría queda al descubierto.

Como segundo paso se podría acotar aun más la búsqueda de cada malla (parte del cuerpo) por separado, para conocer la ubicación concreta de cada una de las partes. Una vez realizado podríamos comenzar visualizando el archivo en un editor hexadecimal y ver si podemos extraer información directamente de él, teniendo en cuenta lo qye ya tenemos.

Pero ei… de momento el engine funciona, y se ve claramente un voceto muy primitivo de Adrianne diseccionada, en forma de puntos de colores.

Proyectos Actuales

Bueno… supongo que a este ritmo tendré que cambiar el nombre del blog por alguno que sea más fidedigno a mi blog. Estos son los proyectos en los que estoy “trabajando” cuando estoy “aburrido”, por supuesto estoy abierto a sugerencias, siempre y cuando sea algo que me interese y tenga ganas de desmarañar:

1º. Engine Gráfico

a) Crear motor gráfico. Completado (Muy rústico, pero funciona)
b) Crear un parser para renderizar los objetos .nmb de nVidia, por ejemplo Adrianne (una Demo de nVidia). Completado 20%
c) Renderizar aunq sea de forma muy primitiva Adrianne de forma completa. 5%
d) Publicar.

2º. Web

a) Crear una Web “decente” y suprimir completamente el blog, de modo que toda la información esté mucho más estructurada, secciones para cada cosa… y también eliminar del todo cualquier dependencia a Google. 0% Completado

2º. Proyecto SonyEricsson C905

a) Modificación del sistema de archivos. Completado (Por medio de a2tool)
b) Archivos importantes. Completado
c) Creación/Modificación de Drivers para Pantalla, Cámara… Completado 80%
d) Artículos sobre actualización/liberación? 0%
e) Otras modificaciones posibles: Temas, ajustes, personalizaciones… 80%

3º. Proyecto ElBruto

a) Compresión del sistema de juego. Completado
b) Desensamblado de la creación de personajes y otros procesos importantes. Completado
c) Modificación “al vuelo” del formulario de envío de datos. Completado
d) Script en Bash (Linux/Cywing) para creación infinita de alumnos. 40% Completado
e) Uso simples de un Bot para la creación de Alumnos. 0% Completado
f) Un “programa” para implementar todo los cheats posibles por hacer. 0% Completado
g) Publicar.

4º. Repositorio Cydia

a) Preparación. Completado
b) Debian, Toolchain… Completado
c) Compilación, creación de scripts y publicación. 0%

Volver a arriba

Sobre Mí

Alma Oscura por Theliel is licensed under a Creative Commons Reconocimiento-No comercial-Sin obras derivadas 3.0 Unported License.
Política de Privacidad.
Para otros permisos que puedan exceder el ámbito de esta licencia, contactar en blog.theliel.es/about/contactar.