]> git.llucax.com Git - z.facultad/75.74/practicos.git/commitdiff
IPIn (consumidor) mínimo funcionando.
authorLeandro Lucarella <llucax@gmail.com>
Tue, 30 May 2006 16:12:55 +0000 (16:12 +0000)
committerLeandro Lucarella <llucax@gmail.com>
Tue, 30 May 2006 16:12:55 +0000 (16:12 +0000)
practicas/pipi/src/Makefile
practicas/pipi/src/ipaddr.cpp
practicas/pipi/src/ipaddr.h
practicas/pipi/src/ipheader.cpp [new file with mode: 0644]
practicas/pipi/src/ipheader.h
practicas/pipi/src/ipin.cpp [new file with mode: 0644]
practicas/pipi/src/ipin.h [new file with mode: 0644]
practicas/pipi/src/test_ipin.cpp [new file with mode: 0644]

index eafc85e2f68ac79677e73783e2fb4e55d071079c..d8d81dae1c6653230e7bc21ea743d11d775a7ccd 100644 (file)
@@ -27,7 +27,7 @@ CXXFLAGS = $(CFLAGS) -fno-inline
 CC=g++
 
 # Programas
-targets=test_send test_recv test_ipaddr
+targets=test_send test_recv test_ipaddr test_ipin
 
 # Fuentes
 fuentes ?= $(wildcard *.cpp)
@@ -44,7 +44,9 @@ test_send: test_send.o dev.o
 
 test_recv: test_recv.o dev.o
 
-test_ipaddr: test_ipaddr.o ipaddr.o
+test_ipaddr: test_ipaddr.o ipaddr.o ipheader.o
+
+test_ipin: test_ipin.o ipin.o ipaddr.o ipheader.o dev.o
 
 depend:
        @makedepend $(fuentes) > /dev/null 2>&1
@@ -68,11 +70,33 @@ dev.o: /usr/include/bits/pthreadtypes.h /usr/include/bits/sched.h
 dev.o: /usr/include/sys/ipc.h /usr/include/bits/ipctypes.h
 dev.o: /usr/include/bits/ipc.h /usr/include/sys/msg.h /usr/include/bits/msq.h
 ipaddr.o: ipaddr.h
-ipin.o: ipin.h dev.h
+ipheader.o: ipheader.h ipaddr.h /usr/include/stdint.h /usr/include/features.h
+ipheader.o: /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h
+ipheader.o: /usr/include/bits/wchar.h /usr/include/bits/wordsize.h
+ipin.o: ipin.h ipaddr.h ipheader.h /usr/include/stdint.h
+ipin.o: /usr/include/features.h /usr/include/sys/cdefs.h
+ipin.o: /usr/include/gnu/stubs.h /usr/include/bits/wchar.h
+ipin.o: /usr/include/bits/wordsize.h dev.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
 test_ipaddr.o: /usr/include/bits/wordsize.h
+test_ipin.o: ipin.h ipaddr.h ipheader.h /usr/include/stdint.h
+test_ipin.o: /usr/include/features.h /usr/include/sys/cdefs.h
+test_ipin.o: /usr/include/gnu/stubs.h /usr/include/bits/wchar.h
+test_ipin.o: /usr/include/bits/wordsize.h dev.h /usr/include/unistd.h
+test_ipin.o: /usr/include/bits/posix_opt.h /usr/include/bits/types.h
+test_ipin.o: /usr/include/bits/typesizes.h /usr/include/bits/confname.h
+test_ipin.o: /usr/include/getopt.h /usr/include/fcntl.h
+test_ipin.o: /usr/include/bits/fcntl.h /usr/include/sys/types.h
+test_ipin.o: /usr/include/time.h /usr/include/endian.h
+test_ipin.o: /usr/include/bits/endian.h /usr/include/sys/select.h
+test_ipin.o: /usr/include/bits/select.h /usr/include/bits/sigset.h
+test_ipin.o: /usr/include/bits/time.h /usr/include/sys/sysmacros.h
+test_ipin.o: /usr/include/bits/pthreadtypes.h /usr/include/bits/sched.h
+test_ipin.o: /usr/include/sys/ipc.h /usr/include/bits/ipctypes.h
+test_ipin.o: /usr/include/bits/ipc.h /usr/include/sys/msg.h
+test_ipin.o: /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 5f33669fb823d6f0dfc8d8988c839968cfd17893..6b052c8d8851c7d8d4074f8464969e3e89512f2c 100644 (file)
@@ -2,6 +2,15 @@
 #include "ipaddr.h"
 #include <sstream>
 
