Forums: Ping - Forums

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Ping own coded

#1 User is offline   gsicht 

  • Private First Class
  • Icon
  • Group: Members
  • Posts: 91
  • Joined: 09-October 03

Post icon  Posted 06 November 2004 - 06:21 AM

hi,
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  ""
#define RED  ""
#define GREEN	""

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 ****/

0

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users

  • Share



Our Sponsors:


SwiftLayer Affiliate Web Hosting