]> git.llucax.com Git - z.facultad/75.74/practicos.git/commitdiff
Base del TP de IP de distribuidos.
authorLeandro Lucarella <llucax@gmail.com>
Sun, 28 May 2006 18:45:52 +0000 (18:45 +0000)
committerLeandro Lucarella <llucax@gmail.com>
Sun, 28 May 2006 18:45:52 +0000 (18:45 +0000)
practicas/pipi/ENUNCIADO [new file with mode: 0644]
practicas/pipi/src/Makefile [new file with mode: 0644]
practicas/pipi/src/dev.h [new file with mode: 0644]
practicas/pipi/src/ethernetframe.h [new file with mode: 0644]
practicas/pipi/src/frame.h [new file with mode: 0644]
practicas/pipi/src/media.cpp [new file with mode: 0644]
practicas/pipi/src/media.h [new file with mode: 0644]
practicas/pipi/src/test_recv.cpp [new file with mode: 0644]
practicas/pipi/src/test_send.cpp [new file with mode: 0644]

diff --git a/practicas/pipi/ENUNCIADO b/practicas/pipi/ENUNCIADO
new file mode 100644 (file)
index 0000000..cfd611c
--- /dev/null
@@ -0,0 +1,41 @@
+Enunciado extraoficial
+
+Hay que hacer 2 procesos, uno que manda y otro que recibe IP, por cada
+host/router. Todos los procesos que envian, ponen las cosas en una cola, todos
+los que reciben, sacan de esa cola. Se usa como MAC la IP, y como ID del mensaje
+de la cola (de esta manera cada proceso saca solo los "paquetes" con el ID/MAC
+que le corresponda).
+
+1) Campos en IP
+        id de paquete
+        ip origen
+        ip destino
+        checksum (0/1, de juguete)
+        tamaño del paquete completo
+        ToS
+        Don't Fragment (0/1)
+        End (0/1)
+        offset
+        TTL
+        tamaño de este fragmento
+        tipo de payload (IP / ICMP)
+        (se que faltan algunos, si tienen algo mas,
+          completen)
+
+2) Casos de descarte de paquetes
+        Error de checksum (silencioso)
+        No hay buffer para fragmento (silencioso)
+        Un host que no rutea recibe un paquete para otro host
+          (silencioso)
+        No hay ruta (icmp)
+        DF == 1 y MTU < size (icmp)
+        TTL == 0 (icmp)
+
+3) Comportamiento del protocolo
+        Debe rutear (si es un router)
+        Debe fragmentar y reensamblar
+        Debe contemplar todos los casos de descarte de
+          paquetes anteriores escribiendo en un archivo
+          los paquetes descartados según corresponda
+          (silecioso, icmp).
+
diff --git a/practicas/pipi/src/Makefile b/practicas/pipi/src/Makefile
new file mode 100644 (file)
index 0000000..aa8d258
--- /dev/null
@@ -0,0 +1,98 @@
+# Makefile de ejemplo para C++
+# 
+# Creado: jue abr 15 15:34:19 ART 2004
+#
+# Copyleft 2004 - Leandro Lucarella, Bajo licencia GPL [http://www.gnu.org/]
+#
+
+# CONFIGURACION 
+################
+
+# Opciones para el compilador C/C++ en modo ansi.
+CFLAGS = -Wall -ansi -pedantic-errors
+
+# Para que explote lo mas posible
+#CFLAGS += -O3 -DNDEBUG
+
+# Para valgrind o debug
+CFLAGS += -ggdb -DDEBUG
+
+# Opciones para el compilador C++.
+CXXFLAGS = $(CFLAGS) -fno-inline
+
+# Opciones del enlazador.
+#LDFLAGS=
+
+# Compilador.
+CC=g++
+
+# Programas
+targets=test_send test_recv
+
+# Fuentes
+fuentes ?= $(wildcard *.cpp)
+
+
+# REGLAS
+#########
+
+.PHONY: all clean
+
+all: $(targets)
+
+test_send: test_send.o media.o
+
+test_recv: test_recv.o media.o
+
+depend:
+       makedepend $(fuentes)
+
+clean:
+       @$(RM) -fv *.o $(targets)
+
+# DO NOT DELETE
+
+media.o: media.h frame.h /usr/include/unistd.h /usr/include/features.h
+media.o: /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h
+media.o: /usr/include/bits/posix_opt.h /usr/include/bits/types.h
+media.o: /usr/include/bits/wordsize.h /usr/include/bits/typesizes.h
+media.o: /usr/include/bits/confname.h /usr/include/getopt.h
+media.o: /usr/include/fcntl.h /usr/include/bits/fcntl.h
+media.o: /usr/include/sys/types.h /usr/include/time.h /usr/include/endian.h
+media.o: /usr/include/bits/endian.h /usr/include/sys/select.h
+media.o: /usr/include/bits/select.h /usr/include/bits/sigset.h
+media.o: /usr/include/bits/time.h /usr/include/sys/sysmacros.h
+media.o: /usr/include/bits/pthreadtypes.h /usr/include/bits/sched.h
+media.o: /usr/include/sys/ipc.h /usr/include/bits/ipctypes.h
+media.o: /usr/include/bits/ipc.h /usr/include/sys/msg.h
+media.o: /usr/include/bits/msq.h
+test_recv.o: ethernetframe.h frame.h media.h /usr/include/unistd.h
+test_recv.o: /usr/include/features.h /usr/include/sys/cdefs.h
+test_recv.o: /usr/include/gnu/stubs.h /usr/include/bits/posix_opt.h
+test_recv.o: /usr/include/bits/types.h /usr/include/bits/wordsize.h
+test_recv.o: /usr/include/bits/typesizes.h /usr/include/bits/confname.h
+test_recv.o: /usr/include/getopt.h /usr/include/fcntl.h
+test_recv.o: /usr/include/bits/fcntl.h /usr/include/sys/types.h
+test_recv.o: /usr/include/time.h /usr/include/endian.h
+test_recv.o: /usr/include/bits/endian.h /usr/include/sys/select.h
+test_recv.o: /usr/include/bits/select.h /usr/include/bits/sigset.h
+test_recv.o: /usr/include/bits/time.h /usr/include/sys/sysmacros.h
+test_recv.o: /usr/include/bits/pthreadtypes.h /usr/include/bits/sched.h
+test_recv.o: /usr/include/sys/ipc.h /usr/include/bits/ipctypes.h
+test_recv.o: /usr/include/bits/ipc.h /usr/include/sys/msg.h
+test_recv.o: /usr/include/bits/msq.h dev.h
+test_send.o: ethernetframe.h frame.h media.h /usr/include/unistd.h
+test_send.o: /usr/include/features.h /usr/include/sys/cdefs.h
+test_send.o: /usr/include/gnu/stubs.h /usr/include/bits/posix_opt.h
+test_send.o: /usr/include/bits/types.h /usr/include/bits/wordsize.h
+test_send.o: /usr/include/bits/typesizes.h /usr/include/bits/confname.h
+test_send.o: /usr/include/getopt.h /usr/include/fcntl.h
+test_send.o: /usr/include/bits/fcntl.h /usr/include/sys/types.h
+test_send.o: /usr/include/time.h /usr/include/endian.h
+test_send.o: /usr/include/bits/endian.h /usr/include/sys/select.h
+test_send.o: /usr/include/bits/select.h /usr/include/bits/sigset.h
+test_send.o: /usr/include/bits/time.h /usr/include/sys/sysmacros.h
+test_send.o: /usr/include/bits/pthreadtypes.h /usr/include/bits/sched.h
+test_send.o: /usr/include/sys/ipc.h /usr/include/bits/ipctypes.h
+test_send.o: /usr/include/bits/ipc.h /usr/include/sys/msg.h
+test_send.o: /usr/include/bits/msq.h dev.h
diff --git a/practicas/pipi/src/dev.h b/practicas/pipi/src/dev.h
new file mode 100644 (file)
index 0000000..d0acea6
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef _DEV_H_
+#define _DEV_H_
+
+#include "frame.h"
+#include "media.h"
+#include <stdexcept>
+
+/// Dispositivo de red (capa de enlace)
+struct Dev
+{
+
+    /// Dirección MAC
+    Frame::mac_type mac;
+
+    /// Medio físico
+    Media& media;
+
+    /// Constructor
+    Dev(const Frame::mac_type& mac, Media& media):
+        mac(mac), media(media)
+    {}
+
+    /// Envía un frame
+    void send(const Frame& frame) throw (std::runtime_error)
+    { media.transmit(frame); }
+
+    /// Recibe un frame
+    void recv(Frame& frame) throw (std::runtime_error)
+    { media.receive(frame); }
+
+    // Nada de andar copiando placas...
+    private:
+    Dev(const Dev&);
+    Dev& operator=(const Dev&);
+
+};
+
+#endif // _DEV_H_
+
+// vim: set et sw=4 sts=4 :
diff --git a/practicas/pipi/src/ethernetframe.h b/practicas/pipi/src/ethernetframe.h
new file mode 100644 (file)
index 0000000..1205202
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef _ETHERNETFRAME_H_
+#define _ETHERNETFRAME_H_
+
+#include "frame.h"
+#include <string>
+#include <stdexcept>
+
+/// Frame de la capa física (en este caso es un mensaje enviado a una cola)
+template < size_t Size = 1500 >
+struct EthernetFrame: Frame
+{
+
+    // Atributos
+    mac_type _mac;
+    size_t _len;
+    char _frame[Size];
+
+    /// Constructor
+    EthernetFrame(const mac_type& mac):
+        _mac(mac)
+    {}
+
+    /// Constructor
+    EthernetFrame(const mac_type& mac, const std::string& d)
+        throw (std::logic_error): _mac(mac)
+    { data(d); }
+
+    /// Setea MAC
+    void mac(const mac_type& mac)
+    { _mac = mac; }
+
+    /// Obtiene MAC
+    mac_type mac() const
+    { return _mac; }
+
+    /// Obtiene longitud
+    size_t len() const
+    { return _len; }
+
+    /// Obtiene tamaño
+    size_t size() const
+    { return Size; }
+
+    /// Setea datos
+    void data(const std::string& d) throw (std::logic_error)
+    {
+        if (d.size() > Size)
+            throw std::logic_error("dato más grande que el frame");
+        _len = d.size();
+        memcpy(_frame, d.c_str(), _len);
+    }
+
+    /// Obtiene datos
+    std::string data() const
+    { return _frame; }
+
+};
+
+#endif // _ETHERNETFRAME_H_
+
+// vim: set et sw=4 sts=4 :
diff --git a/practicas/pipi/src/frame.h b/practicas/pipi/src/frame.h
new file mode 100644 (file)
index 0000000..1e5fe99
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef _FRAME_H_
+#define _FRAME_H_
+
+#include <string>
+
+/// Frame de la capa física (en este caso es un mensaje enviado a una cola)
+struct Frame
+{
+
+    // Tipos
+    typedef long mac_type;
+
+    /// Destructor
+    virtual ~Frame() {}
+
+    /// Setea MAC
+    virtual void mac(const mac_type& mac) = 0;
+
+    /// Obtiene MAC
+    virtual mac_type mac() const = 0;
+
+    /// Obtiene la longitud real del frame
+    virtual size_t len() const = 0;
+
+    /// Obtiene el tamaño máximo del frame (MTU)
+    virtual size_t size() const = 0;
+
+    /// Setea datos
+    virtual void data(const std::string& data) = 0;
+
+    /// Obtiene datos
+    virtual std::string data() const = 0;
+
+};
+
+#endif // _FRAME_H_
+
+// vim: set et sw=4 sts=4 :
diff --git a/practicas/pipi/src/media.cpp b/practicas/pipi/src/media.cpp
new file mode 100644 (file)
index 0000000..5a3077e
--- /dev/null
@@ -0,0 +1,25 @@
+#include "media.h"
+#include <iostream>
+
+Media::Media(key_t key) throw (std::runtime_error)
+{
+    que_id = msgget(key, 0666); // Debe estar previamente creada
+    if (que_id == -1)
+        throw std::runtime_error("No se pudo crear la cola");
+}
+
+void Media::transmit(const Frame& frame)
+{
+    std::cout << "tx -> msgtype = " << *(((int*)&frame)+1) << "\n";
+    if (msgsnd(que_id, ((int*)&frame)+1, frame.size(), 0) == -1)
+        throw std::runtime_error("Error al poner en la cola");
+}
+
+void Media::receive(Frame& frame)
+{
+    std::cout << "rx -> msgtype = " << *(((int*)&frame)+1) << "\n";
+    if (msgrcv(que_id, ((int*)&frame)+1, frame.size(), frame.mac(), 0) == -1)
+        throw std::runtime_error("Error al sacar de la cola");
+}
+
+// vim: set et sw=4 sts=4 :
diff --git a/practicas/pipi/src/media.h b/practicas/pipi/src/media.h
new file mode 100644 (file)
index 0000000..c679812
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef _MEDIA_H_
+#define _MEDIA_H_
+
+#include "frame.h"
+#include <string>
+#include <stdexcept>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+
+/// Medio (o capa física + enlace), 
+struct Media
+{
+
+    /// Identificador de la cola a usar
+    int que_id;
+
+    /// Constructor
+    Media(key_t key) throw (std::runtime_error);
+
+    /// Envía un frame
+    void transmit(const Frame& frame);
+
+    /// Recibe un frame
+    void receive(Frame& frame);
+
+    // Nada de andar copiando cables...
+    private:
+    Media(const Media&);
+    Media& operator=(const Media&);
+
+};
+
+#endif // _MEDIA_H_
+
+// vim: set et sw=4 sts=4 :
diff --git a/practicas/pipi/src/test_recv.cpp b/practicas/pipi/src/test_recv.cpp
new file mode 100644 (file)
index 0000000..b77b5f8
--- /dev/null
@@ -0,0 +1,28 @@
+
+#include "ethernetframe.h"
+#include "media.h"
+#include "dev.h"
+#include <iostream>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+
+int main()
+{
+    Media media(0xabcdef);
+    Dev dev(1234, media);
+    struct msqid_ds minfo;
+    for (msgctl(media.que_id, IPC_STAT, &minfo); minfo.msg_qnum;
+            msgctl(media.que_id, IPC_STAT, &minfo))
+    {
+        std::cout << "Quedan " << minfo.msg_qnum << " mensajes en la cola\n";
+        EthernetFrame<1500> f(1234);
+        dev.recv(f);
+        std::cout << f._mac << " " << f._len << " " << f._frame << "\n";
+    }
+    return 0;
+}
+
+// vim: set et sw=4 sts=4 :
diff --git a/practicas/pipi/src/test_send.cpp b/practicas/pipi/src/test_send.cpp
new file mode 100644 (file)
index 0000000..559ad8c
--- /dev/null
@@ -0,0 +1,20 @@
+
+#include "ethernetframe.h"
+#include "media.h"
+#include "dev.h"
+#include <iostream>
+#include <cassert>
+
+int main()
+{
+    int que_id = msgget(0xabcdef, IPC_CREAT | 0666);
+    assert(que_id != -1);
+    Media media(0xabcdef);
+    Dev dev(1234, media);
+    EthernetFrame<1500> f(1234, "hola mundo");
+    dev.send(f);
+    std::cout << "Enviado '" << f._frame << "' a " << f._mac << "\n";
+    return 0;
+}
+
+// vim: set et sw=4 sts=4 :