Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
8
Добавлен:
01.05.2014
Размер:
5.75 Кб
Скачать
//Пример реализации утилиты для запроса временной метки

#include "stdafx.h"
#include <math.h>
#define ICMP_ECHO ((USHORT)13)  // код сообщения ICMP_ECHO 
#define ICMP_MAXBUF ((DWORD)0x1000) // максимальный размер пакета ICMP 
#define ICMP_DATA ((DWORD)32)   // размер данных ICMP
#define ICMP_TIMEOUT ((DWORD)1000) // интервал
// макрос для инициализации структур
#define constructor() {ZeroMemory(this,sizeof(*this));} 


// структура заголовка пакета IP
typedef struct taglP_HEADER
{
	taglP_HEADER() constructor();
	unsigned char h_len:4;              // длиназаголовка
	unsigned char version :4;            // версия протокола
	unsigned char tos;                      // тип сервиса
	unsigned short totalJen;           // общая длина пакета
	unsigned short ident;                  // идентификатор пакета
	unsigned short frag_and_flags; // флаги 
	unsigned char ttl ;                     // значение TTL
	unsigned char proto;                  // код протокола
	unsigned short checksum;         // контрольная сумма
	unsigned int sourcelP;   // исходный адрес
	unsigned int destlP;                    // конечный адрес
} IP_HEADER,*PIP_HEADER;


// структура заголовка пакета ICMP
typedef struct tagICMP_MSG
{
	tagICMP_MSG() {constructor();}
	BYTE i_type;                                   // тип сообщения
	BYTE i_code;                                  // расширенный код сообщения
	USHORT i_cksum;                         // контрольная сумма
	USHORT i_id;                                 // идентификаторприложения
	USHORT i_seq;                              // номер в последовательности
	// это поле не входит в заголовок пакета и будет 
	// находиться в области дополнительных данных 
	DWORD timestamp;                       // временная метка
	DWORD timestamp_in;                       // временная метка на входе
	DWORD timestamp_out;                       // временная метка на выходе
} ICMP_MSG, *PICMP_MSG;

USHORT g_appid;


// функция: _sc
// назначение: вывод на экран кода ошибки WinSock и
// завершение работы
bool _sc(int wsacode, const char *msg=0)
{ 
	bool ret=false;
	if (wsacode==SOCKET_ERROR)
	{
		printf ("wsaerror=%d,%s\n ",WSAGetLastError(),(msg)?(msg):(""));
		ret=true;
	}
	return ret;
}


// функция:  checksum
// назначение: вычисление контрольной суммы 
USHORT checksum(USHORT* buffer,int size)
{
	unsigned long cksum=0;
	while(size>1) cksum+=*buffer++,size-=sizeof(USHORT);
	if(size)cksum+=*(UCHAR*)buffer;
	cksum=(cksum>>16)+(cksum&0xffff);
	cksum+=(cksum>>16);
	return (USHORT)(~cksum);
}


//функция:  icmp_parse 
// назначение: разбор полученных пакетов 
bool icmp_parse(IP_HEADER *iph, ICMP_MSG *icmph, sockaddr_in *from, int len)
{
	/*if(icmph->i_id=g_appid) 
	{
		printf("(:\n"); 
		return false;
	} */
	SYSTEMTIME SysTime;
	GetLocalTime(&SysTime);

	printf("Reply from %s TTL=%d \nlocal_time     =%d:%d:%d.%d ms.\nserver_time_in =%d:%d:%d.%d ms. \nserver_time_out=%d:%d:%d.%d ms.\nserver_tmestamp=%d\n\n",
		inet_ntoa(from->sin_addr),iph->ttl,
		SysTime.wHour, SysTime.wMinute, SysTime.wSecond, SysTime.wMilliseconds, 
		/*GetTickCount()-icmph->timestamp,*/ 
		icmph->timestamp_in/(60*60*1000),(icmph->timestamp_in%(60*60*1000))/60/1000,(icmph->timestamp_in%(60*1000))/1000,(icmph->timestamp_in%(1000)),
		icmph->timestamp_out/(60*60*1000),(icmph->timestamp_out%(60*60*1000))/60/1000,(icmph->timestamp_out%(60*1000))/1000,(icmph->timestamp_out%(1000)),
		icmph->timestamp_out); 
	return true;
}
//sprintf (szCurrTime, "Current time = %lu Tick count = %lu",dwCurrTime, dwTickCount);