+/// Constructor
+IPAddr::IPAddr()
+{
+    atoms[0] = 0;
+    atoms[1] = 0;
+    atoms[2] = 0;
+    atoms[3] = 0;
+}
+
 /// Constructor
 IPAddr::IPAddr(atom a1, atom a2, atom a3, atom a4)
 {
index eed830d4e4f8c246d37bfe7717b68a466168dcbb..e6dfa5b3a928cad7ff91126b8f5b9ff44a07b0d0 100644 (file)
@@ -15,6 +15,9 @@ struct IPAddr
     /// Representación interna
     atom atoms[4];
 
+    /// Constructor
+    IPAddr();
+
     /// Constructor
     IPAddr(atom a1, atom a2, atom a3, atom a4);
 
diff --git a/practicas/pipi/src/ipheader.cpp b/practicas/pipi/src/ipheader.cpp
new file mode 100644 (file)
index 0000000..0fbfca2
--- /dev/null
@@ -0,0 +1,60 @@
+#include "ipheader.h"
+
+IPHeader::IPHeader(uint8_t version, uint16_t total_len, uint16_t id, bool df,
+        bool mf, uint16_t offset, uint8_t ttl, uint8_t proto,
+        const IPAddr& src, const IPAddr& dst):
+    version(version), total_len(total_len), id(id), reserved_flag(0),
+    df(df), mf(mf), offset(offset), ttl(ttl), proto(proto), checksum(0),
+    src(src), dst(dst)
+{
+    do_checksum();
+}
+
+IPHeader::IPHeader(const std::string& s)
+{
+    *this = *((IPHeader*)s.c_str());
+}
+
+size_t IPHeader::header_len()
+{
+    return sizeof(IPHeader);
+}
+
+bool IPHeader::check_checksum() const
+{
+    IPHeader iph = *this;
+    iph.checksum = 0;
+    char* raw = (char*) &iph;
+    uint16_t sum = 0;
+    for (unsigned i = 0; i < sizeof(IPHeader); ++i)
+        sum += raw[i];
+    return sum == checksum;
+}
+
+void IPHeader::do_checksum()
+{
+    checksum = 0;
+    char* raw = (char*) this;
+    uint16_t sum = 0;
+    for (unsigned i = 0; i < sizeof(IPHeader); ++i)
+        sum += raw[i];
+    checksum = sum;
+}
+
+std::ostream& operator<<(std::ostream& os, const IPHeader& iph)
+{
+    return os
+        << "version=" << iph.version
+        << " total_len=" << iph.total_len
+        << " id=" << iph.id
+        << " DF=" << bool(iph.df)
+        << " MF=" << bool(iph.mf)
+        << " offset=" << unsigned(iph.offset)
+        << " TTL=" << unsigned(iph.ttl)
+        << " proto=" << unsigned(iph.proto)
+        << " checksum=" << iph.checksum
+        << " src=" << IPAddr(iph.src)
+        << " dst=" << IPAddr(iph.dst);
+}
+
+// vim: set et sw=4 sts=4 :
index 98893be6b4645555d6d1d59bdca3b1e418ac4121..f22c703fbbd0bd50b381a37bd0fcdb79331e8fd0 100644 (file)
@@ -28,57 +28,19 @@ struct IPHeader
 
     IPHeader(uint8_t version, uint16_t total_len, uint16_t id, bool df,
             bool mf, uint16_t offset, uint8_t ttl, uint8_t proto,
-            const IPAddr& src, const IPAddr& dst):
-        version(version), total_len(total_len), id(id), reserved_flag(0),
-        df(df), mf(mf), offset(offset), ttl(ttl), proto(proto), checksum(0),
-        src(src), dst(dst)
-    {
-        do_checksum();
-    }
+            const IPAddr& src, const IPAddr& dst);
 
-    IPHeader(const std::string& s)
-    {
-        *this = *((IPHeader*)s.c_str());
-    }
+    IPHeader(const std::string& s);
 
-    bool check_checksum() const
-    {
-        IPHeader iph = *this;
-        iph.checksum = 0;
-        char* raw = (char*) &iph;
-        uint16_t sum = 0;
-        for (unsigned i = 0; i < sizeof(IPHeader); ++i)
-            sum += raw[i];
-        return sum == checksum;
-    }
+    static size_t header_len();
 
-    void do_checksum()
-    {
-        checksum = 0;
-        char* raw = (char*) this;
-        uint16_t sum = 0;
-        for (unsigned i = 0; i < sizeof(IPHeader); ++i)
-            sum += raw[i];
-        checksum = sum;
-    }
+    bool check_checksum() const;
+
+    void do_checksum();
 
 };
 
