首页 -> 网络技术 -> 技术前哨 -> 正文
Ping的源代码

#pragma pack(4)

#define WIN32_LEAN_AND_MEAN

#include

#include

#include

#define ICMP_ECHO 8

#define ICMP_ECHOREPLY 0

#define ICMP_MIN 8 // minimum 8 byte icmp packet (just header)

/* The IP header */

typedef struct iphdr {

unsigned int h_len:4; // length of the header

unsigned int version:4; // Version of IP

unsigned char tos; // Type of service

unsigned short total_len; // total length of the packet

unsigned short ident; // unique identifier

unsigned short frag_and_flags; // flags

unsigned char ttl;

unsigned char proto; // protocol (TCP, UDP etc)

unsigned short checksum; // IP checksum

unsigned int sourceIP;

unsigned int destIP;

}IpHeader;

//

// ICMP header

//

typedef struct _ihdr {

BYTE i_type;

BYTE i_code; /* type sub code */

USHORT i_cksum;

USHORT i_id;

USHORT i_seq;

/* This is not the std header, but we reserve space for time */

ULONG timestamp;

}IcmpHeader;

#define STATUS_FAILED 0xFFFF

#define DEF_PACKET_SIZE 32

#define MAX_PACKET 1024

#define xmalloc(s) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(s))

#define xfree(p) HeapFree (GetProcessHeap(),0,(p))

void fill_icmp_data(char *, int);

USHORT checksum(USHORT *, int);

void decode_resp(char *,int ,struct sockaddr_in *);

void Usage(char *progname){

fprintf(stderr,"Usage:\n");

fprintf(stderr,"%s [data_size]\n",progname);

fprintf(stderr,"datasize can be up to 1Kb\n");

ExitProcess(STATUS_FAILED);

}

int main(int argc, char **argv){

WSADATA wsaData;

SOCKET sockRaw;

struct sockaddr_in dest,from;

struct hostent * hp;

int bread,datasize;

int fromlen = sizeof(from);

int timeout = 1000;

char *dest_ip;

char *icmp_data;

char *recvbuf;

unsigned int addr=0;

USHORT seq_no = 0;

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

fprintf(stderr,"WSAStartup failed: %d\n",GetLastError());

ExitProcess(STATUS_FAILED);

}

if (argc <2 ) {

Usage(argv[0]);

}

sockRaw = WSASocket (AF_INET,

SOCK_RAW,

IPPROTO_ICMP,

NULL, 0,0);

if (sockRaw == INVALID_SOCKET) {

fprintf(stderr,"WSASocket() failed: %d\n",WSAGetLastError());

ExitProcess(STATUS_FAILED);

}

bread = setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,

sizeof(timeout));

if(bread == SOCKET_ERROR) {

fprintf(stderr,"failed to set recv timeout: %d\n",WSAGetLastError());

ExitProcess(STATUS_FAILED);

}

timeout = 1000;

bread = setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout,

sizeof(timeout));

if(bread == SOCKET_ERROR) {

fprintf(stderr,"failed to set send timeout: %d\n",WSAGetLastError());

ExitProcess(STATUS_FAILED);

}

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

hp = gethostbyname(argv[1]);

if (!hp){

addr = inet_addr(argv[1]);

}

if ((!hp) && (addr == INADDR_NONE) ) {

fprintf(stderr,"Unable to resolve %s\n",argv[1]);

ExitProcess(STATUS_FAILED);

}

if (hp != NULL)

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

else

dest.sin_addr.s_addr = addr;

if (hp)

dest.sin_family = hp->h_addrtype;

else

dest.sin_family = AF_INET;

dest_ip = inet_ntoa(dest.sin_addr);

if (argc >2) {

datasize = atoi(argv[2]);

if (datasize == 0)

datasize = DEF_PACKET_SIZE;

}

else

datasize = DEF_PACKET_SIZE;

datasize += sizeof(IcmpHeader);

icmp_data = xmalloc(MAX_PACKET);

recvbuf = xmalloc(MAX_PACKET);

