Ethernet: conectando dos máquinas - Obijuan/URJC-Gsyc-2018-Arquitectura-Internet GitHub Wiki

Contenido

Introducción

Partimos de un escenario con dos máquinas aisladas y aprenderemos sobre sus interfaces de red, y cómo funcionan las redes ethernet. Luego conectaremos las máquinas y las configuraremos para que puedan enviarse mensajes entre ellas, a nivel de ethernet (Nivel de enlace)

Dos máquinas sin conectar

Comenzaremos por crear un escenario en netgui con dos ordenadores PC aislados, sin conexión de red entre ellos

Para poder comunicarse entre ellos necesitamos que los ordenadores dispongan del hardware necesario. Bien Wifi, o bien una tarjeta de red para conectarse por cable. En esta asignatura utilizaremos ordenadores con redes Ethernet, que usan cables

Interfaces de red

Cada ordenador dispondrá de su propia tarjeta de red, que le permite tanto transmitir información hacia la red, como recibirla de ella. Los denominamos de manera genérica: interfaces de red. Un ordenador puede tener varios interfaces de red, que le permite conectarse a redes diferentes

En Linux, los interfaces de red para identificar conexiones de tipo ethernet, se denotan por eth0, eth1, etc. Son interfaces con existencia físicia: eth0 se corresponde con la primera tarjeta de red conectada, eth1 con la segunda, etc.

Todas las máquinas, además de sus interfaces físcios, disponen de una interfaz de red lógica, denominada loopback, y denotada por el nemónico lo. Se trata de una interfaz que hace "eco" de todo lo transmitido por el ordenador. Se usa para poder comunicar procesos dentro del ordenador, simulando una red real (pero en realidad todo se queda dentro del ordenador. Nada sale a la red real)

Mostrando las interfaces de red activas: ifconfig

Arrancamos la máquina pc1, como ya sabemos hacer. Se nos abrirá un terminal como este:

Si ejecutamos el comando ifconfig, nos aparecerán las interfaces de red, tanto virtuales como físicias, que están activas

pc1:~# ifconfig
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:2 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:100 (100.0 B)  TX bytes:100 (100.0 B)

pc1:~#

Vamos a analizar la información que ha aparecido

En la parte superior izquierda nos aparece el nombre (nemónico) de la primer interfaz de red detectada. En este caso es la interfaz virtual de loopback. No es una interfaz física. En la parte de la derecha vemos su descripción: Loopback

En la segunda línea aparece la dirección IP y máscara de red de esta interfaz. Veremos qué significa esto en las prácticas venideras

Dos líneas más abajo podemos ver el estado en el que se encuentra la interfaz. En este caso, la interfaz de Loopback está lanzada (up) y funcionando (running)

Por último vemos información sobre el número de paquetes enviados a través de esta interfaz, el de paquetes recibidos y el número total de bytes recibidos y transmitidos

Mostrando todas las interfaces de red

Para ver TODAS las interfaces de red disponibles, ejecutamos el comando ifconfig -a

pc1:~# ifconfig -a
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:2 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:100 (100.0 B)  TX bytes:100 (100.0 B)

teql0     Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          NOARP  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

pc1:~# 

Ahora nos aparece una nueva: teql0, cuya descripción es UNSPEC (Sin especificar) y que no está lanzada (su estado no es UP). Se trata de una interfaz virtual (no está asociada a ninguna interfaz físicia) que sirve para repartir el tráfico cuando hay varios enlaces entre dos máquinas. NO lo veremos en esta asignatura

Mostrando la interfaz eth0

Con el comando ifconfig podemos obtener información de una interfaz en concreto, simplemente pasando como parámetro el nemónico de la interfaz. Por ejemplo, si queremos ver la información del interfaz de loopback escribiremos:

pc1:~# ifconfig lo
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:2 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:100 (100.0 B)  TX bytes:100 (100.0 B)

pc1:~#

Las redes de ordenadores que utilizaremos en esta asignaturas se conectan mediante redes locales de tipo Ethernet, cuyo nemónico en Linux es eth0. Vamos a obtener más información de eth0:

pc1:~# ifconfig eth0
eth0: error fetching interface information: Device not found
pc1:~# 

