mcpinger/main.cpp
2024-05-08 13:27:23 +02:00

59 lines
2.0 KiB
C++

#include "cli_parser.h"
#include "network_utils.h"
#include "utils.h"
#include <thread>
#include <fstream>
#include <iostream>
#include <atomic>
std::mutex fileMutex;
void scanIp(const std::string &ip, int port, const config &cfg, const std::string &filename) {
std::string result = pingMinecraftServer(ip, port, cfg.virtualHostname, cfg.virtualPort, cfg.protocolVersion,
cfg.nextState);
if (!result.starts_with("ERROR")) {
std::lock_guard<std::mutex> lock(fileMutex); // Locking here to manage concurrent file access
std::ofstream file(filename, std::ios::app | std::ios::out);
if (!file.is_open()) {
std::cerr << "Failed to open file for writing: " << filename << std::endl;
return;
}
// Write the scan result as a tab-separated line
file << ip << '\t'
<< port << '\t'
<< cfg.virtualHostname << '\t'
<< cfg.virtualPort << '\t'
<< cfg.protocolVersion << '\t'
<< cfg.nextState << '\t'
<< result << '\n';
file.close();
}
}
int main(int argc, char *argv[]) {
config cfg;
cfg.parseCommandLine(argc, argv);
std::vector<std::string> ips = parseIps(cfg.hostname); // handles both CIDR and single IPs
std::string outputFilename = "responsive_" + makePathSafe(cfg.hostname) + ".tsv";
// Create and write headers to the output file
std::ofstream outfile(outputFilename, std::ios::out);
if (!outfile.is_open()) {
std::cerr << "Failed to open file for writing: " << outputFilename << std::endl;
return 1;
}
outfile << "IP Address\tPort\tVirtual Hostname\tVirtual Port\tProtocol Version\tNext State\tStatus\n";
outfile.close();
// Multithreaded scanning
std::vector<std::thread> threads;
for (const auto &ip: ips) {
(void) threads.emplace_back(scanIp, ip, cfg.port, std::ref(cfg), outputFilename);
usleep(10000);
}
for (auto &thread: threads) {
thread.join();
}
return 0;
}