Skip to content

Commit bb9e56b

Browse files
author
Your Name
committed
add getopt for some of cli args
1 parent 8f2352b commit bb9e56b

File tree

1 file changed

+129
-35
lines changed

1 file changed

+129
-35
lines changed

sockets/RAW/ping.c

Lines changed: 129 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -10,29 +10,33 @@
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

3537
struct 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);
4753
int routines(struct stuff *conn);
4854
unsigned short in_cksum(unsigned short *addr, size_t len);
4955
void pr_bytes(const char *str, int size);
@@ -53,54 +59,136 @@ jmp_buf env;
5359

5460
int 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

136220
void 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+
289374
end:
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
301387
void 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

327414
unsigned 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

Comments
 (0)