LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Bash script to ping a range or own IP-range (https://www.linuxquestions.org/questions/programming-9/bash-script-to-ping-a-range-or-own-ip-range-874276/)

ugurgazi 04-11-2011 04:47 AM

Bash script to ping a range or own IP-range
 
Hello!
I have a question foy those who can/wants to help me out.

I want to build a bash script, which can ping a range IP adresses which will be filled in by the admin. If there is no IP-adress filled in, then the script must ping the subnet where the system is logged on.

So if my ip is 192.168.1.6, then the script must ping from 192.168.1.1 till 192.168.1.255
Or else, if there is given a beginning and ending ip it must ping that!


The first part of the bash script is to ping a given range (see below). But there is one problem, how can I tell the script to ping from $begin till $end, [..] is of course wrong!
But what must be filled in there???

echo "Enter beginning IP-adres:"
read begin
echo "Enter ending IP-adres:"
read end
ping -c 1 $begin [..] $end


The second part is to find my own ip and ping the whole range.. How to do that?
I only can find my own IP, but I cant ping the whole range,, how to do that??
#!/bin/bash
ifconfig | grep 'inet addr:' | grep -v '127.0.0.1' |
cut -d: -f2 | awk '{ print $1 }'


Many thanks in advance!!!!
Help will be wonderful!

colucix 04-11-2011 06:45 AM

Hi and welcome to LinuxQuestions!
Quote:

Originally Posted by ugurgazi (Post 4320799)
The first part of the bash script is to ping a given range (see below). But there is one problem, how can I tell the script to ping from $begin till $end

You can try a loop to cycle over the range of IP addresses. First you have to extract information from the given IPs, then do a loop incrementing the address from the beginning to the end of the range. Example:
Code:

subnet=$(echo $begin | sed 's/\.[0-4]*$//')

start=$(echo $begin | sed 's/.*\.//')
stop=$(echo $end | sed 's/.*\.//')

while [[ $start -le $stop ]]
do
  ping -c 1 $subnet.$start
  ((start++))
done

Two notes: first you have to check the input from the user, e.g. are they valid IP addresses? Is the begin address before the end address in the sequence? And so on... Second, are you sure you want to ping the broadcast address, since it can generate a lot of traffic? What is the purpose of that?
Quote:

Originally Posted by ugurgazi (Post 4320799)
The second part is to find my own ip and ping the whole range.. How to do that?
I only can find my own IP, but I cant ping the whole range,, how to do that??

You can do that only from the router and it depends on how the subnet is created. For example, are they fixed IP addresses or are they assigned dinamically through DHCP? You may always ping the whole IP range of the subnet from 1 to 254, but... if you explain the purpose of this script maybe someone more experienced in network issues can give some better advice.

A final note: to extract the IP address from the output of ifconfig, you might use only awk. Example:
Code:

/sbin/ifconfig | '/inet addr:/ && ! /127.0.0.1/{sub(/inet addr:/,""); print $1}'
Hope this helps.

grail 04-11-2011 08:55 AM

colucix inspired me :)
Code:

#!/bin/bash

usage()
{
    echo "Usage: $0 [start_address end_address]"
    exit 1
}

