Добавил:
auscoder
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Книги и уч. материалы / ICMP.tar / ICMP
.CPP/*\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
\\//\\//\\//\\//\\//\\//\\//\Lab #5/\\//\\//\\//\\//\\//\\//\\//
//\\//\\//\\//\\//\\/Pinger by Sachko Maxim\//\\//\\//\\//\\//\\
\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\*/
#include <iostream.h>
#include "icmp.h"
int main(void)
{
//Инициализация WinSocket
WSADATA WSAData;
if (WSAStartup(MAKEWORD(2,1),&WSAData) != 0)
{
printf("WSAStartup failed: %d\n",GetLastError());
}
//Открываем сокет
int sockRaw;
/*Создаем "сырой" сокет для его дальнейшего заполнения*/
sockRaw = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
if(sockRaw == INVALID_SOCKET)
{
printf("WSASocket() failed: %d\n",GetLastError());
}
//Устанавливаем таймаут (в милисекундах) на прием ICMP пакета
int timeout = 1000, bread;
bread = setsockopt(sockRaw, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
if(bread == SOCKET_ERROR)
{
printf("failed to set recv timeout: %d\n",GetLastError());
return false;
}
//7. Подготоавливаем пакет.
//***********************************************************************
SOCKADDR_IN dest_sin, from_sin; // Данные о удаленном и локальном хостах
struct hostent *from_host; // Структура хранения данных о хосте
char hname[64]; // Хост-имя удаленного компьютера
int n; // Число отсылаемых пакетов
// Ввод данных
cout << "Enter server host name : ";
cin >> hname; // вводим имя или ip-адрес хоста
cout << "Enter namber of packets : ";
cin >> n; // вводим кол-во отсылаемых пакетов
//проверка существования введеного хост-имени
if((from_host = gethostbyname(hname))==NULL)
{
cout<<"host name error"<<endl;
return 0;
}
ZeroMemory(&dest_sin, sizeof(dest_sin)); // обнуляем память
dest_sin.sin_addr.s_addr = ((struct in_addr *)from_host->h_addr_list[0])->s_addr; // IP адресс клиента
dest_sin.sin_family = AF_INET;
// **********************************************************************
char *icmp_data;
icmp_data = (char *)malloc(MAX_PACKET); // #include <stdlib.h>
memset(icmp_data,0,MAX_PACKET); // обнуляем память
IcmpHeader *icmp_hdr; // ICMP заголовок
char *datapart;
// присваеваем указатель на char указателю на ICMP заголовка
icmp_hdr = (IcmpHeader*)icmp_data;
// заполняем ICMP заголовка
icmp_hdr->i_type = ICMP_ECHO; // тип отправляемого сообщения
icmp_hdr->i_code = 0; // код отправляемого сообщения
icmp_hdr->i_id = (USHORT)GetCurrentProcessId(); // в id ICMP заголовка заносим номер тукущего процесса
icmp_hdr->i_cksum = 0; // обнуляем тестовую сумм
icmp_hdr->i_seq = 0; // обнуляем номер ICMP сообщения
datapart = icmp_data + sizeof(IcmpHeader);
// Заполняем что-нибудь в буфер для отправки.
int datasize;
datasize = DEF_PACKET_SIZE;
memset(datapart,'m', datasize - sizeof(IcmpHeader));
//8. Выполняем ping.
// **********************************************************
// Выполняем пинг
USHORT seq_no = 0; // Счетчик пакетов
char *recvbuf; // буфер присланных сообщений
recvbuf = (char*)malloc(MAX_PACKET); // выделяем память
int iRecvLen;
iRecvLen = sizeof(from_sin);
int bwrote;
while(seq_no<n) // отправляем n-ое количество пакетов
{
// обнуляем проверочную сумм у ICMP заголовке
((IcmpHeader*)icmp_data)->i_cksum = 0;
// заполняе оставшиеся поля ICMP заголовка
((IcmpHeader*)icmp_data)->timestamp = GetTickCount();
((IcmpHeader*)icmp_data)->i_seq = seq_no++;
// указываем контрольную сумму
((IcmpHeader*)icmp_data)->i_cksum = checksum((USHORT*)icmp_data,datasize);
// устанавливаем текущий TTL в IP заголовок
//bwrote = setsockopt(sockRaw, IPPROTO_IP, IP_TTL, (const char*)&TTL, sizeof(TTL));
// отсылаем пакет
bwrote = sendto(sockRaw,icmp_data,datasize,0,(struct sockaddr*)&dest_sin,sizeof(dest_sin));
if(bwrote == SOCKET_ERROR)
{
if (GetLastError() == WSAETIMEDOUT)
{
printf("timed out\n");
continue;
}
fprintf(stderr,"sendto failed: %d\n",GetLastError());
return false;
}
if (bwrote < datasize)
{
fprintf(stdout,"Wrote %d bytes\n",bwrote);
}
// принимаем пакет
bread = recvfrom(sockRaw,recvbuf,MAX_PACKET,0,(struct sockaddr*)&from_sin,&iRecvLen);
if (bread == SOCKET_ERROR)
{
if (GetLastError() == WSAETIMEDOUT)
{
printf("timed out/n");
continue;
}
fprintf(stderr,"recvfrom failed: %d\n",GetLastError());
return false;
}
// разбираем полученный пакет
decode_resp(recvbuf,bread,&from_sin);
// Ждем одну секунду...
Sleep(1000);
// ...продолжаем
}
//Завершаем работу.
// освобождаем память
free(icmp_data);
free(recvbuf);
// закрываем сокет
closesocket(sockRaw);
// Попрощаемся на последок :)
cout << "Ping OK!" << endl << endl;
cout << "Press ENTER to quit" << endl;
cin.getline(hname,15);
cin.getline(hname,15);
return 0;
// На этом все!!!
}