CC=g++
# Programas
-targets=test_send test_recv test_ipaddr test_ipin
+targets=test_send test_recv test_ipaddr test_ipin test_ipout
# Fuentes
fuentes ?= $(wildcard *.cpp)
test_ipin: test_ipin.o ipin.o ipaddr.o ipheader.o dev.o
+test_ipout: test_ipout.o ipout.o ipaddr.o ipheader.o dev.o
+
depend:
@makedepend $(fuentes) > /dev/null 2>&1
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
+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 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_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_ipout.o: ipout.h ipaddr.h ipheader.h /usr/include/stdint.h
+test_ipout.o: /usr/include/features.h /usr/include/sys/cdefs.h
+test_ipout.o: /usr/include/gnu/stubs.h /usr/include/bits/wchar.h
+test_ipout.o: /usr/include/bits/wordsize.h dev.h /usr/include/unistd.h
+test_ipout.o: /usr/include/bits/posix_opt.h /usr/include/bits/types.h
+test_ipout.o: /usr/include/bits/typesizes.h /usr/include/bits/confname.h
+test_ipout.o: /usr/include/getopt.h /usr/include/fcntl.h
+test_ipout.o: /usr/include/bits/fcntl.h /usr/include/sys/types.h
+test_ipout.o: /usr/include/time.h /usr/include/endian.h
+test_ipout.o: /usr/include/bits/endian.h /usr/include/sys/select.h
+test_ipout.o: /usr/include/bits/select.h /usr/include/bits/sigset.h
+test_ipout.o: /usr/include/bits/time.h /usr/include/sys/sysmacros.h
+test_ipout.o: /usr/include/bits/pthreadtypes.h /usr/include/bits/sched.h
+test_ipout.o: /usr/include/sys/ipc.h /usr/include/bits/ipctypes.h
+test_ipout.o: /usr/include/bits/ipc.h /usr/include/sys/msg.h
+test_ipout.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
--- /dev/null
+
+#include "ipout.h"
+#include "ipheader.h"
+
+/// Constructor
+IPOut::IPOut(const IPAddr& ip, Dev& dev, std::ostream& log):
+ ip(ip), dev(dev), log(log)
+{}
+
+void IPOut::drop(const std::string& msg, const std::string& buf)
+{
+ log << "IPOut::drop: " << msg << "\n\tBuffer: " << buf << "\n";
+}
+
+void IPOut::drop(const std::string& msg, const IPHeader& iph)
+{
+ log << "IPOut::drop: " << msg << "\n\tIPHeader: " << iph << "\n";
+}
+
+/// Envía un paquete IP
+bool IPOut::send(const std::string& data, IPAddr& src, IPAddr& dst,
+ uint8_t proto, bool df, uint8_t ttl, uint16_t id)
+ throw (std::runtime_error)
+{
+ // TODO fragmentar
+ if (IPHeader::header_len() + data.size() > dev.mtu)
+ {
+ drop("Tamaño de paquete más grande que MTU", data);
+ return false;
+ }
+ IPHeader iph(4, IPHeader::header_len() + data.size(), id, df, 0, 0,
+ ttl, proto, src, dst);
+ std::string buf((char*) &iph, sizeof(IPHeader));
+ buf += data;
+#ifdef DEBUG
+ log << "IPOut::send: IPHeader: " << iph << "\n";
+ log << "IPOut::send: buf = " << buf << "\n";
+#endif
+ dev.transmit(buf, dst /*TODO rutear */);
+ return true;
+}
+
+// vim: set et sw=4 sts=4 :
--- /dev/null
+#ifndef _IPOUT_H_
+#define _IPOUT_H_
+
+#include "ipaddr.h"
+#include "ipheader.h"
+#include "dev.h"
+#include <iostream>
+#include <string>
+#include <stdexcept>
+
+/// IP de envío
+struct IPOut
+{
+
+ /// Dirección MAC
+ IPAddr ip;
+
+ /// Dispositivo de red
+ Dev& dev;
+
+ /// Dispositivo de logging
+ std::ostream& log;
+
+ /// Constructor
+ IPOut(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);
+
+ /// Envía un paquete IP
+ bool send(const std::string& data, IPAddr& src, IPAddr& dst, uint8_t proto,
+ bool df = 0, uint8_t ttl = 64, uint16_t id = 0)
+ throw (std::runtime_error);
+
+ // Nada de andar copiando...
+ private:
+ IPOut(const IPOut&);
+ IPOut& operator=(const IPOut&);
+
+};
+
+#endif // _IPOUT_H_
+
+// vim: set et sw=4 sts=4 :
--- /dev/null
+
+#include "ipout.h"
+#include "ipaddr.h"
+#include "dev.h"
+#include <iostream>
+#include <cassert>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+
+int main()
+{
+ int que_id = msgget(DEV_DEFAULT_KEY, IPC_CREAT | 0666);
+ assert(que_id != -1);
+ IPAddr addr("10.10.10.2");
+ IPAddr dst("10.10.10.1");
+ Dev dev(addr);
+ IPOut ipout(addr, dev);
+ if (ipout.send("hola mundo", addr, dst, 0))
+ std::cout << "Enviado 'hola mundo' a 10.10.10.1\n";
+ else
+ std::cout << "NO SE PUDO ENVIAR 'hola mundo' a 10.10.10.1\n";
+ return 0;
+}
+
+// vim: set et sw=4 sts=4 :