#include& lt; stdio.h & gt;
#include& lt; sys / types.h & gt;
#include& lt; sys / socket.h & gt;
#include& lt; netinet / in.h & gt;
#include& lt; arpa / inet.h & gt;
#include& lt; netdb.h & gt;
#include& lt; unistd.h & gt;
#include& lt; string.h & gt;
#include& lt; stdlib.h & gt;
#include& lt; netinet / ip_icmp.h & gt;
#include& lt; time.h & gt;
#include& lt; fcntl.h & gt;
#include& lt; signal.h & gt;
#include& lt; time.h & gt;
#define PING_PKT_S 64
#define PORT_NO 0
#define PING_SLEEP_RATE 1000000 x
#define RECV_TIMEOUT 1
int
pingloop = 1;
struct
ping_pkt {
struct
icmphdr hdr;
char
msg[PING_PKT_S -
sizeof
(
struct
icmphdr)];
};
unsigned
short
checksum(
void
* b,
int
len)
{
unsigned
short
* buf = b;
unsigned
int
sum = 0;
unsigned
short
result;
for
(sum = 0; len & gt; 1; len -= 2)
sum += *buf++;
if
(len == 1)
sum += *(unsigned
char
*)buf;
sum = (sum & gt; > 16) + (sum & amp; 0xFFFF);
sum += (sum & gt; > 16);
result = ~sum;
return
result;
}
void
intHandler(
int
dummy) { pingloop = 0; }
char
* dns_lookup(
char
* addr_host,
struct
sockaddr_in* addr_con)
{
printf
("\nResolving DNS..\n & quot;);
struct
hostent* host_entity;
char
* ip = (
char
*)
malloc
(NI_MAXHOST *
sizeof
(
char
));
int
i;
if
((host_entity = gethostbyname(addr_host)) == NULL) {
return
NULL;
}
strcpy
(ip,
inet_ntoa(*(
struct
in_addr*)host_entity - >
h_addr));
(*addr_con).sin_family = host_entity - >
h_addrtype;
(*addr_con).sin_port = htons(PORT_NO);
(*addr_con).sin_addr.s_addr = *(
long
*)host_entity - >
h_addr;
return
ip;
}
char
* reverse_dns_lookup(
char
* ip_addr)
{
struct
sockaddr_in temp_addr;
socklen_t len;
char
buf[NI_MAXHOST], *ret_buf;
temp_addr.sin_family = AF_INET;
temp_addr.sin_addr.s_addr = inet_addr(ip_addr);
len =
sizeof
(
struct
sockaddr_in);
if
(getnameinfo((
struct
sockaddr*)&
temp_addr, len, buf,
sizeof
(buf), NULL,
0, NI_NAMEREQD)) {
printf
(
"
Could not resolve reverse lookup of hostname\n
& quot;);
return
NULL;
}
ret_buf
= (
char
*)
malloc
((
strlen
(buf) + 1) *
sizeof
(
char
));
strcpy
(ret_buf, buf);
return
ret_buf;
}
void
send_ping(
int
ping_sockfd,
struct
sockaddr_in* ping_addr,
char
* ping_dom,
char
* ping_ip,
char
* rev_host)
{
int
ttl_val = 64, msg_count = 0, i, addr_len, flag = 1,
msg_received_count = 0;
char
rbuffer[128];
struct
ping_pkt* r_pckt;
struct
ping_pkt pckt;
struct
sockaddr_in r_addr;
struct
timespec time_start, time_end, tfs, tfe;
long
double
rtt_msec = 0, total_msec = 0;
struct
timeval tv_out;
tv_out.tv_sec = RECV_TIMEOUT;
tv_out.tv_usec = 0;
clock_gettime(CLOCK_MONOTONIC, & tfs);
if
(setsockopt(ping_sockfd, SOL_IP, IP_TTL, &
ttl_val,
sizeof
(ttl_val))
!= 0) {
printf
(
"\nSetting socket options to TTL failed !\n
& quot;);
return
;
}
else
{
printf
("\nSocket set to TTL..\n & quot;);
}
setsockopt(ping_sockfd, SOL_SOCKET, SO_RCVTIMEO,
(
const
char
*)&
tv_out,
sizeof
tv_out);
while
(pingloop) {
flag = 1;
bzero(& pckt,
sizeof
(pckt));
pckt.hdr.type = ICMP_ECHO;
pckt.hdr.un.echo.id = getpid();
for
(i = 0; i & lt;
sizeof
(pckt.msg) - 1; i++)
pckt.msg[i] = i +
'0'
;
pckt.msg[i] = 0;
pckt.hdr.un.echo.sequence = msg_count++;
pckt.hdr.checksum
= checksum(& pckt,
sizeof
(pckt));
usleep(PING_SLEEP_RATE);
clock_gettime(CLOCK_MONOTONIC, & time_start);
if
(sendto(ping_sockfd, &
pckt,
sizeof
(pckt), 0,
(
struct
sockaddr*)ping_addr,
sizeof
(*ping_addr))& lt;
= 0) {
printf
("\nPacket Sending Failed !\n
& quot;);
flag = 0;
}
addr_len =
sizeof
(r_addr);
if
(recvfrom(ping_sockfd,
rbuffer,
sizeof
(rbuffer), 0,
(
struct
sockaddr*)&
r_addr, & addr_len)& lt;
= 0 & amp; & msg_count & gt; 1) {
printf
("\nPacket receive failed !\n
& quot;);
}
else
{
clock_gettime(CLOCK_MONOTONIC, & time_end);
double
timeElapsed
= ((
double
)(time_end.tv_nsec
- time_start.tv_nsec))
/ 1000000.0 rtt_msec
= (time_end.tv_sec - time_start.tv_sec)
* 1000.0
+ timeElapsed;
if
(flag) {
if
(!(r_pckt->hdr.type == 0 & amp; &
r_pckt->hdr.code == 0)) {
printf
(" Error..Packet received
with ICMP type
% d code % d\n
& quot;
, r_pckt->hdr.type, r_pckt->hdr.code);
}
else
{
printf
(" % d bytes from
% s(h
:
% s)(% s) msg_seq
= % d ttl = % d rtt =
% Lf ms.\n & quot;
, PING_PKT_S, ping_dom, rev_host,
ping_ip, msg_count, ttl_val,
rtt_msec);
msg_received_count++;
}
}
}
}
clock_gettime(CLOCK_MONOTONIC, & tfe);
double
timeElapsed
= ((
double
)(tfe.tv_nsec - tfs.tv_nsec)) / 1000000.0;
total_msec = (tfe.tv_sec - tfs.tv_sec) * 1000.0
+ timeElapsed
printf
("\n == = % s ping statistics ==
=\n & quot;
, ping_ip);
printf
("\n % d packets sent, % d packets received,
% f percent packet loss.Total
time
:
% Lf ms.\n\n & quot;
, msg_count, msg_received_count,
((msg_count - msg_received_count) / msg_count)
* 100.0,
total_msec);
}
int
main(
int
argc,
char
* argv[])
{
int
sockfd;
char
*ip_addr, *reverse_hostname;
struct
sockaddr_in addr_con;
int
addrlen =
sizeof
(addr_con);
char
net_buf[NI_MAXHOST];
if
(argc != 2) {
printf
("\nFormat % s & lt;
address & gt;\n & quot;, argv[0]);
return
0;
}
ip_addr = dns_lookup(argv[1], & addr_con);
if
(ip_addr == NULL) {
printf
(
"\nDNS lookup
failed !Could not resolve hostname !\n
& quot;);
return
0;
}
reverse_hostname = reverse_dns_lookup(ip_addr);
printf
("\nTrying to connect to
'%s'
IP
:
% s\n & quot;, argv[1], ip_addr);
printf
("\nReverse Lookup domain
:
% s & quot;, reverse_hostname);
sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if
(sockfd & lt; 0) {
printf
(
"\nSocket file descriptor not received !!\n
& quot;);
return
0;
}
else
printf
("\nSocket file descriptor % d received\n
& quot;
, sockfd);
signal
(SIGINT, intHandler);
send_ping(sockfd, &
addr_con, reverse_hostname, ip_addr, argv[1]);
return
0;
}