Форум программистов, компьютерный форум, киберфорум
Pure
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  

ping и traceroute

Запись от Pure размещена 24.07.2012 в 13:29
Показов 3232 Комментарии 8

может быть кто то захочет посмотреть как эти утилиты устроены в винде.
ниже их примитивы. При желании каждый может довести функционал до уровня ping.exe, добавив немного кода.

В области включений определяем или комментим макро TRACERT, в мэйне вбиваем IP адрес цели.
в зависимости от этого будет результат

Внесены изменения для ручного формирования IP заголовка, для этого определяем макро MANUAL.

Интерфейс winsock очень близок к интерфейсу оного у линукс.

PING + TRACERT
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
#include <WinSock2.h>
#include <ws2tcpip.h>
#include <Ws2ipdef.h>
#include <windows.h>
#include <crtdbg.h>
 
#include <iostream>
using std::cout;
 
 
#pragma comment (lib,"ws2_32")
 
 
//#define TRACERT //если вместо пинга нужен трэйс
 
#define MANUAL //если надо сформировать IP заголовок вручную.
 
 
 
#ifdef MANUAL
#define PACKET_ FullPack
#else
#define PACKET_ Packet
#endif
 
typedef struct ip_hdr //заголовок IP 
{
    unsigned char verhlen;
    unsigned char tos:6;
    unsigned char additional:2;
    unsigned short totallent;
    unsigned short id;  
    unsigned short offset;
    unsigned char ttl;
    unsigned char proto;
    unsigned short checksum;
    unsigned int source;
    unsigned int destination;   
}IpHeader;
 
typedef  struct icmp_hdr //заголовок ICMP
{
    unsigned char i_type;
    unsigned char i_code;
    unsigned short i_crc;
    unsigned short i_seq;
    unsigned short i_id;
    
}IcmpHeader;
 
 
 
 
USHORT crc2 (USHORT* addr, int count) //http://www.ietf.org/rfc/rfc1071.txt подсчет CRC
{
 
    register long sum = 0;
 
    while( count > 1 )  {
        /*  This is the inner loop */
        sum += * (unsigned short*) addr++;
        count -= 2;
    }
 
    /*  Add left-over byte, if any */
    if( count > 0 )
        sum += * (unsigned char *) addr;
 
    /*  Fold 32-bit sum to 16 bits */
    while (sum>>16)
        sum = (sum & 0xffff) + (sum >> 16);
 
    return (USHORT)(~sum);
    
}
 
 
unsigned int analize(char* data, SOCKADDR_IN* adr) //разбор ответа
{
 
 
char* Ip = "";
IpHeader *pHe = (IpHeader*)data;
char Name[NI_MAXHOST]={0};
char servInfo[NI_MAXSERV]={0};
getnameinfo((struct sockaddr *) adr,sizeof (struct sockaddr),Name,  NI_MAXHOST, servInfo, NI_MAXSERV, NI_NUMERICSERV);
Ip = inet_ntoa(adr->sin_addr);
 
#ifdef TRACERT
IcmpHeader *ic = (IcmpHeader*)data;
cout<<"Reply from "<<" "<<Name<<" ["<<Ip<<"]\n";
return pHe->source;
 
#else
int TTL = (int)pHe->ttl;
data+=sizeof(IpHeader);
IcmpHeader *ic = (IcmpHeader*)data;
if(GetCurrentProcessId()==ic->i_id)//проверка что это мы слали.
cout<<"Reply from "<<Ip<<" TTL="<<TTL<<"\n";
else
cout<<"Fake packet\n";
return pHe->source;
#endif
 
}
 
int main()
{
    _CrtSetDbgFlag(33);
    const char* Ip = "213.180.204.3"; //сюда вбить пингуемый адрес, сейчас это ЯНДЕКС
        const char* IpLocal  = "тут ваш локальный адрес, для заголовка IPv4";
 
    //удаленный адрес
    SOCKADDR_IN list_adr = {0};
    list_adr.sin_addr.S_un.S_addr = inet_addr(Ip);
    list_adr.sin_family = AF_INET;
    list_adr.sin_port = htons(6666);
 
    //локальный адрес
    SOCKADDR_IN bnd = {0};
    bnd.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    bnd.sin_family = AF_INET;
    bnd.sin_port = htons(6666);
 
    WSADATA wsd = {0};
    WSAStartup(0x202,&wsd);
 
    SOCKET listn = WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,0,0,WSA_FLAG_OVERLAPPED);
    bind(listn,(sockaddr*)&bnd,sizeof(bnd));
    IcmpHeader pac = {0};
    int timeout = 3000;
    setsockopt(listn,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout)); //таймаут получения
    pac.i_type = 8;
    pac.i_code = 0;
    pac.i_seq = 0x2;
    pac.i_crc =0;
    pac.i_id = (USHORT)GetCurrentProcessId();//записать в ICMP идентификатор процесса.        
    //создаем довесок из данных в 32 байта заполненый буквой Z, чтоб было похоже на настоящее
    int size = sizeof(pac)+32;
    char* Icmp = new char [size];
    memcpy(Icmp,&pac,sizeof(pac));
    memset(Icmp+sizeof(pac),'Z',32);
 
    IcmpHeader *Packet = (IcmpHeader *)Icmp;
    Packet->i_crc = crc2((USHORT*)Packet,size);//считаем контрольную сумму пакета, заголовок+данные
    char bf [256] = {0};
    int outlent = sizeof(SOCKADDR_IN);
    SOCKADDR_IN out_ = {0};
    out_.sin_family = AF_INET;
 
 
 
