0
  1. Problem: So recently i want to try to write a simple script to detect OS from a ping script( base on TTL(time-to-live))

  2. Things i have tried: i have try some things like this

#!/bin/bash                                                                    

sn=${1:-$1}

for host in $(seq 1 255); do
                            
    ttlstr=$(ping -c1 -w1 $sn.$host | grep -o 'ttl=[0-9][0-9]*') || {
        printf "%s is Offline\n" "$sn.$host"
        continue;
    }
    ttl="${ttlstr#*=}"           
    printf "%s is Online, ttl=%d\n" "$sn.$host" "$ttl"
    if [ $ttl -eq 64 ]
            then
                echo "Operating is Linux"
            elif [ $ttl -eq 128 ]
            then
                echo "Operating is Windows"
            else
                echo "Operating is IOS"
                fi

done
  1. So as you can see it can ping every ip with the given Ip address. But if user want to enter: 192.168.1.0/24 how can i solve that ?

Lastly, thanks for your answer :D

Ta219
  • 13
  • 2
  • 2
    Unless you want to write your own parser, why not use a CLI tool like ipcalc? – Todd A. Jacobs Jul 09 '20 at 13:49
  • I have an assigntment about bash script :D Tks for your answer :D – Ta219 Jul 09 '20 at 14:10
  • What do you want to achieve with `${1:-$1}`? `${1:-x}` means the value of `$1`, if it is defined and not null or `x` otherwise. But your `x` is `$1` and that makes the expression mean "use $1 if it is set or $1 otherwise". – axiac Jul 09 '20 at 14:40
  • @axiac thank you for pointing out my mistake. Im pretty new to bash so i still make mistake :D. Still trying to improve my Bash skill – Ta219 Jul 09 '20 at 23:52

1 Answers1

1

You can use this script :

#!/bin/bash                                                                    

if [ -z $1 ] ; then 
    echo "Please enter ip address"
    exit 1
fi 

function print_os_type() {
    case $2  in 
       64) echo "$1 Linux" ;;
       128) echo "$1  Windows" ;;
       *) echo "$1 Unknown os type";;
    esac
}

function get_ttl() {
    ping -c1 -w1 $1 | grep ttl | awk '{print $6}' | tr -d "ttl="
}

if [ ! -z $2 ] ; then 
    IPS=$(nmap -sL -n $1/$2 | grep report | awk '{print $5}')  
    for I in ${IPS[@]}
    do
        ttl=$(get_ttl $I) 
        print_os_type $I $ttl
    done
else
    ttl=$(ping -c1 -w1 $1 | grep ttl | awk '{print $6}' | tr -d "ttl=")
    print_os_type $1 $ttl
fi

Usage :

./script.sh 192.168.1.1 #For single ip 
./script.sh 172.16.10.0 24 #For subnet of ips

or simply use this command :

nmap -n -O 192.168.1.0/24 | grep 'OS details'

Note :
this is horrible idea for using ttl to detect os type .
some peoples like me change this ttl manually :

root@HOSTNAME:~# echo 110 >  /proc/sys/net/ipv4/ip_default_ttl
root@HOSTNAME:~# ping -c1 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=110 time=0.069 ms

--- 127.0.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.069/0.069/0.069/0.000 ms
mah454
  • 1,571
  • 15
  • 38
  • Well, that said, if you are having `nmap` then just detect OS with `nmap`. – KamilCuk Jul 09 '20 at 14:28
  • @mah454 But if I dont have nmap the script wont work. How do you solve that ? thank you :D – Ta219 Jul 10 '20 at 04:15
  • @Ta219 too hard man ! please see this : https://stackoverflow.com/questions/16986879/bash-script-to-list-all-ips-in-prefix – mah454 Jul 10 '20 at 05:06