]> git.llucax.com Git - z.facultad/75.74/practicos.git/commitdiff
Ruteo básico aparentemente andando. Se parametrizan las pruebas para poder
authorLeandro Lucarella <llucax@gmail.com>
Fri, 2 Jun 2006 02:15:07 +0000 (02:15 +0000)
committerLeandro Lucarella <llucax@gmail.com>
Fri, 2 Jun 2006 02:15:07 +0000 (02:15 +0000)
cambiar algunas cosas via línea de comandos.

practicas/pipi/src/Makefile
practicas/pipi/src/ipaddr.cpp
practicas/pipi/src/ipaddr.h
practicas/pipi/src/ipout.cpp
practicas/pipi/src/ipout.h
practicas/pipi/src/routetable.cpp [new file with mode: 0644]
practicas/pipi/src/routetable.h [new file with mode: 0644]
practicas/pipi/src/test_ipin.cpp
practicas/pipi/src/test_ipout.cpp

index 50224e2d3d12de0e2c04e8bc8642b2e1c3191ba8..a1538a78026ba86ce3f45713dcbf1de5ae11f517 100644 (file)
@@ -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
index 6b052c8d8851c7d8d4074f8464969e3e89512f2c..1cdd5735353083c5fa903768073ff68516370f5a 100644 (file)
@@ -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());
     }
 }
 
index e6dfa5b3a928cad7ff91126b8f5b9ff44a07b0d0..19197a1034b1f9527741d93da483029ff5797c63 100644 (file)
@@ -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;
index d673f8d133cb6c566b6c7f89bcd245a853d8c01e..e7e211ba49b357ca9db3cf53eea62ff475ed2da9 100644 (file)
@@ -4,9 +4,10 @@
 #include <ctime>
 
 /// 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;
 }
index 61c21116991eb6e836f094b859f748688c03a69e..ae885090b61af468e04a1c41f52bd6b970c25fb2 100644 (file)
@@ -3,7 +3,7 @@
 
 #include "ipaddr.h"
 #include "ipheader.h"
-#include "dev.h"
+#include "routetable.h"
 #include <iostream>
 #include <string>
 #include <stdexcept>
@@ -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 (file)
index 0000000..66ccd80
--- /dev/null
@@ -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 (file)
index 0000000..2fe1586
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef _ROUTETABLE_H_
+#define _ROUTETABLE_H_
+
+#include "dev.h"
+#include "ipaddr.h"
+#include <map>
+
+/// 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 :
index 7b56b11bea844abba5db2edcc08c23ab4d31b59a..01b19aa97e7731d31047586330e20027cf641895 100644 (file)
@@ -3,16 +3,30 @@
 #include "ipaddr.h"
 #include "dev.h"
 #include <iostream>
+#include <cstdlib>
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/types.h>
 #include <sys/ipc.h>
 #include <sys/msg.h>
 
-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;
 }
index e7eb9641ce03207b3acd9e8496bf86ef716f2068..acdb77fb3000f92ae5c2e3afda252be1a71416ad 100644 (file)
@@ -1,8 +1,10 @@
 
 #include "ipout.h"
 #include "ipaddr.h"
+#include "routetable.h"
 #include "dev.h"
 #include <iostream>
+#include <string>
 #include <cassert>
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/ipc.h>
 #include <sys/msg.h>
 
-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;
 }