From 918a7b42017533f6f18edc8735d6d82a5494f055 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Sun, 11 Jun 2006 06:08:57 +0000 Subject: [PATCH] =?utf8?q?Se=20emprolija=20un=20poco=20el=20terreno:=20*?= =?utf8?q?=20Se=20hace=20un=20programa=20completo=20que=20hace=202=20forks?= =?utf8?q?=20(3=20procesos),=20uno=20que=20recibe=20=20=20entrada=20de=20u?= =?utf8?q?suario=20y=20manda,=20otro=20que=20forwardea=20y=20otro=20que=20?= =?utf8?q?recibe.=20*=20Se=20corrigen=20pruebas=20e=20informe.=20*=20Se=20?= =?utf8?q?agrega=20MTU=20a=20las=20tablas,=20para=20dejar=20simple=20el=20?= =?utf8?q?dispositivo=20f=C3=ADsico=20y=20tener=20=20=20siempre=20uno=20s?= =?utf8?q?=C3=B3lo.=20*=20Se=20mejora=20levemente=20la=20generaci=C3=B3n?= =?utf8?q?=20de=20IDs=20de=20IP.?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- practicas/pipi/README | 236 +++++------------- practicas/pipi/TODO | 1 - practicas/pipi/rutas_ejemplo/route.txt | 6 +- .../pipi/rutas_ejemplo/route_10.10.10.1.txt | 9 +- .../pipi/rutas_ejemplo/route_10.10.10.2.txt | 9 +- .../pipi/rutas_ejemplo/route_10.10.10.3.txt | 9 +- .../pipi/rutas_ejemplo/route_10.10.10.4.txt | 5 + .../pipi/rutas_ejemplo/route_10.10.10.5.txt | 9 +- practicas/pipi/src/Makefile | 29 ++- practicas/pipi/src/dev.cpp | 2 +- practicas/pipi/src/dev.h | 2 +- practicas/pipi/src/ip.cpp | 139 +++++++++++ practicas/pipi/src/ipout.cpp | 42 ++-- practicas/pipi/src/ipout.h | 3 + practicas/pipi/src/routetable.cpp | 5 +- practicas/pipi/src/routetable.h | 9 +- practicas/pipi/src/test.sh | 29 +-- practicas/pipi/src/test2.sh | 38 ++- 18 files changed, 320 insertions(+), 262 deletions(-) create mode 100644 practicas/pipi/rutas_ejemplo/route_10.10.10.4.txt create mode 100644 practicas/pipi/src/ip.cpp diff --git a/practicas/pipi/README b/practicas/pipi/README index 2243ff3..cca4337 100644 --- a/practicas/pipi/README +++ b/practicas/pipi/README @@ -14,6 +14,8 @@ Organización En el directorio `src` se encuentra el código fuente del trabajo, con su correspondiente `Makefile` para compilarlo tan solo ejecutando `make`. +Dentro de este directorio hay también dos scripts de pruebas completas: +`test.sh` (con 1 router) y `test2.sh` (con 2 routers). En el directorio `rutas_ejemplo` contiene algunos archivos con descripciones de rutas de ejemplo para correr los programas. @@ -22,23 +24,17 @@ rutas de ejemplo para correr los programas. Uso === -El trabajo tiene 2 programas de prueba principales: `test_ipin` y `test_ipout`, -ambos generados en el directorio `src` luego de compilar el código. - -test_ipin ---------- - -Este programa es el proceso que recibe paquetes IP y los procesa. +El trabajo consta de un programa llamado `ip` (más algunas otras pruebas que no +tiene relevancia). Este programa corre 3 procesos, uno que recibe paquetes IP +otro que recibe entrada del usuario y envía paquetes IP y otro que redirecciona +(forward) paquetes IP en caso de ser pertinente. Uso:: - ./test_ipin [ip] [mtu] [router] [forward] [proto] [queue_id] + ./ip ip [router [forward [route_file [queue_id [proto]]]]] ip - IP que utiliza este proceso (default 10.10.10.1) - -mtu - MTU de la capa física de este proceso (default 25) + IP que utiliza este proceso router 0 si es router, 1 si no lo es (default 0) @@ -46,8 +42,11 @@ router forward 0 si puede hacer forwarding, 1 si no (default 0) -proto - Protocolo que transporta (default 0) +route_file + Archivo con las rutas. El formato del archivo es una ruta por línea, cada + línea se compone de red (por ahora sólo soporta IPs puntuales), gateway (si es + cero es que están en la misma red), MTU y métrica (todavía no se usa), + separados por uno o más espacios o tabs (default `route.txt`) queue_id Identificador de la cola a usar como medio físico, también establece el @@ -55,39 +54,19 @@ queue_id (`test_ipout`) para hacer forwarding, que será queue_id + 1 (default `DEV_DEFAULT_KEY` obtenido de `dev.h`) +proto + Protocolo que transporta (default 0) -test_ipout ----------- - -Este programa es el proceso que envía paquetes IP y rutea. - -Uso:: - - ./test_ipout [ip] [dst] [mtu] [routes_file] [proto] [queue_id] - -ip - IP que utiliza este proceso (default 10.10.10.2) - -dst - IP del destino al cual mandar paquetes (default 10.10.10.1) - -mtu - MTU de la capa física de este proceso (default 25) -route_file - Archivo con las rutas. El formato del archivo es una ruta por línea, cada - línea se compone de red (por ahora sólo soporta IPs puntuales), gateway (si es - cero es que están en la misma red) y métrica (todavía no se usa), separados - por uno o más espacios o tabs (default `route.txt`) +El programa se queda esperando la entrada del usuario, y sale cuando está se +termina (Ctrl-D). El formato de entrada es:: -proto - Protocolo que transporta (default 0) + IP DESTINO + MENSAJE -queue_id - Identificador de la cola a usar como medio físico, también establece el - identificador de la cola a usar para comunicarse con el otro proceso - (`test_ipout`) para hacer forwarding, que será queue_id + 1 (default - `DEV_DEFAULT_KEY` obtenido de `dev.h`) +Es decir, en una línea se pone la IP de destino y en la línea siguiente el +mensaje. Para enviar otro mensaje, nuevamente se pone IP de destino en una línea +y el mensaje en la siguiente. Diseño del trabajo @@ -115,8 +94,8 @@ RouteTable Encapsula una tabla de ruteo. Por falta de tiempo y simplicidad por ahora sólo soporta rutas a un sólo host (no a una red) pero es muy fácilmente extensible y transparente para el resto de las clases que la usan. Las rutas se componen - de red (en realidad por ahora host), geteway, metrica y dispositivo de red por - el cual salir (Dev). + de red (en realidad por ahora host), geteway, MTU, metrica y dispositivo de + red por el cual salir (Dev). IPIn Es la clase encargada de recibir paquetes IP. Hace chequeos varios y descarta @@ -125,6 +104,7 @@ IPIn * Cabecera incompleta o no es IP * Versión IP incorrecta * Mal checksum + * TTL=0 * No es para nosotros y no hacemos forward * Es para nosotros pero somos un router @@ -148,160 +128,66 @@ Host 10.10.10.1 Rutas: -* 10.10.10.1 0.0.0.0 0 -* 10.10.10.3 10.10.10.5 0 -* 10.10.10.5 0.0.0.0 0 +* 10.10.10.1 0.0.0.0 35 0 +* 10.10.10.3 10.10.10.5 35 1 +* 10.10.10.5 0.0.0.0 35 0 Envía "adios mundo cruel!!!" al host 10.10.10.3:: - $ ./test_ipout 10.10.10.1 10.10.10.3 25 ../rutas_ejemplo/route_10.10.10.1.txt - Se agregó tabla para 10.10.10.1: gw = 0.0.0.0, metric = 0 - Se agregó tabla para 10.10.10.2: gw = 0.0.0.0, metric = 0 - Se agregó tabla para 10.10.10.3: gw = 10.10.10.5, metric = 0 - Se agregó tabla para 10.10.10.5: gw = 0.0.0.0, metric = 0 - adios mundo cruel!!! - IPOut::send: Fragmento 0 => IPHeader: version= total_len=40 id=56121 DF=0 MF=1 offset=0 TTL=64 proto=0 checksum=196 src=10.10.10.1 dst=10.10.10.3 - data (5) = adios - Dev::transmit(msgtype/mac = 168430085, size = 25) - IPOut::send: Fragmento 0 => IPHeader: version= total_len=35 id=56121 DF=0 MF=1 offset=5 TTL=64 proto=0 checksum=231 src=10.10.10.1 dst=10.10.10.3 - data (5) = mund - Dev::transmit(msgtype/mac = 168430085, size = 25) - IPOut::send: Fragmento 0 => IPHeader: version= total_len=30 id=56121 DF=0 MF=1 offset=10 TTL=64 proto=0 checksum=266 src=10.10.10.1 dst=10.10.10.3 - data (5) = o cru - Dev::transmit(msgtype/mac = 168430085, size = 25) - IPOut::send: Fragmento 0 => IPHeader: version= total_len=25 id=56121 DF=0 MF=0 offset=15 TTL=64 proto=0 checksum=297 src=10.10.10.1 dst=10.10.10.3 + $ (echo -e '10.10.10.3\nAdios mundo cruel!!!'; sleep 1) | ./ip 10.10.10.1 0 0 ../rutas_ejemplo/route_10.10.10.1.txt + IPOut::send (10.10.10.1): Fragmento 0 => IPHeader: version=4 total_len=40 id=44919 DF=0 MF=1 offset=0 TTL=64 proto=0 checksum=214 src=10.10.10.1 dst=10.10.10.3 + data (15) = Adios mundo cru + IPOut::send (10.10.10.1): Fragmento 1 => IPHeader: version=4 total_len=25 id=44919 DF=0 MF=0 offset=15 TTL=64 proto=0 checksum=315 src=10.10.10.1 dst=10.10.10.3 data (5) = el!!! - Dev::transmit(msgtype/mac = 168430085, size = 25) - Enviado 'adios mundo cruel!!!' a 10.10.10.3 + Enviado 'Adios mundo cruel!!!' a 10.10.10.3 -El proceso test_ipin de este host no tiene relevancia. Router 10.10.10.5 ----------------- Rutas: -* 10.10.10.1 0.0.0.0 0 -* 10.10.10.3 0.0.0.0 0 -* 10.10.10.5 0.0.0.0 0 +* 10.10.10.1 0.0.0.0 35 0 +* 10.10.10.3 0.0.0.0 32 0 +* 10.10.10.5 0.0.0.0 35 0 Recibe el mensaje:: - $ ./test_ipin 10.10.10.5 25 1 1 - Quedan 4 mensajes en la cola - Dev::receive(msgtype/mac = 168430085, size = 25) - IPIn::recv: IPHeader: version= total_len=40 id=56121 DF=0 MF=1 offset=0 TTL=64 proto=0 checksum=196 src=10.10.10.1 dst=10.10.10.3 - data (5) = adios - Dev::transmit(msgtype/mac = 168430085, size = 25) - Dev::receive(msgtype/mac = 168430085, size = 25) - IPIn::recv: IPHeader: version= total_len=35 id=56121 DF=0 MF=1 offset=5 TTL=64 proto=0 checksum=231 src=10.10.10.1 dst=10.10.10.3 - data (5) = mund - Dev::transmit(msgtype/mac = 168430085, size = 25) - Dev::receive(msgtype/mac = 168430085, size = 25) - IPIn::recv: IPHeader: version= total_len=30 id=56121 DF=0 MF=1 offset=10 TTL=64 proto=0 checksum=266 src=10.10.10.1 dst=10.10.10.3 - data (5) = o cru - Dev::transmit(msgtype/mac = 168430085, size = 25) - Dev::receive(msgtype/mac = 168430085, size = 25) - IPIn::recv: IPHeader: version= total_len=25 id=56121 DF=0 MF=0 offset=15 TTL=64 proto=0 checksum=297 src=10.10.10.1 dst=10.10.10.3 + $ ./ip 10.10.10.5 1 1 ../rutas_ejemplo/route_10.10.10.5.txt + IPIn::recv (10.10.10.5): IPHeader: version=4 total_len=40 id=44919 DF=0 MF=1 offset=0 TTL=64 proto=0 checksum=214 src=10.10.10.1 dst=10.10.10.3 + data (15) = Adios mundo cru + IPIn::recv (10.10.10.5): IPHeader: version=4 total_len=25 id=44919 DF=0 MF=0 offset=15 TTL=64 proto=0 checksum=315 src=10.10.10.1 dst=10.10.10.3 data (5) = el!!! - Dev::transmit(msgtype/mac = 168430085, size = 25) - -Y lo forwardea (refragmentando porque tiene un MTU más pequeño):: - - $ ./test_ipout 10.10.10.5 10.10.10.1 23 ../rutas_ejemplo/route_10.10.10.5.txt - Se agregó tabla para 10.10.10.1: gw = 0.0.0.0, metric = 0 - Se agregó tabla para 10.10.10.2: gw = 0.0.0.0, metric = 0 - Se agregó tabla para 10.10.10.3: gw = 0.0.0.0, metric = 0 - Se agregó tabla para 10.10.10.5: gw = 0.0.0.0, metric = 0 - a - IPOut::send: Fragmento 0 => IPHeader: version= total_len=21 id=56140 DF=0 MF=0 offset=0 TTL=64 proto=0 checksum=194 src=10.10.10.5 dst=10.10.10.1 - data (1) = a - Dev::transmit(msgtype/mac = 168430081, size = 21) - Enviado 'a' a 10.10.10.1 - a - Dev::receive(msgtype/mac = 168430085, size = 25) - IPOut::send: A forwardear - IPOut::send: Fragmento 0 => IPHeader: version= total_len=40 id=56121 DF=0 MF=1 offset=0 TTL=64 proto=0 checksum=196 src=10.10.10.1 dst=10.10.10.3 - data (3) = adi - Dev::transmit(msgtype/mac = 168430083, size = 23) - IPOut::send: Fragmento 0 => IPHeader: version= total_len=37 id=56121 DF=0 MF=1 offset=3 TTL=64 proto=0 checksum=217 src=10.10.10.1 dst=10.10.10.3 - data (2) = os - Dev::transmit(msgtype/mac = 168430083, size = 22) - Dev::receive(msgtype/mac = 168430085, size = 25) - IPOut::send: A forwardear - IPOut::send: Fragmento 0 => IPHeader: version= total_len=35 id=56121 DF=0 MF=1 offset=5 TTL=64 proto=0 checksum=231 src=10.10.10.1 dst=10.10.10.3 - data (3) = mu - Dev::transmit(msgtype/mac = 168430083, size = 23) - IPOut::send: Fragmento 0 => IPHeader: version= total_len=32 id=56121 DF=0 MF=1 offset=8 TTL=64 proto=0 checksum=252 src=10.10.10.1 dst=10.10.10.3 - data (2) = nd - Dev::transmit(msgtype/mac = 168430083, size = 22) - Dev::receive(msgtype/mac = 168430085, size = 25) - IPOut::send: A forwardear - IPOut::send: Fragmento 0 => IPHeader: version= total_len=30 id=56121 DF=0 MF=1 offset=10 TTL=64 proto=0 checksum=266 src=10.10.10.1 dst=10.10.10.3 - data (3) = o c - Dev::transmit(msgtype/mac = 168430083, size = 23) - IPOut::send: Fragmento 0 => IPHeader: version= total_len=27 id=56121 DF=0 MF=1 offset=13 TTL=64 proto=0 checksum=287 src=10.10.10.1 dst=10.10.10.3 - data (2) = ru - Dev::transmit(msgtype/mac = 168430083, size = 22) - Dev::receive(msgtype/mac = 168430085, size = 25) - IPOut::send: A forwardear - IPOut::send: Fragmento 0 => IPHeader: version= total_len=25 id=56121 DF=0 MF=1 offset=15 TTL=64 proto=0 checksum=301 src=10.10.10.1 dst=10.10.10.3 - data (3) = el! - Dev::transmit(msgtype/mac = 168430083, size = 23) - IPOut::send: Fragmento 0 => IPHeader: version= total_len=22 id=56121 DF=0 MF=0 offset=18 TTL=64 proto=0 checksum=62 src=10.10.10.1 dst=10.10.10.3 - data (2) = !! - Dev::transmit(msgtype/mac = 168430083, size = 22) - IPOut::send: Fragmento 0 => IPHeader: version= total_len=21 id=56147 DF=0 MF=0 offset=0 TTL=64 proto=0 checksum=201 src=10.10.10.5 dst=10.10.10.1 - data (1) = a - Dev::transmit(msgtype/mac = 168430081, size = 21) - Enviado 'a' a 10.10.10.1 - -(notar que para que haga el forwarding se tuvo que enviar un paquete -*dummy* para que busque en la cola de paquetes a forwardear (es un error -de diseño que tendré que corregir de alguna forma) + IPOut::forward_loop (10.10.10.5): A forwardear (id 44919) + IPOut::send (10.10.10.5): Fragmento 0 => IPHeader: version=4 total_len=40 id=44919 DF=0 MF=1 offset=0 TTL=64 proto=0 checksum=214 src=10.10.10.1 dst=10.10.10.3 + data (12) = Adios mundo + IPOut::send (10.10.10.5): Fragmento 1 => IPHeader: version=4 total_len=28 id=44919 DF=0 MF=1 offset=12 TTL=64 proto=0 checksum=298 src=10.10.10.1 dst=10.10.10.3 + data (3) = cru + IPOut::forward_loop (10.10.10.5): A forwardear (id 44919) + IPOut::send (10.10.10.5): Fragmento 0 => IPHeader: version=4 total_len=25 id=44919 DF=0 MF=0 offset=15 TTL=64 proto=0 checksum=315 src=10.10.10.1 dst=10.10.10.3 + data (5) = el!!! + Host 10.10.10.3 --------------- Rutas: -* 10.10.10.1 10.10.10.5 0 -* 10.10.10.3 0.0.0.0 0 -* 10.10.10.5 0.0.0.0 0 +* 10.10.10.1 10.10.10.5 32 1 +* 10.10.10.3 0.0.0.0 32 0 +* 10.10.10.5 0.0.0.0 32 0 Finalmente este host recibe todos los fragmentos, reensabla y pasa el paquete completo a la capa superior:: - $ ./test_ipin 10.10.10.3 23 - Quedan 8 mensajes en la cola - Dev::receive(msgtype/mac = 168430083, size = 23) - IPIn::recv: IPHeader: version= total_len=40 id=56121 DF=0 MF=1 offset=0 TTL=64 proto=0 checksum=196 src=10.10.10.1 dst=10.10.10.3 - data (3) = adi - Dev::receive(msgtype/mac = 168430083, size = 22) - IPIn::recv: IPHeader: version= total_len=37 id=56121 DF=0 MF=1 offset=3 TTL=64 proto=0 checksum=217 src=10.10.10.1 dst=10.10.10.3 - data (2) = os - Dev::receive(msgtype/mac = 168430083, size = 23) - IPIn::recv: IPHeader: version= total_len=35 id=56121 DF=0 MF=1 offset=5 TTL=64 proto=0 checksum=231 src=10.10.10.1 dst=10.10.10.3 - data (3) = mu - Dev::receive(msgtype/mac = 168430083, size = 22) - IPIn::recv: IPHeader: version= total_len=32 id=56121 DF=0 MF=1 offset=8 TTL=64 proto=0 checksum=252 src=10.10.10.1 dst=10.10.10.3 - data (2) = nd - Dev::receive(msgtype/mac = 168430083, size = 23) - IPIn::recv: IPHeader: version= total_len=30 id=56121 DF=0 MF=1 offset=10 TTL=64 proto=0 checksum=266 src=10.10.10.1 dst=10.10.10.3 - data (3) = o c - Dev::receive(msgtype/mac = 168430083, size = 22) - IPIn::recv: IPHeader: version= total_len=27 id=56121 DF=0 MF=1 offset=13 TTL=64 proto=0 checksum=287 src=10.10.10.1 dst=10.10.10.3 - data (2) = ru - Dev::receive(msgtype/mac = 168430083, size = 23) - IPIn::recv: IPHeader: version= total_len=25 id=56121 DF=0 MF=1 offset=15 TTL=64 proto=0 checksum=301 src=10.10.10.1 dst=10.10.10.3 - data (3) = el! - Dev::receive(msgtype/mac = 168430083, size = 22) - IPIn::recv: IPHeader: version= total_len=22 id=56121 DF=0 MF=0 offset=18 TTL=64 proto=0 checksum=62 src=10.10.10.1 dst=10.10.10.3 - data (2) = !! - IPIn::recv: Paquete completo: data = 'adios mundo cruel!!!' - Recibido 'adios mundo cruel!!!' (len 20) de 10.10.10.1 para 10.10.10.3 (proto = 0) - -El proceso test_ipout de este host no tiene relevancia. - + $ ./ip 10.10.10.3 0 0 ../rutas_ejemplo/route_10.10.10.3.txt + IPIn::recv (10.10.10.3): IPHeader: version=4 total_len=40 id=44919 DF=0 MF=1 offset=0 TTL=64 proto=0 checksum=214 src=10.10.10.1 dst=10.10.10.3 + data (12) = Adios mundo + IPIn::recv (10.10.10.3): IPHeader: version=4 total_len=28 id=44919 DF=0 MF=1 offset=12 TTL=64 proto=0 checksum=298 src=10.10.10.1 dst=10.10.10.3 + data (3) = cru + IPIn::recv (10.10.10.3): IPHeader: version=4 total_len=25 id=44919 DF=0 MF=0 offset=15 TTL=64 proto=0 checksum=315 src=10.10.10.1 dst=10.10.10.3 + data (5) = el!!! + IPIn::recv (10.10.10.3): Paquete completo: data = 'Adios mundo cruel!!!' + Recibido 'Adios mundo cruel!!!' (len 20) de 10.10.10.1 para 10.10.10.3 (proto = 0) .. vim: filetype=rst : diff --git a/practicas/pipi/TODO b/practicas/pipi/TODO index b052d5b..e2ebac8 100644 --- a/practicas/pipi/TODO +++ b/practicas/pipi/TODO @@ -1,6 +1,5 @@ - Implementar metricas - Implementar rutas de redes completas -- Encolar paquetes a mandar en la misma cola que paquetes a forwardear - Arreglar cola de forwarding para que no dependa del medio fisico/dispositivo - Tener en cuenta el TTL para limpiar buffers - Ver que hayan llegado todos los fragmentos antes de subir a capa superior diff --git a/practicas/pipi/rutas_ejemplo/route.txt b/practicas/pipi/rutas_ejemplo/route.txt index 3aae5e1..5efe7da 100644 --- a/practicas/pipi/rutas_ejemplo/route.txt +++ b/practicas/pipi/rutas_ejemplo/route.txt @@ -1,3 +1,3 @@ -10.10.10.1 0.0.0.0 0 -10.10.10.2 0.0.0.0 0 -10.10.10.3 10.10.10.5 0 +10.10.10.1 0.0.0.0 25 0 +10.10.10.2 0.0.0.0 25 0 +10.10.10.3 10.10.10.5 25 0 diff --git a/practicas/pipi/rutas_ejemplo/route_10.10.10.1.txt b/practicas/pipi/rutas_ejemplo/route_10.10.10.1.txt index cc877c8..e74908d 100644 --- a/practicas/pipi/rutas_ejemplo/route_10.10.10.1.txt +++ b/practicas/pipi/rutas_ejemplo/route_10.10.10.1.txt @@ -1,4 +1,5 @@ -10.10.10.1 0.0.0.0 0 -10.10.10.2 0.0.0.0 0 -10.10.10.3 10.10.10.5 0 -10.10.10.5 0.0.0.0 0 +10.10.10.1 0.0.0.0 35 0 +10.10.10.2 10.10.10.5 35 2 +10.10.10.3 10.10.10.5 35 1 +10.10.10.4 10.10.10.5 35 1 +10.10.10.5 0.0.0.0 35 0 diff --git a/practicas/pipi/rutas_ejemplo/route_10.10.10.2.txt b/practicas/pipi/rutas_ejemplo/route_10.10.10.2.txt index cc877c8..cff2d1b 100644 --- a/practicas/pipi/rutas_ejemplo/route_10.10.10.2.txt +++ b/practicas/pipi/rutas_ejemplo/route_10.10.10.2.txt @@ -1,4 +1,5 @@ -10.10.10.1 0.0.0.0 0 -10.10.10.2 0.0.0.0 0 -10.10.10.3 10.10.10.5 0 -10.10.10.5 0.0.0.0 0 +10.10.10.1 10.10.10.4 25 2 +10.10.10.2 0.0.0.0 25 0 +10.10.10.3 10.10.10.4 25 2 +10.10.10.4 0.0.0.0 25 0 +10.10.10.5 10.10.10.4 25 1 diff --git a/practicas/pipi/rutas_ejemplo/route_10.10.10.3.txt b/practicas/pipi/rutas_ejemplo/route_10.10.10.3.txt index 11ff580..a4e4cfb 100644 --- a/practicas/pipi/rutas_ejemplo/route_10.10.10.3.txt +++ b/practicas/pipi/rutas_ejemplo/route_10.10.10.3.txt @@ -1,4 +1,5 @@ -10.10.10.1 10.10.10.5 0 -10.10.10.2 10.10.10.5 0 -10.10.10.3 0.0.0.0 0 -10.10.10.5 0.0.0.0 0 +10.10.10.1 10.10.10.5 32 1 +10.10.10.2 10.10.10.5 32 2 +10.10.10.3 0.0.0.0 32 0 +10.10.10.4 10.10.10.5 32 1 +10.10.10.5 0.0.0.0 32 0 diff --git a/practicas/pipi/rutas_ejemplo/route_10.10.10.4.txt b/practicas/pipi/rutas_ejemplo/route_10.10.10.4.txt new file mode 100644 index 0000000..54c7650 --- /dev/null +++ b/practicas/pipi/rutas_ejemplo/route_10.10.10.4.txt @@ -0,0 +1,5 @@ +10.10.10.1 10.10.10.5 28 1 +10.10.10.2 0.0.0.0 25 0 +10.10.10.3 10.10.10.5 28 1 +10.10.10.4 0.0.0.0 28 0 +10.10.10.5 0.0.0.0 28 0 diff --git a/practicas/pipi/rutas_ejemplo/route_10.10.10.5.txt b/practicas/pipi/rutas_ejemplo/route_10.10.10.5.txt index d57116e..c19729c 100644 --- a/practicas/pipi/rutas_ejemplo/route_10.10.10.5.txt +++ b/practicas/pipi/rutas_ejemplo/route_10.10.10.5.txt @@ -1,4 +1,5 @@ -10.10.10.1 0.0.0.0 0 -10.10.10.2 0.0.0.0 0 -10.10.10.3 0.0.0.0 0 -10.10.10.5 0.0.0.0 0 +10.10.10.1 0.0.0.0 35 0 +10.10.10.2 10.10.10.4 28 1 +10.10.10.3 0.0.0.0 32 0 +10.10.10.4 0.0.0.0 28 0 +10.10.10.5 0.0.0.0 35 0 diff --git a/practicas/pipi/src/Makefile b/practicas/pipi/src/Makefile index 58539ef..9980baf 100644 --- a/practicas/pipi/src/Makefile +++ b/practicas/pipi/src/Makefile @@ -27,7 +27,8 @@ CXXFLAGS = $(CFLAGS) -fno-inline CC=g++ # Programas -targets=test_send test_recv test_ipaddr test_ipin test_ipout +targets=ip +tests=test_send test_recv test_ipaddr test_ipin test_ipout # Fuentes fuentes ?= $(wildcard *.cpp) @@ -40,6 +41,8 @@ fuentes ?= $(wildcard *.cpp) all: depend $(targets) +tests: depend $(tests) + test_send: test_send.o dev.o test_recv: test_recv.o dev.o @@ -50,6 +53,8 @@ test_ipin: test_ipin.o ipin.o ipaddr.o ipheader.o dev.o test_ipout: test_ipout.o ipout.o ipaddr.o ipheader.o dev.o routetable.o +ip: ip.o ipout.o ipin.o ipaddr.o ipheader.o dev.o routetable.o + depend: @makedepend $(fuentes) > /dev/null 2>&1 @@ -71,6 +76,28 @@ dev.o: /usr/include/bits/time.h /usr/include/sys/sysmacros.h dev.o: /usr/include/bits/pthreadtypes.h /usr/include/bits/sched.h dev.o: /usr/include/sys/ipc.h /usr/include/bits/ipctypes.h dev.o: /usr/include/bits/ipc.h /usr/include/sys/msg.h /usr/include/bits/msq.h +ip.o: ipout.h ipaddr.h ipheader.h /usr/include/stdint.h +ip.o: /usr/include/features.h /usr/include/sys/cdefs.h +ip.o: /usr/include/gnu/stubs.h /usr/include/bits/wchar.h +ip.o: /usr/include/bits/wordsize.h routetable.h dev.h ipin.h +ip.o: /usr/include/unistd.h /usr/include/bits/posix_opt.h +ip.o: /usr/include/bits/types.h /usr/include/bits/typesizes.h +ip.o: /usr/include/bits/confname.h /usr/include/getopt.h /usr/include/fcntl.h +ip.o: /usr/include/bits/fcntl.h /usr/include/sys/types.h /usr/include/time.h +ip.o: /usr/include/endian.h /usr/include/bits/endian.h +ip.o: /usr/include/sys/select.h /usr/include/bits/select.h +ip.o: /usr/include/bits/sigset.h /usr/include/bits/time.h +ip.o: /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h +ip.o: /usr/include/bits/sched.h /usr/include/sys/wait.h /usr/include/signal.h +ip.o: /usr/include/bits/signum.h /usr/include/bits/siginfo.h +ip.o: /usr/include/bits/sigaction.h /usr/include/bits/sigcontext.h +ip.o: /usr/include/asm/sigcontext.h /usr/include/asm-i486/sigcontext.h +ip.o: /usr/include/linux/compiler.h /usr/include/bits/sigstack.h +ip.o: /usr/include/bits/sigthread.h /usr/include/sys/resource.h +ip.o: /usr/include/bits/resource.h /usr/include/bits/waitflags.h +ip.o: /usr/include/bits/waitstatus.h /usr/include/sys/ipc.h +ip.o: /usr/include/bits/ipctypes.h /usr/include/bits/ipc.h +ip.o: /usr/include/sys/msg.h /usr/include/bits/msq.h ipaddr.o: ipaddr.h ipheader.o: ipheader.h ipaddr.h /usr/include/stdint.h /usr/include/features.h ipheader.o: /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h diff --git a/practicas/pipi/src/dev.cpp b/practicas/pipi/src/dev.cpp index d9465a6..57e1d3d 100644 --- a/practicas/pipi/src/dev.cpp +++ b/practicas/pipi/src/dev.cpp @@ -16,7 +16,7 @@ struct Frame char frame[1]; }; -Dev::Dev(mac_type mac, size_t mtu, key_t key) +Dev::Dev(mac_type mac, key_t key, size_t mtu) throw (std::runtime_error, std::logic_error): mac(mac), mtu(mtu) { diff --git a/practicas/pipi/src/dev.h b/practicas/pipi/src/dev.h index 129f78f..bae7e17 100644 --- a/practicas/pipi/src/dev.h +++ b/practicas/pipi/src/dev.h @@ -23,7 +23,7 @@ struct Dev int que_id; /// Constructor - Dev(mac_type mac, size_t mtu = DEV_MAX_MTU, key_t key = DEV_DEFAULT_KEY) + Dev(mac_type mac, key_t key = DEV_DEFAULT_KEY, size_t mtu = DEV_MAX_MTU) throw (std::runtime_error, std::logic_error); /// Envía un frame diff --git a/practicas/pipi/src/ip.cpp b/practicas/pipi/src/ip.cpp new file mode 100644 index 0000000..dd38b9b --- /dev/null +++ b/practicas/pipi/src/ip.cpp @@ -0,0 +1,139 @@ + +#include "ipout.h" +#include "ipin.h" +#include "ipaddr.h" +#include "routetable.h" +#include "dev.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Uso: ./test_ipout ip [router forward routes_file queue_id proto] + +void send_loop(IPOut& ipout, unsigned proto); + +void add_routes(RouteTable& rt, std::istream& is, Dev& dev); + +int main(int argc, char* argv[]) +{ + bool router = false; + bool forward = false; + unsigned proto = 0; + key_t queue_id = DEV_DEFAULT_KEY; + std::string fname = "route.txt"; + if (argc < 2) + { + std::cerr << "Uso: ./test_ipout ip [router forward routes_file " + "queue_id proto]\n"; + return 1; + } + IPAddr addr(argv[1]); + if (argc > 2) + router = atoi(argv[2]); + if (argc > 3) + forward = atoi(argv[3]); + if (argc > 4) + fname = argv[4]; + if (argc > 5) + queue_id = atoi(argv[5]); + if (argc > 6) + proto = atoi(argv[6]); + // Creo colas + int que_id = msgget(queue_id, IPC_CREAT | 0666); assert(que_id != -1); + que_id = msgget(DEV_DEFAULT_KEY-1, IPC_CREAT | 0666); assert(que_id != -1); + // Abro archivo con rutas + std::ifstream ifs(fname.c_str()); assert(ifs); + // Creo medio físico y cola para forwarding + Dev dev(addr, queue_id); + Dev fwque(addr, DEV_DEFAULT_KEY-1); + // Creo procesos + pid_t pid_send = fork(); + if (pid_send == -1) + { + perror("fork() send"); + return 2; + } + if (pid_send) // IPOut + { + RouteTable table(dev); + add_routes(table, ifs, dev); + IPOut ipout(addr, table, fwque, std::cerr); + pid_t pid_fw = fork(); + if (pid_fw == -1) + { + perror("fork() forward"); + return 3; + } + if (pid_fw) // Padre (IPOut send) + { + int ret; + send_loop(ipout, proto); + kill(pid_send, SIGTERM); + waitpid(pid_send, &ret, 0); + kill(pid_fw, SIGTERM); + waitpid(pid_fw, &ret, 0); + return 0; + } + else // Hijo 1 (IPOut forward) + { + ipout.forward_loop(); + return 0; + } + } + else // Hijo 2 (IPIn) + { + IPIn ipin(addr, dev, fwque, router, forward, std::cerr); + while (true) + { + IPAddr src, dst; + std::string s = ipin.recv(proto, src, dst); + std::cout << "Recibido '" << s << "' (len " << s.size() << ") de " + << src << " para " << dst << " (proto = " << proto << ")\n"; + } + return 0; + } + return 0; +} + +void send_loop(IPOut& ipout, unsigned proto) +{ + std::string dst; + std::string msg; + while (std::getline(std::cin, dst)) + { + if (!std::getline(std::cin, msg)) + break; + if (ipout.send(msg, proto, IPAddr(dst.c_str()))) + std::cout << "Enviado '" << msg << "' a " << dst << "\n"; + else + std::cout << "NO SE PUDO ENVIAR '" << msg << "' a " << dst << "\n"; + } +} + +void add_routes(RouteTable& rt, std::istream& is, Dev& dev) +{ + std::string line; + while (std::getline(is, line)) + { + std::istringstream iss(line); + std::string net; + std::string gw; + unsigned mtu; + unsigned metric; + iss >> net >> gw >> mtu >> metric; + if (net == "0") net = "0.0.0.0"; + if (gw == "0") gw = "0.0.0.0"; + rt.add(net.c_str(), gw.c_str(), metric, mtu, dev); + } +} + +// vim: set et sw=4 sts=4 : diff --git a/practicas/pipi/src/ipout.cpp b/practicas/pipi/src/ipout.cpp index 9c6d705..c98c4b5 100644 --- a/practicas/pipi/src/ipout.cpp +++ b/practicas/pipi/src/ipout.cpp @@ -34,17 +34,6 @@ bool IPOut::send(const std::string& data, uint8_t proto, IPAddr dst, IPAddr src, bool df, uint8_t ttl, uint16_t id) throw (std::runtime_error) { - // Mando todo lo que tengo para forwardear - while (to_forward()) - { - std::string buf = forward_que.receive(); - IPHeader iph(buf); -#ifdef DEBUG - std::cout << "IPOut::send (" << ip << "): A forwardear\n"; -#endif - send(iph, buf.substr(iph.header_len())); - } - // Mando el paquete en sí // Armamos cabecera if (!src) src = ip; @@ -52,6 +41,7 @@ bool IPOut::send(const std::string& data, uint8_t proto, IPAddr dst, IPAddr src, id = get_id(); IPHeader iph(4, IPHeader::header_len() + data.size(), id, df, 0, 0, ttl, proto, src, dst); + // Enviamos return send(iph, data); } @@ -67,14 +57,14 @@ bool IPOut::send(IPHeader iph, std::string data) throw (std::runtime_error) return false; } // No quieren fragmentar - if (iph.df && (IPHeader::header_len() + data.size() > r->iface->mtu)) + if (iph.df && (IPHeader::header_len() + data.size() > r->mtu)) { // Silencioso drop("Tamaño de paquete más grande que MTU y DF=1", iph); return false; } // Fragmenta (de ser necesario) - int max_payload = r->iface->mtu - IPHeader::header_len(); + int max_payload = r->mtu - IPHeader::header_len(); int cant_frag = data.size() / max_payload; if (data.size() % max_payload) ++cant_frag; @@ -99,18 +89,28 @@ bool IPOut::send(IPHeader iph, std::string data) throw (std::runtime_error) return true; } -/// Obtiene un identificador para el paquete -uint16_t IPOut::get_id() const +/// Realiza el forwarding de paquetes (en un loop infinito) +void IPOut::forward_loop() + throw (std::runtime_error) { - return time(NULL); + while (true) + { + std::string buf = forward_que.receive(); + IPHeader iph(buf); +#ifdef DEBUG + std::cout << "IPOut::forward_loop (" << ip << "): A forwardear (id " + << iph.id << ")\n"; +#endif + send(iph, buf.substr(iph.header_len())); + } } -/// Se fija si hay paquetes a forwardear (y devuelve cuantos hay) -unsigned IPOut::to_forward() +/// Obtiene un identificador para el paquete +uint16_t IPOut::get_id() const { - struct msqid_ds minfo; - msgctl(forward_que.que_id, IPC_STAT, &minfo); - return minfo.msg_qnum; + static uint16_t st = time(NULL); + uint16_t tt = time(NULL); + return (tt == st) ? ++st : tt; } // vim: set et sw=4 sts=4 : diff --git a/practicas/pipi/src/ipout.h b/practicas/pipi/src/ipout.h index effe150..96cbbb6 100644 --- a/practicas/pipi/src/ipout.h +++ b/practicas/pipi/src/ipout.h @@ -40,6 +40,9 @@ struct IPOut /// Envía un paquete IP ya armado bool send(IPHeader iph, std::string data) throw (std::runtime_error); + /// Realiza el forwarding de paquetes (en un loop infinito) + void forward_loop() throw (std::runtime_error); + /// Obtiene un identificador para el paquete uint16_t get_id() const; diff --git a/practicas/pipi/src/routetable.cpp b/practicas/pipi/src/routetable.cpp index 3363952..40de2d3 100644 --- a/practicas/pipi/src/routetable.cpp +++ b/practicas/pipi/src/routetable.cpp @@ -7,9 +7,10 @@ RouteTable::RouteTable(Dev& default_iface): default_iface(default_iface) { } -void RouteTable::add(const IPAddr& net, const IPAddr& gw, unsigned metric, Dev& iface) +void RouteTable::add(const IPAddr& net, const IPAddr& gw, unsigned mtu, + unsigned metric, Dev& iface) { - table[net] = Route(gw, metric, iface); + table[net] = Route(gw, metric, mtu, iface); #ifdef DEBUG //std::cout << "Se agregó tabla para " << net << ": gw = " << gw // << ", metric = " << metric << "\n"; diff --git a/practicas/pipi/src/routetable.h b/practicas/pipi/src/routetable.h index 2fe1586..20f62e8 100644 --- a/practicas/pipi/src/routetable.h +++ b/practicas/pipi/src/routetable.h @@ -13,11 +13,12 @@ struct RouteTable struct Route { IPAddr gateway; + unsigned mtu; unsigned metric; Dev* iface; - Route(): gateway(0), metric(0), iface(0) {} - Route(const IPAddr& gateway, unsigned metric, Dev& iface): - gateway(gateway), metric(metric), iface(&iface) {} + Route(): gateway(0), mtu(0), metric(0), iface(0) {} + Route(const IPAddr& gateway, unsigned mtu, unsigned metric, Dev& iface): + gateway(gateway), mtu(mtu), metric(metric), iface(&iface) {} }; /// Tabla @@ -30,7 +31,7 @@ struct RouteTable RouteTable(Dev& default_iface); /// Agrega ruta - void add(const IPAddr& net, const IPAddr& gw, unsigned metric, Dev& iface); + void add(const IPAddr& net, const IPAddr& gw, unsigned mtu, unsigned metric, Dev& iface); /// Borra ruta void del(const IPAddr& net); diff --git a/practicas/pipi/src/test.sh b/practicas/pipi/src/test.sh index dafb6d2..c97dddd 100755 --- a/practicas/pipi/src/test.sh +++ b/practicas/pipi/src/test.sh @@ -1,28 +1,25 @@ -#!/bin/sh -# -# 10.10.10.1 ----- 10.10.10.5 ------ 10.10.10.4 ----- 10.10.10.2 +#!/bin/bash +# 35 28 25 +# 10.10.10.1 ------ 10.10.10.5 ------ 10.10.10.4 ------ 10.10.10.2 # | +# | 32 # | # 10.10.10.3 # # Host 10.10.10.1 -./test_ipin 10.10.10.5 25 1 1 & -echo 'Adios mundo cruel!!!' | ./test_ipout 10.10.10.1 10.10.10.3 25 \ - ../rutas_ejemplo/route_10.10.10.1.txt +(echo -e '10.10.10.3\nAdios mundo cruel!!!'; sleep 1) \ + | ./ip 10.10.10.1 0 0 ../rutas_ejemplo/route_10.10.10.1.txt & -# Router 10.10.10.5 -./test_ipin 10.10.10.5 25 1 1 & -echo | ./test_ipout 10.10.10.5 10.10.10.1 23 \ - ../rutas_ejemplo/route_10.10.10.5.txt +# Host 10.10.10.5 +(echo ; sleep 2) \ + | ./ip 10.10.10.5 1 1 ../rutas_ejemplo/route_10.10.10.5.txt & # Host 10.10.10.3 -./test_ipin 10.10.10.3 23 0 0 & -echo | ./test_ipout 10.10.10.3 10.10.10.5 25 \ - ../rutas_ejemplo/route_10.10.10.3.txt +(echo ; sleep 3) \ + | ./ip 10.10.10.3 0 0 ../rutas_ejemplo/route_10.10.10.3.txt & # Limpio -sleep 1 -killall test_ipin +sleep 4 ipcrm -Q 0x1abcdef1 -ipcrm -Q 0x1abcdef2 +ipcrm -Q 0x1abcdef0 diff --git a/practicas/pipi/src/test2.sh b/practicas/pipi/src/test2.sh index bf18238..cd60ac2 100755 --- a/practicas/pipi/src/test2.sh +++ b/practicas/pipi/src/test2.sh @@ -1,34 +1,30 @@ -#!/bin/sh -# -# 10.10.10.1 ----- 10.10.10.5 ------ 10.10.10.4 ----- 10.10.10.2 +#!/bin/bash +# 35 28 25 +# 10.10.10.1 ------ 10.10.10.5 ------ 10.10.10.4 ------ 10.10.10.2 # | +# | 32 # | # 10.10.10.3 # # Host 10.10.10.1 -./test_ipin 10.10.10.5 30 1 1 & -echo 'Adios mundo cruel!!!' \ - | ./test_ipout 10.10.10.1 10.10.10.2 30 \ - ../rutas_ejemplo/route_10.10.10.1.txt +(echo -e '10.10.10.2\nAdios mundo cruel!!!'; sleep 1) \ + | ./ip 10.10.10.1 0 0 ../rutas_ejemplo/route_10.10.10.1.txt & -# Router 10.10.10.5 -./test_ipin 10.10.10.5 30 1 1 & -echo | ./test_ipout 10.10.10.5 10.10.10.1 27 \ - ../rutas_ejemplo/route_10.10.10.5.txt +# Host 10.10.10.5 +(echo ; sleep 2) \ + | ./ip 10.10.10.5 1 1 ../rutas_ejemplo/route_10.10.10.5.txt & -# Router 10.10.10.4 -./test_ipin 10.10.10.4 27 1 1 & -echo | ./test_ipout 10.10.10.4 10.10.10.1 25 \ - ../rutas_ejemplo/route_10.10.10.4.txt +# Host 10.10.10.4 +(echo ; sleep 3) \ + | ./ip 10.10.10.4 1 1 ../rutas_ejemplo/route_10.10.10.4.txt & # Host 10.10.10.2 -./test_ipin 10.10.10.2 25 0 0 & -echo | ./test_ipout 10.10.10.2 10.10.10.1 25 \ - ../rutas_ejemplo/route_10.10.10.2.txt +(echo ; sleep 4) \ + | ./ip 10.10.10.2 0 0 ../rutas_ejemplo/route_10.10.10.2.txt & # Limpio -sleep 1 -killall test_ipin +sleep 5 ipcrm -Q 0x1abcdef1 -ipcrm -Q 0x1abcdef2 +ipcrm -Q 0x1abcdef0 + -- 2.43.0