if (( $# == 1 || $# > 2 ))
then
    usage
elif (( $# == 2 ))
then
    REGEX='^[1-9][0-9]{,2}[.]([0-9]{1,3}[.]){2}[0-9]{1,3}$'
    BEGIN=$1
    END=$2

    if ! [[ $BEGIN =~ $REGEX && $END =~ $REGEX ]]
    then
        usage
    elif [[ ${BEGIN%[0-9]*} == ${END%[0-9]*} ]]
    then
        SUBNET=${BEGIN%[0-9]*}
        START=${BEGIN##*.}
        STOP=${END##*.}
    else
        echo "First three octets must match when entering range!!"
        exit 2
    fi
else
    START=1
    STOP=254
    SUBNET=$(/sbin/ifconfig | awk '!/lo/{print gensub(/[^:]*:|[^.]+$/,"","g",$7)}' RS="")
fi

#in case you wish to kill it
trap 'exit 3' 1 2 3 15

while (( START <= STOP ))
do
    ping -c 1 $SUBNET$START
    ((START++))
done


PTrenholme 04-11-2011 11:54 AM

If IP addresses segments are three digit octal numbers, wouldn't the range span be %[0-8]* rather than %[0-9]*? And aren't they two bit unsigned integer values, so 0 <= ((address+0)) < 256?

I wonder, since I've never tried it, if one could use two digit hex digits, x00 ... xFF, for the IP address components rather than octal? That might make the map from www/xxx/yyy/zzz to "unsigned int64" somewhat more explicit, although I don't suppose that there is any need for that.

I.e., I think the "valid address" test could be a little sharper.

grail 04-11-2011 10:48 PM

Quote:

If IP addresses segments are three digit octal numbers, wouldn't the range span be %[0-8]* rather than %[0-9]*? And aren't they two bit unsigned integer values, so 0 <= ((address+0)) < 256?

I wonder, since I've never tried it, if one could use two digit hex digits, x00 ... xFF, for the IP address components rather than octal? That might make the map from www/xxx/yyy/zzz to "unsigned int64" somewhat more explicit, although I don't suppose that there is any need for that.

I.e., I think the "valid address" test could be a little sharper.
Hey PT, Yes I am open to suggestion as I am a novice to intermediate network person :) Whilst I do understand that the digits are referred to as an octet
in an ip address, I was not aware that a particular decimal value was not allowed??

On my home network the first 3 'octets' are 192.168.1, as the first one has a 9 in it does this not disprove that the limit to individual digits is an 8?
Also my work network uses all ip's in the range 75 - 254 for workstations, so again a machine can have 249 as last octet.

If I have missed the point or am confused (easily done sometimes :) ) please advise where my thinking has gone astray?

PTrenholme 04-12-2011 04:35 PM

Quote:

Originally Posted by grail (Post 4321752)
Hey PT, Yes I am open to suggestion as I am a novice to intermediate network person :) Whilst I do understand that the digits are referred to as an octet
in an ip address, I was not aware that a particular decimal value was not allowed??

On my home network the first 3 'octets' are 192.168.1, as the first one has a 9 in it does this not disprove that the limit to individual digits is an 8?
...

Oops! :redface: No, I was confused by the "octet" comment you included, and the time of night when I was posting. The second part of my comment, that the numbers in the four "positions" of the address are in the range [0-256) as a decimal number (or [\x00=\x100) as a hexadecimal number) is correct. So the check could be sharpened to check that the value in in the correct range.

Another error I made: :o The IPv4 address is a 32-bit unsigned integer, not a 64-bit one.

I do wonder if the OP needs to consider private, non-routable, address spaces, that is, the /10.0-255.0-255.0-255/, /172.16-31.0-255,0-255/. and /192.168.0-255,0-255/ ones.

ugurgazi 04-14-2011 07:47 AM

So far so good.....


ifconfig | grep 'Bcast:' | cut -d: -f3 | awk '{print $1}'


with the above I can see by broadcast IP...
but how can I tell the script in the same line to ping the output??

Output for: ifconfig | grep 'Bcast:' | cut -d: -f3 | awk '{print $1}' is 192.168.101.255 or something else. How can I also ping -b the output?



Thanks in advance

PTrenholme 04-14-2011 05:10 PM

Code:

$ ping -bc1 `ifconfig | grep 'Bcast:' | cut -d":" -f3 | cut -d\  -f1`
WARNING: pinging broadcast address
PING 192.168.0.255 (192.168.0.255) 56(84) bytes of data.
^C
--- 192.168.0.255 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms


ugurgazi 04-26-2011 04:18 AM

Hello again,
I have got 2 scripts now which I want to place in one script..
When no input is given at first part then the second part must be run.. How can I accomplish that with if else statement?
When no beginning and ending ip is given, then run a ping to broadcast.


#INPUT 1
#!/bin/bash
read -p "Enter beginning IP-addres: " host1
read -p "Enter ending IP-addres: " host2
SUBNET=${host1%.*}
netId1=${host1#$SUBNET.}
netId2=${host2#$SUBNET.}
for ((i=netId1; i<=netId2; i++)); do
ping -c 1 ${SUBNET}.$i
done


#INPUT 2
#!/bin/bash
ping -bc 2 'ifconfig | grep 'Bcast:' | cut -d ":" -f3 | cut -d\ -f1'



Many thanks in advance!!!

grail 04-26-2011 04:41 AM

Well I would have to say I am feeling a little neglected ... did you bother to read the script I put together?

Not only is there no need for 2 scripts but it also handled the situation where nothing is passed.

Maybe I missed something??

Shao Lung 04-28-2011 08:44 PM

Quote:

Originally Posted by grail (Post 4336563)
Well I would have to say I am feeling a little neglected ... did you bother to read the script I put together?

Not only is there no need for 2 scripts but it also handled the situation where nothing is passed.

Maybe I missed something??

Well I just tried your code, thats pretty sweet. I was trying to build something similar, though not limiting to my own computer. You rock!!

catkin 04-29-2011 08:54 AM

As 8-bit numbers (octets) the range of a single octet is decimal 0 to 255 (octal 0 to 377, hex 0 to FF).

The netmask must be used to determine the range of IP addresses.

In the common case of netmask 255.255.255.0 (a.k.a /24), the possible range of addresses is x.x.x.1-254 (because 0 is the network address and 255 the broadcast address).

For netmask 255.255.0.0 I'm less confident what the range is; if the network address is x.x.0.0 and the broadcast is x.x.255.255 (I think that's right) then all other possibilities are the IP address range.

If the netmask splits an octet then calculating the range becomes harder; in the simple case of 255.255.255.252 the range is x.x.x.253 to 254 (252 is the network address and 255 the broadcast address).

EDIT: the netmask 255.255.255.252 part is wrong, it should be: the range is x.x.x.x+1 to x+2 (x+0 is the network address and x+3 the broadcast address).

sanju_sethi2004 05-02-2016 07:43 AM

hi,

I am new to shell scripting in sed and regular expression.

colucix can you please explain

Quote:

subnet=$(echo $begin | sed 's/\.[0-4]*$//')
grail please explain
Quote:

then
REGEX='^[1-9][0-9]{,2}[.]([0-9]{1,3}[.]){2}[0-9]{1,3}$'
BEGIN=$1
END=$2

if ! [[ $BEGIN =~ $REGEX && $END =~ $REGEX ]]
then
usage
elif [[ ${BEGIN%[0-9]*} == ${END%[0-9]*} ]]
then
SUBNET=${BEGIN%[0-9]*}
START=${BEGIN##*.}
STOP=${END##*.}
else
echo "First three octets must match when entering range!!"
exit 2
fi

grail 05-02-2016 09:08 AM

Please start your own question and not resurrect a 4 year old thread :)


All times are GMT -5. The time now is 07:54 PM.