X-Git-Url: https://git.llucax.com/z.facultad/75.74/practicos.git/blobdiff_plain/e90dc82d43fa53ae404e8f525bc02439fc2e3db4..78d6e1ce97611abe9f0d083033197773f93c33f7:/practicas/pipi/src/ipin.cpp diff --git a/practicas/pipi/src/ipin.cpp b/practicas/pipi/src/ipin.cpp index b5d346f..1ff0560 100644 --- a/practicas/pipi/src/ipin.cpp +++ b/practicas/pipi/src/ipin.cpp @@ -1,24 +1,34 @@ #include "ipin.h" #include "ipheader.h" +#ifdef DEBUG +#include +#endif /// Constructor -IPIn::IPIn(const IPAddr& ip, Dev& dev, std::ostream& log): - ip(ip), dev(dev), log(log) -{} +IPIn::IPIn(const IPAddr& ip, Dev& dev, Dev& forward_que, bool router, + bool forward, std::ostream& log): + ip(ip), dev(dev), forward_que(forward_que), router(router), + forward(forward), log(log) +{ + if (router) forward = true; +} 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) { @@ -26,38 +36,78 @@ 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"; + std::cout << "IPIn::recv (" << ip << "): IPHeader: " << iph << "\n"; + std::string tmp = buf.substr(iph.header_len()); + 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; } - // TODO forwarding (ponerlo en una cola para el proceso que manda) - if (iph.dst != ip) + // 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; } - //TODO a un buffer - if (iph.proto != proto) + // No es para nosotros pero forwardeamos + else if (iph.dst != ip) { - drop("No es el protocolo pedido", iph); + forward_que.transmit(buf, ip); continue; } + // 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, sigo + if (iph.mf) + continue; + // No hay más fragmentos, reensamblamos (de ser necesario) + std::string data; + for (offsetmap_type::iterator i = buffer[iph].begin(); + i != buffer[iph].end(); ++i) + { + //TODO chequear que los fragmentos estén todos + data += i->second; + } +#ifdef DEBUG + 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; - std::string data = buf.substr(iph.header_len()); + proto = iph.proto; return data; } }