]> git.llucax.com Git - z.facultad/75.74/practicos.git/commitdiff
Forwarding casi implementado. Hay un bug cuando se usan distintos MTU que hay
authorLeandro Lucarella <llucax@gmail.com>
Fri, 2 Jun 2006 06:06:37 +0000 (06:06 +0000)
committerLeandro Lucarella <llucax@gmail.com>
Fri, 2 Jun 2006 06:06:37 +0000 (06:06 +0000)
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).

15 files changed:
practicas/pipi/rutas_ejemplo/route.txt [new file with mode: 0644]
practicas/pipi/rutas_ejemplo/route_10.10.10.1.txt [new file with mode: 0644]
practicas/pipi/rutas_ejemplo/route_10.10.10.2.txt [new file with mode: 0644]
practicas/pipi/rutas_ejemplo/route_10.10.10.3.txt [new file with mode: 0644]
practicas/pipi/rutas_ejemplo/route_10.10.10.5.txt [new file with mode: 0644]
practicas/pipi/src/Makefile
practicas/pipi/src/ipaddr.cpp
practicas/pipi/src/ipaddr.h
practicas/pipi/src/ipin.cpp
practicas/pipi/src/ipin.h
practicas/pipi/src/ipout.cpp
practicas/pipi/src/ipout.h
practicas/pipi/src/routetable.cpp
practicas/pipi/src/test_ipin.cpp
practicas/pipi/src/test_ipout.cpp

diff --git a/practicas/pipi/rutas_ejemplo/route.txt b/practicas/pipi/rutas_ejemplo/route.txt
new file mode 100644 (file)
index 0000000..3aae5e1
--- /dev/null
@@ -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 (file)
index 0000000..cc877c8
--- /dev/null
@@ -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 (file)
index 0000000..cc877c8
--- /dev/null
@@ -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 (file)
index 0000000..11ff580
--- /dev/null
@@ -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 (file)
index 0000000..d57116e
--- /dev/null
@@ -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
index a1538a78026ba86ce3f45713dcbf1de5ae11f517..58539eff2f337ba227ce112394db79580ff1ea9d 100644 (file)
@@ -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
index 1cdd5735353083c5fa903768073ff68516370f5a..7b153b27b295df3a81d0b949a10227f50be5ee9a 100644 (file)
@@ -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
 {
index 19197a1034b1f9527741d93da483029ff5797c63..0c0c54924c87a19c75b407ff39b33503020a2c62 100644 (file)
@@ -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;
 
index 2d94158fee63e24ba8dac46867d401f19ed9b8c0..a9029c67c14b994b502f9100117ee5cd70340bb7 100644 (file)
@@ -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
index 5d0d7a82cc279b056df1f874bdc475eaa743392f..86202784f477e7eb66e07fd396da89fff73e2963 100644 (file)
@@ -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);
index e7e211ba49b357ca9db3cf53eea62ff475ed2da9..cf5c28c905a23a895316a89e9435d89a6f371815 100644 (file)
@@ -2,10 +2,15 @@
 #include "ipout.h"
 #include "ipheader.h"
 #include <ctime>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
 
 /// 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 :
index ae885090b61af468e04a1c41f52bd6b970c25fb2..effe150c5bf61a267da700ae13c3e92096521206 100644 (file)
@@ -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&);
index 66ccd80c97199893c0bb4827248aed65df26701d..4a043cd79a30ed4bbc256e71612da96066fd0478 100644 (file)
@@ -1,4 +1,7 @@
 #include "routetable.h"
+#ifdef DEBUG
+#include <iostream>
+#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)
index 01b19aa97e7731d31047586330e20027cf641895..a3c8e5f186268ec85de6c232a8b5bb6f562c3b25 100644 (file)
 #include <sys/ipc.h>
 #include <sys/msg.h>
 
-// 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))
index acdb77fb3000f92ae5c2e3afda252be1a71416ad..ec4430f63fe5b48d0297494aa49590c629d90c47 100644 (file)
@@ -4,6 +4,8 @@
 #include "routetable.h"
 #include "dev.h"
 #include <iostream>
+#include <fstream>
+#include <sstream>
 #include <string>
 #include <cassert>
 #include <unistd.h>
 #include <sys/ipc.h>
 #include <sys/msg.h>
 
-// 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 :