1010#include <stdlib.h>
1111#include <time.h>
1212#include <limits.h>
13+ #include <string.h>
14+ #include <pthread.h>
15+ #include <setjmp.h>
16+ #include <signal.h>
17+ #include <ctype.h>
1318
1419#include <sys/types.h>
1520#include <sys/socket.h>
1621#include <netinet/in.h>
1722#include <netdb.h>
1823#include <netinet/ip_icmp.h>
1924#include <netinet/ip.h>
20- #include <string.h>
21- #include <pthread.h>
22- #include <setjmp.h>
23- #include <signal.h>
2425
2526#if DEBUG > 0
2627#define pr_dbg (...) fprintf(stderr, __VA_ARGS__)
2728#else
2829#define pr_dbg (...) ;
2930#endif
3031
31- #define DELAY 8050
32+ #define MAX_NAME_SIZ 256
33+ #define DELAY 500000
3234#define BUF_SIZ 1000
3335#define LOAD_SIZ 5
3436
3537struct stuff {
38+ useconds_t delay ;
39+ char hname [MAX_NAME_SIZ ];
3640 int recv_sock , send_sock ;
3741 struct sockaddr_in recv_sockaddr , send_sockaddr ;
3842 struct hostent * h_ent ;
@@ -43,7 +47,9 @@ struct s_frame {
4347 char payload [LOAD_SIZ ];
4448};
4549
46- int ping (const char * name );
50+ void usage (int st );
51+ int ping4 (struct stuff * conn );
52+ int ping6 (struct stuff * conn );
4753int routines (struct stuff * conn );
4854unsigned short in_cksum (unsigned short * addr , size_t len );
4955void pr_bytes (const char * str , int size );
@@ -53,54 +59,136 @@ jmp_buf env;
5359
5460int main (int argc , char * argv [])
5561{
56- pr_dbg ("pr_dbg is works\n" );
57- if (argc < 2 ) {
58- fprintf (stderr , "need hostname\n" );
59- exit (1 );
62+ int res , i ;
63+ struct stuff * conn = NULL ;
64+ const char optstring [] = "hp:qd:H:" ;
65+ char q_fl = 0 , h_fl = 0 proto = 4 ;
66+ if (argc < 3 ) {
67+ usage (0 );
68+ return 1 ;
6069 }
61- if (ping (argv [1 ])) {
62- printf ("host %s is alive\n" , argv [1 ]);
63- return 0 ;
64- } else {
65- printf ("host %s is not alive\n" , argv [1 ]);
70+ conn = malloc (sizeof (struct stuff ));
71+ if (!conn ) {
72+ perror ("malloc: " );
6673 return 1 ;
6774 }
75+ conn -> delay = DELAY ;
76+ for (;;) {
77+ res = getopt (argc , argv , optstring );
78+ if (res == -1 ) {
79+ break ;
80+ }
81+ switch (res ) {
82+ case 'd' :
83+ for (i = 0 ; optarg [i ]; i ++ ) {
84+ if (!isdigit ((int )optarg [i ] & 0xff )) {
85+ usage (0 );
86+ res = 1 ;
87+ goto exit ;
88+ }
89+ }
90+ conn -> delay = atoi (optarg );
91+ break ;
92+ case 'h' :
93+ usage (1 );
94+ goto exit ;
95+ break ;
96+ case 'H' :
97+ strcpy (conn -> hname , optarg );
98+ h_fl = 1 ;
99+ break ;
100+ case 'p' :
101+ if (strcmp (optarg , "6" ) == 0 ||
102+ strcmp (optarg , "4" ) == 0 ) {
103+ proto = atoi (optarg );
104+ } else {
105+ res = 1 ;
106+ usage (0 );
107+ goto exit ;
108+ }
109+ break ;
110+ case 'q' :
111+ q_fl = 1 ;
112+ break ;
113+ case '?' :
114+ fprintf (stderr , "unrecognized option: %c\n" ,
115+ res );
116+ res = 1 ;
117+ usage (0 );
118+ goto exit ;
119+ break ;
120+ default :
121+ fprintf (stderr , "getopt return code 0x%x\n" ,
122+ res & 0xff );
123+ res = 1 ;
124+ usage (0 );
125+ goto exit ;
126+ break ;
127+ }
128+ }
129+ if (!h_fl ) {
130+ usage (0 );
131+ res = 1 ;
132+ goto exit ;
133+ }
134+ if (proto == 6 ) {
135+ fprintf (stderr , "ipv6 under construction\n" );
136+ res = 1 ;
137+ goto exit ;
138+ if (ping6 (conn ))
139+ goto succ ;
140+ else
141+ goto fail ;
142+ } else {
143+ if (ping4 (conn ))
144+ goto succ ;
145+ else
146+ goto fail ;
147+ }
148+ succ :
149+ res = 0 ;
150+ if (q_fl == 0 ) {
151+ printf ("host %s is alive\n" , conn -> hname );
152+ }
153+ goto exit ;
154+ fail :
155+ res = 1 ;
156+ if (q_fl == 0 ) {
157+ printf ("host %s is not alive\n" , conn -> hname );
158+ }
159+ exit :
160+ free (conn );
161+ exit (res );
68162}
69163
70- int ping ( const char * name )
164+ int ping4 ( struct stuff * conn )
71165{
166+ struct sigaction act ;
72167 void * succ_cnt ;
73- struct stuff * conn ;
74168 pthread_t routin_th ;
75169 int th_result ;
76- conn = malloc (sizeof (struct stuff ));
77- if (!conn ) {
78- perror ("malloc: " );
79- return 0 ;
80- }
81- conn -> h_ent = gethostbyname (name );
170+ conn -> h_ent = gethostbyname (conn -> hname );
82171 if (!conn -> h_ent ) {
83172 perror ("gethostbyname: " );
84- goto bad ;
173+ return 0 ;
85174 }
86175 if ( (conn -> send_sock = socket (AF_INET , SOCK_RAW , IPPROTO_ICMP )) ==
87176 -1 ) {
88177 perror ("socket: " );
89- goto bad ;
178+ return 0 ;
90179 }
91180 conn -> send_sockaddr .sin_family = AF_INET ;
92181 conn -> send_sockaddr .sin_addr .s_addr =
93182 * (in_addr_t * )conn -> h_ent -> h_addr_list [0 ];
94183 if ( (conn -> recv_sock = socket (AF_INET , SOCK_RAW , IPPROTO_ICMP )) ==
95184 -1 ) {
96185 perror ("socket: " );
97- goto bad ;
186+ return 0 ;
98187 }
99188 conn -> recv_sockaddr .sin_family = AF_INET ;
100189 conn -> recv_sockaddr .sin_addr .s_addr = * (long * )conn ->
101190 h_ent -> h_addr_list [0 ];
102191 /* set sighandler */
103- struct sigaction act ;
104192 memset (& act , 0 , sizeof (act ));
105193 act .sa_handler = sighndlr ;
106194 sigaction (SIGUSR1 , & act , 0 );
@@ -109,28 +197,24 @@ int ping(const char *name)
109197 (void * )conn );
110198 if (th_result != 0 ) {
111199 perror ("!!!!!ptread: " );
112- goto bad ;
200+ return 0 ;
113201 }
114- usleep (DELAY );
202+ usleep (conn -> delay );
115203 /* send SIGUSR1 to thread */
116204 pthread_kill (routin_th , SIGUSR1 );
117205 /* get the number of sucessful ping */
118206 if (pthread_join (routin_th , & succ_cnt ) == 0 ) {
119207 if (((long )succ_cnt ) >= 3 ) {
120208 pr_dbg ("total ping recieved: %lu\n" , (long )succ_cnt );
121- free (conn );
122209 return 1 ;
123210 } else {
124211 pr_dbg ("total ping recieved: %lu\n" , (long )succ_cnt );
125- goto bad ;
212+ return 0 ;
126213 }
127214 } else {
128215 perror ("pthread_joint: " );
129- goto bad ;
216+ return 0 ;
130217 }
131- bad :
132- free (conn );
133- return 0 ;
134218}
135219
136220void sighndlr (int sig )
@@ -286,6 +370,7 @@ int routines(struct stuff *conn)
286370#endif
287371 pr_dbg ("next sequence is %hu\n=============\n" , seqtmp );
288372 }
373+
289374end :
290375 /* set block for SIGUSR1 */
291376 sigemptyset (& set );
@@ -298,6 +383,7 @@ int routines(struct stuff *conn)
298383 pthread_exit (succ_cnt );
299384}
300385
386+ #if DEBUG > 1
301387void pr_bytes (const char * str , int size )
302388{
303389 unsigned char hex [] = {'0' ,'1' ,'2' ,'3' ,'4' ,'5' ,
@@ -323,6 +409,7 @@ void pr_bytes(const char *str, int size)
323409 }
324410 fprintf (stderr , "\n" );
325411}
412+ #endif
326413
327414unsigned short in_cksum (unsigned short * addr , size_t len )
328415{
@@ -347,3 +434,10 @@ unsigned short in_cksum(unsigned short *addr, size_t len)
347434 return (answer );
348435}
349436
437+ void usage (int st )
438+ {
439+ if (st )
440+ printf ("usage:./a.out [-h] -H localhost [-p 4|6] [-q] [-d]\n" );
441+ else
442+ fprintf (stderr , "usage:./a.out [-h] -H localhost [-p 4|6] [-q] [-d delay in nanosec]\n" );
443+ }
0 commit comments