Unable To Ping External Hosts Using In Perl Using Net::Ping - linux

In Perl (5.16.3), I'm trying to use Net::Ping to test whether a remote host is available or not. I'm able to ping "internal" hosts which I know are online within my company's LAN, but I'm unable to ping "external" ones. Specifically, trying to ping 'www.google.com' fails.
My code:
#!/usr/bin/perl
use strict;
use warnings;
use Net::Ping;
my $hostname1 = 'prophet'; #internal
my $hostname2 = 'www.google.com'; #external
my $p;
my $rv1;
my $rv2;
$p = Net::Ping->new();
$rv1 = $p->ping($hostname1);
$rv2 = $p->ping($hostname2);
print "Response1: $rv1\n";
print "Response2: $rv2\n";
Yields this result:
[oracle#prophet:bin]$ ./ping_test
Response1: 1
Response2: 0
[oracle#prophet:bin]$
Even though using the (CentOS) ping utility does show that 'www.google.com' is available:
[oracle#prophet:bin]$ which ping; ping www.google.com
/usr/bin/ping
PING www.google.com (64.233.177.105) 56(84) bytes of data.
64 bytes from 64.233.177.105: icmp_seq=1 ttl=46 time=15.6 ms
64 bytes from 64.233.177.105: icmp_seq=2 ttl=46 time=15.6 ms
64 bytes from 64.233.177.105: icmp_seq=3 ttl=46 time=15.7 ms
64 bytes from 64.233.177.105: icmp_seq=4 ttl=46 time=16.5 ms
^C
--- www.google.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 15.614/15.884/16.547/0.394 ms
[oracle#prophet:bin]$
I realize that if I do this (in my Perl program):
$p = Net::Ping->new('icmp');
Then su - root before I run the program, it'll work...
[oracle#prophet:bin]$ su root
Password:
[root#prophet:bin]# ./ping_test
Response1: 1
Response2: 1
[root#prophet:bin]#
... but, I'd like to be able to use Net::Ping (w/ icmp packets) without having to su - root. It's actually a requirement for an automation program I need to write. It seems a little crazy to me that I can run the ping (CentOS) utility as a regular user and get the expected results, but that trying to use Net::Ping as a regular user is a no-go.
Any ideas?
G

The ping utility works because it's setuid — it runs with root privileges, even when executed by a normal user:
-rwsr-xr-x 1 root root 44168 May 7 2014 /bin/ping
Like it or not, using ICMP inherently requires root privileges. You can't do it as a normal user.
If you want to check for connectivity, consider making a TCP connection. (Or, heck, a full HTTP request.)

Related

NixOS - how to add ping command on code-server terminal

Which package should I add to extraPackages property to make ping command available?
I have tried
extraPackages = with pkgs; [ ping ];
But it didnot work, it installs completely different package.
If you mean this ping, it's in the iputils package:
bash-5.1# ping 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.075 ms
^C
--- 127.0.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.075/0.075/0.075/0.000 ms
bash-5.1# which ping
/sbin/ping
bash-5.1# ls -l /sbin/ping
lrwxrwxrwx 1 root root 69 Jan 1 1980 /sbin/ping -> /nix/store/c8i7qgcvnj3123n8k7yilimgvdl23a31-iputils-20211215/bin/ping
ping is part of iputils so adding this package to extraPackages will make it available. You can find an executable with the tool like nix-locate <bin/executable> from the package nix-index
However keep in mind that ping normally requires the SUID bit set.
This tool is available in /run/wrappers/bin/ping ( command -v ping ). This wrapper is created in nixos/modules/tasks/network-interfaces.nix:
security.wrappers = {
ping = {
owner = "root";
group = "root";
capabilities = "cap_net_raw+p";
source = "${pkgs.iputils.out}/bin/ping";
};
};

Is there a way to monitor and create a log file for my internet connection in Linux Mint 19.3 for a Time interval?

I'm experiencing some problems with my internet connection so my provider told me to make a logfile for an evening (min. 3 Hours) to see when the connection drops out to see what's the cause of the problem.
When I'm losing connection, I still remain in the network but my Inernet is simply 0B/s. Is there a way to make a log for a certain Time interval that constantly checks the internet connection (and ideally the download/upload speed). I'm kinda beginner in the Linux world and it would be very helpful when the answer will be good explained and every step will be described.
Thanks in advance.
For checking every 10 seconds that your connection is available you could use
ping 8.8.8.8 -D -i 1 2>&1 | tee my.log
where 8.8.8.8 is a DNS server run by Google.
File my.log will receive entries like:
[1583495940.797787] 64 bytes from 8.8.8.8: icmp_seq=1 ttl=55 time=17.9 ms
[1583495950.809658] 64 bytes from 8.8.8.8: icmp_seq=2 ttl=55 time=18.7 ms
ping: sendmsg: Network is unreachable
The number in square brackets is the time in seconds since 1970-01-01T00:00:00Z. For our example:
1583495950 = 2020-03-06T11:59:10Z
If you want to really transfer data, you could use a script like:
#!/bin/sh
URL=https://example.com
while [ true ]
do
wget $URL -O /dev/null 2>&1 | grep 'saved' | tee my.log
sleep 10
done
But mind the traffic cost on both sides.

Why ping unknown host is happening when inside a while loop?

I am trying to get a column from a csv file and ping each line in a while loop
But every time it just show ping:unknown host (website)
#!/bin/bash
while IFS=, read num ip; do
echo $num
ping -c 10 $ip
done <site.csv
And the format of the csv file is
1, facebook.com
2, google.com
And the result will always be
ping: unknown host facebook.com
ping: unknown host google.com
But when I just ping the website directly, it is actually working, so i think is not the network problem
-bash-4.1$ ping -c 2 facebook.com
PING facebook.com (173.252.120.6) 56(84) bytes of data.
64 bytes from edge-star-shv-12-frc3.facebook.com (173.252.120.6): icmp_seq=1 ttl=70 time=94.1 ms
64 bytes from edge-star-shv-12-frc3.facebook.com (173.252.120.6): icmp_seq=2 ttl=70 time=93.8 ms
--- facebook.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1094ms
rtt min/avg/max/mdev = 93.882/94.040/94.199/0.345 ms
Is it the while loop or read the column from the csv causing the prooblem?
Is there a way to use a wile loop to read the site from the csv file and ping it?
Following up on Glenn Jackman's suggestion that the problem is DOS line-endings, here is a simple way to make sure that they are removed from the input. Replace:
while IFS=, read num ip; do
With:
while IFS=$',\r' read num ip; do
By adding \r to IFS, this makes the shell treat the DOS character as a field separator. This means it does not become part of ip.

How to find application working or down using ping command in linux?

Is there any command to find website is working or down in linux ? Hope ping command helps...but how to check return packets successfull or not ?
ping www.google.com
Please advise is there any way to find website is working or not using ping command in shell script ?
Rather than ping use this telnet command to make sure port 80 is open:
telnet www.domain.com 80
You can even send HEAD request after opening telnet session if website is not blocking it.
Not every website responds to ping, and a successful ping does not prove the site is actually working correctly. With lynx, you can test the actual contents of a page:
lynx -dump www.google.com \
| grep --silent '________' \
&& echo "Google search form found." \
|| echo "No Google search form found."
nmap will tell you if the port is listening:
nmap www.google.com -p 80
tcptraceroute will also tell you if a port is open:
tcptraceroute www.google.com 80
There's also wget, curl...
In script you can look for echo $? output after you test using ping as explained below.
If the ping is successful which means the website is up, the echo output will return 0 else non-zero.
esunboj#L9AGC12:~$ ping 155.53.12.255
PING 155.53.12.255 (155.53.12.255) 56(84) bytes of data.
^C
--- 155.53.12.255 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2000ms
esunboj#L9AGC12:~$ echo $?
1
esunboj#L9AGC12:~$ ping 155.53.12.7
PING 155.53.12.7 (155.53.12.7) 56(84) bytes of data.
64 bytes from 155.53.12.7: icmp_req=1 ttl=48 time=239 ms
64 bytes from 155.53.12.7: icmp_req=2 ttl=48 time=240 ms
64 bytes from 155.53.12.7: icmp_req=3 ttl=48 time=241 ms
^C
--- 155.53.12.7 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 239.250/240.304/241.451/0.985 ms
esunboj#L9AGC12:~$ echo $?
0
ping send will send ICMP ECHO_REQUEST to network hosts and on success it will receive ICMP ECHO_REPLAY you can run tcpdump to verify

Linux - ping all devices in a file to check accessibility

I have a file with about 500 devices which I need to ping to check if they're currently accessible or not from various subnets around my network. It's essentially a basic test to check for routing/accessibility issue.
Not sure where to start really. I have a basic file in which I have put each individual IP in a file line-by-line.
For example, the file looks like this:
192.168.1.1
192.168.1.2
192.168.1.3
192.168.1.4
I'd need it to return something like the following, if the third in line didn't get a reply:
192.168.1.1 Accessible
192.168.1.2 Accessible
192.168.1.3 Inaccessible
192.168.1.4 Accessible
I'm running Ubuntu here. Apologies for not having any idea where to start !
Cheers
Steve.
You should use nmap in ping scan mode with:
nmap -sn -oG - -v -iL hosts_to_scan.txt
This will try to ping all hosts contained in the hosts_to_scan.txt file.
By the way, you can also specifify a subnet, if that is the case:
nmap -sn -oG - -v 192.168.1.0/24
And/or save the result to file:
nmap -sn -oG status.txt -v 192.168.1.0/24
nmap -sn -oG status.txt -v -iL hosts_to_scan.txt
I would use nmap probably for a long list, but if you are in a command line and need a quick one-liner, this will do also:
$ for i in `cat file.txt `;do ping -c 1 $i;done
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: icmp_seq=0 ttl=50 time=16.271 ms
--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 16.271/16.271/16.271/0.000 ms
PING 8.8.4.4 (8.8.4.4): 56 data bytes
64 bytes from 8.8.4.4: icmp_seq=0 ttl=50 time=16.030 ms
--- 8.8.4.4 ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 16.030/16.030/16.030/0.000 ms
On a positive note, this method it's quick and easy to remember. Works (probably) with all major shells (bash, zsh, *sh?).
On the other hand it's fairly verbose and you don't want that in say 200 IP's, even 10 might be hard to monitor.
I would write a script in ruby, or pytho or whatever language you like if nmap can't cut it.
EDIT: This one is cleaner and also has some additional stats:
for i in `cat file.txt `;do ping -c 1 $i|grep 64;done
64 bytes from 8.8.8.8: icmp_seq=0 ttl=50 time=15.397 ms
64 bytes from 8.8.4.4: icmp_seq=0 ttl=50 time=13.170 ms
There's virtually nothing that can't be done with gnu-tools.
Basic schema would be to ping each one of the servers and print the result.
If you store the IPs in a ips.txt file, you could do:
while read my_ip
do
test_ping $my_ip
done < ips.txt
And then create a function such as test_ping, that pings once to each IP:
test_ping () {
if ping -c 1 $1 &> /dev/null
then
echo "$1 Accessible"
else
echo "$1 Inaccessible"
fi
}

Resources