}
/// Recibe un paquete IP
-std::string IPIn::recv(uint8_t proto, IPAddr& src, IPAddr& dst) throw (std::runtime_error)
+std::string IPIn::recv(uint8_t proto, IPAddr& src, IPAddr& dst, bool filter)
+ throw (std::runtime_error)
{
while (true)
{
+ // Reviso buffers completos a ver si puedo sacar algo
+ buffer_complete_type::iterator f = buffer_complete.find(proto);
+ if (f != buffer_complete.end()) // Hay algo
+ {
+ srcmap_type& srcmap = f->second;
+ srcmap_type::iterator b;
+ if (filter)
+ b = srcmap.find(src); // Si filtro, busco el que me interesa
+ else
+ b = srcmap.begin(); // Si no filtro, agarro el primero
+ if (b != srcmap.end())
+ {
+ src = b->first;
+ dst = (b->second).dst;
+ std::string data = b->second.data;
+ // Limpio buffers
+ srcmap.erase(src);
+ if (srcmap.empty())
+ buffer_complete.erase(proto);
+ return data;
+ }
+ }
+ // Si no pude sacar nada, recibo
std::string buf = dev.receive();
// No es siquiera IP
if (buf.size() < IPHeader::header_len())
// Es para nosotros y somos un host
// Guarda en buffer
buffer[iph][iph.offset] = buf.substr(iph.header_len());
- // Si tiene más fragmentos o es un protocolo distinto, sigo
- if (iph.mf || (iph.proto != proto))
+ // Si tiene más fragmentos, sigo
+ if (iph.mf)
continue;
// No hay más fragmentos, reensamblamos (de ser necesario)
std::string data;
<< data << "'\n";
#endif
buffer.erase(iph);
+ // Si es un protocolo distinto o no es de quien quiero, rearmo paquete
+ // (ya sé que no hay más fragmentos) y guardo en buffer nomás
+ if ((iph.proto != proto) || (filter == true && src != iph.src))
+ {
+ buffer_complete[proto][iph.src] = BufferPkt(iph.dst, data);
+ continue;
+ }
//TODO faltaría limpiar fragmentos viejos cada tanto (timer?)
src = iph.src;
dst = iph.dst;
typedef std::map< BufferKey, offsetmap_type > buffer_type;
buffer_type buffer;
+ /// Buffers de paquetes completos
+ struct BufferPkt
+ {
+ uint32_t dst;
+ std::string data;
+ BufferPkt() {}
+ BufferPkt(const IPAddr& dst, const std::string& data):
+ dst(dst), data(data) {}
+ };
+ typedef std::map< IPAddr, BufferPkt > srcmap_type;
+ typedef std::map< uint8_t, srcmap_type > buffer_complete_type;
+ buffer_complete_type buffer_complete;
+
/// Constructor
IPIn(const IPAddr& ip, Dev& dev, Dev& forward_que, bool router = false,
bool forward = false, std::ostream& log = std::cout);
void drop(const std::string& msg, const IPHeader& iph);
/// Recibe un paquete IP
- std::string recv(uint8_t proto, IPAddr& src, IPAddr& dst)
+ std::string recv(uint8_t proto, IPAddr& src, IPAddr& dst,
+ bool filter = false)
throw (std::runtime_error);
// Nada de andar copiando placas...