Ethernet: conectando dos máquinas - Obijuan/URJC-Gsyc-2018-Arquitectura-Internet GitHub Wiki
Contenido
- Introducción
- Dos máquinas sin conectar
- Ethernet
- Dos máquinas conectadas por ethernet
- Resumen de comandos
- Autores
- Créditos
- Licencia
- Enlaces
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
- Felipe Ortega
- Juan González-Gómez (Obijuan)
Creditos
- Creado a partir del contenido generado por profesores del departamento GSYC para la asignatura de Arquitectura de Internet: Jose Centeno González, Pedro de las Heras