#ifdef MANUAL
 
 //здесь формируем IP заголовок вручную
 // и собираем пакет наш IP+Icmp+32байта данных 
 
    int icmp_size = sizeof(pac)+32;
    size = sizeof(IpHeader)+sizeof(IcmpHeader)+32;
    int param = 1;
    setsockopt(listn,IPPROTO_IP,IP_HDRINCL,(char*)&param,sizeof(param));//сообщаем что сами слепим заголовок
    IpHeader IpHead = {0};
    IpHead.verhlen = 69;
    IpHead.ttl = 200;
    IpHead.source = inet_addr(IpLocal );
    IpHead.destination = inet_addr(Ip);
    IpHead.totallent = size-icmp_size;
    IpHead.proto = 1;
    char* FullPack = new char [size];
 
    memcpy(FullPack,&IpHead,sizeof(IpHeader));
    memcpy(FullPack+sizeof(IpHeader),Packet,icmp_size);
 
 
    //crc IP система посчитает сама, с ним можно не париться
    //однако для ICMP расчет обязателен    
 
 
#endif
 
 
#ifdef TRACERT
 
    unsigned int control = list_adr.sin_addr.S_un.S_addr; 
 
    cout<<"TRACE route to >>> "<<Ip<<" with 20 hops\n";
    for(int i=1;i<=20;++i)
    {
#ifdef MANUAL
        IpHeader* ipH = (IpHeader*)PACKET_;
        ipH->ttl = i;
#else
        setsockopt(listn,IPPROTO_IP,IP_TTL,(char*)&i,4);
#endif
        int bytes =sendto(listn,(char*)PACKET_,size,0,(sockaddr*)&list_adr,sizeof(list_adr));
        Sleep(1000);
 
        if(recvfrom(listn,bf,256,0,(sockaddr*)&out_,&outlent)==SOCKET_ERROR)
        {
            
            if(WSAGetLastError()==WSAETIMEDOUT)
            {
                cout<<"Request timeout\n";
                continue;
            }
        }   
        cout<<i<<" ";
        if(analize(bf,&out_)==control)break;
        memset(bf,0,0);
 
    }
 
#else
   //ПИНГИ
    cout<<"Pinging address >) "<<Ip<<"\n";
    
    for(int i = 0;i<4; ++i)
    {
    int bytes =sendto(listn,(char*)PACKET_,size,0,(sockaddr*)&list_adr,sizeof(list_adr));
    Sleep(1000);
 
    if(recvfrom(listn,bf,256,0,(sockaddr*)&out_,&outlent)==SOCKET_ERROR)
    {
        if(WSAGetLastError()==WSAETIMEDOUT)
        {
            cout<<"Request timeout\n";
            continue;
        }
    }
    analize(bf,&out_);
    memset(bf,0,0);
    }
#endif
 
    delete [] Icmp;
#ifdef MANUAL 
    delete [] FullPack;
#endif
 
    cout<<"COMLETE\n";
    closesocket(listn);
    WSACleanup();
 
    system("Pause");
return 0;
}
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 8
Комментарии
  1. Старый комментарий
    Аватар для Pure
    +IPv4 заголовок. вот в таком виде пусть и лежит.
    Запись от Pure размещена 25.07.2012 в 16:00 Pure вне форума
  2. Старый комментарий
    Аватар для Avazart
    Интерфейс winsock очень близок к интерфейсу оного у линукс.
    Ну не странно он ведь вроде содран с Unix
    Запись от Avazart размещена 21.10.2012 в 01:43 Avazart вне форума
  3. Старый комментарий
    Аватар для basili4
    >Ну не странно он ведь вроде содран с Unix
    Содран и обезображен асинхроным режимом.
    Запись от basili4 размещена 22.10.2012 в 10:22 basili4 вне форума
  4. Старый комментарий
    Аватар для Avazart
    Ну тут как сказать....
    Запись от Avazart размещена 22.10.2012 в 12:00 Avazart вне форума
  5. Старый комментарий
    Аватар для raxper
    ...вот еще в тему, tcping (c исходниками).
    Запись от raxper размещена 22.10.2012 в 19:26 raxper вне форума
  6. Старый комментарий
    Аватар для machito
    Цитата Сообщение от raxp
    ...вот еще в тему, tcping (c исходниками).
    raxp, извините а можно в двух словах, для чего это консольное приложение ?
    Запись от machito размещена 23.01.2013 в 00:19 machito вне форума
  7. Старый комментарий
    Аватар для raxper
    ...проверка открытых портов по TCP, виндозный аналог линуксовому tcp-пингу. Пингатор можно использовать как альтернатива ICMP-пингу.
    Запись от raxper размещена 23.01.2013 в 02:19 raxper вне форума
  8. Старый комментарий
    Аватар для machito
    Цитата Сообщение от raxp
    ...проверка открытых портов по TCP, виндозный аналог линуксовому tcp-пингу. Пингатор можно использовать как альтернатива ICMP-пингу.
    Спасибо, всё доходчиво понятно.
    Запись от machito размещена 23.01.2013 в 09:32 machito вне форума
 
Новые блоги и статьи
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru