-#include <arpa/inet.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include "busybox.h"
-
-
-/* It turns out that libc5 doesn't have proper icmp support
- * built into it header files, so we have to supplement it */
-#if __GNU_LIBRARY__ < 5
-static const int ICMP_MINLEN = 8; /* abs minimum */
-
-struct icmp_ra_addr
-{
- u_int32_t ira_addr;
- u_int32_t ira_preference;
-};
-
-
-struct icmp
-{
- u_int8_t icmp_type; /* type of message, see below */
- u_int8_t icmp_code; /* type sub code */
- u_int16_t icmp_cksum; /* ones complement checksum of struct */
- union
- {
- u_char ih_pptr; /* ICMP_PARAMPROB */
- struct in_addr ih_gwaddr; /* gateway address */
- struct ih_idseq /* echo datagram */
- {
- u_int16_t icd_id;
- u_int16_t icd_seq;
- } ih_idseq;
- u_int32_t ih_void;
-
- /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */
- struct ih_pmtu
- {
- u_int16_t ipm_void;
- u_int16_t ipm_nextmtu;
- } ih_pmtu;
-
- struct ih_rtradv
- {
- u_int8_t irt_num_addrs;
- u_int8_t irt_wpa;
- u_int16_t irt_lifetime;
- } ih_rtradv;
- } icmp_hun;
-#define icmp_pptr icmp_hun.ih_pptr
-#define icmp_gwaddr icmp_hun.ih_gwaddr
-#define icmp_id icmp_hun.ih_idseq.icd_id
-#define icmp_seq icmp_hun.ih_idseq.icd_seq
-#define icmp_void icmp_hun.ih_void
-#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void
-#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu
-#define icmp_num_addrs icmp_hun.ih_rtradv.irt_num_addrs
-#define icmp_wpa icmp_hun.ih_rtradv.irt_wpa
-#define icmp_lifetime icmp_hun.ih_rtradv.irt_lifetime
- union
- {
- struct
- {
- u_int32_t its_otime;
- u_int32_t its_rtime;
- u_int32_t its_ttime;
- } id_ts;
- struct
- {
- struct ip idi_ip;
- /* options and then 64 bits of data */
- } id_ip;
- struct icmp_ra_addr id_radv;
- u_int32_t id_mask;
- u_int8_t id_data[1];
- } icmp_dun;
-#define icmp_otime icmp_dun.id_ts.its_otime
-#define icmp_rtime icmp_dun.id_ts.its_rtime
-#define icmp_ttime icmp_dun.id_ts.its_ttime
-#define icmp_ip icmp_dun.id_ip.idi_ip
-#define icmp_radv icmp_dun.id_radv
-#define icmp_mask icmp_dun.id_mask
-#define icmp_data icmp_dun.id_data
-};
+#include "libbb.h"
+
+//config:config PING
+//config: bool "ping"
+//config: default y
+//config: select PLATFORM_LINUX
+//config: help
+//config: ping uses the ICMP protocol's mandatory ECHO_REQUEST datagram to
+//config: elicit an ICMP ECHO_RESPONSE from a host or gateway.
+//config:
+//config:config PING6
+//config: bool "ping6"
+//config: default y
+//config: depends on FEATURE_IPV6 && PING
+//config: help
+//config: This will give you a ping that can talk IPv6.
+//config:
+//config:config FEATURE_FANCY_PING
+//config: bool "Enable fancy ping output"
+//config: default y
+//config: depends on PING
+//config: help
+//config: Make the output from the ping applet include statistics, and at the
+//config: same time provide full support for ICMP packets.
+
+/* Needs socket(AF_INET, SOCK_RAW, IPPROTO_ICMP), therefore BB_SUID_MAYBE: */
+//applet:IF_PING(APPLET(ping, BB_DIR_BIN, BB_SUID_MAYBE))
+//applet:IF_PING6(APPLET(ping6, BB_DIR_BIN, BB_SUID_MAYBE))
+
+//kbuild:lib-$(CONFIG_PING) += ping.o
+//kbuild:lib-$(CONFIG_PING6) += ping.o
+
+//usage:#if !ENABLE_FEATURE_FANCY_PING
+//usage:# define ping_trivial_usage
+//usage: "HOST"
+//usage:# define ping_full_usage "\n\n"
+//usage: "Send ICMP ECHO_REQUEST packets to network hosts"
+//usage:# define ping6_trivial_usage
+//usage: "HOST"
+//usage:# define ping6_full_usage "\n\n"
+//usage: "Send ICMP ECHO_REQUEST packets to network hosts"
+//usage:#else
+//usage:# define ping_trivial_usage
+//usage: "[OPTIONS] HOST"
+//usage:# define ping_full_usage "\n\n"
+//usage: "Send ICMP ECHO_REQUEST packets to network hosts\n"
+//usage: "\nOptions:"
+//usage: "\n -4,-6 Force IP or IPv6 name resolution"
+//usage: "\n -c CNT Send only CNT pings"
+//usage: "\n -s SIZE Send SIZE data bytes in packets (default:56)"
+//usage: "\n -t TTL Set TTL"
+//usage: "\n -I IFACE/IP Use interface or IP address as source"
+//usage: "\n -W SEC Seconds to wait for the first response (default:10)"
+//usage: "\n (after all -c CNT packets are sent)"
+//usage: "\n -w SEC Seconds until ping exits (default:infinite)"
+//usage: "\n (can exit earlier with -c CNT)"
+//usage: "\n -q Quiet, only displays output at start"
+//usage: "\n and when finished"
+//usage:
+//usage:# define ping6_trivial_usage
+//usage: "[OPTIONS] HOST"
+//usage:# define ping6_full_usage "\n\n"
+//usage: "Send ICMP ECHO_REQUEST packets to network hosts\n"
+//usage: "\nOptions:"
+//usage: "\n -c CNT Send only CNT pings"
+//usage: "\n -s SIZE Send SIZE data bytes in packets (default:56)"
+//usage: "\n -I IFACE/IP Use interface or IP address as source"
+//usage: "\n -q Quiet, only displays output at start"
+//usage: "\n and when finished"
+//usage:
+//usage:#endif
+//usage:
+//usage:#define ping_example_usage
+//usage: "$ ping localhost\n"
+//usage: "PING slag (127.0.0.1): 56 data bytes\n"
+//usage: "64 bytes from 127.0.0.1: icmp_seq=0 ttl=255 time=20.1 ms\n"
+//usage: "\n"
+//usage: "--- debian ping statistics ---\n"
+//usage: "1 packets transmitted, 1 packets received, 0% packet loss\n"
+//usage: "round-trip min/avg/max = 20.1/20.1/20.1 ms\n"
+//usage:#define ping6_example_usage
+//usage: "$ ping6 ip6-localhost\n"
+//usage: "PING ip6-localhost (::1): 56 data bytes\n"
+//usage: "64 bytes from ::1: icmp6_seq=0 ttl=64 time=20.1 ms\n"
+//usage: "\n"
+//usage: "--- ip6-localhost ping statistics ---\n"
+//usage: "1 packets transmitted, 1 packets received, 0% packet loss\n"
+//usage: "round-trip min/avg/max = 20.1/20.1/20.1 ms\n"
+
+#if ENABLE_PING6
+# include <netinet/icmp6.h>
+/* I see RENUMBERED constants in bits/in.h - !!?
+ * What a fuck is going on with libc? Is it a glibc joke? */
+# ifdef IPV6_2292HOPLIMIT
+# undef IPV6_HOPLIMIT
+# define IPV6_HOPLIMIT IPV6_2292HOPLIMIT
+# endif