From: Leandro Lucarella Date: Fri, 2 Jun 2006 02:15:07 +0000 (+0000) Subject: Ruteo básico aparentemente andando. Se parametrizan las pruebas para poder X-Git-Tag: svn_import~61 X-Git-Url: https://git.llucax.com/z.facultad/75.74/practicos.git/commitdiff_plain/0a2739fe97762f57a80599ef170df98e07422a3d Ruteo básico aparentemente andando. Se parametrizan las pruebas para poder cambiar algunas cosas via línea de comandos. --- diff --git a/practicas/pipi/src/Makefile b/practicas/pipi/src/Makefile index 50224e2..a1538a7 100644 --- a/practicas/pipi/src/Makefile +++ b/practicas/pipi/src/Makefile @@ -48,7 +48,7 @@ test_ipaddr: test_ipaddr.o ipaddr.o ipheader.o test_ipin: test_ipin.o ipin.o ipaddr.o ipheader.o dev.o -test_ipout: test_ipout.o ipout.o ipaddr.o ipheader.o dev.o +test_ipout: test_ipout.o ipout.o ipaddr.o ipheader.o dev.o routetable.o depend: @makedepend $(fuentes) > /dev/null 2>&1 @@ -82,7 +82,8 @@ ipin.o: /usr/include/bits/wordsize.h dev.h 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 dev.h +ipout.o: /usr/include/bits/wordsize.h routetable.h dev.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 test_ipaddr.o: /usr/include/gnu/stubs.h /usr/include/bits/wchar.h @@ -106,19 +107,19 @@ test_ipin.o: /usr/include/bits/msq.h test_ipout.o: ipout.h ipaddr.h ipheader.h /usr/include/stdint.h test_ipout.o: /usr/include/features.h /usr/include/sys/cdefs.h test_ipout.o: /usr/include/gnu/stubs.h /usr/include/bits/wchar.h -test_ipout.o: /usr/include/bits/wordsize.h dev.h /usr/include/unistd.h -test_ipout.o: /usr/include/bits/posix_opt.h /usr/include/bits/types.h -test_ipout.o: /usr/include/bits/typesizes.h /usr/include/bits/confname.h -test_ipout.o: /usr/include/getopt.h /usr/include/fcntl.h -test_ipout.o: /usr/include/bits/fcntl.h /usr/include/sys/types.h -test_ipout.o: /usr/include/time.h /usr/include/endian.h -test_ipout.o: /usr/include/bits/endian.h /usr/include/sys/select.h -test_ipout.o: /usr/include/bits/select.h /usr/include/bits/sigset.h -test_ipout.o: /usr/include/bits/time.h /usr/include/sys/sysmacros.h -test_ipout.o: /usr/include/bits/pthreadtypes.h /usr/include/bits/sched.h -test_ipout.o: /usr/include/sys/ipc.h /usr/include/bits/ipctypes.h -test_ipout.o: /usr/include/bits/ipc.h /usr/include/sys/msg.h -test_ipout.o: /usr/include/bits/msq.h +test_ipout.o: /usr/include/bits/wordsize.h routetable.h dev.h +test_ipout.o: /usr/include/unistd.h /usr/include/bits/posix_opt.h +test_ipout.o: /usr/include/bits/types.h /usr/include/bits/typesizes.h +test_ipout.o: /usr/include/bits/confname.h /usr/include/getopt.h +test_ipout.o: /usr/include/fcntl.h /usr/include/bits/fcntl.h +test_ipout.o: /usr/include/sys/types.h /usr/include/time.h +test_ipout.o: /usr/include/endian.h /usr/include/bits/endian.h +test_ipout.o: /usr/include/sys/select.h /usr/include/bits/select.h +test_ipout.o: /usr/include/bits/sigset.h /usr/include/bits/time.h +test_ipout.o: /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h +test_ipout.o: /usr/include/bits/sched.h /usr/include/sys/ipc.h +test_ipout.o: /usr/include/bits/ipctypes.h /usr/include/bits/ipc.h +test_ipout.o: /usr/include/sys/msg.h /usr/include/bits/msq.h test_recv.o: dev.h /usr/include/unistd.h /usr/include/features.h test_recv.o: /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h test_recv.o: /usr/include/bits/posix_opt.h /usr/include/bits/types.h diff --git a/practicas/pipi/src/ipaddr.cpp b/practicas/pipi/src/ipaddr.cpp index 6b052c8..1cdd573 100644 --- a/practicas/pipi/src/ipaddr.cpp +++ b/practicas/pipi/src/ipaddr.cpp @@ -21,7 +21,7 @@ IPAddr::IPAddr(atom a1, atom a2, atom a3, atom a4) } /// Constructor -IPAddr::IPAddr(unsigned ip) +IPAddr::IPAddr(int ip) { atoms[0] = ip >> 24; atoms[1] = ip >> 16; @@ -30,14 +30,15 @@ IPAddr::IPAddr(unsigned ip) } /// Constructor -IPAddr::IPAddr(std::string ip) throw (std::logic_error) +IPAddr::IPAddr(const char* ip) throw (std::logic_error) { std::istringstream iss(ip); + std::string ips; for (int i = 0; i < 4; ++i) { - if (!std::getline(iss, ip, '.')) + if (!std::getline(iss, ips, '.')) throw std::logic_error("Dirección IP inválida"); - atoms[i] = std::atoi(ip.c_str()); + atoms[i] = std::atoi(ips.c_str()); } } diff --git a/practicas/pipi/src/ipaddr.h b/practicas/pipi/src/ipaddr.h index e6dfa5b..19197a1 100644 --- a/practicas/pipi/src/ipaddr.h +++ b/practicas/pipi/src/ipaddr.h @@ -22,10 +22,10 @@ struct IPAddr IPAddr(atom a1, atom a2, atom a3, atom a4); /// Constructor - IPAddr(unsigned ip); + IPAddr(int ip); /// Constructor - IPAddr(std::string ip) throw (std::logic_error); + IPAddr(const char* ip) throw (std::logic_error); /// Operador de casteo a unsigned operator unsigned () const; diff --git a/practicas/pipi/src/ipout.cpp b/practicas/pipi/src/ipout.cpp index d673f8d..e7e211b 100644 --- a/practicas/pipi/src/ipout.cpp +++ b/practicas/pipi/src/ipout.cpp @@ -4,9 +4,10 @@ #include /// Constructor -IPOut::IPOut(const IPAddr& ip, Dev& dev, std::ostream& log): - ip(ip), dev(dev), log(log) -{} +IPOut::IPOut(const IPAddr& ip, RouteTable& rtable, std::ostream& log): + ip(ip), rtable(rtable), log(log) +{ +} void IPOut::drop(const std::string& msg, const std::string& buf) { @@ -23,20 +24,28 @@ 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) { - // No quieren fragmentar - if (df && (IPHeader::header_len() + data.size() > dev.mtu)) - { - drop("Tamaño de paquete más grande que MTU y DF=1", data); - return false; - } + // Armamos cabecera if (!src) src = ip; if (!id) id = get_id(); IPHeader iph(4, IPHeader::header_len() + data.size(), id, df, 0, 0, ttl, proto, src, dst); + // Buscamos ruta + RouteTable::Route* r = rtable.get(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)) + { + drop("Tamaño de paquete más grande que MTU y DF=1", iph); + return false; + } // Fragmenta (de ser necesario) - int max_payload = dev.mtu - IPHeader::header_len(); + int max_payload = r->iface->mtu - IPHeader::header_len(); int cant_frag = data.size() / max_payload; if (data.size() % max_payload) ++cant_frag; @@ -54,7 +63,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 - dev.transmit(buf, dst); + r->iface->transmit(buf, r->gateway ? r->gateway : dst); } return true; } diff --git a/practicas/pipi/src/ipout.h b/practicas/pipi/src/ipout.h index 61c2111..ae88509 100644 --- a/practicas/pipi/src/ipout.h +++ b/practicas/pipi/src/ipout.h @@ -3,7 +3,7 @@ #include "ipaddr.h" #include "ipheader.h" -#include "dev.h" +#include "routetable.h" #include #include #include @@ -15,14 +15,14 @@ struct IPOut /// Dirección MAC IPAddr ip; - /// Dispositivo de red - Dev& dev; + /// Dispositivo de logging + RouteTable& rtable; /// Dispositivo de logging std::ostream& log; /// Constructor - IPOut(const IPAddr& ip, Dev& dev, std::ostream& log = std::cout); + IPOut(const IPAddr& ip, RouteTable& rtable, std::ostream& log = std::cout); /// Descarta un paquete void drop(const std::string& msg, const std::string& buf); diff --git a/practicas/pipi/src/routetable.cpp b/practicas/pipi/src/routetable.cpp new file mode 100644 index 0000000..66ccd80 --- /dev/null +++ b/practicas/pipi/src/routetable.cpp @@ -0,0 +1,25 @@ +#include "routetable.h" + +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); +} + +void RouteTable::del(const IPAddr& net) +{ + table.erase(net); +} + +RouteTable::Route* RouteTable::get(const IPAddr& dst) +{ + // No existe + if (table.find(dst) == table.end()) + return 0; + return &table[dst]; +} + +// vim: set et sw=4 sts=4 : diff --git a/practicas/pipi/src/routetable.h b/practicas/pipi/src/routetable.h new file mode 100644 index 0000000..2fe1586 --- /dev/null +++ b/practicas/pipi/src/routetable.h @@ -0,0 +1,45 @@ +#ifndef _ROUTETABLE_H_ +#define _ROUTETABLE_H_ + +#include "dev.h" +#include "ipaddr.h" +#include + +/// Tabla de ruteo +struct RouteTable +{ + + /// Ruta + struct Route + { + IPAddr gateway; + unsigned metric; + Dev* iface; + Route(): gateway(0), metric(0), iface(0) {} + Route(const IPAddr& gateway, unsigned metric, Dev& iface): + gateway(gateway), metric(metric), iface(&iface) {} + }; + + /// Tabla + std::map< IPAddr, Route > table; + + /// Interfaz por default + Dev& default_iface; + + /// Constructor + RouteTable(Dev& default_iface); + + /// Agrega ruta + void add(const IPAddr& net, const IPAddr& gw, unsigned metric, Dev& iface); + + /// Borra ruta + void del(const IPAddr& net); + + /// Obtiene dirección e interfaz por la cual salir para un destino + Route* get(const IPAddr& dst); + +}; + +#endif // _ROUTETABLE_H_ + +// vim: set et sw=4 sts=4 : diff --git a/practicas/pipi/src/test_ipin.cpp b/practicas/pipi/src/test_ipin.cpp index 7b56b11..01b19aa 100644 --- a/practicas/pipi/src/test_ipin.cpp +++ b/practicas/pipi/src/test_ipin.cpp @@ -3,16 +3,30 @@ #include "ipaddr.h" #include "dev.h" #include +#include #include #include #include #include #include -int main() +// Uso: ./test_ipin ip mtu proto queue_id + +int main(int argc, char* argv[]) { IPAddr addr("10.10.10.1"); - Dev dev(addr); + unsigned mtu = 25; + unsigned proto = 0; + key_t queue_id = DEV_DEFAULT_KEY; + if (argc > 1) + addr = IPAddr(argv[1]); + if (argc > 2) + mtu = atoi(argv[2]); + if (argc > 3) + proto = atoi(argv[3]); + if (argc > 4) + queue_id = atoi(argv[4]); + Dev dev(addr, mtu, queue_id); IPIn ipin(addr, dev); struct msqid_ds minfo; for (msgctl(dev.que_id, IPC_STAT, &minfo); minfo.msg_qnum; @@ -20,8 +34,9 @@ int main() { IPAddr src, dst; std::cout << "Quedan " << minfo.msg_qnum << " mensajes en la cola\n"; - std::string s = ipin.recv(0, src, dst); - std::cout << "Recibido '" << s << "' (len " << s.size() << ")\n"; + std::string s = ipin.recv(proto, src, dst); + std::cout << "Recibido '" << s << "' (len " << s.size() << ") de " + << src << " para " << dst << " (proto = " << proto << ")\n"; } return 0; } diff --git a/practicas/pipi/src/test_ipout.cpp b/practicas/pipi/src/test_ipout.cpp index e7eb964..acdb77f 100644 --- a/practicas/pipi/src/test_ipout.cpp +++ b/practicas/pipi/src/test_ipout.cpp @@ -1,8 +1,10 @@ #include "ipout.h" #include "ipaddr.h" +#include "routetable.h" #include "dev.h" #include +#include #include #include #include @@ -10,17 +12,40 @@ #include #include -int main() +// Uso: ./test_ipout ip dst msg mtu proto queue_id + +int main(int argc, char* argv[]) { - int que_id = msgget(DEV_DEFAULT_KEY, IPC_CREAT | 0666); - assert(que_id != -1); IPAddr addr("10.10.10.2"); - Dev dev(addr, 25); - IPOut ipout(addr, dev); - if (ipout.send("hola mundo", 0, IPAddr("10.10.10.1"))) - std::cout << "Enviado 'hola mundo' a 10.10.10.1\n"; + IPAddr dst("10.10.10.1"); + std::string msg = "hola mundo"; + unsigned mtu = 25; + unsigned proto = 0; + key_t queue_id = DEV_DEFAULT_KEY; + if (argc > 1) + addr = IPAddr(argv[1]); + if (argc > 2) + dst = IPAddr(argv[2]); + if (argc > 3) + msg = argv[3]; + if (argc > 4) + mtu = atoi(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); + Dev dev(addr, mtu, queue_id); + 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 'hola mundo' a 10.10.10.1\n"; + std::cout << "NO SE PUDO ENVIAR '" << msg << "' a " << dst << "\n"; return 0; }