--- /dev/null
+#
+# Copyright (C) 2006 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+# $Id$
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=fping
+PKG_VERSION:=2.4b2_to-ipv6
+PKG_RELEASE:=1
+PKG_MD5SUM:=3ad516765514249a40d3c5b6caab812a
+
+PKG_SOURCE_URL:=http://www.fping.com/download/
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_CAT:=zcat
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/fping
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=A program to ping multiple hosts in parallel
+ DESCRIPTION:=fping is a ping(1) like program which uses the Internet Control Message Protocol\\\
+(ICMP) echo request to determine if a host is up. fping is different from ping in\\\
+that you can specify any number of hosts on the command line, or specify a file\\\
+containing the lists of hosts to ping. Instead of trying one host until it timeouts\\\
+or replies, fping will send out a ping packet and move on to the next host in a\\\
+round-robin fashion. If a host replies, it is noted and removed from the list of\\\
+hosts to check. If a host does not respond within a certain time limit and/or retry\\\
+limit it will be considered unreachable.\\\
+ URL:=http://www.fping.com
+endef
+
+define Build/Configure
+$(call Build/Configure/Default)
+endef
+
+define Build/Compile
+ $(MAKE) -j1 CC=$(TARGET_CC) CFLAGS="$(TARGET_CFLAGS)" -C $(PKG_BUILD_DIR) clean $(PKG_NAME)
+ mv $(PKG_BUILD_DIR)/$(PKG_NAME) $(PKG_BUILD_DIR)/$(PKG_NAME)4
+ $(MAKE) -j1 CC=$(TARGET_CC) CFLAGS="$(TARGET_CFLAGS) -DIPV6=1" -C $(PKG_BUILD_DIR) clean $(PKG_NAME)
+ mv $(PKG_BUILD_DIR)/$(PKG_NAME) $(PKG_BUILD_DIR)/$(PKG_NAME)6
+endef
+
+define Package/fping/install
+ mkdir -p $(1)/usr/bin
+ $(CP) $(PKG_BUILD_DIR)/$(PKG_NAME)4 $(1)/usr/bin/$(PKG_NAME)
+ $(CP) $(PKG_BUILD_DIR)/$(PKG_NAME)6 $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,fping))
--- /dev/null
+--- fping-2.4b2-to-ipv6.orig/fping.8
++++ fping-2.4b2-to-ipv6/fping.8
+@@ -1,4 +1,4 @@
+-.TH fping l\r
++.TH fping 8\r
+ .SH NAME\r
+ fping \- send ICMP ECHO_REQUEST packets to network hosts\r
+ .SH SYNOPSIS\r
+@@ -152,7 +152,7 @@
+ example none the less. \r
+ .nf\r
+ \r
+-#!/usr/local/bin/perl\r
++#!/usr/bin/perl\r
+ require 'open2.pl';\r
+ \r
+ $MAILTO = "root";\r
+@@ -178,7 +178,7 @@
+ that are currently reachable.\r
+ .nf\r
+ \r
+-#!/usr/local/bin/perl\r
++#!/usr/bin/perl\r
+ \r
+ $hosts_to_backup = `cat /etc/hosts.backup | fping -a`;\r
+ \r
+--- fping-2.4b2-to-ipv6.orig/fping.c
++++ fping-2.4b2-to-ipv6/fping.c
+@@ -42,7 +42,6 @@
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+-#define IPV6 1 /* This should be a compiler option, or even better be done from the Makefile... ;) */
+
+ #ifndef _NO_PROTO
+ #if !__STDC__ && !defined( __cplusplus ) && !defined( FUNCPROTO ) \
+@@ -101,13 +100,8 @@
+ #endif
+ #include <netinet/in_systm.h>
+
+-/* Linux has bizarre ip.h and ip_icmp.h */
+-#if defined( __linux__ )
+-#include "linux.h"
+-#else
+ #include <netinet/ip.h>
+ #include <netinet/ip_icmp.h>
+-#endif /* defined(__linux__) */
+
+ #include <arpa/inet.h>
+ #include <netdb.h>
+@@ -150,7 +144,11 @@
+ #define MIN_PING_DATA sizeof( PING_DATA )
+ #define MAX_IP_PACKET 65536 /* (theoretical) max IP packet size */
+ #define SIZE_IP_HDR 20
++#ifndef IPV6
+ #define SIZE_ICMP_HDR ICMP_MINLEN /* from ip_icmp.h */
++#else
++#define SIZE_ICMP_HDR sizeof(FPING_ICMPHDR)
++#endif
+ #define MAX_PING_DATA ( MAX_IP_PACKET - SIZE_IP_HDR - SIZE_ICMP_HDR )
+
+ /* sized so as to be like traditional ping */
+@@ -474,6 +472,35 @@
+ sizeof(opton)))
+ err(1, "setsockopt(IPV6_RTHDR)");
+ #endif
++#ifndef USE_SIN6_SCOPE_ID
++#ifdef IPV6_RECVPKTINFO
++ if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO, &opton,
++ sizeof(opton)))
++ err(1, "setsockopt(IPV6_RECVPKTINFO)");
++#else /* old adv. API */
++ if (setsockopt(s, IPPROTO_IPV6, IPV6_PKTINFO, &opton,
++ sizeof(opton)))
++ err(1, "setsockopt(IPV6_PKTINFO)");
++#endif
++#endif /* USE_SIN6_SCOPE_ID */
++#ifdef IPV6_RECVHOPLIMIT
++ if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &opton,
++ sizeof(opton)))
++ err(1, "setsockopt(IPV6_RECVHOPLIMIT)");
++#else /* old adv. API */
++ if (setsockopt(s, IPPROTO_IPV6, IPV6_HOPLIMIT, &opton,
++ sizeof(opton)))
++ err(1, "setsockopt(IPV6_HOPLIMIT)");
++#endif
++#ifdef IPV6_CHECKSUM
++#ifndef SOL_RAW
++#define SOL_RAW IPPROTO_IPV6
++#endif
++ opton = 2;
++ if (setsockopt(s, SOL_RAW, IPV6_CHECKSUM, &opton,
++ sizeof(opton)))
++ err(1, "setsockopt(SOL_RAW,IPV6_CHECKSUM)");
++#endif
+ #endif
+
+ if( ( uid = getuid() ) )
+@@ -1112,7 +1139,7 @@
+ /* but allow time for the last one to come in */
+ if( count_flag )
+ {
+- if( ( cursor->num_sent >= count ) && ( ht > cursor->timeout ) )
++ if( ( cursor->num_sent >= count ) && ( cursor->num_recv >= count || ht > cursor->timeout ) )
+ {
+ remove_job( cursor );
+ continue;
+@@ -1382,15 +1409,15 @@
+ if( h->num_recv_i <= h->num_sent_i )
+ {
+ fprintf( stderr, " xmt/rcv/%%loss = %d/%d/%d%%",
+- h->num_sent_i, h->num_recv_i,
+- ( ( h->num_sent_i - h->num_recv_i ) * 100 ) / h->num_sent_i );
++ h->num_sent_i, h->num_recv_i, h->num_sent_i > 0 ?
++ ( ( h->num_sent_i - h->num_recv_i ) * 100 ) / h->num_sent_i : 0 );
+
+ }/* IF */
+ else
+ {
+ fprintf( stderr, " xmt/rcv/%%return = %d/%d/%d%%",
+- h->num_sent_i, h->num_recv_i,
+- ( ( h->num_recv_i * 100 ) / h->num_sent_i ) );
++ h->num_sent_i, h->num_recv_i, h->num_sent_i > 0 ?
++ ( ( h->num_recv_i * 100 ) / h->num_sent_i ) : 0 );
+
+ }/* ELSE */
+
+@@ -2165,20 +2192,33 @@
+ struct addrinfo *res, hints;
+ int ret_ga;
+ char *hostname;
++ size_t len;
+
+ /* getaddrinfo */
+ bzero(&hints, sizeof(struct addrinfo));
+- hints.ai_flags = AI_CANONNAME;
++ hints.ai_flags = name_flag ? AI_CANONNAME : 0;
+ hints.ai_family = AF_INET6;
+ hints.ai_socktype = SOCK_RAW;
+ hints.ai_protocol = IPPROTO_ICMPV6;
+
+ ret_ga = getaddrinfo(name, NULL, &hints, &res);
+- if (ret_ga) errx(1, "%s", gai_strerror(ret_ga));
++ if (ret_ga) {
++ if(!quiet_flag)
++ warnx("%s", gai_strerror(ret_ga));
++ num_noaddress++;
++ return;
++ }
+ if (res->ai_canonname) hostname = res->ai_canonname;
+ else hostname = name;
+- if (!res->ai_addr) errx(1, "getaddrinfo failed");
+- (void)memcpy(&dst, res->ai_addr, sizeof(FPING_SOCKADDR)); /*res->ai_addrlen);*/
++ if (!res->ai_addr) {
++ if(!quiet_flag)
++ warnx("getaddrinfo failed");
++ num_noaddress++;
++ return;
++ }
++ len = res->ai_addrlen;
++ if (len > sizeof(FPING_SOCKADDR)) len = sizeof(FPING_SOCKADDR);
++ (void)memcpy(&dst, res->ai_addr, len);
+ add_addr(name, name, &dst);
+ #endif
+ } /* add_name() */