Mercurial > hg > toybox
comparison toys/pending/ping.c @ 1495:4542db35efd8 draft
Start on ping.c.
author | Rob Landley <rob@landley.net> |
---|---|
date | Sun, 21 Sep 2014 22:44:20 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1494:ca340df928bc | 1495:4542db35efd8 |
---|---|
1 /* ping.c - check network connectivity | |
2 * | |
3 * Copyright 2014 Rob Landley <rob@landley.net> | |
4 * | |
5 * Not in SUSv4. | |
6 | |
7 USE_PING(NEWTOY(ping, "<1>1t#<0>255c#<0s#<0>65535I:W#<0w#<0q46[-46]", TOYFLAG_ROOTONLY|TOYFLAG_USR|TOYFLAG_BIN)) | |
8 | |
9 config PING | |
10 bool "ping" | |
11 default n | |
12 help | |
13 usage: ping [OPTIONS] HOST | |
14 | |
15 Check network connectivity by sending packets to a host and reporting | |
16 its response. | |
17 | |
18 Send ICMP ECHO_REQUEST packets to ipv4 or ipv6 addresses and prints each | |
19 echo it receives back, with round trip time. | |
20 | |
21 Options: | |
22 -4, -6 Force IPv4 or IPv6 | |
23 -c CNT Send CNT many packets | |
24 -I IFACE/IP Source interface or address | |
25 -q Quiet, only displays output at start and when finished | |
26 -s SIZE Packet SIZE in bytes (default 56) | |
27 -t TTL Set Time (number of hops) To Live | |
28 -W SEC Seconds to wait for response after all packets sent (default 10) | |
29 -w SEC Exit after this many seconds | |
30 */ | |
31 | |
32 #define FOR_ping | |
33 #include "toys.h" | |
34 | |
35 #include <ifaddrs.h> | |
36 | |
37 GLOBALS( | |
38 long wait_exit; | |
39 long wait_resp; | |
40 char *iface; | |
41 long size; | |
42 long count; | |
43 long ttl; | |
44 | |
45 int sock; | |
46 ) | |
47 | |
48 void ping_main(void) | |
49 { | |
50 int family, protocol; | |
51 union { | |
52 struct in_addr in; | |
53 struct in6_addr in6; | |
54 } src_addr; | |
55 char *host = 0; | |
56 | |
57 // Determine IPv4 vs IPv6 type | |
58 | |
59 if(!(toys.optflags & (FLAG_4|FLAG_6))) { | |
60 // todo getaddrinfo instead? | |
61 if (inet_pton(AF_INET6, toys.optargs[0], (void*)&src_addr)) | |
62 toys.optflags |= FLAG_6; | |
63 } | |
64 | |
65 if (toys.optflags & FLAG_6) { | |
66 family = AF_INET6; | |
67 protocol = IPPROTO_ICMPV6; | |
68 } else { | |
69 family = AF_INET; | |
70 protocol = IPPROTO_ICMP; | |
71 } | |
72 | |
73 if (!(toys.optflags & FLAG_s)) TT.size = 56; // 64-PHDR_LEN | |
74 | |
75 if (TT.iface) { | |
76 memset(&src_addr, 0, sizeof(src_addr)); | |
77 | |
78 // IP address? | |
79 if (!inet_pton(family, TT.iface, &src_addr)) { | |
80 struct ifaddrs *ifsave, *ifa = 0; | |
81 | |
82 // Interface name? | |
83 if (!getifaddrs(&ifsave)) { | |
84 for (ifa = ifsave; ifa; ifa = ifa->ifa_next) { | |
85 if (!ifa->ifa_addr || ifa->ifa_addr->sa_family != family) continue; | |
86 if (!strcmp(ifa->ifa_name, TT.iface)) { | |
87 if (family == AF_INET) | |
88 memcpy(&src_addr, | |
89 &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr, | |
90 sizeof(struct in_addr)); | |
91 else memcpy(&src_addr, | |
92 &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr, | |
93 sizeof(struct in6_addr)); | |
94 break; | |
95 } | |
96 } | |
97 freeifaddrs(ifsave); | |
98 } | |
99 if (!ifa) | |
100 error_exit("no v%d addr for -I %s", 4+2*(family==AF_INET6), TT.iface); | |
101 } | |
102 inet_ntop(family, &src_addr, toybuf, sizeof(toybuf)); | |
103 host = xstrdup(toybuf); | |
104 } | |
105 | |
106 printf("host=%s\n", host); | |
107 | |
108 // Open raw socket | |
109 TT.sock = xsocket(family, SOCK_RAW, protocol); | |
110 } |