From: Leandro Lucarella Date: Sun, 28 May 2006 22:48:15 +0000 (+0000) Subject: Se refactoriza y simplifica la capa física. Se deja sólo el dispositivo de red X-Git-Tag: svn_import~71 X-Git-Url: https://git.llucax.com/z.facultad/75.74/practicos.git/commitdiff_plain/9145fe7228349a5f457d65f33b7888d2b69b6306 Se refactoriza y simplifica la capa física. Se deja sólo el dispositivo de red (con MAC y MTU variables en tiempo de ejecución, chau templates y virtualidad!). --- diff --git a/practicas/pipi/src/Makefile b/practicas/pipi/src/Makefile index d0290d4..a6852d2 100644 --- a/practicas/pipi/src/Makefile +++ b/practicas/pipi/src/Makefile @@ -40,9 +40,9 @@ fuentes ?= $(wildcard *.cpp) all: depend $(targets) -test_send: test_send.o media.o +test_send: test_send.o dev.o -test_recv: test_recv.o media.o +test_recv: test_recv.o dev.o test_ipaddr: test_ipaddr.o ipaddr.o @@ -54,49 +54,46 @@ clean: # DO NOT DELETE +dev.o: dev.h /usr/include/unistd.h /usr/include/features.h +dev.o: /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h +dev.o: /usr/include/bits/posix_opt.h /usr/include/bits/types.h +dev.o: /usr/include/bits/wordsize.h /usr/include/bits/typesizes.h +dev.o: /usr/include/bits/confname.h /usr/include/getopt.h +dev.o: /usr/include/fcntl.h /usr/include/bits/fcntl.h +dev.o: /usr/include/sys/types.h /usr/include/time.h /usr/include/endian.h +dev.o: /usr/include/bits/endian.h /usr/include/sys/select.h +dev.o: /usr/include/bits/select.h /usr/include/bits/sigset.h +dev.o: /usr/include/bits/time.h /usr/include/sys/sysmacros.h +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 -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_ipaddr.o: ipaddr.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 +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 +test_recv.o: /usr/include/bits/wordsize.h /usr/include/bits/typesizes.h +test_recv.o: /usr/include/bits/confname.h /usr/include/getopt.h +test_recv.o: /usr/include/fcntl.h /usr/include/bits/fcntl.h +test_recv.o: /usr/include/sys/types.h /usr/include/time.h +test_recv.o: /usr/include/endian.h /usr/include/bits/endian.h +test_recv.o: /usr/include/sys/select.h /usr/include/bits/select.h +test_recv.o: /usr/include/bits/sigset.h /usr/include/bits/time.h +test_recv.o: /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h +test_recv.o: /usr/include/bits/sched.h /usr/include/sys/ipc.h +test_recv.o: /usr/include/bits/ipctypes.h /usr/include/bits/ipc.h +test_recv.o: /usr/include/sys/msg.h /usr/include/bits/msq.h +test_send.o: dev.h /usr/include/unistd.h /usr/include/features.h +test_send.o: /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h +test_send.o: /usr/include/bits/posix_opt.h /usr/include/bits/types.h +test_send.o: /usr/include/bits/wordsize.h /usr/include/bits/typesizes.h +test_send.o: /usr/include/bits/confname.h /usr/include/getopt.h +test_send.o: /usr/include/fcntl.h /usr/include/bits/fcntl.h +test_send.o: /usr/include/sys/types.h /usr/include/time.h +test_send.o: /usr/include/endian.h /usr/include/bits/endian.h +test_send.o: /usr/include/sys/select.h /usr/include/bits/select.h +test_send.o: /usr/include/bits/sigset.h /usr/include/bits/time.h +test_send.o: /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h +test_send.o: /usr/include/bits/sched.h /usr/include/sys/ipc.h +test_send.o: /usr/include/bits/ipctypes.h /usr/include/bits/ipc.h +test_send.o: /usr/include/sys/msg.h /usr/include/bits/msq.h diff --git a/practicas/pipi/src/dev.cpp b/practicas/pipi/src/dev.cpp new file mode 100644 index 0000000..494d188 --- /dev/null +++ b/practicas/pipi/src/dev.cpp @@ -0,0 +1,68 @@ +#include "dev.h" +#include +#include +#include +#include +#include +#include +#ifdef DEBUG +#include +#endif + +struct Frame +{ + Dev::mac_type mac; + size_t size; + char frame[1]; +}; + +Dev::Dev(mac_type mac, size_t mtu, key_t key) throw (std::runtime_error): + mac(mac), mtu(mtu) +{ + que_id = msgget(key, 0666); // Debe estar previamente creada + if (que_id == -1) + throw std::runtime_error("No se pudo crear la cola"); +} + +void Dev::transmit(const std::string& data, const mac_type& mac) + throw (std::runtime_error, std::logic_error) +{ + if (data.size() > mtu) + throw std::logic_error("Tamaño de datos mayor al MTU"); + Frame* f = (Frame*) malloc(sizeof(Frame) + mtu); + if (!f) + throw std::runtime_error("No se puede reservar memoria"); + f->mac = mac; + f->size = data.size(); + memcpy(f->frame, data.c_str(), data.size()); + int res = msgsnd(que_id, f, mtu + sizeof(size_t), 0); +#ifdef DEBUG + std::cout << "Dev::transmit(msgtype/mac = " << f->mac << ", size = " + << f->size << ", data = " << f->frame << ")\n"; +#endif + free(f); + if (res == -1) + throw std::runtime_error("Error al poner en la cola"); +} + +std::string Dev::receive() throw (std::runtime_error) +{ + Frame* f = (Frame*) malloc(sizeof(Frame) + mtu); + if (!f) + throw std::runtime_error("No se puede reservar memoria"); + int res = msgrcv(que_id, f, mtu + sizeof(size_t), mac, 0); + if (res == -1) + { + free(f); + throw std::runtime_error("Error al sacar de la cola"); + } + std::string s((char*) f->frame, f->size); + free(f); +#ifdef DEBUG + std::cout << "Dev::receive(msgtype/mac = " << mac << ", size = " + << s.size() << ", data = " << s << ")\n"; +#endif + return s; +} + +// vim: set et sw=4 sts=4 : diff --git a/practicas/pipi/src/dev.h b/practicas/pipi/src/dev.h index d0acea6..f8bd771 100644 --- a/practicas/pipi/src/dev.h +++ b/practicas/pipi/src/dev.h @@ -1,32 +1,37 @@ #ifndef _DEV_H_ #define _DEV_H_ -#include "frame.h" -#include "media.h" #include +#define DEV_DEFAULT_KEY 0x1abcdef1 + /// Dispositivo de red (capa de enlace) struct Dev { + /// Tipo de la mac + typedef long mac_type; + /// Dirección MAC - Frame::mac_type mac; + mac_type mac; + + /// MTU + size_t mtu; - /// Medio físico - Media& media; + /// Identificador de la cola a usar + int que_id; /// Constructor - Dev(const Frame::mac_type& mac, Media& media): - mac(mac), media(media) - {} + Dev(mac_type mac, size_t mtu = 1500, key_t key = DEV_DEFAULT_KEY) + throw (std::runtime_error); /// Envía un frame - void send(const Frame& frame) throw (std::runtime_error) - { media.transmit(frame); } + void transmit(const std::string& data, const mac_type& mac) + throw (std::runtime_error, std::logic_error); /// Recibe un frame - void recv(Frame& frame) throw (std::runtime_error) - { media.receive(frame); } + std::string receive() + throw (std::runtime_error); // Nada de andar copiando placas... private: diff --git a/practicas/pipi/src/media.cpp b/practicas/pipi/src/media.cpp deleted file mode 100644 index 823703c..0000000 --- a/practicas/pipi/src/media.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "media.h" -#ifdef DEBUG -#include -#endif - -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) -{ -#ifdef DEBUG - std::cout << "Media::transmit(msgtype/mac = " << *(((int*)&frame)+1) - << ", size = " << frame.size() << ", data = " << frame.data() << ")\n"; -#endif - // HACK ASQUEROSO para pasarle por encima a la vtable... :-O~ - 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) -{ - // HACK ASQUEROSO para pasarle por encima a la vtable... :-O~ - if (msgrcv(que_id, ((int*)&frame)+1, frame.size(), frame.mac(), 0) == -1) - throw std::runtime_error("Error al sacar de la cola"); -#ifdef DEBUG - std::cout << "Media::receive(msgtype/mac = " << *(((int*)&frame)+1) - << ", size = " << frame.size() << ", data = " << frame.data() << ")\n"; -#endif -} - -// vim: set et sw=4 sts=4 : diff --git a/practicas/pipi/src/media.h b/practicas/pipi/src/media.h deleted file mode 100644 index c679812..0000000 --- a/practicas/pipi/src/media.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef _MEDIA_H_ -#define _MEDIA_H_ - -#include "frame.h" -#include -#include -#include -#include -#include -#include -#include - -/// 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 index b77b5f8..2471b4a 100644 --- a/practicas/pipi/src/test_recv.cpp +++ b/practicas/pipi/src/test_recv.cpp @@ -1,6 +1,4 @@ -#include "ethernetframe.h" -#include "media.h" #include "dev.h" #include #include @@ -11,16 +9,14 @@ int main() { - Media media(0xabcdef); - Dev dev(1234, media); + Dev dev(4321); struct msqid_ds minfo; - for (msgctl(media.que_id, IPC_STAT, &minfo); minfo.msg_qnum; - msgctl(media.que_id, IPC_STAT, &minfo)) + for (msgctl(dev.que_id, IPC_STAT, &minfo); minfo.msg_qnum; + msgctl(dev.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"; + std::string s = dev.receive(); + std::cout << "Recibido '" << s << "' (len " << s.size() << ")\n"; } return 0; } diff --git a/practicas/pipi/src/test_send.cpp b/practicas/pipi/src/test_send.cpp index 559ad8c..618b862 100644 --- a/practicas/pipi/src/test_send.cpp +++ b/practicas/pipi/src/test_send.cpp @@ -1,19 +1,20 @@ -#include "ethernetframe.h" -#include "media.h" #include "dev.h" #include #include +#include +#include +#include +#include +#include int main() { - int que_id = msgget(0xabcdef, IPC_CREAT | 0666); + int que_id = msgget(DEV_DEFAULT_KEY, 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"; + Dev dev(1234); + dev.transmit("hola mundo", 4321); + std::cout << "Enviado 'hola mundo' a 4321\n"; return 0; }