Red de conocimiento informático - Conocimiento del nombre de dominio - ¿Cómo capturar paquetes inalcanzables del puerto ICMP? Gracias.

¿Cómo capturar paquetes inalcanzables del puerto ICMP? Gracias.

#include

#include

#include

# include

#include

//#define WIN32_LEAN_AND_MEAN

#define IP_RECORD_ROUTE 0X7 //Indica que la ruta debe ser registrado

#define DEF_PACKET_SIZE 32 //Tamaño de datagrama predeterminado

#define MAX_PACKET 1024 //Longitud máxima del datagrama ICMP

#define MAX_IP_HDR_SIZE 60 //IP máxima Longitud del encabezado

#define ICMP_ECHO 8 //Solicitud de eco

#define ICMP_ECHOREPLY 0 //Respuesta de eco

#define ICMP_MIN 8 //Tamaño mínimo del datagrama ICMP

void InitPing();

void UserHelp();

void GetArgments();

USHORT CheckSum(USHORT *buffer,int size);

void FillICMPData(char *icmp_data,int datasize);

void FreeRes();

void DecodeIPOptions(char *buf, int bytes) ;

void DecodeICMPHeader(char *buf,int bytes,SOCKADDR_IN *from);

void PingTest(int timeout);

void CalSpeed ​​();

typedef struct _iphdr

{

unsigned int h_len:4; //longitud del encabezado ip

unsigned int version: 4; Versión de IP

unsigned char tos; //Tipo de servicio

unsigned short total_len; //Longitud total del datagrama

unsigned short ident; /p>

unsigned short frag_flags; //Indicadores de fragmentos

unsigned char ttl;

unsigned char proto; //Tipo de protocolo

suma de comprobación corta unsigned; ; //suma de verificación

unsigned int sourceIP; //source IP

unsigned int destIP; //dest IP

}IpHeader;

typedef estructura _icmphdr

{

> BYTE i_type; //Tipo de mensaje

BYTE i_code; //Número de código

USHORT i_cksum; //Suma de comprobación

USHORT i_id; /p>

USHORT i_seq; //número de serie

marca de tiempo ULONG;//marca de tiempo

}IcmpHeader;

typedef struct _ipoptionhdr

{

código de carácter unsigned; //Tipo de opción

unsigned char len; //Longitud de la opción

unsigned char ptr;

unsigned long addr[9]; //Lista de direcciones IP registradas

}IpOptionHeader;

#define n 5

SOCKET m_socket ;

IpOptionHeader IpOption;

SOCKADDR_IN DestAddr;

SOCKADDR_IN SourceAddr;

char *icmp_data;

p>

char *recvbuf;

USHORT seq_no;

char *Ipdest;

int datasize;

BOOL RecordFlag

doble PacketNum;

BOOL SucessFlag;

char ipd[20];

DWORD tick;

int veces[n ];

Velocidad de flotación;

FILETIME inicio, fin;

duración larga;

int timeo=0

;

/*WSADATA Esta estructura se utiliza para almacenar datos de Windows Sockets devueltos después de ser llamados por la función WSAStartup. Contiene datos ejecutados por Winsock.dll.

struct WSAData {

WORD wVersion;

WORD wHighVersion;

char szDescription[WSADESCRIPTION_LEN+1];

char szSystemStatus[WSASYSSTATUS_LEN+1];

iMaxSockets cortos sin firmar;

iMaxUdpDg corto sin firmar;

char *lpVendorInfo;

};

*/

void InitPing()

{

WSADATA wsaData;

icmp_data = NULL ;

seq_no = 0;

recvbuf = NULL;

RecordFlag = FALSE;

Ipdest = NULL;

datasize = DEF_PACKET_SIZE;

PacketNum = n;

SucessFlag = FALSE;

/*Para llamar a cualquier función API de Winsock en la aplicación,

En primer lugar, lo primero es completar la inicialización del servicio Winsock a través de la función WSAStartup, por lo que es necesario llamar a la función WSAStartup.

Los programas que utilizan Socket deben llamar a la función WSAStartup antes de utilizar Socket. El primer parámetro de esta función indica la versión de Socket solicitada por el programa.

El byte de orden superior indica la versión menor y el byte de orden inferior indica la versión principal que el sistema operativo usa. para devolver la información de versión de Socket solicitada.

Cuando una aplicación llama a la función WSAStartup, el sistema operativo busca la biblioteca de Socket correspondiente según la versión de Socket solicitada,

y luego vincula la biblioteca de Socket encontrada a la aplicación. Luego, la aplicación puede llamar a otras funciones de Socket en la biblioteca de Socket solicitada.

*/

memset(times,255,n*sizeof(times[0]));

if(WSAStartup(MAKEWORD(2,2) , &wsaData)!=0)

{

printf("WSAStartup() falló: %d\n",GetLastError());

}

m_socket = INVALID_SOCKET;

}

void UserHelp()

{

printf("UserHelp: ping -r [tamaño de datos]\n");

printf(" -r ruta de registro\n");

printf(" -n cantidad de registro\n" );

printf(" host de la máquina remota a Ping\n");

printf(" el tamaño de datos puede ser de hasta 1 KB\n");

Proceso de salida(-1);

}