Nos sale un mensaje indicando que NO SE HA ENCONTRADO EL DISPOSITIVO. Claro, hemos arrancado el pc1, pero está aislado. No lo hemos conectado a ninguna red de area local, por lo no dispone de tarjeta de red. En los siguientes apartados conectaremos dos ordenadores entre sí, y entonces ya sí que nos aparecerán sus interfaces red

Más sobre interfaces de red

En esta asignatura vamos a utilizar la nomenclatura clásica para las interfaces de red de tipo ethernet: eth0, eth1, etc. Sin embargo, desde el 2015, la mayoría de las distribuciones de Linux, incluida Ubuntu, que es la que usamos en el laboratorio, han migrado a systemd, un sistema de arranque que ha renombrado las interfaces de red. Las comentaremos aquí para tenerlas como referencia

La nueva nomenclatura es un poco más complicada para los humanos, pero ofrece muchas ventanas y hace la vida de los administradores de red un poco más fácil. Se denomina nombres de interfaces de red predecibles

Si ejecutamos el comando ifconfig desde alguna de las máquinas físicas del laboratorio (no desde las máquinas lanzadas desde netgui), obtendremos algo como esto:

Los nombres están formados por identificadores y números. Estos son algunos ejemplos: enp1s0, wlp2s0, eno1...

En este enlace se puede encontrar más información sobre el significado de los campos. Aquí haremos un breve resumen:

Cadena Descripción
en Identifica a los interfaces de tipo Ethernet
wl Interfaces de tipo wireless (wifi)
p Número de bus PCI
s Número de slot
o Dispositivo integrado

En mi portátil tengo tarjeta ethernet y wifi. Si lo ejecuto en mi portátil, que tiene Ubuntu 16.04, obtengo:

Las interfaces activas que aparecen son:

Interfaz Descripción
enp1s0 Como empieza por en, se trata de una tarjeta ethernet, que se encuentra en el bus PCI 1, en el slot 0. Como no estoy conectado por cable en el momento de la captura, aunque la interfaz está activa, no se está ejecutando (running). Vemos también que el número de bytes tanto enviados como recibidos es de cero
lo Es el interfaz de loopback que ya conocemos
wlp2s0 Es la interfaz de la wifi, que se encuentra en el bus PCI 2, slot 0

El comando lspci nos muestra los dispositivos conectados en el bus PCI. Si lo ejecuto en mi portátil, observo que hay dos líneas donde aparece la tarjeta de red y la wifi.

$ lspci
[...]
01:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8101/2/6E PCI Express Fast/Gigabit Ethernet controller (rev 05)
02:00.0 Network controller: Intel Corporation Wireless 3160 (rev 83)
[...]

La ethernet está en el bus 1, slot 0, y la wifi en el bus 2, slot 0. Se corresponden con los números que aparecen en las interfaces de red

Otra forma de obtener las interfaces de red

En Linux se puede acceder a todos los dispositivos a través del sistema de ficheros. Todo son ficheros. Así, para sacar las interfaces de red, además de usar el comando ifconfig, podemos directamente mostrar los ficheros del directorio /sys/class/net

obijuan@alpha02:~$ ls /sys/class/net/
docker0  eno1  lo
obijuan@alpha02:~$

Ethernet

Los ordenadores los conectamos entre sí formando una red de área local. En esta asignatura usaremos el estándar Ethernet

La conexión se realiza a través de un cable único que llega a todas las máquinas. Este tipo de conexión se denomina topología en bus

Tiene una propiedad muy importante: cuando una máquina realiza una transmisión, la señal llega a través del cable a todas las máquinas.

Direcciones físicas

Todas las interfaces de red físicas, tiene asignado un número único que denominamos dirección física o MAC, de 6 bytes (48 bits). No hay dos dispositivos con la misma dirección física en el mundo. Cada dirección se representa mediante 6 números en hexadecimal separados por dos puntos (:). Un ejemplo de dirección física es: 00:16:96:e5:05:e7

En esta figura se muestra un ejemplo de 4 máquinas conectadas a través de una red ethernet. Se muestran las direcciones físicas de cada interfaz, así como el nemónico usado para representar esa interfaz física (eth0)

Tramas ethernet

Cuando una máquina quiero transmitir información a cualquier otra de la red, envía una trama por la tarjeta de red, indicando la dirección física de la máquina destino. La trama tiene el siguiente formato:

Las partes en verdes son detalles del nivel físico. Inicialmente, el transmisor envía un preámbulo, que le permite al receptor sincronizarse. A continuación envía un byte especial para indicarle que la trama empieza. Envía los datos de trama, que comentaremos más adelante, y finaliza con el envío del CRC para comprobar la integridad de la trama (detectar errores)

Tanto el preámbulo, el comienzo de trama y el CRC se gestionan a nivel físico, en la propia tarjeta de red. Por lo que la información que se almacena para ser leída por los niveles superiores es la mostrada en la siguiente figura. Si el CRC fuese incorrecto, la trama se descartaría y el nivel superior no recibiría nada

Tamaño mínimo

Las tramas ethernet deben tener un tamaño mínimo de 60 bytes (64 si se cuenta el CRC). Puesto que se emplean 6 bytes para la dirección destino, otros 6 para le dirección origen y 2 para el tipo de protocolo, 14 bytes en total, al menos hay que enviar 60 - 14 = 46 bytes de datos. Por ello, si el ordenador origen tiene que enviar menos de 46 bytes, deberá añadir datos de relleno (padding) hasta completar esos 46, y tener así una trama de ethernet válida

Asi, por ejemplo, si una máquina quiere enviar el mensaje "HOLA", que tiene 4 bytes, deberá generar una trama ethernet con esos 4 bytes de datos más 42 bytes de relleno

Tamaño máximo

Por otro lado, las tramas ethernet NO PUEDEN tener un tamaño mayor a 1514 (sin incluir el CRC). Teniendo en cuenta los 14 bytes de la cabecera, significa que como máximo una máquina puede enviar 1500 bytes de una sola vez. Si tiene que enviar mayor cantidad de datos, deberá fragmentarlo en dos o más tramas

En este ejemplo, la máquina quiere enviar un total de 1600 bytes. Tendrá que partir los datos, y enviar una trama con 1500 bytes y otra con los 100 restantes

Colisiones

Al estar varias máquinas conectadas en el mismo bus, puedo ocurrir que dos o más de ellas transmitan a la vez. En ese caso, los datos del bus NO SON VÁLIDOS (Es basura) y hay que descartarlos y repetir las transmisiones. Esto se denomina colisión

En Ethernet, las máquinas realizan la transmisión de la siguiente forma:

  • Todas las máquinas que quieren transmitir están escuchando el bus, para saber si está libre u ocupado
  • Si está libre, transmiten, y siguen escuchando
  • Si detectan que ha habido colisión, esperan un tiempo aleatorio, y vuelven a transmitir (si el bus está libre)

Cableado estructurado

El conexionado de las máquinas en una red ethernet se hace actualmente usando cableado estructurado. En vez de tirar un cable de bus que pase por todas las máquinas, se coloca un aparato llamado hub (concentrador) al que se conectan directametne todas las máquinas. El hub retransmite las señales al resto de máquinas, a nivel físico

Así por ejemplo, si queremos tener 4 máquinas conectadas a una red ethernet, necesitamos colocar el hub y cuatro cables de red que vayan desde cada ordenador al hub

El hub es un aparato que funciona a nivel físico: es decir, no procesa las tramas que llegan, sino que simplemente difunde las señales para que lleguen a todas las máquinas. NO es un nodo más de la red ethernet (no tiene dirección física)

Usaremos el hub en todos los escenarios a partir de ahora, aunque sólo sea para conectar dos máquinas

Dos máquinas conectadas por Ethernet

Conectaremos las dos máquinas que antes estaban aisladas mediante una red ethernet con cableado estructurado. El escenario es el siguiente:

Creando el escenario

El escenario con Netgui ya lo sabemos crear. En esta animación se resume el proceso

El escenario está disponible en este archivo: escenario-2-maq.zip. Descomprimirlo y abrir la carpeta escenario-2-maq desde netgui

Activando la ethernet en PC1

Arrancamos la máquina PC1, y ejecutamos el comando ifconfig para ver qué interfaces de red están activas

Observamos que sale exactamente lo mismo que en el caso de la máquina aislada: Sólo está activa la interfaz de loopback. No hemos configurado todavía la conexión ethernet, por lo que no está activada.

