From 093ef819f410add240cf97b72f9e7dcab5abd16c Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Fri, 2 Jun 2006 06:06:37 +0000 Subject: [PATCH] Forwarding casi implementado. Hay un bug cuando se usan distintos MTU que hay que resolver. Probablemente venga por un problema con la cola que se usa para pasar los paquetes a forwardear de un proceso a otro (IPIn a IPOut). --- practicas/pipi/rutas_ejemplo/route.txt | 3 ++ .../pipi/rutas_ejemplo/route_10.10.10.1.txt | 4 ++ .../pipi/rutas_ejemplo/route_10.10.10.2.txt | 4 ++ .../pipi/rutas_ejemplo/route_10.10.10.3.txt | 4 ++ .../pipi/rutas_ejemplo/route_10.10.10.5.txt | 4 ++ practicas/pipi/src/Makefile | 14 ++++- practicas/pipi/src/ipaddr.cpp | 6 +++ practicas/pipi/src/ipaddr.h | 3 ++ practicas/pipi/src/ipin.cpp | 27 ++++++++-- practicas/pipi/src/ipin.h | 12 ++++- practicas/pipi/src/ipout.cpp | 40 ++++++++++++-- practicas/pipi/src/ipout.h | 14 ++++- practicas/pipi/src/routetable.cpp | 7 +++ practicas/pipi/src/test_ipin.cpp | 17 ++++-- practicas/pipi/src/test_ipout.cpp | 52 ++++++++++++++----- 15 files changed, 179 insertions(+), 32 deletions(-) create mode 100644 practicas/pipi/rutas_ejemplo/route.txt create mode 100644 practicas/pipi/rutas_ejemplo/route_10.10.10.1.txt create mode 100644 practicas/pipi/rutas_ejemplo/route_10.10.10.2.txt create mode 100644 practicas/pipi/rutas_ejemplo/route_10.10.10.3.txt create mode 100644 practicas/pipi/rutas_ejemplo/route_10.10.10.5.txt diff --git a/practicas/pipi/rutas_ejemplo/route.txt b/practicas/pipi/rutas_ejemplo/route.txt new file mode 100644 index 0000000..3aae5e1 --- /dev/null +++ b/practicas/pipi/rutas_ejemplo/route.txt @@ -0,0 +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 diff --git a/practicas/pipi/rutas_ejemplo/route_10.10.10.1.txt b/practicas/pipi/rutas_ejemplo/route_10.10.10.1.txt new file mode 100644 index 0000000..cc877c8 --- /dev/null +++ b/practicas/pipi/rutas_ejemplo/route_10.10.10.1.txt @@ -0,0 +1,4 @@ +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 diff --git a/practicas/pipi/rutas_ejemplo/route_10.10.10.2.txt b/practicas/pipi/rutas_ejemplo/route_10.10.10.2.txt new file mode 100644 index 0000000..cc877c8 --- /dev/null +++ b/practicas/pipi/rutas_ejemplo/route_10.10.10.2.txt @@ -0,0 +1,4 @@ +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 diff --git a/practicas/pipi/rutas_ejemplo/route_10.10.10.3.txt b/practicas/pipi/rutas_ejemplo/route_10.10.10.3.txt new file mode 100644 index 0000000..11ff580 --- /dev/null +++ b/practicas/pipi/rutas_ejemplo/route_10.10.10.3.txt @@ -0,0 +1,4 @@ +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 diff --git a/practicas/pipi/rutas_ejemplo/route_10.10.10.5.txt b/practicas/pipi/rutas_ejemplo/route_10.10.10.5.txt new file mode 100644 index 0000000..d57116e --- /dev/null +++ b/practicas/pipi/rutas_ejemplo/route_10.10.10.5.txt @@ -0,0 +1,4 @@ +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 diff --git a/practicas/pipi/src/Makefile b/practicas/pipi/src/Makefile index a1538a7..58539ef 100644 --- a/practicas/pipi/src/Makefile +++ b/practicas/pipi/src/Makefile @@ -54,7 +54,7 @@ depend: @makedepend $(fuentes) > /dev/null 2>&1 clean: - @$(RM) -fv *.o $(targets) + @$(RM) -fv *.o Makefile.bak $(targets) # DO NOT DELETE @@ -83,6 +83,18 @@ ipout.o: ipout.h ipaddr.h ipheader.h /usr/include/stdint.h ipout.o: /usr/include/features.h /usr/include/sys/cdefs.h ipout.o: /usr/include/gnu/stubs.h /usr/include/bits/wchar.h ipout.o: /usr/include/bits/wordsize.h routetable.h dev.h +ipout.o: /usr/include/unistd.h /usr/include/bits/posix_opt.h +ipout.o: /usr/include/bits/types.h /usr/include/bits/typesizes.h +ipout.o: /usr/include/bits/confname.h /usr/include/getopt.h +ipout.o: /usr/include/fcntl.h /usr/include/bits/fcntl.h +ipout.o: /usr/include/sys/types.h /usr/include/time.h /usr/include/endian.h +ipout.o: /usr/include/bits/endian.h /usr/include/sys/select.h +ipout.o: /usr/include/bits/select.h /usr/include/bits/sigset.h +ipout.o: /usr/include/bits/time.h /usr/include/sys/sysmacros.h +ipout.o: /usr/include/bits/pthreadtypes.h /usr/include/bits/sched.h +ipout.o: /usr/include/sys/ipc.h /usr/include/bits/ipctypes.h +ipout.o: /usr/include/bits/ipc.h /usr/include/sys/msg.h +ipout.o: /usr/include/bits/msq.h routetable.o: routetable.h dev.h ipaddr.h test_ipaddr.o: ipaddr.h ipheader.h /usr/include/stdint.h test_ipaddr.o: /usr/include/features.h /usr/include/sys/cdefs.h diff --git a/practicas/pipi/src/ipaddr.cpp b/practicas/pipi/src/ipaddr.cpp index 1cdd573..7b153b2 100644 --- a/practicas/pipi/src/ipaddr.cpp +++ b/practicas/pipi/src/ipaddr.cpp @@ -42,6 +42,12 @@ IPAddr::IPAddr(const char* ip) throw (std::logic_error) } } +/// Constructor +//IPAddr::IPAddr(const std::string& ip) throw (std::logic_error) +//{ +// IPAddr(ip.c_str()); +//} + /// Operador de casteo a unsigned IPAddr::operator unsigned () const { diff --git a/practicas/pipi/src/ipaddr.h b/practicas/pipi/src/ipaddr.h index 19197a1..0c0c549 100644 --- a/practicas/pipi/src/ipaddr.h +++ b/practicas/pipi/src/ipaddr.h @@ -27,6 +27,9 @@ struct IPAddr /// Constructor IPAddr(const char* ip) throw (std::logic_error); + /// Constructor + //IPAddr(const std::string& ip) throw (std::logic_error); + /// Operador de casteo a unsigned operator unsigned () const; diff --git a/practicas/pipi/src/ipin.cpp b/practicas/pipi/src/ipin.cpp index 2d94158..a9029c6 100644 --- a/practicas/pipi/src/ipin.cpp +++ b/practicas/pipi/src/ipin.cpp @@ -3,9 +3,13 @@ #include "ipheader.h" /// 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) { @@ -43,12 +47,25 @@ std::string IPIn::recv(uint8_t proto, IPAddr& src, IPAddr& dst) throw (std::runt drop("Mal checksum", iph); continue; } - //TODO forwarding (ponerlo en una cola para el proceso que manda) - if (iph.dst != ip) + // No es para nosotros y no forwardeamos + if (iph.dst != ip && !forward) { drop("No es para nosotros y no hacemos forward", iph); continue; } + // No es para nosotros pero forwardeamos + else if (iph.dst != ip) + { + forward_que.transmit(buf, ip); + continue; + } + // Es para nosotros pero somos router + else if (router) + { + 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 diff --git a/practicas/pipi/src/ipin.h b/practicas/pipi/src/ipin.h index 5d0d7a8..8620278 100644 --- a/practicas/pipi/src/ipin.h +++ b/practicas/pipi/src/ipin.h @@ -19,6 +19,15 @@ struct IPIn /// Dispositivo de red Dev& dev; + /// Cola para forwardear paquetes + Dev& forward_que; + + /// Indica si es un router + bool router; + + /// Indica si hace forwarding + bool forward; + /// Dispositivo de logging std::ostream& log; @@ -39,7 +48,8 @@ struct IPIn buffer_type buffer; /// Constructor - IPIn(const IPAddr& ip, Dev& dev, std::ostream& log = std::cout); + IPIn(const IPAddr& ip, Dev& dev, Dev& forward_que, bool router = false, + bool forward = false, std::ostream& log = std::cout); /// Descarta un paquete void drop(const std::string& msg, const std::string& buf); diff --git a/practicas/pipi/src/ipout.cpp b/practicas/pipi/src/ipout.cpp index e7e211b..cf5c28c 100644 --- a/practicas/pipi/src/ipout.cpp +++ b/practicas/pipi/src/ipout.cpp @@ -2,10 +2,15 @@ #include "ipout.h" #include "ipheader.h" #include +#include +#include +#include +#include +#include /// 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 +29,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 + log << "IPOut::send: A forwardear => IPHeader: " << iph << "\n"; +#endif + send(iph, buf.substr(iph.header_len())); + } + // Mando el paquete en sí // Armamos cabecera if (!src) src = ip; @@ -31,15 +47,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; @@ -63,7 +85,7 @@ bool IPOut::send(const std::string& data, uint8_t proto, IPAddr dst, IPAddr src, log << "IPOut::send: Fragmento 0 => IPHeader: " << iph2 << "\n"; log << "\tbuf (" << buf.size() << ") = " << buf << "\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 +96,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 : diff --git a/practicas/pipi/src/ipout.h b/practicas/pipi/src/ipout.h index ae88509..effe150 100644 --- a/practicas/pipi/src/ipout.h +++ b/practicas/pipi/src/ipout.h @@ -18,24 +18,34 @@ struct IPOut /// Dispositivo de logging RouteTable& rtable; + /// Cola para forwardear paquetes + Dev& forward_que; + /// Dispositivo de logging std::ostream& log; /// Constructor - IPOut(const IPAddr& ip, RouteTable& rtable, std::ostream& log = std::cout); + IPOut(const IPAddr& ip, RouteTable& rtable, Dev& forward_que, + std::ostream& log = std::cout); /// Descarta un paquete void drop(const std::string& msg, const std::string& buf); void drop(const std::string& msg, const IPHeader& iph); - /// Envía un paquete IP + /// Envía un paquete IP a armar (y forwardea los encolados, de haber) bool send(const std::string& data, uint8_t proto, IPAddr dst, IPAddr src = 0, bool df = 0, uint8_t ttl = 64, uint16_t id = 0) throw (std::runtime_error); + /// Envía un paquete IP ya armado + bool send(IPHeader iph, std::string data) throw (std::runtime_error); + /// Obtiene un identificador para el paquete uint16_t get_id() const; + /// Se fija si hay paquetes a forwardear (y devuelve cuantos hay) + unsigned to_forward(); + // Nada de andar copiando... private: IPOut(const IPOut&); diff --git a/practicas/pipi/src/routetable.cpp b/practicas/pipi/src/routetable.cpp index 66ccd80..4a043cd 100644 --- a/practicas/pipi/src/routetable.cpp +++ b/practicas/pipi/src/routetable.cpp @@ -1,4 +1,7 @@ #include "routetable.h" +#ifdef DEBUG +#include +#endif RouteTable::RouteTable(Dev& default_iface): default_iface(default_iface) { @@ -7,6 +10,10 @@ RouteTable::RouteTable(Dev& default_iface): default_iface(default_iface) void RouteTable::add(const IPAddr& net, const IPAddr& gw, unsigned metric, Dev& iface) { table[net] = Route(gw, metric, iface); +#ifdef DEBUG + std::cout << "Se agregó tabla para " << net << ": gw = " << gw + << ", metric = " << metric << "\n"; +#endif } void RouteTable::del(const IPAddr& net) diff --git a/practicas/pipi/src/test_ipin.cpp b/practicas/pipi/src/test_ipin.cpp index 01b19aa..a3c8e5f 100644 --- a/practicas/pipi/src/test_ipin.cpp +++ b/practicas/pipi/src/test_ipin.cpp @@ -10,12 +10,14 @@ #include #include -// Uso: ./test_ipin ip mtu proto queue_id +// Uso: ./test_ipin ip mtu router forward proto queue_id int main(int argc, char* argv[]) { IPAddr addr("10.10.10.1"); unsigned mtu = 25; + bool router = false; + bool forward = false; unsigned proto = 0; key_t queue_id = DEV_DEFAULT_KEY; if (argc > 1) @@ -23,11 +25,18 @@ int main(int argc, char* argv[]) if (argc > 2) mtu = atoi(argv[2]); if (argc > 3) - proto = atoi(argv[3]); + router = atoi(argv[3]); if (argc > 4) - queue_id = atoi(argv[4]); + forward = atoi(argv[4]); + if (argc > 5) + proto = atoi(argv[5]); + if (argc > 6) + queue_id = atoi(argv[6]); Dev dev(addr, mtu, queue_id); - IPIn ipin(addr, dev); + int que_id = msgget(queue_id+1, IPC_CREAT | 0666); + assert(que_id != -1); + Dev fwque(addr, mtu, queue_id+1); + IPIn ipin(addr, dev, fwque, router, forward); struct msqid_ds minfo; for (msgctl(dev.que_id, IPC_STAT, &minfo); minfo.msg_qnum; msgctl(dev.que_id, IPC_STAT, &minfo)) diff --git a/practicas/pipi/src/test_ipout.cpp b/practicas/pipi/src/test_ipout.cpp index acdb77f..ec4430f 100644 --- a/practicas/pipi/src/test_ipout.cpp +++ b/practicas/pipi/src/test_ipout.cpp @@ -4,6 +4,8 @@ #include "routetable.h" #include "dev.h" #include +#include +#include #include #include #include @@ -12,41 +14,63 @@ #include #include -// Uso: ./test_ipout ip dst msg mtu proto queue_id +// Uso: ./test_ipout ip dst mtu routes_file proto queue_id + +void add_routes(RouteTable& rt, std::istream& is, Dev& dev); int main(int argc, char* argv[]) { IPAddr addr("10.10.10.2"); IPAddr dst("10.10.10.1"); - std::string msg = "hola mundo"; unsigned mtu = 25; unsigned proto = 0; key_t queue_id = DEV_DEFAULT_KEY; + std::string fname = "route.txt"; if (argc > 1) addr = IPAddr(argv[1]); if (argc > 2) dst = IPAddr(argv[2]); if (argc > 3) - msg = argv[3]; + mtu = atoi(argv[3]); if (argc > 4) - mtu = atoi(argv[4]); + fname = argv[4]; if (argc > 5) proto = atoi(argv[5]); if (argc > 6) queue_id = atoi(argv[6]); - int que_id = msgget(queue_id, IPC_CREAT | 0666); - assert(que_id != -1); + int que_id = msgget(queue_id, IPC_CREAT | 0666); assert(que_id != -1); + que_id = msgget(queue_id+1, IPC_CREAT | 0666); assert(que_id != -1); + std::ifstream ifs(fname.c_str()); assert(ifs); Dev dev(addr, mtu, queue_id); + Dev fwque(addr, mtu, queue_id+1); RouteTable table(dev); - table.add("10.10.10.1", 0, 0, dev); - table.add("10.10.10.2", 0, 0, dev); - table.add("10.10.10.3", "10.10.10.10", 0, dev); - IPOut ipout(addr, table); - if (ipout.send(msg, proto, dst)) - std::cout << "Enviado '" << msg << "' a " << dst << "\n"; - else - std::cout << "NO SE PUDO ENVIAR '" << msg << "' a " << dst << "\n"; + add_routes(table, ifs, dev); + IPOut ipout(addr, table, fwque); + std::string msg; + while (std::getline(std::cin, msg)) + { + if (ipout.send(msg, proto, dst)) + std::cout << "Enviado '" << msg << "' a " << dst << "\n"; + else + std::cout << "NO SE PUDO ENVIAR '" << msg << "' a " << dst << "\n"; + } return 0; } +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 metric; + iss >> net >> gw >> 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, dev); + } +} + // vim: set et sw=4 sts=4 : -- 2.43.0