IPv4Reassembler::PacketStatus IPv4Reassembler::process(PDU& pdu) { IP* ip = pdu.find_pdu<IP>(); if (ip && ip->inner_pdu()) { // There's fragmentation if (ip->is_fragmented()) { key_type key = make_key(ip); // Create it or look it up, it's the same Internals::IPv4Stream& stream = streams_[key]; stream.add_fragment(ip); if (stream.is_complete()) { PDU* pdu = stream.allocate_pdu(); // Use all field values from the first fragment *ip = stream.first_fragment(); // Erase this stream, since it's already assembled streams_.erase(key); // The packet is corrupt if (!pdu) { return FRAGMENTED; } ip->inner_pdu(pdu); ip->fragment_offset(0); ip->flags(static_cast<IP::Flags>(0)); return REASSEMBLED; } else { return FRAGMENTED; } } } return NOT_FRAGMENTED; }
IPv4Reassembler::packet_status IPv4Reassembler::process(PDU &pdu) { IP *ip = pdu.find_pdu<IP>(); if(ip && ip->inner_pdu()) { // There's fragmentation if(ip->is_fragmented()) { // Create it or look it up, it's the same Internals::IPv4Stream &stream = streams[make_key(ip)]; stream.add_fragment(ip); if(stream.is_complete()) { PDU *pdu = stream.allocate_pdu(); // The packet is corrupt if(!pdu) { streams.erase(make_key(ip)); return FRAGMENTED; } ip->inner_pdu(pdu); ip->frag_off(0); return REASSEMBLED; } else return FRAGMENTED; } } return NOT_FRAGMENTED; }