1 /* ping.c - check network connectivity
3 * Copyright 2014 Rob Landley <rob@landley.net>
7 USE_PING(NEWTOY(ping, "<1>1t#<0>255c#<0s#<0>65535I:W#<0w#<0q46[-46]", TOYFLAG_ROOTONLY|TOYFLAG_USR|TOYFLAG_BIN))
13 usage: ping [OPTIONS] HOST
15 Check network connectivity by sending packets to a host and reporting
18 Send ICMP ECHO_REQUEST packets to ipv4 or ipv6 addresses and prints each
19 echo it receives back, with round trip time.
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
57 // Determine IPv4 vs IPv6 type
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;
65 if (toys.optflags & FLAG_6) {
67 protocol = IPPROTO_ICMPV6;
70 protocol = IPPROTO_ICMP;
73 if (!(toys.optflags & FLAG_s)) TT.size = 56; // 64-PHDR_LEN
76 memset(&src_addr, 0, sizeof(src_addr));
79 if (!inet_pton(family, TT.iface, &src_addr)) {
80 struct ifaddrs *ifsave, *ifa = 0;
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)
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));
100 error_exit("no v%d addr for -I %s", 4+2*(family==AF_INET6), TT.iface);
102 inet_ntop(family, &src_addr, toybuf, sizeof(toybuf));
103 host = xstrdup(toybuf);
106 printf("host=%s\n", host);
109 TT.sock = xsocket(family, SOCK_RAW, protocol);