Saturday, 23 January 2016

Code Snippet: Ping local IP addresses


Here is a code snippet that I have created for the purpose of finding a Raspberry Pi when it is connected to a network without a screen. For my setup, I have both an ethernet connection and a WiFi connection. Normally the ethernet connection is connected directly to the raspberry pi, and the WiFi connection goes directly to the router. My code was written and tested on Windows 8.1, with Python 2.7.10. 

from __future__ import print_function
import socket
import os
import time
import subprocess
from threading import Thread

def ping(hostname, timeout=100):

    timeout=str(timeout)

    #perform ping command. -n sets the number (1 here) and -w sets the timeout.
    #creationflag=8 hides the window.
    response = subprocess.Popen(["ping", hostname, "-n", '1', "-w", timeout],
                                stdout=subprocess.PIPE, creationflags=8).stdout.read()
    ping_reply=0

    if "time=" in response.lower() or "time<" in response.lower():
        ping_reply=1

    return ping_reply

def ping_and_print(hostname):

    #perform ping command
    ping_reply=ping(hostname)

    #print whether ip address responded to ping or not.
    #I added the "\n" character to the print command because
    #when multiple threads try to print, it was causing
    #overlapping for some reason. It seems there is a bit of a delay
    #between the string being printed and the end of line
    #character being printed.
    if (ping_reply==1):
        print(hostname + " - UP!\n", end="")
    else:
        if verbose==1:
            print(hostname + " - Down!\n", end="")
    return


verbose=0 #also print out ips that aren't responding to pings.

#this gets the local ip range, the range with the ethernet adapter
local_ip=socket.gethostbyname(socket.gethostname())

#this pings the gmail server and gets the IP address used to connect, so
#should always be the ip address used for internet connections
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("gmail.com",80))
web_facing_ip=s.getsockname()[0]
s.close()

print("Local IP     : " + str(local_ip))
print("Web facing IP: " + str(web_facing_ip))

#check we can actually ping the internet
hostname="8.8.8.8"
ping_reply=ping(hostname,5000)

print("Internet ping: " + str(ping_reply))

#create the network stem for the local ip range
network_stem=".".join(local_ip.split(".")[0:3])

#ping primary ip range
for ip in range(1,255):
    this_ip_address=network_stem + "." + str(ip)

    t = Thread(target=ping_and_print, args=(this_ip_address,))
    t.start()

#create the network stem for the internet connecting ip range
network_stem=".".join(web_facing_ip.split(".")[0:3])

#check we are running on a second network range and not just repeating the
#previous tests.
if local_ip<>web_facing_ip:
    #ping secondary ip range
    for ip in range(1,255):
        this_ip_address=network_stem + "." + str(ip)

        t = Thread(target=ping_and_print, args=(this_ip_address,))
        t.start()

#sleep at the end for a bit to wait for remaining responses.
for i in range(1,100):
    time.sleep(0.01)

print("Done.")

No comments:

Post a Comment