void GetArgments()

{

scanf("%s",ipd) ;

Ipdest=ipd;

}

Suma de comprobación USHORT(USHORT *búfer, tamaño int)

{

unsigned long cksum=0;

while(size>1)

{

cksum+=*buffer++;

tamaño- =tamañode(USHORT);

}

if(tamaño)

{

cksum +=*(UCHAR*)buffer;

}

cksum = (cksum>>16)+ (cksum & 0xffff);

cksum +=(cksum>>16);

return (USHORT)(~cksum);

}

void FillICMPData(char *icmp_data, int datasize)

{

IcmpHeader *icmp_hdr = NULL;

char *datapart = NULL;

icmp_hdr = (IcmpHeader*)icmp_data;

icmp_hdr->i_type = ICMP_ECHO ;

icmp_hdr->i_code = 0;

icmp_hdr->i_id = (USHORT)GetCurrentProcessId();

icmp_hdr->i_c

ksum = 0;

icmp_hdr->i_seq = 0;

datapart = icmp_data + sizeof(IcmpHeader);

memset(datapart,'E',datasize -sizeof(IcmpHeader));

}

void FreeRes()

{

if(m_socket != INVALID_SOCKET)

closesocket(m_socket);

HeapFree(GetProcessHeap(), 0, recvbuf);

HeapFree(GetProcessHeap(), 0, icmp_data);

WSACleanup();

return ;

}

void DecodeIPOptions(char *buf, int bytes)

{

IpOptionHeader *ipopt = NULL;

IN_ADDR inaddr;

int i;

HOSTENT *host = NULL;

ipopt = (IpOptionHeader *)(buf+20);

printf("RR: ");

for(i = 0; i<(ipopt->ptr/ 4)-1;i++)

{

inaddr.S_un.S_addr = ipopt->addr[i];

if(i!=0)

printf(" ");

host = gethostbyaddr((char *)&inaddr.S_un.S_addr,sizeof(inaddr.S_un.S_addr),AF_INET);

if(host)

printf("(%-15s) %s\n",inet_ntoa(inaddr),host->h_name);

else

printf("(%-15s)\n",inet_ntoa(inaddr));

}

return ;

}

void DecodeICMPHeader(char *buf,int bytes,SOCKADDR_IN *from)

{

IpHeader *iphdr = NULL;

IcmpHeader *icmphdr = NULL;

iphdrlen corto sin firmar;

// DWORD tick;

static int icmpcount =0;

iphdr = (IpHeader * )buf;

iphdrlen = iphdr->h_len * 4;

// tick = Ge

tTickCount();

if((iphdrlen == MAX_IP_HDR_SIZE) && (!icmpcount))

DecodeIPOptions(buf,bytes);

if(bytes< iphdrlen + ICMP_MIN)

{

printf("Muy pocos bytes de %s\n",

inet_ntoa(from->sin_addr)); p>

}

icmphdr = (IcmpHeader*)(buf+iphdrlen);

if((icmphdr->i_type != ICMP_ECHOREPLY) )

{

printf("nonecho type %d recvd\n",icmphdr->i_type);

return ;

}

if(icmphdr->i_id != (USHORT)GetCurrentProcessId())

{

printf("¡el paquete de otra persona!\n");

return ;

}

SucessFlag = TRUE;

printf("%d bytes de %s:",bytes,inet_ntoa(from->sin_addr )) ;

printf("icmp_seq = %d. ",icmphdr->i_seq);

times[icmphdr->i_seq]=tick-icmphdr->marca de tiempo;

printf("hora: %d ms",tick-icmphdr->marca de tiempo);

printf("\n");

icmpcount++;

// Sleep(1000);

return ;

}

void PingTest(int timeout)

{

// int ret;

int readNum;

int writeNum;

int fromlen;

struct hostent *hp = NULL;

/*Crea un socket sin formato, que se utiliza para el protocolo ICMP*/

m_socket = WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,WSA_FLAG_OVERLAPPED );

/*Si la creación del socket no tiene éxito*/

if(m_socket == INVALID_SOCKET)

{

printf ( "WSASocket() falló: %d\n",WSAGetLastError());

retorno

;

}

/*Opciones de enrutamiento de registros

if(RecordFlag)

{

ZeroMemory(&IpOption ,sizeof(IpOption));

IpOption.code = IP_RECORD_ROUTE;

IpOption.ptr = 4;

IpOption.len = 39;

ret = setsockopt(m_socket, IPPROTO_IP,IP_OPTIONS,(char *)&IpOption,sizeof(IpOption));

if(ret== SOCKET_ERROR)

{

printf("setsockopt(IP_OPTIONS) falló: %d\n",WSAGetLastError());

}

}

*/

/*Establecer el valor del tiempo de espera de recepción*/

readNum = setsockopt(m_socket, SOL_SOCKET, SO_RCVTIMEO,(char *)&timeout,sizeof(timeout));