Al ejecutar el comando ifconfig -a para ver todas las interfaces disponibles, nos aparece eth0, además de lo y teql0 que también aparecían en el caso de la máquina aislada

pc1:~# ifconfig -a
eth0      Link encap:Ethernet  HWaddr 7e:b1:11:0e:0d:a9  
          BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
          Interrupt:5 

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:2 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:100 (100.0 B)  TX bytes:100 (100.0 B)

teql0     Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          NOARP  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

pc1:~#

Vamos a analizar la información de la interfaz eth0, usando el comando ifconfig eth0

Vemos que la interfaz eth0 es efectivamente una red ethernet, cuya dirección física es: 7e:b1:11:0e:0d:a9. Sabemos que esta interfaz NO está funcionando, porque NO aparece la palabra clave UP al comienzo de la segunda línea. Nos muestra también información sobre la unidad máxima de datos que se puede enviar por esta red (MTU): 1500 bytes. Es un dato que ya conocíamos. Significa que los programas que envíen más de 1500 bytes deberán dividirlo e varias tramos, y en cada una de ellas no pueden enviar más de 1500 bytes

También nos da información sobre los paquetes enviados, las coliciones y el número total de bytes enviados y recibidos. Todos estos valores están a cero porque esta interfaz no está operativa todavía

Vamos a activar la interfaz eth0. Para ello ejecutamos el siguiente comando:

ifconfig eth0 up

Al hacerlo no notaremos nada. No aparece ningún mensaje ni nada. Pero si ahora ejecutamos el comando ifconfig, nos mostrará las dos interfazces que están activas: eth0 y lo

Efectivamente, ahora vemos la palabra UP en el estado de la interfaz eth0. ¡Tenemos la interfaz de red lanzada! Esto significa que el sistema operativo (u otros programas) pueden acceder a la tarjeta de red para enviar tramas

Activando la ethernet en PC2

Repetimos el proceso en PC2. Arrancamos la máquina. Si ejecutamos ifconfig veremos que sólo está activada la intefaz lo. Pero si ejecutamos ifconfig eth0 veremos que exite la interfaz de red, pero NO está lanzada. La lanzamos con ifconfig eth0 up. Volvemos a ejecutar ifconfig para confirmar que la interfaz eth0 está activa

En esta animación se muestra todo el proceso. ¡Ya tenemos las dos máquinas con sus interfaces ethernet activadas, listas para comunicarse!

Enviando tramas y escuchando la red

Para trabajar directamente con ethernet, vamos a utilizar las siguientes utilidades en python:

  • eth-sniffer.py: Escucha la red, y muestra TODAS las tramas que aparecen
  • eth-send.py: Enviar un mensaje de texto a una dirección física, usando ethernet
  • eth-receive.py: Mostrar las tramas recibidas por el nivel superior

Para usarlas es necesario descargarlas y guardarlas en nuestra carpeta personal (HOME), para así poder ejecutarlas desde las máquinas virtuales en la ruta /hosthome/. No olvidar dar permisos de ejecución a estos ficheros

Escuchando desde PC2

Desde la máquina PC2, vamos al directorio /hosthome y ejecutamos ./eth-sniffer.py. Este programa se queda escuchando todo el tiempo la red, e imprime en pantalla la información de TODAS las tramas que haya en la red

Los comandos a ejecutar son:

cd /hosthome/
./eth-sniffer.py
Mostrar todos los paquetes que hay en la Ethernet
Mi direccion Ethernet es: 86:6A:35:CE:0A:DB

Escuchando la red por el interfaz eth0....

Enviando tramas desde PC1

En PC1 nos vamos también a /hosthome y ejecutamos ./eth-send.py. Este programa envía una trama de prueba, a la máquina con dirección física aa:bb:cc:dd:ee:ff

cd /hosthome
./eth-send.py

Parametros: 
 Dir: AA:BB:CC:DD:EE:FF 
 Msg: Testing--->

Longitud mensaje: 11
Longitud padding: 35

El mensaje de texto que se envía es "Testing--->" que tiene una longitud de 11 bytes, por lo que se agrega un relleno de 35 bytes para que los datos tengan la longitud mínima requerida por el estándar ethernet: 46 bytes

