X-Git-Url: https://git.llucax.com/z.facultad/75.74/practicos.git/blobdiff_plain/0a2739fe97762f57a80599ef170df98e07422a3d..6758589f5ff68b1775d5a83b01d7ac49f1b612ef:/practicas/pipi/src/ipout.cpp diff --git a/practicas/pipi/src/ipout.cpp b/practicas/pipi/src/ipout.cpp index e7e211b..6e0c807 100644 --- a/practicas/pipi/src/ipout.cpp +++ b/practicas/pipi/src/ipout.cpp @@ -2,10 +2,18 @@ #include "ipout.h" #include "ipheader.h" #include +#include +#include +#include +#include +#include +#ifdef DEBUG +#include +#endif /// Constructor -IPOut::IPOut(const IPAddr& ip, RouteTable& rtable, std::ostream& log): - ip(ip), rtable(rtable), log(log) +IPOut::IPOut(const IPAddr& ip, RouteTable& rtable, Dev& forward_que, std::ostream& log): + ip(ip), rtable(rtable), forward_que(forward_que), log(log) { } @@ -24,6 +32,17 @@ 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: A forwardear\n"; +#endif + send(iph, buf.substr(iph.header_len())); + } + // Mando el paquete en sí // Armamos cabecera if (!src) src = ip; @@ -31,15 +50,21 @@ 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); + return send(iph, data); +} + +/// Envía un paquete IP +bool IPOut::send(IPHeader iph, std::string data) throw (std::runtime_error) +{ // Buscamos ruta - RouteTable::Route* r = rtable.get(dst); + RouteTable::Route* r = rtable.get(iph.dst); if (!r) { drop("No existe una ruta para el destino", iph); return false; } // No quieren fragmentar - if (df && (IPHeader::header_len() + data.size() > r->iface->mtu)) + if (iph.df && (IPHeader::header_len() + data.size() > r->iface->mtu)) { drop("Tamaño de paquete más grande que MTU y DF=1", iph); return false; @@ -60,10 +85,11 @@ bool IPOut::send(const std::string& data, uint8_t proto, IPAddr dst, IPAddr src, std::string buf((char*) &iph2, sizeof(IPHeader)); buf += data.substr(i * max_payload, max_payload); #ifdef DEBUG - log << "IPOut::send: Fragmento 0 => IPHeader: " << iph2 << "\n"; - log << "\tbuf (" << buf.size() << ") = " << buf << "\n"; + std::cout << "IPOut::send: Fragmento 0 => IPHeader: " << iph2 << "\n"; + std::string tmp = data.substr(i * max_payload, max_payload); + std::cout << "\tdata (" << tmp.size() << ") = " << tmp << "\n"; #endif - r->iface->transmit(buf, r->gateway ? r->gateway : dst); + r->iface->transmit(buf, r->gateway ? r->gateway : IPAddr(iph.dst)); } return true; } @@ -74,4 +100,12 @@ uint16_t IPOut::get_id() const return time(NULL); } +/// Se fija si hay paquetes a forwardear (y devuelve cuantos hay) +unsigned IPOut::to_forward() +{ + struct msqid_ds minfo; + msgctl(forward_que.que_id, IPC_STAT, &minfo); + return minfo.msg_qnum; +} + // vim: set et sw=4 sts=4 :