diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ec22307..7c724ce 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,6 +14,7 @@ jobs: run: | sudo apt-get update -qq sudo apt-get install libcap2-bin libtest-command-perl lcov + sudo sysctl net.ipv4.ping_group_range='0 2147483647' - name: Build run: | diff --git a/ci/test-11-nopriv-fail.pl b/ci/test-11-nopriv-fail.pl deleted file mode 100755 index 243362e..0000000 --- a/ci/test-11-nopriv-fail.pl +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/perl -w - -use English; -use Test::Command; -use Test::More; - -if( $^O eq 'darwin' ) { - plan skip_all => 'Test irrelevant on MacOS'; - exit 0; -} - -sub get_ping_gid_range { - open FD, "/proc/sys/net/ipv4/ping_group_range" or return undef; - chomp(my $line = ); - my @range = split(/\s+/, $line); - close FD; - return @range; -} - -my @gids = split(' ', $EGID); -my @allowed_gid_range = get_ping_gid_range(); - -# Linux test for unprivileged ping support -foreach(@gids) { - if ($_ >= $allowed_gid_range[0] && $_ <= $allowed_gid_range[1]) { - plan skip_all => "Userspace pings are allowed, gid $_ in range [$allowed_gid_range[0], $allowed_gid_range[1]]"; - exit 0; - } -} - -plan tests => 3; - -# run without privileges -my $fping_bin = `which fping`; chomp $fping_bin; -system("cp $fping_bin /tmp/fping.copy; chmod +x /tmp/fping.copy"); - -# fping -{ -my $cmd = Test::Command->new(cmd => "/tmp/fping.copy 127.0.0.1"); -$cmd->exit_is_num(4); -$cmd->stdout_is_eq(""); -$cmd->stderr_like(qr{: can't create socket \(must run as root\?\)}); -} diff --git a/ci/test-11-unpriv.pl b/ci/test-11-unpriv.pl new file mode 100755 index 0000000..9141c3e --- /dev/null +++ b/ci/test-11-unpriv.pl @@ -0,0 +1,57 @@ +#!/usr/bin/perl -w + +use English; +use Test::Command; +use Test::More; + +if( $^O eq 'darwin' ) { + plan skip_all => 'Test irrelevant on MacOS'; + exit 0; +} + +sub get_ping_gid_range { + open FD, "/proc/sys/net/ipv4/ping_group_range" or return undef; + chomp(my $line = ); + my @range = split(/\s+/, $line); + close FD; + return @range; +} + +my @gids = split(' ', $EGID); +my @allowed = get_ping_gid_range(); + +# Make a copy of the binary so that we get rid of setuid bit +my $fping_bin = `which fping`; chomp $fping_bin; +system("cp $fping_bin /tmp/fping.copy; chmod +x /tmp/fping.copy"); + +# Determine what test to run, based on whether unprivileged +# pings are allowed. +if(scalar grep { $_ >= $allowed[0] && $_ <= $allowed[1] } @gids) { + diag('test unprivileged mode'); + test_unprivileged_works(); +} +else { + test_privileged_fails(); +} + +sub test_unprivileged_works { + plan tests => 3; + + { + my $cmd = Test::Command->new(cmd => "fping 127.0.0.1"); + $cmd->exit_is_num(0); + $cmd->stdout_is_eq("127.0.0.1 is alive\n"); + $cmd->stderr_is_eq(""); + } +} + +sub test_privileged_fails { + plan tests => 3; + + { + my $cmd = Test::Command->new(cmd => "/tmp/fping.copy 127.0.0.1"); + $cmd->exit_is_num(4); + $cmd->stdout_is_eq(""); + $cmd->stderr_like(qr{: can't create socket \(must run as root\?\)}); + } +} diff --git a/src/fping.c b/src/fping.c index e26b216..0bd2b70 100644 --- a/src/fping.c +++ b/src/fping.c @@ -1104,11 +1104,11 @@ int main(int argc, char** argv) exit(num_noaddress ? 2 : 1); } - if (src_addr_set && socket4 >= 0) { + if (socket4 >= 0 && (src_addr_set || socktype4 == SOCK_DGRAM)) { socket_set_src_addr_ipv4(socket4, &src_addr, (socktype4 == SOCK_DGRAM) ? &ident4 : NULL); } #ifdef IPV6 - if (src_addr6_set && socket6 >= 0) { + if (socket6 >= 0 && (src_addr6_set || socktype4 == SOCK_DGRAM)) { socket_set_src_addr_ipv6(socket6, &src_addr6, (socktype6 == SOCK_DGRAM) ? &ident6 : NULL); } #endif