#include <stdio.h>
#include <errno.h>
#include <sys/time.h>
#include <signal.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netdb.h>
#define PING_MAXPACKET 4096 /*
max packet size */
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 64
#endif
typedef struct par
{
int min_cycle;
int nbre_of_tries;
int time_interval;
} parameters;
typedef struct st
{
char name[7];
int connected;
int packet_size;
} host_state;
host_state host[24];
parameters
para;
int host_nbre=0;
u_char packet[PING_MAXPACKET];
int i,ident;
extern int
errno;
int globsocket; /* Socket file descriptor */
struct hostent *hp; /* Pointer to host
info */
struct sockaddr whereto;/* Who to ping */
struct sockaddr_in pktaddr;
struct sockaddr_in *to = (struct
sockaddr_in *) &whereto;
struct protoent *proto;
char *hostname;
char hnamebuf[MAXHOSTNAMELEN];
void continue_test();
void create_socket(char machname[8]);
void print_result();
void read_file(void);
/*****************************************************
* M A I N *
*****************************************************/
main()
{
int
count1, count2;
int
maxpkt = sizeof (packet);
int
addrlen = sizeof (pktaddr);
int
rcvlen;
struct icmp *msg = (struct icmp *)&packet;
read_file();
/*******************************************
* TESTS ON THE
PROTOCOLE *
*******************************************/
if ((proto = getprotobyname("icmp")) == NULL)
{
fprintf(stderr, "icmp: unknown
protocol\n");
exit(1);
}
if ((globsocket = socket(AF_INET, SOCK_RAW, proto->p_proto)) < 0)
{
perror("ping: socket");
exit(2);
}
for( ; ; ) /* infinite loop*/
{
for(count1 =1; count1<=host_nbre; count1++)
{
/********************Create The Socket*****************
* *
******************************************************/
create_socket(host[count1].name);
count2=1;
while(count2<=para.nbre_of_tries)
{
printf("\n*********************************************************\n");
printf("Trial:
%d\n",count2);
printf("%s\n", host[count1].name);
pinger();
/***********************************************************
* RECEIVING THE
ECHO_REPLY *
***********************************************************/
alarm(para.time_interval);
signal(SIGALRM, continue_test);
if((rcvlen = recvfrom(globsocket, packet, maxpkt,0,
(struct sockaddr* )&pktaddr, &addrlen))<0)
{
count2++;
}
if (rcvlen>0) {
host[count1].connected=1; /*host
connected*/
host[count1].packet_size=rcvlen;
/* size of the packet*/
printf("\nThe Host Is
Responding\n");
printf("\nThe Packet Size:
%d\n",host[count1].packet_size);
break; /*exit the loop if the
host respond to the echo*/
}
if((count2==para.nbre_of_tries)&&(rcvlen<0))
{
host[count1].connected=0; /* host not connected*/
}
}
/* end of while*/
} /* end of 2nd for*/
print_result();
sleep(1);
sleep(para.min_cycle); /* the program stops for
10 minutes between each
prop*/
/* end of the first for */
}
} /*end of main*/
/*********************************************
* CONTINUE TEST *
*********************************************/
/* THIS FUNCTION IS USED IN THE CASE OF A
HOST THAT DID NOT RESPOND
IT JUST PRINT A MESSAGE AFTER ONE SECOND THEN LET THE PROGRAM
SENDING ICMP ECHOS
*/
void continue_test()
{
printf("The Host Is Not Responding\n");
}
/********************************
* PINGER *
********************************/
/* THE PINGER IS A FUNCTION THAT SENDS AN
ICMP ECHO TO A DTE IN THE
NETWORK*/
pinger()
{
/************SENDING ICMP ECHOS*********/
static
u_char outpack[PING_MAXPACKET];
register
struct icmp *msg = (struct icmp *) outpack;
register u_char *datap = &outpack[8+sizeof(struct timeval)];
int
i, cc;
msg->icmp_type
= ICMP_ECHO;
msg->icmp_code
= 0;
msg->icmp_cksum
= 0;
msg->icmp_id
= ident = getpid() & 0xFFFF; /*
PROCESS ID */
cc=64;
/******
COMPUTE THE CHECK SUM *****/
msg->icmp_cksum
= in_cksum(msg,cc);
/********** SENDING ***************/
i
= sendto( globsocket, outpack, cc, 0, &whereto, sizeof(struct sockaddr) );
/* in the case of an error */
if(
i < 0 || i != cc )
{
if( i<0 )
perror("sendto");
printf("ping: wrote %s %d chars,
ret=%d\n",hostname, cc, i );
fflush(stdout);
}
}
/**********************************************************************************************************/
/*
this function is for Internet Protocol family headers */
in_cksum(addr, len)
u_short *addr;
int len;
{
register
int nleft = len;
register
u_short *w = addr;
register
int sum = 0;
u_short
answer = 0;
while(
nleft > 1 ) {
sum += *w++;
nleft -= 2;
}
/*
mop up an odd byte, if necessary */
if(
nleft == 1 ) {
*(u_char *)(&answer) = *(u_char
*)w ;
sum += answer;
}
/*
* add back carry outs from top 16 bits to low
16 bits
*/
sum
= (sum >> 16) + (sum & 0xffff); /*
add hi 16 to low 16 */
sum
+= (sum >> 16); /*
add possible carry */
answer
= ~sum; /* ones complement & truncate to 16 bits */
return
(answer);
}
/*****************************************
* R E A D - F I L E *
*****************************************/
/* THIS FUNCTION READS THE PARAMETERS AS
WELL AS THE DTE NAMES FROM AN
INPUT FILE*/
void read_file(void)
{
FILE *fp;
char c;
fp = fopen("input.txt", "r");
if ( fp == NULL)
{
printf(" Can not open the file input.txt \n");
return;
}
c
=fgetc(fp);
while( c != EOF)
{
if ((c=='%')&&(c!= EOF))
{
c=fgetc(fp);
fscanf(fp,"%d",¶.min_cycle);
printf("\n*********************************************************\n");
printf("%25s%d\n","The minute cycle:
",para.min_cycle);
/* the minute cycle */
fscanf(fp,"%d",¶.nbre_of_tries);
printf("%25s%d\n","The number of tries:
",para.nbre_of_tries);
fscanf(fp,"%d",¶.time_interval);
/* the interval between trials */
printf("%25s%d\n","The sec interval:
",para.time_interval);
printf("\n*********************************************************\n");
sleep(2);
printf("\nTHE LIST OF THE CONNECTED STATIONS:\n");
printf("\n*********************************************************\n");
}
if (( c== '+')&& (c!= EOF))
{
++host_nbre;
fscanf(fp,"%s",&host[host_nbre].name);
printf("Host Name: %20s\n",host[host_nbre].name);
c=fgetc(fp);
}
else c=fgetc(fp);
}
printf("\n*********************************************************\n");
sleep(2);
}
/******************************************
* CREATE THE SOCKET *
******************************************/
/* THIS FUNCTION FILL THE SOCKET'S
STRUCTURE FIELDS FOR A KNOWN HOST
IF THE HOST IS UNKNOWN, IT EXITS*/
void create_socket(char machname[8])
{
bzero((char
*)&whereto, sizeof(struct sockaddr));
to->sin_family
= AF_INET;
to->sin_addr.s_addr
= inet_addr(machname);
if(to->sin_addr.s_addr
!= (unsigned)-1)
{
strcpy(hnamebuf, machname);
hostname = hnamebuf;
}
else {
hp = gethostbyname(machname);
if (hp) {
to->sin_family =
hp->h_addrtype;
bcopy(hp->h_addr,
(caddr_t)&to->sin_addr, hp->h_length);
strncpy( hnamebuf, hp->h_name,
sizeof(hnamebuf)-1 );
hostname = hnamebuf;
}
else {
printf("%s: unknown host
\n", machname);
exit(3);
}
}
}
/***********************************************
* PRINT RESULT *
***********************************************/
/* THIS FUNCTION PRINTS THE STOLEN DTE
NAMES*/
void print_result(void)
{
int count;
for( count =1; count<=host_nbre; count++)
{
if( host[count].connected == 0)
{
printf("\n*********************************************************\n");
printf("*\n* Warning: The
Host %21s Is Not Alive*\n*", host[count].name);
}
}
printf("\n*********************************************************\n");
}
/******************************END**************************/