]> git.llucax.com Git - z.facultad/75.74/practicos.git/blob - practicas/pipi/src/ipin.cpp
Forwarding casi implementado. Hay un bug cuando se usan distintos MTU que hay
[z.facultad/75.74/practicos.git] / practicas / pipi / src / ipin.cpp
1
2 #include "ipin.h"
3 #include "ipheader.h"
4
5 /// Constructor
6 IPIn::IPIn(const IPAddr& ip, Dev& dev, Dev& forward_que, bool router,
7         bool forward, std::ostream& log):
8     ip(ip), dev(dev), forward_que(forward_que), router(router),
9     forward(forward), log(log)
10 {
11     if (router) forward = true;
12 }
13
14 void IPIn::drop(const std::string& msg, const std::string& buf)
15 {
16     log << "IPIn::drop: " << msg << "\n\tBuffer: " << buf << "\n";
17 }
18
19 void IPIn::drop(const std::string& msg, const IPHeader& iph)
20 {
21     log << "IPIn::drop: " << msg << "\n\tIPHeader: " << iph << "\n";
22 }
23
24 /// Recibe un paquete IP
25 std::string IPIn::recv(uint8_t proto, IPAddr& src, IPAddr& dst) throw (std::runtime_error)
26 {
27     while (true)
28     {
29         std::string buf = dev.receive();
30         // No es siquiera IP
31         if (buf.size() < IPHeader::header_len())
32         {
33             drop("Cabecera incompleta o no es IP", buf);
34             continue;
35         }
36         IPHeader iph(buf);
37 #ifdef DEBUG
38         log << "IPIn::recv: IPHeader: " << iph << "\n";
39 #endif
40         if (iph.version != 4)
41         {
42             drop("Versión IP incorrecta", iph);
43             continue;
44         }
45         if (!iph.check_checksum())
46         {
47             drop("Mal checksum", iph);
48             continue;
49         }
50         // No es para nosotros y no forwardeamos
51         if (iph.dst != ip && !forward)
52         {
53             drop("No es para nosotros y no hacemos forward", iph);
54             continue;
55         }
56         // No es para nosotros pero forwardeamos
57         else if (iph.dst != ip)
58         {
59             forward_que.transmit(buf, ip);
60             continue;
61         }
62         // Es para nosotros pero somos router
63         else if (router)
64         {
65             drop("Es para nosotros pero somos un router", iph);
66             continue;
67         }
68         // Es para nosotros y somos un host
69         // Guarda en buffer
70         buffer[iph][iph.offset] = buf.substr(iph.header_len());
71         // Si tiene más fragmentos o es un protocolo distinto, sigo
72         if (iph.mf || (iph.proto != proto))
73             continue;
74         // No hay más fragmentos, reensamblamos (de ser necesario)
75         std::string data;
76         for (offsetmap_type::iterator i = buffer[iph].begin();
77                 i != buffer[iph].end(); ++i)
78         {
79             //TODO chequear que los fragmentos estén todos
80             data += i->second;
81         }
82 #ifdef DEBUG
83         log << "IPIn::recv: Paquete completo: data = '" << data << "'\n";
84 #endif
85         buffer.erase(iph);
86         //TODO faltaría limpiar fragmentos viejos cada tanto (timer?)
87         src = iph.src;
88         dst = iph.dst;
89         return data;
90     }
91 }
92
93 // vim: set et sw=4 sts=4 :