#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/signal.h>
#include <string.h>
#define DEFDATALEN 56
#define MAXIPLEN 60
#define MAXICMPLEN 76
static char *hostname = NULL;
static int in_cksum(unsigned short *buf, int sz)
{
int nleft = sz;
int sum = 0;
unsigned short *w = buf;
unsigned short ans = 0;
while (nleft > 1) {
sum += *w++;
nleft -= 2;
}
if (nleft == 1) {
*(unsigned char *) (&ans) = *(unsigned char *) w;
sum += ans;
}
sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);
ans = ˜sum;
return (ans);
}
static void noresp(int ign)
{
printf("No response from %s\n", hostname);
exit(0);
}
static void ping(const char *host)
{
struct hostent *h;
struct sockaddr_in pingaddr;
struct icmp *pkt;
int pingsock, c;
char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN];
if ((pingsock = socket(AF_INET, SOCK_RAW, 1)) < 0) { /* 1 == ICMP */
perror("ping: creating a raw socket");
exit(1);
}
/* drop root privs if running setuid */
setuid(getuid());
memset(&pingaddr, 0, sizeof(struct sockaddr_in));
pingaddr.sin_family = AF_INET;
if (!(h = gethostbyname(host))) {
fprintf(stderr, "ping: unknown host %s\n", host);
exit(1);
}
memcpy(&pingaddr.sin_addr, h->h_addr, sizeof(pingaddr.sin_addr));
hostname = h->h_name;
pkt = (struct icmp *) packet;
memset(pkt, 0, sizeof(packet));
pkt->icmp_type = ICMP_ECHO;
pkt->icmp_cksum = in_cksum((unsigned short *) pkt, sizeof(packet));
c = sendto(pingsock, packet, sizeof(packet), 0,
(struct sockaddr *) &pingaddr, sizeof(struct sockaddr_in));
if (c < 0 || c != sizeof(packet)) {
if (c < 0)
perror("ping: sendto");
fprintf(stderr, "ping: write incomplete\n");
exit(1);
}
signal(SIGALRM, noresp);
alarm(2); /* give the host 5000ms to respond */
/* listen for replies */
while (1) {
struct sockaddr_in from;
size_t fromlen = sizeof(from);
if ((c = recvfrom(pingsock, packet, sizeof(packet), 0,
(struct sockaddr *) &from, &fromlen)) < 0) {
if (errno == EINTR)
continue;
perror("ping: recvfrom");
continue;
}
if (c >= 76) { /* ip + icmp */
struct iphdr *iphdr = (struct iphdr *) packet;
pkt = (struct icmp *) (packet + (iphdr->ihl << 2)); /* skip ip hdr */
if (pkt->icmp_type == ICMP_ECHOREPLY)
break;
}
}
printf("%s is alive!\n", hostname);
return;
}
int main ()
{
ping ("192.168.1.2");
}
Reference: http://www.koders.com/c/fid30EA22902AFF5800481BBC6F65DADCDAF92D6E37.aspx
Thanks... Its helpfull...:-)
ReplyDeleteGreat! Just what I needed... but where do I get in.h, ip.h, ip_icmp.h? Are these standard or proprietary?
ReplyDeleteThanks!
Yes, These are standard header files.
ReplyDeleteyour code is not working :)
ReplyDeleteraw socket need sudo permission to run... it is correct program..
Deletesize_t fromlen = sizeof(from);
use int instead of size_t "int fromlen = sizeof(from)"
The ping function doesn't return any status, so it would be difficult to know if ping succeeded or failed. If failed, what was the reason.
ReplyDelete