// функция: echo
// назначение: цикл посылки/принятия сообщений
void echo(const char *hostname)
{ 
	hostent *he;
	SOCKET sock;
	WSADATA wsad;
	sockaddr_in dest;
	unsigned size;
	char buf[ICMP_MAXBUF];
	PIP_HEADER iph=(PIP_HEADER)buf;
	// инициализация библиотеки WinSock 
	if(_sc(WSAStartup(MAKEWORD(2,1),&wsad))) ExitProcess(-1);
	// создание сокета ICMP 
	sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,0,0,0);
	printf("Pinging host \\\\%s\n",hostname);
	// получение адреса хоста no его имени
	if ((he=gethostbyname(hostname))==0)
	{
		_sc(SOCKET_ERROR);
		ExitProcess(-1);
	}
	ZeroMemory(&dest,sizeof(dest)); 
	CopyMemory(&(dest.sin_addr),he->h_addr,he->h_length);
	dest.sin_family=he->h_addrtype;
	printf("Host IP %s\n",inet_ntoa(dest.sin_addr));
	
	for (;;)   //цикл посылки/принятия сообщений
	{
		ICMP_MSG data_out; 
		int len=sizeof(dest);
		size=sizeof(ICMP_MSG)+ICMP_DATA; // общий размер пакета 
		// заполнение поля необязательных данных пакета 
		memset((char*)(buf+sizeof(ICMP_MSG)),'#',ICMP_DATA); 
		// заполнение заголовка пакета
		data_out.timestamp=GetTickCount();     // время отправления 
		data_out.timestamp_in=0;
		data_out.timestamp_out=0;
		data_out.i_type=ICMP_ECHO;                 // тип
		data_out.i_id=g_appid;                              // хэндл приложения
		data_out.i_cksum=checksum((USHORT*)&data_out,size);  // контрольная сумма 
		// отправка пакета с запросом ICMP_ECHO
		_sc(sendto(sock,(char*)&data_out,size,0,(sockaddr*)&dest,sizeof(dest))); // получение ответа и разбор пакета
		do _sc(recvfrom(sock,buf,ICMP_MAXBUF,0,(sockaddr*)&dest,&len)); 
		while(!icmp_parse((IP_HEADER*)buf,(ICMP_MSG*)(buf+iph->h_len*4),&dest,ICMP_DATA)); 
		// пауза между посылаемыми пакетами 
		Sleep(ICMP_TIMEOUT);
	} 
}


// функция:  main
// назначение: точка входа в приложение
int main(int argc, char* argv[])
{
	// если нет параметров командной строки, то вывод информации
	if(argc!=2)
	{
		printf("Usage: ping.exe [hostname]\n");
	}
	else 
	{
		g_appid=(USHORT)GetCurrentProcessId();
		echo(argv[1]);
	}
	return 0;
}


Соседние файлы в папке Timestamp
  • #
    01.05.20141.23 Кб8ReadMe.txt
  • #
    01.05.2014296 б8StdAfx.cpp
  • #
    01.05.2014794 б8StdAfx.h
  • #
    01.05.20145.75 Кб8Timestamp.cpp
  • #
    01.05.20144.61 Кб8Timestamp.dsp
  • #
    01.05.2014543 б8Timestamp.dsw
  • #
    01.05.201450.18 Кб8Timestamp.ncb
  • #
    01.05.201448.64 Кб8Timestamp.opt
  • #
    01.05.20141.33 Кб8Timestamp.plg