-std::ostream& operator<<(std::ostream& os, const IPHeader& iph)
-{
-    return os
-        << "version=" << iph.version
-        << " total_len=" << iph.total_len
-        << " id=" << iph.id
-        << " DF=" << bool(iph.df)
-        << " MF=" << bool(iph.mf)
-        << " offset=" << unsigned(iph.offset)
-        << " TTL=" << unsigned(iph.ttl)
-        << " proto=" << unsigned(iph.proto)
-        << " checksum=" << iph.checksum
-        << " src=" << IPAddr(iph.src)
-        << " dst=" << IPAddr(iph.dst);
-}
+std::ostream& operator<<(std::ostream& os, const IPHeader& iph);
 
 #endif // _IPHEADER_H_
 
diff --git a/practicas/pipi/src/ipin.cpp b/practicas/pipi/src/ipin.cpp
new file mode 100644 (file)
index 0000000..45e340e
--- /dev/null
@@ -0,0 +1,65 @@
+
+#include "ipin.h"
+#include "ipheader.h"
+
+/// Constructor
+IPIn::IPIn(const IPAddr& ip, Dev& dev, std::ostream& log):
+    ip(ip), dev(dev), log(log)
+{}
+
+void IPIn::drop(const std::string& msg, const std::string& buf)
+{
+    log << "IPIn::drop: " << msg << "\n\tBuffer: " << buf << "\n";
+}
+
+void IPIn::drop(const std::string& msg, const IPHeader& iph)
+{
+    log << "IPIn::drop: " << msg << "\n\tIPHeader: " << iph << "\n";
+}
+
+/// Recibe un paquete IP
+std::string IPIn::recv(uint8_t proto, IPAddr& src, IPAddr& dst) throw (std::runtime_error)
+{
+    while (true)
+    {
+        std::string buf = dev.receive();
+        // No es siquiera IP
+        if (buf.size() < IPHeader::header_len())
+        {
+            drop("Cabecera incompleta o no es IP", buf);
+            continue;
+        }
+        IPHeader iph(buf);
+#ifdef DEBUG
+        log << iph << "\n";
+#endif
+        if (iph.version != 4)
+        {
+            drop("Versión IP incorrecta", iph);
+            continue;
+        }
+        if (!iph.check_checksum())
+        {
+            drop("Mal checksum", iph);
+            continue;
+        }
+        // TODO forwarding (ponerlo en una cola para el proceso que manda)
+        if (iph.dst != ip)
+        {
+            drop("No es para nosotros y no hacemos forward", iph);
+            continue;
+        }
+        //TODO a un buffer
+        if (iph.proto != proto)
+        {
+            drop("No es el protocolo pedido", iph);
+            continue;
+        }
+        src = iph.src;
+        dst = iph.dst;
+        std::string data = buf.substr(iph.total_len - iph.header_len());
+        return data;
+    }
+}
+
+// vim: set et sw=4 sts=4 :
diff --git a/practicas/pipi/src/ipin.h b/practicas/pipi/src/ipin.h
new file mode 100644 (file)
index 0000000..2c64911
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef _IPIN_H_
+#define _IPIN_H_
+
+#include "ipaddr.h"
+#include "ipheader.h"
+#include "dev.h"
+#include <iostream>
+#include <string>
+#include <stdexcept>
+
+/// IP de recepción
+struct IPIn
+{
+
+    /// Dirección MAC
+    IPAddr ip;
+
+    /// Dispositivo de red
+    Dev& dev;
+
+    /// Dispositivo de logging
+    std::ostream& log;
+
+    /// Constructor
+    IPIn(const IPAddr& ip, Dev& dev, 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);
+
+    /// Recibe un paquete IP
+    std::string recv(uint8_t proto, IPAddr& src, IPAddr& dst)
+        throw (std::runtime_error);
+
+    // Nada de andar copiando placas...
+    private:
+    IPIn(const IPIn&);
+    IPIn& operator=(const IPIn&);
+
+};
+
+#endif // _IPIN_H_
+
+// vim: set et sw=4 sts=4 :
diff --git a/practicas/pipi/src/test_ipin.cpp b/practicas/pipi/src/test_ipin.cpp
new file mode 100644 (file)
index 0000000..750ffd4
--- /dev/null
@@ -0,0 +1,27 @@
+
+#include "ipin.h"
+#include "ipaddr.h"
+#include <iostream>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+
+int main()
+{
+    Dev dev(4321);
+    IPIn ipin(IPAddr("10.10.10.1"), dev);
+    struct msqid_ds minfo;
+    for (msgctl(dev.que_id, IPC_STAT, &minfo); minfo.msg_qnum;
+            msgctl(dev.que_id, IPC_STAT, &minfo))
+    {
+        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";
+    }
+    return 0;
+}
+
+// vim: set et sw=4 sts=4 :