En PC2 vemos que se ha capturado la trama. La máquina con dirección 52:C0:6E:45:34:97(que es PC1) ha enviado una trama a la máquina AA:BB:CC:DD:EE:FF, de 46 bytes

Se muestra en funcionamiento en esta animación:

Aunque la trama que se envía no tiene la dirección destino PC2, es una trama que está en el medio comportido, y por tanto, llega a todas las máquinas que estén conectadas a esa red. Sin embargo, el sistema operativo se encarga de que sólo se transmita al nivel superior los datos con destino a esa máquina, ignorando el resto de tramas, que son para otras máquinas diferentes

Enviando tramas de PC1 a PC2

Ahora ejecutamos desde PC2 el programa eth-receive.py, que emula el software de recepción de tramas del sistema operativa. Ahora sólo recibirá las tramas que van para PC2 (que tienen su dirección MAC) o bien las tramas de broadcast, destinadas a todas las máquinas de la red (Dirección FF:FF:FF:FF:FF:FF). El resto de tramas se ignoran. Así es como funcionan todas las máquinas conectadas a una red local

pc2:~# cd /hosthome/
pc2:/hosthome# ./eth-receive.py 
Paquetes recibidos en esta maquina
Direccion Ethernet local: FA:2C:C1:E1:F6:46

Esperando tramas por el interfaz eth0....

El programa se queda esperando a recibir tramas dirigidas sólo a PC2

Desde PC1 nos vamos al directorio /hosthome y ejecutamos .eth-send.py para enviar tramas, como hicimos en el ejemplo anterior. Pero ahora sólo se recibirán si colocamos la dirección físicia de PC2 (o la de broadcast)

Al ejecutar el comando eth-send.py se envía una trama con dirección destino AA:BB:CC:DD:EE:FF, que NO es la dirección de PC2, por lo que no recibe nada (en su terminal no cambiará nada)

cd /hosthome
pc1:/hosthome# ./eth-send.py

Parametros: 
 Dir: AA:BB:CC:DD:EE:FF 
 Msg: Testing--->

Longitud mensaje: 11
Longitud padding: 35
pc1:/hosthome# 

Sin embargo, si ahora, desde PC1 ejecutamos el comando:

./eth-send.py FA:2C:C1:E1:F6:46

Se envía la trama sólo a PC2, y en su terminal veremos el siguiente mensaje:

-----------------------------------------------------
Desde               bytes   data
46:EF:D6:05:D5:6D     46    Testing--->.........

Con el programa eth-send.py también podemos escribir el mensaje que queremos enviar. El primer parámetro es la dirección ethernet destino, y el segundo el mensaje de texto a enviar:

./eth-send.py FA:2C:C1:E1:F6:46 Probando

Se pueden enviar mensajes más largos si se incluyen entrecomillados:

./eth-send.py FA:2C:C1:E1:F6:46 "Mensaje para PC2"

Sin embargo, si cambiamos la dirección destino, en mensaje sale por la red, pero nunca llegará a PC2

./eth-send.py AA:BB:CC:DD:EE:FF "Mensaje para PC2? llega?"

Lo que vemos hasta ahora en la consola de PC2 son los tres mensajes recibidos:

Por último, si enviamos un mensaje a la dirección de broadcast: FF:FF:FF:FF:FF:FF, lo recibirán todas las máquinas conectadas a la red, incluido PC2:

 ./eth-send.py FF:FF:FF:FF:FF:FF "Mensaje para todos"

En esta animación se muestra el funcionamiento

Resumen de comandos

Comando Descripcion
ifconfig Mostrar todas las interfaces de red activas
ifconfig -a Mostrar todas las interfaces de red disponibles, aunque no estén activadas
ifconfig eth0 Mostrar información sobre la interfaz de red eth0
ifconfig eth0 up Activar la interfaz de red eth0
ifconfig eth0 down Desactivar la interfaz de red eth0
./eth-sniffer.py Mostrar todos los paquetes que aparecen en la ethernet
./eth-receive.py Mostrar los paquetes cuyo destino son la máquina donde se ejecuta el comando
./eth-send.py dir msg Enviar tramas ethernet a la dirección destino especefificada (dir) con el mensaje de texto msg

Autores

Creditos

Licencia

Enlaces