From: Leandro Lucarella Date: Tue, 30 May 2006 16:12:55 +0000 (+0000) Subject: IPIn (consumidor) mínimo funcionando. X-Git-Tag: svn_import~68 X-Git-Url: https://git.llucax.com/z.facultad/75.74/practicos.git/commitdiff_plain/7a01801db38786c0f1cab79b3867b8b529d5cb1c IPIn (consumidor) mínimo funcionando. --- diff --git a/practicas/pipi/src/Makefile b/practicas/pipi/src/Makefile index eafc85e..d8d81da 100644 --- a/practicas/pipi/src/Makefile +++ b/practicas/pipi/src/Makefile @@ -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 diff --git a/practicas/pipi/src/ipaddr.cpp b/practicas/pipi/src/ipaddr.cpp index 5f33669..6b052c8 100644 --- a/practicas/pipi/src/ipaddr.cpp +++ b/practicas/pipi/src/ipaddr.cpp @@ -2,6 +2,15 @@ #include "ipaddr.h" #include +/// 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) { diff --git a/practicas/pipi/src/ipaddr.h b/practicas/pipi/src/ipaddr.h index eed830d..e6dfa5b 100644 --- a/practicas/pipi/src/ipaddr.h +++ b/practicas/pipi/src/ipaddr.h @@ -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 index 0000000..0fbfca2 --- /dev/null +++ b/practicas/pipi/src/ipheader.cpp @@ -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 : diff --git a/practicas/pipi/src/ipheader.h b/practicas/pipi/src/ipheader.h index 98893be..f22c703 100644 --- a/practicas/pipi/src/ipheader.h +++ b/practicas/pipi/src/ipheader.h @@ -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 index 0000000..45e340e --- /dev/null +++ b/practicas/pipi/src/ipin.cpp @@ -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 index 0000000..2c64911 --- /dev/null +++ b/practicas/pipi/src/ipin.h @@ -0,0 +1,44 @@ +#ifndef _IPIN_H_ +#define _IPIN_H_ + +#include "ipaddr.h" +#include "ipheader.h" +#include "dev.h" +#include +#include +#include + +/// 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 index 0000000..750ffd4 --- /dev/null +++ b/practicas/pipi/src/test_ipin.cpp @@ -0,0 +1,27 @@ + +#include "ipin.h" +#include "ipaddr.h" +#include +#include +#include +#include +#include +#include + +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 :