1
#include
<
cstdlib
>
2
#include
<
iostream
>
3
#include
<
windows.h
>
4
5
6
using namespace std;
7
typedef struct _iphdr
//
定义IP首部
8
{
9
unsigned char h_verlen;
//
4位首部长度,4位IP版本号
10
unsigned char tos;
//
8位服务类型TOS
11
unsigned short total_len;
//
16位总长度(字节)
12
unsigned short ident;
//
16位标识
13
unsigned short frag_and_flags;
//
3位标志位
14
unsigned char ttl;
//
8位生存时间 TTL
15
unsigned char proto;
//
8位协议 (TCP, UDP 或其他)
16
unsigned short checksum;
//
16位IP首部校验和
17
unsigned
int
sourceIP;
//
32位源IP地址
18
unsigned
int
destIP;
//
32位目的IP地址
19
}IP_HEADER;
20
21
typedef struct _ihdr
22
{
23
BYTE
i_type;
//
8位类型
24
BYTE
i_code;
//
8位代码
25
USHORT i_checksum;
//
16位校验和
26
USHORT i_id;
//
识别号(一般用进程号作为识别号)
27
USHORT i_sequence;
//
报文序列号
28
ULONG i_timestamp;
//
时间戳
29
}ICMP_HEADER,
*
PICMP_HEADER;
30
31
32
USHORT checksum(USHORT
*
buff,
int
size)
33
{
34
unsigned
long
cksum
=
0
;
35
while
(size
>
1
){
36
cksum
+=*
buff
++
;
37
size
-=
sizeof(USHORT);
38
}
39
if
(size){
40
cksum
+=*
(UCHAR
*
)(buff);
41
}
42
cksum
=
(cksum
>>
16
)
+
(cksum
&
0xffff);
43
cksum
+=
(cksum
>>
16
);
44
return (USHORT)(~cksum);
45
46
}
47
48
49
50
int
main(
int
argc, char
*
argv[])
51
{
52
char a;
53
WSADATA wsa;
54
sockaddr_in dest;
55
int
nRet;
56
int
nTimeout
=
1000
;
57
//
char buff[sizeof(ICMP_HEADER)
+
32
];
58
char buff[sizeof(ICMP_HEADER)];
59
int
ttl
=
32
;
60
if
(argc
<
2
){
61
std::cout
<<
"
Usage : ping ip/host
"
<<
endl;
62
cin
>>
a;
63
exit
(
0
);
64
}
65
if
(WSAStartup(MAKEWORD(
2
,
1
),
&
wsa)!
=
0
){
66
std::cout
<<
"
Error when Initialize the socket
"
<<
endl;
67
system(
"
pause
"
);
68
exit
(
0
);
69
}
70
SOCKET sRaw
=
socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
71
if
(sRaw
==
INVALID_SOCKET){
72
std::cout
<<
"
Error when create the rawsocket
"
<<
endl;
73
cin
>>
a;
74
exit
(
0
);
75
}
76
/*
77
nRet
=
setsockopt(sRaw, IPPROTO_IP, IP_TTL, (
const
char
*
)
&
ttl,sizeof(ttl));
78
if
(nRet
==
SOCKET_ERROR){
79
std::cout
<<
"
Error shen setsockopt ttl
"
<<
endl;
80
std::cout
<<
"
Error Code :
"
<<
WSAGetLastError()
<<
endl;
81
cin
>>
a;
82
exit
(
0
);
83
}
84
*/
85
nRet
=
setsockopt(sRaw,SOL_SOCKET,SO_RCVTIMEO,(char
*
)
&
nTimeout,sizeof(nTimeout));
86
87
if
(nRet
==
SOCKET_ERROR){
88
std::cout
<<
"
Error when setsockopt sendtimeout
"
<<
endl;
89
std::cout
<<
"
Error Code :
"
<<
WSAGetLastError()
<<
endl;
90
cin
>>
a;
91
WSACleanup();
92
exit
(
0
);
93
}
94
dest.sin_addr.s_addr
=
inet_addr(argv[
1
]);
95
//
dest.sin_port
=
htons(
0
);
96
dest.sin_family
=
AF_INET;
97
98
99
100
PICMP_HEADER picmp
=
(PICMP_HEADER) buff;
101
picmp
->
i_type
=
8
;
102
//
picmp
->
i_type
=
ICMP_ECHO;
103
picmp
->
i_code
=
0
;
104
picmp
->
i_id
=
(USHORT)GetCurrentProcessId();
105
106
picmp
->
i_sequence
=
0
;
107
//
memset(
&
buff[sizeof(ICMP_HEADER)],
'
E',32);
108
USHORT nSeq
=
0
;
109
char recvbuff[
1024
];
110
sockaddr_in from;
111
int
nLen
=
sizeof(from);
112
while
(
1
){
113
static
int
nCount;
114
int
nRet;
115
116
picmp
->
i_checksum
=
0
;
117
picmp
->
i_sequence
=
nSeq
++
;
118
picmp
->
i_timestamp
=
GetTickCount();
119
picmp
->
i_checksum
=
checksum((USHORT
*
)buff,sizeof(buff));
120
121
if
(
++
nCount
>
4
)
122
break;
123
//
nRet
=
sendto(sRaw,buff,sizeof(ICMP_HEADER)
+
32
,
0
,(SOCKADDR
*
)
&
dest,sizeof(dest));
124
nRet
=
sendto(sRaw,buff,sizeof(buff),
0
,(SOCKADDR
*
)
&
dest,sizeof(dest));
125
if
(nRet
==
SOCKET_ERROR){
126
std::cout
<<
"
Error when sendto
"
<<
endl;
127
cin
>>
a;
128
exit
(
0
);
129
}
130
nRet
=
recvfrom(sRaw,recvbuff,
1024
,
0
,(sockaddr
*
)
&
from,
&
nLen);
131
if
(nRet
==
SOCKET_ERROR){
132
if
(WSAGetLastError()!
=
WSAETIMEDOUT){
133
134
std::cout
<<
"
Error when recvfrom ,Error Code:
"
<<
WSAGetLastError()
<<
endl;
135
cin
>>
a;
136
exit
(
0
);
137
}
else
138
{
139
std::cout
<<
"
Recv timeout
"
<<
endl;
140
continue;
141
}
142
}
143
int
nTick
=
GetTickCount();
144
if
(nRet
<
sizeof(IP_HEADER)
+
sizeof(ICMP_HEADER)){
145
std::cout
<<
"
recv too few bytes from :
"
<<
inet_ntoa(from.sin_addr);
146
}
147
ICMP_HEADER
*
pic
=
(ICMP_HEADER
*
)(recvbuff
+
sizeof(IP_HEADER));
148
if
(pic
->
i_type!
=
0
){
149
std::cout
<<
"
nonecho type ,recved type is :
"
<<
pic
->
i_type
<<
endl;
150
cin
>>
a;
151
exit
(
0
);
152
}
153
if
(pic
->
i_id!
=
GetCurrentProcessId()){
154
std::cout
<<
"
someone else's data
"
<<
endl;
155
cin
>>
a;
156
exit
(
0
);
157
}
158
printf(
"
%d bytes from %s:
"
,nRet,inet_ntoa(from.sin_addr));
159
printf(
"
icmp_seq = %d.
"
,pic
->
i_sequence);
160
printf(
"
time : %d ms \n
"
,nTick
-
pic
->
i_timestamp);
161
Sleep(
1000
);
162
}
163
164
165
166
167
WSACleanup();
168
system(
"
PAUSE
"
);
169
return EXIT_SUCCESS;
170
}
171