i coded a little alternative to ping. it uses raw sockets.
so it needs root rights.
/*
* anping 1.3
*
* ...is a simple ping programm, that
* sends icmp packets to a host to see
* whether it is up or not
*
* anping works with raw sockets, so you
* need to be root
*
* compiling: gcc anping.c -o anping
* usage: [root@localhost home]# ./anping
*
* coded by anfeu (gsicht) 06.11.2004
* anfeu@lycos.de
*
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <sys/select.h>
#include <sys/time.h>
#include <signal.h>
#define ANSWER_TIMEOUT 3
#define WHITE "[0m"
#define RED "[1;31m"
#define GREEN "[1;32m"
void printerr(char *message)
{
printf("%sERROR: %s%s\n",RED,message,WHITE);
}
void usage(char *prog)
{
printf("\n%sUSAGE:%s\n",GREEN,WHITE);
printf("%s -s [source ip] -d [target host] -t <timeout> -c <packetnum>\n",prog);
printf(" -d [host]\tdest host\n");
printf(" -p [port]\tport to connect\n");
printf(" -t [seconds]\ttimeout for answer\n");
printf(" -c [packet number]\thow much packets?\n");
printf("example: %s -s 80.80.80.80 -d 80.61.54.22 -t 1 -c 5\n\n",prog);
exit(0);
}
void sigfunc(int sig)
{
char c;
if(sig != SIGINT)
return;
else
{
printf("\n--interrupt--\n");
sleep(1);
}
exit(0);
}
// i found this function somewhere in the internet
unsigned short in_cksum(unsigned short *ptr, int nbytes)
{
register long sum;
u_short oddbyte;
register u_short answer;
sum = 0;
while(nbytes > 1)
{
sum += *ptr++;
nbytes -= 2;
}
if(nbytes == 1)
{
oddbyte = 0;
*((u_char *) &oddbyte) = *(u_char *)ptr;
sum += oddbyte;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
answer = ~sum;
return(answer);
}
////
int main(int argc, char *argv[])
{
signal(SIGINT,sigfunc);
int sock,test=1,num;
int recvd = 0,sent = 0;
int i,n,c,timeout;
struct iphdr *ip;
struct icmphdr *icmp;
struct sockaddr_in addr;
struct in_addr addr2;
fd_set fdreadme;
char *packet;
char *data = "PING";
char buffer[512];
char *hostname;
char *sip;
struct hostent *host;
for(i=0;i<8;i++)
{
if(argv[i] == NULL)
usage(argv[0]);
// if((strcmp(argv[i],"-h") != NULL) || (strcmp(argv[i],"--help") != NULL))
// usage(argv[0]);
}
while((c = getopt(argc, argv, "s:d:t:c:"))!= EOF)
{
switch (c)
{
case 's':
sip = optarg;
if(sip == NULL)
{
printerr("i don't know your ip address");
usage(argv[0]);
}
break;
case 'd':
hostname = optarg;
if(hostname == NULL)
{
printerr("do this: -d dest host");
usage(argv[0]);
}
break;
case 't':
if(optarg == NULL)
timeout = ANSWER_TIMEOUT;
timeout = atoi(optarg);
break;
case 'c':
num = 3;
if(optarg != NULL)
num = atoi(optarg);
break;
default:
usage(argv[0]);
return 1;
}
}
ip = (struct iphdr *) malloc(sizeof(struct iphdr));
icmp = (struct icmphdr *) malloc(sizeof(struct icmphdr));
packet = (char *) malloc(sizeof(struct iphdr) + sizeof(struct icmphdr) + sizeof(data) + 1);
memset(packet,0x00,sizeof(packet));
ip = (struct iphdr *)packet;
icmp = (struct icmphdr *) (packet + sizeof(struct iphdr));
strcpy(packet+sizeof(struct iphdr)+sizeof(struct icmphdr),data);
printf("\nsending ICMP packets to %s...\n\n",argv[2]);
ip->ihl = 5;
ip->version = 4;
ip->tos = 0;
ip->tot_len = sizeof(struct iphdr) + sizeof(struct icmphdr) + sizeof(data) + 1;
ip->id = htons(getuid());
ip->ttl = 255;
ip->protocol = IPPROTO_ICMP;
ip->saddr = inet_addr(sip);
ip->daddr = inet_addr(hostname);
ip->check = in_cksum((unsigned short *)ip, sizeof(struct iphdr));
sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if(sock == -1)
{
printerr("couldn't creat socket");
return -1;
}
if(setsockopt(sock, IPPROTO_IP,IP_HDRINCL,&test,sizeof(test)) < 0)
{
printerr("couldn't set IP_HDRINCL");
return -1;
}
icmp->type = ICMP_ECHO;
icmp->code = 0;
icmp->un.echo.id = 0;
icmp->un.echo.sequence = 0;
icmp->checksum = in_cksum((unsigned short *)icmp,sizeof(struct icmphdr)+sizeof(data)+1);
addr.sin_family = AF_INET;
addr.sin_port = htons(31337);
addr.sin_addr.s_addr = inet_addr(hostname);
printf("starting...\n");
for(i=0;i<num;i++)
{
fprintf(stdout,"PING...");
if((sendto(sock,packet,ip->tot_len,0,(struct sockaddr *)&addr,sizeof(struct sockaddr))) < ip->tot_len)
{
printerr("couldn't send the packet");
}
else sent++;
struct timeval tv;
tv.tv_usec = 0;
tv.tv_sec = timeout;
FD_SET(sock, &fdreadme);
FD_SET(0, &fdreadme);
if(select(sock+1, &fdreadme, NULL, NULL, &tv) < 0 )
{
printerr("select() error");
return -1;
}
if(FD_ISSET(sock, &fdreadme))
{
if(n = recv(sock, buffer, sizeof(buffer), 0) > 0)
{
addr2.s_addr = ip->daddr;
printf("received ICMP packet from %s\n",inet_ntoa(addr2));
recvd++;
}
if(n == -1)
printerr("recv() failed");
}
else
printerr("didn't receive answer. host seems down");
}
printf("\n-------- stats --------\n");
printf("%d packets transmitted, %d received\n...and the rest is silence\n",sent,recvd);
return 0;
}
/**** EOF ****/

Sign In
Register
Help
MultiQuote