if (!icmp_data) {

fprintf(stderr,"HeapAlloc failed %d\n",GetLastError());

ExitProcess(STATUS_FAILED);

}

memset(icmp_data,0,MAX_PACKET);

fill_icmp_data(icmp_data,datasize);

while(1) {

int bwrote;

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

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

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

((IcmpHeader*)icmp_data)->i_cksum = checksum((USHORT*)icmp_data,

datasize);

bwrote = sendto(sockRaw,icmp_data,datasize,0,(struct sockaddr*)&dest,

sizeof(dest));

if (bwrote == SOCKET_ERROR){

if (WSAGetLastError() == WSAETIMEDOUT) {

printf("timed out\n");

continue;

}

fprintf(stderr,"sendto failed: %d\n",WSAGetLastError());

ExitProcess(STATUS_FAILED);

}

if (bwrote < datasize ) {

fprintf(stdout,"Wrote %d bytes\n",bwrote);

}

bread = recvfrom(sockRaw,recvbuf,MAX_PACKET,0,(struct sockaddr*)&from,

&fromlen);

if (bread == SOCKET_ERROR){

if (WSAGetLastError() == WSAETIMEDOUT) {

printf("timed out\n");

continue;

}

fprintf(stderr,"recvfrom failed: %d\n",WSAGetLastError());

ExitProcess(STATUS_FAILED);

}

decode_resp(recvbuf,bread,&from);

Sleep(1000);

}

return 0;

}

/*

The response is an IP packet. We must decode the IP header to locate

the ICMP data

*/

void decode_resp(char *buf, int bytes,struct sockaddr_in *from) {

IpHeader *iphdr;

IcmpHeader *icmphdr;

unsigned short iphdrlen;

iphdr = (IpHeader *)buf;

iphdrlen = iphdr->h_len * 4 ; // number of 32-bit words *4 = bytes

if (bytes < iphdrlen + ICMP_MIN) {

printf("Too few bytes from %s\n",inet_ntoa(from->sin_addr));

}

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

if (icmphdr->i_type != ICMP_ECHOREPLY) {

fprintf(stderr,"non-echo type %d recvd\n",icmphdr->i_type);

return;

}

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

fprintf(stderr,"someone else's packet!\n");

return ;

}

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

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

printf(" time: %d ms ",GetTickCount()-icmphdr->timestamp);

printf("\n");

}

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);

}

/*

Helper function to fill in various stuff in our ICMP request.

*/

void fill_icmp_data(char * icmp_data, int datasize){

IcmpHeader *icmp_hdr;

char *datapart;

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_cksum = 0;

icmp_hdr->i_seq = 0;

datapart = icmp_data + sizeof(IcmpHeader);

//

// Place some junk in the buffer.

//

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

}

 PING专题文章列表

·Ping程序在TCP/IP中的应用

·Ping命令应用实例三则

·如何正确使用Windows的Ping命令

·如何使用ping和tracert命令检测丢包

·使用Ping命令细节点特别提醒

·ping的作用

·高效排除网络故障 从用好Ping命令开始

·网关无法Ping通故障及解决方法

·通过ping检测网络故障的典型次序

·通过Ping命令排除路由器故障

·网管应透过现象轻松解决Ping故障

·检测网络故障的利器!ping命令的使用

·启用IP安全策略防Ping

·IPSec安全策略 防Ping还是要慎用

·Ping命令幕后过程及其返回信息分析

·教你快速深入了解Ping

·什么是Ping不能告诉你的?

·Ping的工作过程及单向Ping通的原因

·Ping的源代码

·show,ping,trace and debug 命令介绍

·网络不通不用愁 Ping命令来帮忙

·完美解决Vista不能Ping问题

·Ping命令不能PING通的种种解惑

·四个Ping命令判断网络的故障

·使用PING判断TCP/IP网络故障

·浅谈IP安全策略:防范被Ping与封闭端口

·伪装IP地址的洪水Ping攻击

·不可忽视 彻底封杀Ping命令漏洞

文章搜索

覆盖全国各省会城市及海外城市的网速测试
→选择要测试的地区
→选择目标测试点
>> 测试点注册