]> git.llucax.com Git - z.facultad/75.74/practicos.git/blobdiff - practicas/pipi/src/ipin.cpp
Se verifica si expiró el cache y se lo elimina si así fuere.
[z.facultad/75.74/practicos.git] / practicas / pipi / src / ipin.cpp
index 55bc85626cf086b438b1c4b7cd1a8e591a268b06..7cb5abcfb95b42404fda0979ffe1721aa1126d84 100644 (file)
@@ -1,6 +1,9 @@
 
 #include "ipin.h"
 #include "ipheader.h"
+#ifdef DEBUG
+#include <iostream>
+#endif
 
 /// Constructor
 IPIn::IPIn(const IPAddr& ip, Dev& dev, Dev& forward_que, bool router,
@@ -13,16 +16,19 @@ IPIn::IPIn(const IPAddr& ip, Dev& dev, Dev& forward_que, bool router,
 
 void IPIn::drop(const std::string& msg, const std::string& buf)
 {
-    log << "IPIn::drop: " << msg << "\n\tBuffer: " << buf << "\n";
+    log << "IPIn::drop (" << ip << "): " << msg << "\n\tBuffer: " << buf
+            << "\n";
 }
 
 void IPIn::drop(const std::string& msg, const IPHeader& iph)
 {
-    log << "IPIn::drop: " << msg << "\n\tIPHeader: " << iph << "\n";
+    log << "IPIn::drop (" << ip << "): " << msg << "\n\tIPHeader: " << iph
+            << "\n";
 }
 
 /// Recibe un paquete IP
-std::string IPIn::recv(uint8_t proto, IPAddr& src, IPAddr& dst) throw (std::runtime_error)
+std::string IPIn::recv(uint8_t& proto, IPAddr& src, IPAddr& dst)
+    throw (std::runtime_error)
 {
     while (true)
     {
@@ -30,28 +36,39 @@ std::string IPIn::recv(uint8_t proto, IPAddr& src, IPAddr& dst) throw (std::runt
         // No es siquiera IP
         if (buf.size() < IPHeader::header_len())
         {
+            // Silencioso
             drop("Cabecera incompleta o no es IP", buf);
             continue;
         }
         IPHeader iph(buf);
-#ifdef DEBUG
-        log << "IPIn::recv: IPHeader: " << iph << "\n";
+#ifdef DEBUG_IP
+        std::cout << "IPIn::recv (" << ip << "): IPHeader: " << iph << "\n";
         std::string tmp = buf.substr(iph.header_len());
-        log << "\tdata (" << tmp.size() << ") = " << tmp << "\n";
+        std::cout << "\tdata (" << tmp.size() << ") = " << tmp << "\n";
 #endif
         if (iph.version != 4)
         {
+            // Silencioso
             drop("Versión IP incorrecta", iph);
             continue;
         }
         if (!iph.check_checksum())
         {
+            // Silencioso
             drop("Mal checksum", iph);
             continue;
         }
+        // Si el TTL se va a 0
+        if (!--iph.ttl)
+        {
+            // ICMP
+            drop("TTL == 0 -> ICMP", iph);
+            continue;
+        }
         // No es para nosotros y no forwardeamos
         if (iph.dst != ip && !forward)
         {
+            // Silencioso
             drop("No es para nosotros y no hacemos forward", iph);
             continue;
         }
@@ -64,14 +81,15 @@ std::string IPIn::recv(uint8_t proto, IPAddr& src, IPAddr& dst) throw (std::runt
         // Es para nosotros pero somos router
         else if (router)
         {
+            // Silencioso
             drop("Es para nosotros pero somos un router", iph);
             continue;
         }
         // Es para nosotros y somos un host
         // Guarda en buffer
         buffer[iph][iph.offset] = buf.substr(iph.header_len());
-        // Si tiene más fragmentos o es un protocolo distinto, sigo
-        if (iph.mf || (iph.proto != proto))
+        // Si tiene más fragmentos, sigo
+        if (iph.mf)
             continue;
         // No hay más fragmentos, reensamblamos (de ser necesario)
         std::string data;
@@ -81,13 +99,15 @@ std::string IPIn::recv(uint8_t proto, IPAddr& src, IPAddr& dst) throw (std::runt
             //TODO chequear que los fragmentos estén todos
             data += i->second;
         }
-#ifdef DEBUG
-        log << "IPIn::recv: Paquete completo: data = '" << data << "'\n";
+#ifdef DEBUG_IP
+        std::cout << "IPIn::recv (" << ip << "): Paquete completo: data = '"
+                << data << "'\n";
 #endif
         buffer.erase(iph);
         //TODO faltaría limpiar fragmentos viejos cada tanto (timer?)
         src = iph.src;
         dst = iph.dst;
+        proto = iph.proto;
         return data;
     }
 }