#!/usr/bin/perl -w
 
-use Test::Command tests => 12;
+use Test::Command tests => 15;
 
 my $I_HELP = "   -I, --iface=IFACE  bind to a particular interface\n";
 $I_HELP = '' if $^O eq 'darwin';
 $cmd3->exit_is_num(1);
 $cmd3->stdout_is_eq("");
 $cmd3->stderr_like(qr{^fping: (illegal|invalid) option -- '?Z'?\nsee 'fping -h' for usage information\n$});
+
+# fping with unknown long option
+my $cmd5 = Test::Command->new(cmd => "fping --unknown-long-option");
+$cmd5->exit_is_num(1);
+$cmd5->stdout_is_eq("");
+$cmd5->stderr_like(qr{^fping: (illegal|invalid) option -- '?unknown-long-option'?\nsee 'fping -h' for usage information\n$});
 
 #!/usr/bin/perl -w
 
-use Test::Command tests => 51;
+use Test::Command tests => 63;
+use Test::More;
 
-#  -c n       count of pings to send to each target (default 1)
-#  -C n       same as -c, report results in verbose format
-#  -D         print timestamp before each output line
-#  -e         show elapsed time on return packets
+#  -c n           count of pings to send to each target (default 1)
+#  -C n           same as -c, report results in verbose format
+#  --check-source discard replies not from target address
+#  -D             print timestamp before each output line
+#  -e             show elapsed time on return packets
 
 # fping -c n
 {
 });
 }
 
+# fping --check-source
+{
+my $cmd = Test::Command->new(cmd => "fping --check-source 127.0.0.1 127.0.0.2");
+$cmd->exit_is_num(0);
+$cmd->stdout_is_eq("127.0.0.1 is alive\n127.0.0.2 is alive\n");
+$cmd->stderr_is_eq("");
+}
+
+# fping --check-source (to IPv6 multicast address -> accept no reply)
+SKIP: {
+    if($ENV{SKIP_IPV6}) {
+        skip 'Skip IPv6 tests', 3;
+    }
+    my $cmd = Test::Command->new(cmd => "fping --check-source ff02::1");
+    $cmd->exit_is_num(1);
+    $cmd->stdout_is_eq("ff02::1 is unreachable\n");
+    $cmd->stderr_is_eq("");
+}
+
+# fping -c N --check-source
+SKIP: {
+    if($ENV{SKIP_IPV6}) {
+        skip 'Skip IPv6 tests', 3;
+    }
+    my $cmd = Test::Command->new(cmd => "fping -c1 --check-source 127.0.0.1 ff02::1");
+    $cmd->exit_is_num(1);
+    $cmd->stdout_like(qr{127\.0\.0\.1 : \[0\], 64 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
+ff02::1   : \[0\], timed out \(NaN avg, 100% loss\)
+});
+    $cmd->stderr_like(qr{
+127\.0\.0\.1 : xmt/rcv/%loss = 1/1/0%, min/avg/max = \d\.\d+/\d\.\d+/\d\.\d+
+ff02::1   : xmt/rcv/%loss = 1/0/100%
+});
+}
+
+# fping -C N --check-source
+SKIP: {
+    if($ENV{SKIP_IPV6}) {
+        skip 'Skip IPv6 tests', 3;
+    }
+    my $cmd = Test::Command->new(cmd => "fping -C1 --check-source 127.0.0.1 ff02::1");
+    $cmd->exit_is_num(1);
+    $cmd->stdout_like(qr{127\.0\.0\.1 : \[0\], 64 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
+ff02::1   : \[0\], timed out \(NaN avg, 100% loss\)
+});
+    $cmd->stderr_like(qr{
+127\.0\.0\.1 : \d\.\d+
+ff02::1   : -
+});
+}
+
 # fping -D
 {
 my $cmd = Test::Command->new(cmd => "fping -D -c 2 -p 100 127.0.0.1");
 
 C<-> indicating that no response was received to the fourth request.  This
 option overrides B<-a> or B<-u>.
 
+=item B<--check-source>
+
+Discard Echo replies that are sourced from a different address than the target
+address. This avoids spurious reachability results on busy monitoring systems
+where two B<fping> instances with the same lower 16 bits of the process ID may
+be running at the same time.
+
 =item B<-d>, B<--rdns>
 
 Use DNS to lookup address of ping target. This allows you to give fping
 
 int timestamp_format_flag = 0;
 int random_data_flag = 0;
 int cumulative_stats_flag = 0;
+int check_source_flag = 0;
 #if defined(DEBUG) || defined(_DEBUG)
 int randomly_lose_flag, trace_flag, print_per_system_flag;
 int lose_factor;
         { "version", 'v', OPTPARSE_NONE },
         { "reachable", 'x', OPTPARSE_REQUIRED },
         { "fast-reachable", 'X', OPTPARSE_REQUIRED },
+        { "check-source", '0', OPTPARSE_NONE },
 #if defined(DEBUG) || defined(_DEBUG)
         { NULL, 'z', OPTPARSE_REQUIRED },
 #endif
               }else{
                 usage(1);
               }
+            } else if (strstr(optparse_state.optlongname, "check-source") != NULL) {
+                check_source_flag = 1;
+            } else {
+                usage(1);
             }
             break;
         case '4':
 
     dbg_printf("received [%d] from %s\n", this_count, h->host);
 
+    /* optionally require reply source equal to target address */
+    if (check_source_flag && addr_cmp((struct sockaddr *)&response_addr, (struct sockaddr *)&h->saddr)) {
+        dbg_printf("discarding reply from wrong source address\n");
+        return 1;
+    }
+
     /* discard duplicates */
     if (!loop_flag && h->resp_times[this_count] >= 0) {
         if (!per_recv_flag) {
     fprintf(out, "   -S, --src=IP       set source address\n");
     fprintf(out, "   -t, --timeout=MSEC individual target initial timeout (default: %.0f ms,\n", timeout / 1e6);
     fprintf(out, "                      except with -l/-c/-C, where it's the -p period up to 2000 ms)\n");
+    fprintf(out, "       --check-source discard replies not from target address\n");
     fprintf(out, "\n");
     fprintf(out, "Output options:\n");
     fprintf(out, "   -a, --alive        show targets that are alive\n");