]> git.llucax.com Git - z.facultad/75.74/practicos.git/blob - practicas/pipi/src/ipin.cpp
Ya estamos fragmentando! (falta testing intensivo pero parece andar)
[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, std::ostream& log):
7     ip(ip), dev(dev), log(log)
8 {}
9
10 void IPIn::drop(const std::string& msg, const std::string& buf)
11 {
12     log << "IPIn::drop: " << msg << "\n\tBuffer: " << buf << "\n";
13 }
14
15 void IPIn::drop(const std::string& msg, const IPHeader& iph)
16 {
17     log << "IPIn::drop: " << msg << "\n\tIPHeader: " << iph << "\n";
18 }
19
20 /// Recibe un paquete IP
21 std::string IPIn::recv(uint8_t proto, IPAddr& src, IPAddr& dst) throw (std::runtime_error)
22 {
23     while (true)
24     {
25         std::string buf = dev.receive();
26         // No es siquiera IP
27         if (buf.size() < IPHeader::header_len())
28         {
29             drop("Cabecera incompleta o no es IP", buf);
30             continue;
31         }
32         IPHeader iph(buf);
33 #ifdef DEBUG
34         log << "IPIn::recv: IPHeader: " << iph << "\n";
35 #endif
36         if (iph.version != 4)
37         {
38             drop("Versión IP incorrecta", iph);
39             continue;
40         }
41         if (!iph.check_checksum())
42         {
43             drop("Mal checksum", iph);
44             continue;
45         }
46         //TODO forwarding (ponerlo en una cola para el proceso que manda)
47         if (iph.dst != ip)
48         {
49             drop("No es para nosotros y no hacemos forward", iph);
50             continue;
51         }
52         // Guarda en buffer
53         buffer[iph][iph.offset] = buf.substr(iph.header_len());
54         // Si tiene más fragmentos o es un protocolo distinto, sigo
55         if (iph.mf || (iph.proto != proto))
56             continue;
57         // No hay más fragmentos, reensamblamos (de ser necesario)
58         std::string data;
59         for (offsetmap_type::iterator i = buffer[iph].begin();
60                 i != buffer[iph].end(); ++i)
61         {
62             //TODO chequear que los fragmentos estén todos
63             data += i->second;
64         }
65 #ifdef DEBUG
66         log << "IPIn::recv: Paquete completo: data = '" << data << "'\n";
67 #endif
68         buffer.erase(iph);
69         //TODO faltaría limpiar fragmentos viejos cada tanto (timer?)
70         src = iph.src;
71         dst = iph.dst;
72         return data;
73     }
74 }
75
76 // vim: set et sw=4 sts=4 :