if(readNum == SOCKET_ERROR)

{

printf("setsockopt(SO_RCVTIMEO) falló: %d\n",WSAGetLastError());

return ;

}

/*Establecer el valor de tiempo de espera para el envío*/

timeout=1000;

readNum = setsockopt(m_socket , SOL_SOCKET, SO_SNDTIMEO,(char *)&timeout,sizeof(timeout));

if(readNum == SOCKET_ERROR)

{

printf("setsockopt ( SO_SNDTIMEO) falló: %d\n",WSAGetLastError());

return ;

}

/*Inicializar la dirección de destino con ceros*/

memset(&DestAddr,0,sizeof(DestAddr));

/*Establezca la familia de direcciones, lo que indica que se utiliza la familia de direcciones IP*/

DestAddr.sin_family = AF_INET;

if((DestAddr.sin_addr.s_addr = inet_addr(Ipdest))==INADDR_NONE)

{

/*Si el la entrada es un nombre de dominio, luego conviértala al formato de IP estándar, de lo contrario no se procesará */

if((hp=gethostbyname(Ipdest)) != NULL)

{

/*obtendrá La dirección IP está asignada a DestAddr*/

memcpy(&(DestAddr.sin_addr),hp->h_addr,hp->h_length);

/*Asigne el valor de la familia de direcciones al campo correspondiente en DestAddr*/

DestAddr.sin_family = hp->h_addrtype;

printf("DestAddr.sin_addr = %s\n",inet_ntoa(DestAddr.sin_addr));

}

else

{

printf("gethostbyname() falló: %d\n",WSAGetLastError());

return

}

}

/*El tamaño del datagrama debe incluir el encabezado ICMP*/

datasize +=sizeof( IcmpHeader);

// printf("datasize=%d\n",datasize);

icmp_data = (char *)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,MAX_PACKET);

recvbuf=(char *)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,MAX_PACKET);

if(!icmp_data)

{

printf(" HeapAlloc() falló:%d\n",GetLastError());

return ;

}

memset(icmp_data,0, MAX_PACKET);

FillICMPData(icmp_data,datasize);

while(1)

{

static int nCount = 0;

if(nCount++==PacketNum) //Salir mientras después de cinco pruebas

descanso;

((IcmpHeader*)icmp_data)->i_cksum = 0;

/*Establecer la hora de inicio*/

// GetSystemTimeAsFileTime(&beg);

((IcmpHeader*)icmp_data)->timestamp = timeGetTime();

((IcmpHeader*)icmp_data)->i_seq = seq_no++;

/*Calcular suma de comprobación*/

((IcmpHeader*)icmp_data)->i_cksum = CheckSum((USHORT *)icmp_data,datasize);

wri

teNum= sendto(m_socket, icmp_data, datasize, 0,(struct sockaddr*) &DestAddr,sizeof(DestAddr));

// printf("SendDataSize = %d\n",writeNum);

if(writeNum == SOCKET_ERROR)

{

if(WSAGetLastError()== WSAETIMEDOUT)

{

timeo=1;

printf("Se agotó el tiempo de envío\n");

continuar;

}

printf(" sendto() falló: %d\n",WSAGetLastError());

return ;

}

fromlen=sizeof(SourceAddr);

readNum=recvfrom(m_socket,recvbuf,MAX_PACKET, 0,(struct sockaddr*)&SourceAddr,&fromlen);

// printf("RecvDataSize = %d\n",readNum);

// tick=GetTickCount();

tick=timeGetTime();

// GetSystemTimeAsFileTime(&end);

// dur=100*(end.dwLowDateTime-beg.dwLowDateTime);

// printf("Hora: %ld us\n",dur/1000);

if(readNum == SOCKET_ERROR)

{

if(WSAGetLastError()== WSAETIMEDOUT)

{

timeo=1;

printf("Se agotó el tiempo de recepción\n");

continuar;

}

printf("recepción fallida: %d\n" ,WSAGetLastError());

return ;

}

DecodeICMPHeader(recvbuf,readNum,&SourceAddr);

}

printf("\nLos bytes de envío y recepción son %d B",writeNum+readNum);

}<

/p>

void CalSpeed()

{

int i;

int l=0;

int min= veces[0];

for(i=1;i

{

si(min>veces[i])

{

min=veces[i];

l=i;

}

}

// printf("\ntimes[l]====%d\n",times[l]);

if(times[l])

{

Velocidad = (float)(108)/times[l];

printf("\nEl TTL mínimo es %d ms",times[l]) ;

printf("\nVelocidad estimada = %.2f KB/S\n\n",Velocidad);

}

else

{

printf("\nSu host y su host de destino están en la misma LAN\n");

}

}

int main()

{

printf("Ingrese el DIP del que desea hacer ping: ");

InitPing();

GetArgments();

PingTest(1000);

CalSpeed();

// Sleep(1000);

// if(SucessFlag)

// printf("\n¡Fin, tienes %.0f registros!\n",PacketNum);

// else

// printf("\nFin, ¡sin registro!");

FreeRes();

getchar();

devolver 0;

}