Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <winsock2.h>
- #include <ws2tcpip.h>
- #include <iphlpapi.h>
- #include <chrono>
- #include <iomanip>
- #pragma comment(lib, "ws2_32.lib")
- #pragma comment(lib, "iphlpapi.lib")
- using namespace std;
- // ICMP-заголовок
- struct ICMPHeader {
- unsigned char type; // тип
- unsigned char code; // код
- unsigned short checksum; // контрольная сумма
- unsigned short id; // идентификатор
- unsigned short sequence; // номер последовательности
- };
- // вычисление контрольной суммы
- unsigned short calculate_checksum(unsigned short* buffer, int size) {
- unsigned long checksum = 0;
- while (size > 1) {
- checksum += *buffer++;
- size -= sizeof(unsigned short);
- }
- if (size == 1) {
- checksum += *(unsigned char*)buffer;
- }
- checksum = (checksum >> 16) + (checksum & 0xFFFF);
- checksum += (checksum >> 16);
- return (unsigned short)(~checksum);
- }
- int main() {
- // инициализация Winsock
- system("chcp 1251");
- WSADATA wsaData;
- if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
- cerr << "Ошибка: не удалось инициализировать Winsock." << endl;
- return 1;
- }
- string target_ip;
- cout << "Введите IP-адрес целевого узла: ";
- cin >> target_ip;
- // создание RAW-сокета
- SOCKET sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
- if (sock == INVALID_SOCKET) {
- cerr << "Ошибка: не удалось создать RAW-сокет. Код ошибки: " << WSAGetLastError() << endl;
- WSACleanup();
- return 1;
- }
- // настройка адреса назначения
- sockaddr_in dest_addr;
- dest_addr.sin_family = AF_INET;
- dest_addr.sin_port = 0;
- inet_pton(AF_INET, target_ip.c_str(), &dest_addr.sin_addr);
- // настройка таймаута для сокета
- int timeout = 1000;
- setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout));
- ICMPHeader icmp_request;
- char recv_buffer[1024];
- for (int ttl = 1; ttl <= 30; ++ttl) {
- // установка TTL
- setsockopt(sock, IPPROTO_IP, IP_TTL, (const char*)&ttl, sizeof(ttl));
- cout << ttl;
- bool reached_target = false;
- string last_ip = "";
- for (int packet = 1; packet <= 3; ++packet) { /*отправка пакета */
- // заполнение ICMP-запроса
- memset(&icmp_request, 0, sizeof(icmp_request));
- icmp_request.type = 8; // Echo Request
- icmp_request.code = 0;
- icmp_request.id = (unsigned short)GetCurrentProcessId();
- icmp_request.sequence = ttl * 3 + packet; // номер последовательности
- icmp_request.checksum = calculate_checksum((unsigned short*)&icmp_request, sizeof(icmp_request));
- // время отправки
- auto start_time = chrono::high_resolution_clock::now();
- // отправка ICMP-запроса
- int sent_bytes = sendto(sock, (const char*)&icmp_request, sizeof(icmp_request), 0, (sockaddr*)&dest_addr, sizeof(dest_addr));
- if (sent_bytes == SOCKET_ERROR) {
- cerr << "Ошибка отправки пакета. Код ошибки: " << WSAGetLastError() << endl;
- cout << " *";
- continue;
- }
- // ожидание ответа
- sockaddr_in reply_addr;
- int reply_addr_len = sizeof(reply_addr);
- int received_bytes = recvfrom(sock, recv_buffer, sizeof(recv_buffer), 0, (sockaddr*)&reply_addr, &reply_addr_len);
- // время получения ответа
- auto end_time = chrono::high_resolution_clock::now();
- double elapsed_time = chrono::duration<double, milli>(end_time - start_time).count();
- if (received_bytes > 0) {
- // преобразование IP-адреса в строку через inet_ntop
- char ip_str[INET_ADDRSTRLEN];
- inet_ntop(AF_INET, &reply_addr.sin_addr, ip_str, sizeof(ip_str));
- // Сохраняем IP-адрес
- last_ip = string(ip_str);
- // вывод информации о времени
- cout << "\t" << fixed << setprecision(2) << elapsed_time << " ms";
- // Если это целевой узел, отмечаем, что достигли цели
- if (reply_addr.sin_addr.S_un.S_addr == dest_addr.sin_addr.S_un.S_addr) {
- reached_target = true;
- }
- }
- else {
- // Таймаут
- cout << "\t*";
- }
- }
- if (!last_ip.empty()) {
- cout << "\t" << last_ip;
- }
- cout << endl;
- // Если целевой узел достигнут, прекращаем работу
- if (reached_target) {
- cout << "Целевой узел достигнут." << endl;
- break;
- }
- }
- // закрытие сокета и очистка Winsock
- closesocket(sock);
- WSACleanup();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement