1 ===============================
2 Sistemas Distribuidos I (75.74)
3 ===============================
5 ----------------------------
6 Trabajo práctico de stack IP
7 ----------------------------
9 :Author: Leandro Lucarella (77891)
15 En el directorio `src` se encuentra el código fuente del trabajo, con su
16 correspondiente `Makefile` para compilarlo tan solo ejecutando `make`.
18 En el directorio `rutas_ejemplo` contiene algunos archivos con descripciones de
19 rutas de ejemplo para correr los programas.
25 El trabajo tiene 2 programas de prueba principales: `test_ipin` y `test_ipout`,
26 ambos generados en el directorio `src` luego de compilar el código.
31 Este programa es el proceso que recibe paquetes IP y los procesa.
35 ./test_ipin [ip] [mtu] [router] [forward] [proto] [queue_id]
38 IP que utiliza este proceso (default 10.10.10.1)
41 MTU de la capa física de este proceso (default 25)
44 0 si es router, 1 si no lo es (default 0)
47 0 si puede hacer forwarding, 1 si no (default 0)
50 Protocolo que transporta (default 0)
53 Identificador de la cola a usar como medio físico, también establece el
54 identificador de la cola a usar para comunicarse con el otro proceso
55 (`test_ipout`) para hacer forwarding, que será queue_id + 1 (default
56 `DEV_DEFAULT_KEY` obtenido de `dev.h`)
62 Este programa es el proceso que envía paquetes IP y rutea.
66 ./test_ipout [ip] [dst] [mtu] [routes_file] [proto] [queue_id]
69 IP que utiliza este proceso (default 10.10.10.2)
72 IP del destino al cual mandar paquetes (default 10.10.10.1)
75 MTU de la capa física de este proceso (default 25)
78 Archivo con las rutas. El formato del archivo es una ruta por línea, cada
79 línea se compone de red (por ahora sólo soporta IPs puntuales), gateway (si es
80 cero es que están en la misma red) y métrica (todavía no se usa), separados
81 por uno o más espacios o tabs (default `route.txt`)
84 Protocolo que transporta (default 0)
87 Identificador de la cola a usar como medio físico, también establece el
88 identificador de la cola a usar para comunicarse con el otro proceso
89 (`test_ipout`) para hacer forwarding, que será queue_id + 1 (default
90 `DEV_DEFAULT_KEY` obtenido de `dev.h`)
96 El trabajo fue desarrollado en C++, orientado a objetos. Se compone de las
100 Encapsula la capa física y el dispositivo de red. Utiliza una cola como medio
101 físico y el id representaría el cable (si 2 dispositivos tienen cola con id
102 distinto serían como si no compartieran el mismo cable). Por simplicidad a la
103 cola siempre se envía el tamaño del MTU completo pero se agrega una cabecera
104 con el tamaño real del frame.
107 Clase auxiliar que encapsula una dirección IP.
110 Encapsula una cabecera IP. El cálculo de checksum se simplificó (haciendo una
111 suma byte a byte de toda la cabecera) porque cumple con el objetivo didactico
115 Encapsula una tabla de ruteo. Por falta de tiempo y simplicidad por ahora sólo
116 soporta rutas a un sólo host (no a una red) pero es muy fácilmente extensible
117 y transparente para el resto de las clases que la usan. Las rutas se componen
118 de red (en realidad por ahora host), geteway, metrica y dispositivo de red por
122 Es la clase encargada de recibir paquetes IP. Hace chequeos varios y descarta
123 paquetes según los siguientes criterios:
125 * Cabecera incompleta o no es IP
126 * Versión IP incorrecta
128 * No es para nosotros y no hacemos forward
129 * Es para nosotros pero somos un router
131 Si hace forwarding le pasa a IPOut el paquete por una cola y reensabla de ser
135 Es la clase encargada de enviar paquetes IP. Tiene una RouteTable para hacer
136 el ruteo y verifica si hay paquetes a forwardear antes de enviar lo que le
137 piden. También fragmenta y puede "descartar" paquetes según estos criterios:
139 * No existe una ruta para el destino
140 * Tamaño de paquete más grande que MTU y DF=1
151 * 10.10.10.1 0.0.0.0 0
152 * 10.10.10.3 10.10.10.5 0
153 * 10.10.10.5 0.0.0.0 0
155 Envía "adios mundo cruel!!!" al host 10.10.10.3::
157 $ ./test_ipout 10.10.10.1 10.10.10.3 25 ../rutas_ejemplo/route_10.10.10.1.txt
158 Se agregó tabla para 10.10.10.1: gw = 0.0.0.0, metric = 0
159 Se agregó tabla para 10.10.10.2: gw = 0.0.0.0, metric = 0
160 Se agregó tabla para 10.10.10.3: gw = 10.10.10.5, metric = 0
161 Se agregó tabla para 10.10.10.5: gw = 0.0.0.0, metric = 0
163 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
165 Dev::transmit(msgtype/mac = 168430085, size = 25)
166 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
168 Dev::transmit(msgtype/mac = 168430085, size = 25)
169 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
171 Dev::transmit(msgtype/mac = 168430085, size = 25)
172 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
174 Dev::transmit(msgtype/mac = 168430085, size = 25)
175 Enviado 'adios mundo cruel!!!' a 10.10.10.3
177 El proceso test_ipin de este host no tiene relevancia.
184 * 10.10.10.1 0.0.0.0 0
185 * 10.10.10.3 0.0.0.0 0
186 * 10.10.10.5 0.0.0.0 0
190 $ ./test_ipin 10.10.10.5 25 1 1
191 Quedan 4 mensajes en la cola
192 Dev::receive(msgtype/mac = 168430085, size = 25)
193 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
195 Dev::transmit(msgtype/mac = 168430085, size = 25)
196 Dev::receive(msgtype/mac = 168430085, size = 25)
197 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
199 Dev::transmit(msgtype/mac = 168430085, size = 25)
200 Dev::receive(msgtype/mac = 168430085, size = 25)
201 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
203 Dev::transmit(msgtype/mac = 168430085, size = 25)
204 Dev::receive(msgtype/mac = 168430085, size = 25)
205 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
207 Dev::transmit(msgtype/mac = 168430085, size = 25)
209 Y lo forwardea (refragmentando porque tiene un MTU más pequeño)::
211 $ ./test_ipout 10.10.10.5 10.10.10.1 23 ../rutas_ejemplo/route_10.10.10.5.txt
212 Se agregó tabla para 10.10.10.1: gw = 0.0.0.0, metric = 0
213 Se agregó tabla para 10.10.10.2: gw = 0.0.0.0, metric = 0
214 Se agregó tabla para 10.10.10.3: gw = 0.0.0.0, metric = 0
215 Se agregó tabla para 10.10.10.5: gw = 0.0.0.0, metric = 0
217 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
219 Dev::transmit(msgtype/mac = 168430081, size = 21)
220 Enviado 'a' a 10.10.10.1
222 Dev::receive(msgtype/mac = 168430085, size = 25)
223 IPOut::send: A forwardear
224 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
226 Dev::transmit(msgtype/mac = 168430083, size = 23)
227 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
229 Dev::transmit(msgtype/mac = 168430083, size = 22)
230 Dev::receive(msgtype/mac = 168430085, size = 25)
231 IPOut::send: A forwardear
232 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
234 Dev::transmit(msgtype/mac = 168430083, size = 23)
235 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
237 Dev::transmit(msgtype/mac = 168430083, size = 22)
238 Dev::receive(msgtype/mac = 168430085, size = 25)
239 IPOut::send: A forwardear
240 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
242 Dev::transmit(msgtype/mac = 168430083, size = 23)
243 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
245 Dev::transmit(msgtype/mac = 168430083, size = 22)
246 Dev::receive(msgtype/mac = 168430085, size = 25)
247 IPOut::send: A forwardear
248 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
250 Dev::transmit(msgtype/mac = 168430083, size = 23)
251 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
253 Dev::transmit(msgtype/mac = 168430083, size = 22)
254 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
256 Dev::transmit(msgtype/mac = 168430081, size = 21)
257 Enviado 'a' a 10.10.10.1
259 (notar que para que haga el forwarding se tuvo que enviar un paquete
260 *dummy* para que busque en la cola de paquetes a forwardear (es un error
261 de diseño que tendré que corregir de alguna forma)
268 * 10.10.10.1 10.10.10.5 0
269 * 10.10.10.3 0.0.0.0 0
270 * 10.10.10.5 0.0.0.0 0
272 Finalmente este host recibe todos los fragmentos, reensabla y pasa el
273 paquete completo a la capa superior::
275 $ ./test_ipin 10.10.10.3 23
276 Quedan 8 mensajes en la cola
277 Dev::receive(msgtype/mac = 168430083, size = 23)
278 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
280 Dev::receive(msgtype/mac = 168430083, size = 22)
281 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
283 Dev::receive(msgtype/mac = 168430083, size = 23)
284 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
286 Dev::receive(msgtype/mac = 168430083, size = 22)
287 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
289 Dev::receive(msgtype/mac = 168430083, size = 23)
290 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
292 Dev::receive(msgtype/mac = 168430083, size = 22)
293 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
295 Dev::receive(msgtype/mac = 168430083, size = 23)
296 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
298 Dev::receive(msgtype/mac = 168430083, size = 22)
299 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
301 IPIn::recv: Paquete completo: data = 'adios mundo cruel!!!'
302 Recibido 'adios mundo cruel!!!' (len 20) de 10.10.10.1 para 10.10.10.3 (proto = 0)
304 El proceso test_ipout de este host no tiene relevancia.
307 .. vim: filetype=rst :