|
@@ -103,6 +103,70 @@ std::string pcap_processor::merge_pcaps(const std::string pcap_path) {
|
|
|
return new_filepath;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * Merges two PCAP files, given by paths in filePath and parameter pcap_path.
|
|
|
+ * @param pcap_path The path to the file which should be merged with the loaded PCAP file.
|
|
|
+ * @param output_path: The path to the output file which the two PCAPs are merged into.
|
|
|
+ * @return The string containing the file path to the merged PCAP file.
|
|
|
+ */
|
|
|
+std::string pcap_processor::merge_pcaps_into(const std::string pcap_path, const std::string output_path) {
|
|
|
+ // If filename does not end with .pcap, add .pcap extension
|
|
|
+ std::string new_filepath = output_path;
|
|
|
+ const std::string &pcap_ext = ".pcap";
|
|
|
+ std::string::size_type h = new_filepath.rfind('.', new_filepath.length());
|
|
|
+ if (h != std::string::npos) {
|
|
|
+ if (new_filepath.compare(h, new_filepath.length() - h, pcap_ext) != 0) {
|
|
|
+ new_filepath.append(pcap_ext);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ new_filepath.append(pcap_ext);
|
|
|
+ }
|
|
|
+
|
|
|
+ FileSniffer sniffer_base(filePath);
|
|
|
+ SnifferIterator iterator_base = sniffer_base.begin();
|
|
|
+
|
|
|
+ FileSniffer sniffer_attack(pcap_path);
|
|
|
+ SnifferIterator iterator_attack = sniffer_attack.begin();
|
|
|
+
|
|
|
+ PacketWriter writer(new_filepath, PacketWriter::ETH2);
|
|
|
+
|
|
|
+ bool all_attack_pkts_processed = false;
|
|
|
+ // Go through base PCAP and merge packets by timestamp
|
|
|
+ for (; iterator_base != sniffer_base.end();) {
|
|
|
+ auto tstmp_base = (iterator_base->timestamp().seconds()) + (iterator_base->timestamp().microseconds()*1e-6);
|
|
|
+ auto tstmp_attack = (iterator_attack->timestamp().seconds()) + (iterator_attack->timestamp().microseconds()*1e-6);
|
|
|
+ if (!all_attack_pkts_processed && tstmp_attack <= tstmp_base) {
|
|
|
+ try {
|
|
|
+ writer.write(*iterator_attack);
|
|
|
+ } catch (serialization_error) {
|
|
|
+ std::cout << std::setprecision(15) << "Could not serialize attack packet with timestamp " << tstmp_attack << std::endl;
|
|
|
+ }
|
|
|
+ iterator_attack++;
|
|
|
+ if (iterator_attack == sniffer_attack.end())
|
|
|
+ all_attack_pkts_processed = true;
|
|
|
+ } else {
|
|
|
+ try {
|
|
|
+ writer.write(*iterator_base);
|
|
|
+ } catch (serialization_error) {
|
|
|
+ std::cout << "Could not serialize base packet with timestamp " << std::setprecision(15) << tstmp_attack << std::endl;
|
|
|
+ }
|
|
|
+ iterator_base++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // This may happen if the base PCAP is smaller than the attack PCAP
|
|
|
+ // In this case append the remaining packets of the attack PCAP
|
|
|
+ for (; iterator_attack != sniffer_attack.end(); iterator_attack++) {
|
|
|
+ try {
|
|
|
+ writer.write(*iterator_attack);
|
|
|
+ } catch (serialization_error) {
|
|
|
+ auto tstmp_attack = (iterator_attack->timestamp().seconds()) + (iterator_attack->timestamp().microseconds()*1e-6);
|
|
|
+ std::cout << "Could not serialize attack packet with timestamp " << std::setprecision(15) << tstmp_attack << std::endl;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return new_filepath;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* Collect statistics of the loaded PCAP file. Calls for each packet the method process_packets.
|
|
|
*/
|
|
@@ -337,6 +401,7 @@ using namespace boost::python;
|
|
|
BOOST_PYTHON_MODULE (libpcapreader) {
|
|
|
class_<pcap_processor>("pcap_processor", init<std::string, std::string>())
|
|
|
.def("merge_pcaps", &pcap_processor::merge_pcaps)
|
|
|
+ .def("merge_pcaps_into", &pcap_processor::merge_pcaps_into)
|
|
|
.def("collect_statistics", &pcap_processor::collect_statistics)
|
|
|
.def("get_timestamp_mu_sec", &pcap_processor::get_timestamp_mu_sec)
|
|
|
.def("write_to_database", &pcap_processor::write_to_database);
|