Multiple IP addresse PING - python

The below code works perfectly if the input file ip_file.txt have the following format.
8.8.8.8
www.google.com
www.yahoo.com
www.microsoft.com
But how can I ping the IPs if the input is something like this and write the output same in format.
8.8.8.8, www.google.com
www.yahoo.com,www.microsoft.com
My code is given below:
import subprocess
import threading
import time
import re
timestr = time.strftime("%Y-%m-%d %H%M%S")
timesec = time.strftime("%Y-%m-%d%H:%M:%S")
raw_list = []
def ping(host):
results_file = open("results_bng_" + str(timestr) + ".txt", "a")
p = subprocess.Popen(["ping", host, "-n", "5"], shell=True, universal_newlines=True, stdout=subprocess.PIPE)
response = p.communicate()[0]
for i in response.split("\n"):
para =i.split("=")
# print(para)
try:
if para[0].strip() =="Minimum":
latency =para[3].strip()
print(latency)
latfin = re.findall('\d+', latency)
latfin1 = latfin[0]
except:
print("time run")
if "Received = 1" and "Approximate" in response:
print(f"UP {host} Ping Successful")
results_file.write(f"{host},UP,{latfin1},{timesec}"+ "\n")
else:
print(f"Down {host} Ping Unsuccessful")
results_file.write(f"{host},Down,0,{timesec}" + "\n")
results_file.close()
with open(r'bng.txt', "r") as server_list_file:
hosts = server_list_file.read()
hosts_list =hosts.split('\n')
num_threads = 1
number = 0
while number< len(hosts_list):
# print(number)
for i in range(num_threads):
t = threading.Thread(target=ping, args=(hosts_list[number+i],))
t.start()
t.join()
number = number +1

You could replace each newline character with a comma and split at each comma:
bng.txt:
8.8.8.8, www.google.com
www.yahoo.com,www.microsoft.com
Code:
with open(r'bng.txt', "r") as server_list_file:
hosts = server_list_file.read()
hosts_list = hosts.replace('\n', ',').split(',')
for host in hosts_list:
print(host.strip()) # strip remaining whitespaces
Out:
8.8.8.8
www.google.com
www.yahoo.com
www.microsoft.com

Pings are specific IP packets that can only be sent to one ip at a time. There are special IP which are meant for broadcasting. For example, you could direct your ping at a specific subnet and the devices connected to that subnet could all choose to answer to a ping. Note that most routers or IP stacks do not answer to such broadcast pings nowadays as they could be used to discover the devices that are connected to the subnet.

After you open your file you need to do a for loop and read each line at a time and split based on comma. That will ultimately give you a list of all single IPs / hosts to ping. Something like.
listOfAllIPs = []
for line in file:
x = line.split(',') ## this makes x a list
listOfAllIPs = listOfAllIPs + x
After that runs you should be able to use listOfAllIPs as your input. It will have 1 IP or host per item. Just iterate through.

this will be useful for you
import os
import subprocess
list = []
with open('./ip.txt', 'r') as f:
ip = f.read().split(',')
list.append(ip)
for i in range(len(list[0])):
ip = list[0][i]
print(30*'-')
if subprocess.Popen(["ping", "-n", "1", "-w", "200", ip], shell=True).wait() == 1: print('active', ip)
else: print('inactive', ip)

Related

Python script - add file read as alternative option

I have the following code:
#!/usr/bin/env python
# coding=utf-8
import threading
import requests
import Queue
import sys
import re
#ip to num
def ip2num(ip):
ip = [int(x) for x in ip.split('.')]
return ip[0] << 24 | ip[1] << 16 | ip[2] << 8 | ip[3]
#num to ip
def num2ip(num):
return '%s.%s.%s.%s' % ((num & 0xff000000) >> 24,(num & 0x00ff0000) >> 16,(num & 0x0000ff00) >> 8,num & 0x000000ff)
def ip_range(start, end):
return [num2ip(num) for num in range(ip2num(start), ip2num(end) + 1) if num & 0xff]
def bThread(iplist):
threadl = []
queue = Queue.Queue()
for host in iplist:
queue.put(host)
for x in xrange(0, int(SETTHREAD)):
threadl.append(tThread(queue))
for t in threadl:
t.start()
for t in threadl:
t.join()
#create thread
class tThread(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue
def run(self):
while not self.queue.empty():
host = self.queue.get()
try:
checkServer(host)
except:
continue
def checkServer(host):
ports = [80]
for k in ports:
try:
aimurl = "http://"+host+":"+str(k)
response = requests.get(url=aimurl,timeout=3)
serverText = response.headers['server']
if (response.status_code) == 403:
print "-"*50+"\n"+aimurl +" Server: "+serverText
except:
pass
if __name__ == '__main__':
print '\n############# CDN IP #############'
print ' '
print '################################################\n'
global SETTHREAD
try:
SETTHREAD = sys.argv[2]
iplist = []
file = open(sys.argv[1], 'r')
tmpIpList = file.readlines()
for ip in tmpIpList:
iplist.append(ip.rstrip("\n"))
print '\nEscaneando '+str(len(iplist))+" IP's...\n"
bThread(iplist)
except KeyboardInterrupt:
print 'Keyboard Interrupt!'
sys.exit()
This script works as follows, a range of ip is entered:
python2 script.py 104.0.0.0-104.0.1.255 100 (100 is the number of threads)
I want to add support so that it reads the ip of a file, and that the range also works.
python2 script.py ips.txt 100
I tried this:
file = open(sys.argv[1], 'r')
iplist = file.readlines()
But it does not work.
Edit1: added file reading code recommended by user Syed Hasan, the problem seems to be the bThread(iplist) function
I assume you're attempting to use 'iplist' the same way as your CLI input was attempting to parse it. However, the readlines function simply reads the entire file at once and appends a newline (\n) at the end (provided you do format the IPs with a succeeding newline character).
Currently, you should be getting a list of IPs with a succeeding newline character. Try removing it from the rightmost end using rstrip:
file = open(sys.argv[1], 'r')
tmpIpList = file.readlines()
for ip in tmpIpList:
iplist.append(ip.rstrip("\n"))
How you switch between the two modes is a challenge you should attempt to solve. Perhaps use command-line parameter support to identify the mode of operations (look into the argparse library).

I need help completing my code. Note I am a beginner in Python

I am trying to develop a script which sends an email about checking ping regularly at one hour interval of time. I am using Python to program this script and I cannot create a log file to keep the ping logs which I need to mail. I'm new to using subprocess module and its functions.
import threading
import os
def check_ping():
threading.Timer(5.0, check_ping).start()
hostname = "www.google.com"
response = os.system("ping -c 4 " + hostname)
'''
def trace_route():
threading.Timer(5.0, trace_route).start()
hostname = "www.google.com"
response = os.system("traceroute" + hostname)
'''
check_ping()
#trace_route()
output = check_ping()
file = open("sample.txt","a")
file.write(output)
file.close()
import os, platform
import threading
def check_ping():
threading.Timer(10.0,check_ping).start()
hostname = "www.google.com"
response = os.system("ping " + ("-n 1 " if platform.system().lower()=="windows" else "-c 1 ") + hostname)
# and then check the response...
if response == 0:
pingstatus = "Network Active"
else:
pingstatus = "Network Error"
return pingstatus
pingstatus = check_ping()
This is what I came up with:
using subprocess instead of os.system
added timeout of 8 seconds
writing to csv file instead of txt file
added timestamps to csv file, without which I don't really see the point of logging in the first place
import os
import threading
import time
from subprocess import Popen, PIPE
def check_ping():
threading.Timer(10.0,check_ping).start()
# Get current time
timestamp = int(time.time())
# Build the command
hostname = "www.google.com"
if os.name == 'nt':
command = ['ping', '-n', '1', hostname]
else:
command = ['ping', '-c', '1', hostname]
# Create process
pingProcess = Popen(command, stdout=PIPE, stderr=PIPE)
try:
# Timeout 8 seconds, to avoid overlap with the next ping command
outs, errs = pingProcess.communicate(timeout=8)
except TimeoutExpired:
# If timed out, kill
pingProcess.kill()
outs, errs = pingProcess.communicate()
# Get the return code of the process
response = pingProcess.returncode
# and then check the response...
# These four lines can be removed, they are just to see if the system
# works.
if response == 0:
print("Network Active")
else:
print("Network Error")
# You most likely want a CSV file, as most programs accept this file type,
# including Microsoft Excel and LibreOffice Calc
# Further, I'm sure you want timestamps with the results.
file = open("ping.csv","a")
file.write(str(timestamp) + "," + str(response) + "\n")
file.close()
check_ping()
Here is another version without using the system's ping command, but instead using a python library for pinging. This ensures that the code works on all operating systems:
import threading
import time
from ping3 import ping
def check_ping():
threading.Timer(10.0,check_ping).start()
# Get current time
timestamp = int(time.time())
# Build the command
hostname = "www.google.com"
# Run ping
ping_result = ping(hostname, timeout=8)
ping_success = False if ping_result is None else True
# and then check the response...
# These four lines can be removed, they are just to see if the system
# works.
if ping_success:
print("Network Active (" + str(ping_result) + ")")
else:
print("Network Error")
# You most likely want a CSV file, as most programs accept this file type,
# including Microsoft Excel and LibreOffice Calc
# Further, I'm sure you want timestamps with the results.
file = open("ping.csv", "a")
ping_value_str = str(ping_result) if ping_success else "NaN"
file.write(str(timestamp) + "," + ("0" if ping_success else "1") + "," + ping_value_str + "\n")
file.close()
check_ping()

How to read list of ip address from a text file and print it out

*I want to print out ip addresses from textfile (solved)
****no ip address in the textfile and error message will be shown.** (solved)
I have attached my current codes at the bottom, can any one please help?**
**
****IP addresses in the textfile will look like this.****
**
192.168.12.1
192.168.12.28
*****And the following is my current codes...*****
f=open('output.txt','r')
print "IP address is ", f.read()
f.close()
Use file.readlines() inside a loop.
So, the Code will be:
f=open('output2.txt','r')
c=f.readlines()
for i in c :
print ("IP address of attacker is ", i)
f.close()
Get IP address from text file and check. See my code on git.
import socket
import re
f = open('ip_list.txt', 'r') #Text file with many ip address
o = f.read()
ip1 = re.findall( r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", o )
hosts = ip1
ports = [80]
for host in hosts:
for port in ports:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(1)
result = s.connect_ex((host, port))
if result == 0:
print(" [*] Port " + str(port) + " open!" + host)
else: print("[+] CLOSE HOST " + host + ":" + str(port))
except:
pass
It is best to open the file in its own context with 'with'. This way it will be closed automatically after the last line has been reached. Then loop trough the lines and add your text before each line. Another upside of this solution is that you do not have to keep all IPs in memory. The IPs will be streamed one at a time.
This code will also print a message if no ip was found.
with open('output2.txt','r') as f:
ip_not_found = True
for line in f:
ip_not_found = False
print "IP address of attacker is {IP}".format(IP=line)
if ip_not_found:
print 'no ip address was found'
import sys
import os
import time
b='sudo tshark -i ens33 -Y "tcp contains "attack"" -T fields -e ip.src -a duration:20>output2.txt'
a=os.popen(b)
time.sleep(22)
with open(output2.txt,"r") as f:
ip=f.read.split('\n')
for Ip in ip:
print "IP address of attacker is ", Ip
You have to just split the contents of the file at every newline.
import ipaddress
ip_address_file = open('ip.txt', 'r') # open text file with ip addresses
for i in ip_address_file: # loop through the ip text file
i = i.strip() # read each line
try:
i = ipaddress.ip_address(str(i)) #validates either ip is ipv4 or 6
except ValueError: #catch error for invalid ip format
print('invalid ip '.format(i))
continue # if line empty continue with loop

Sending, receiving with python socket

I'm currently trying to write process that embeds a sequence of n IPs into packets and send it off to n server. Each server remove the outermost IP and then forward it to said IP. This is exactly like tunneling I know. During the process I also want the server to do a traceroute to where it's forwarding the packet and send that back to the previous server.
My code currently will forward the packets but it's stuck on performing the traceroute and getting it. I believe it's currently stuck in the while loop in the intermediate server. I think it's having something to do with me not closing the sockets properly. Any suggestion?
Client
#!/usr/bin/env python
import socket # Import socket module
import sys
import os
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 17353 # Reserve a port
FILE = raw_input("Enter filename: \n ")
NIP = raw_input("Enter Number of IPs: ")
accepted_IP = 0
IP= []
while accepted_IP < int(NIP):
IP.append(raw_input("Enter destination IP: \n"))
accepted_IP +=1
#cIP = raw_input("Enter intemediate IP: \n ")
ipv = raw_input("Enter IP version... 4/6")
try:
s.connect((host, port))
print "Connection sucessful!"
except socket.error as err:
print "Connection failed. Error: %s" %err
quit()
raw = open(FILE,"rb")
size = os.stat(FILE).st_size
ls = ""
buf = 0
for i in IP:
while len(i) < 15:
i += "$"
ls += i
header = ipv+NIP+ls+FILE
print ls
s.sendall(header + "\n")
print "Sent header"
data = raw.read(56) +ipv + NIP + ls
print "Begin sending file"
while buf <= size:
s.send(data)
print data
buf += 56
data = raw.read(56) + ipv + NIP + ls
raw.close()
print "Begin receiving traceroute"
with open("trace_log.txt","w") as tracert:
trace = s.recv(1024)
while trace:
treacert.write(trace)
if not trace: break
trace = s.recv(1024)
print "finished forwarding"
s.close()
Intermediate server
#!/usr/bin/env python
import socket
import subprocess
srvsock = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
srvsock.bind( (socket.gethostname(), 17353) )
srvsock.listen( 5 ) # Begin listening with backlog of 5
# Run server
while True:
clisock, (remhost, remport) = srvsock.accept() #Accept connection
print
d = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
header = ""
while True:
b = clisock.recv(1)
if b == "\n":
break
header += b
num = 15 * int(header[1]) + 2
file_name = header[num:]
nheader = header[0]+ str(int(header[1])-1) + header[17:]
d.connect((socket.gethostname(), 12355))
d.sendall(nheader+'\n')
print "begin forwarding"
while True:
raw = clisock.recv(56 + num) # recieve data
ip = raw[-15:] # extract IP
ipv, NIP = raw[57] , str(int(raw[57])-1)
if NIP == "0":
while (raw):
print "stuck in this loop"
d.send(raw[:56])
raw=clisock.recv(56+num)
if not raw: break
else:
while (raw):
print raw[:57] + NIP + raw[59:-15]
print "\n"
d.send(raw[:57] + NIP + raw[59:-15])
raw = clisock.recv(56+num)
if not raw :break
print "Finish forwarding"
d.close()
break
print "Begin traceroute"
tracrt = subprocess.Popen(['traceroute','google.com'], stdout=subprocess.PIPE)
s.sendall(tracrt.communicate()[0])
print "Finished"
clisock.close()
s.close()
Destination server
import socket
s = socket.socket()
host = socket.gethostname()
port = 12355
s.bind((host,port))
s.listen(5)
while True:
csock, (client, cport) = s.accept()
print client
header = ""
while True:
b = csock.recv(1)
if b == "\n":
break
header += b
file_name = header[2:]
r = open("File_test_"+file_name,"wb")
print 'Opening file for writing'
while True:
print "Begin writing file" + " " + file_name
raw = csock.recv(56)
while (raw):
print raw
r.write(raw)
raw = csock.recv(56)
r.flush()
r.close()
print "finish writing"
break
print "closing connection"
csock.close()
s.close()
The intermediate server is stuck in clisock.recv() in this loop because the break condition not raw isn't met before the connection is closed by the client, and the client doesn't close the connection before receiving the traceroute from the intermediate server, so they are waiting on each other.
To remedy this, you might consider sending the file size to the intermediate server, so that it can be used to determine when the receive loop is done. Or, if your platform supports shutting down one half of the connection, you can use
s.shutdown(socket.SHUT_WR)
in the client after sending the file.

Measuring ping latency of a server - Python

I have a list of server IP addresses, I need to check if each one is online and how long the latency is.
I haven't found any straight forward ways of implementing this, and there seems to be a few problems in calculating latency accurately.
Any ideas?
If you are already comfortable with parsing strings, you can use the subprocess module to get the data you are looking for into a string, like this:
>>> import subprocess
>>> p = subprocess.Popen(["ping.exe","www.google.com"], stdout = subprocess.PIPE)
>>> print p.communicate()[0]
Pinging www.l.google.com [209.85.225.99] with 32 bytes of data:
Reply from 209.85.225.99: bytes=32 time=59ms TTL=52
Reply from 209.85.225.99: bytes=32 time=64ms TTL=52
Reply from 209.85.225.99: bytes=32 time=104ms TTL=52
Reply from 209.85.225.99: bytes=32 time=64ms TTL=52
Ping statistics for 209.85.225.99:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 59ms, Maximum = 104ms, Average = 72ms
Following hlovdal's suggestion to work with fping, here is my solution that I use for testing proxies. I only tried it under Linux. If no ping time could be measured, a big value is returned. Usage: print get_ping_time('<ip>:<port>').
import shlex
from subprocess import Popen, PIPE, STDOUT
def get_simple_cmd_output(cmd, stderr=STDOUT):
"""
Execute a simple external command and get its output.
"""
args = shlex.split(cmd)
return Popen(args, stdout=PIPE, stderr=stderr).communicate()[0]
def get_ping_time(host):
host = host.split(':')[0]
cmd = "fping {host} -C 3 -q".format(host=host)
res = [float(x) for x in get_simple_cmd_output(cmd).strip().split(':')[-1].split() if x != '-']
if len(res) > 0:
return sum(res) / len(res)
else:
return 999999
This post is a bit old and I think better ways exists today. I'm new to python but here's what I did on my project:
from pythonping import ping
def ping_host(host):
ping_result = ping(target=host, count=10, timeout=2)
return {
'host': host,
'avg_latency': ping_result.rtt_avg_ms,
'min_latency': ping_result.rtt_min_ms,
'max_latency': ping_result.rtt_max_ms,
'packet_loss': ping_result.packet_loss
}
hosts = [
'192.168.48.1',
'192.168.48.135'
]
for host in hosts:
print(ping_host(host))
Result:
{'host': '192.168.48.1', 'avg_latency': 2000.0, 'min_latency': 2000, 'max_latency': 2000, 'packet_loss': 1.0}
{'host': '192.168.48.135', 'avg_latency': 42.67, 'min_latency': 41.71, 'max_latency': 44.17, 'packet_loss': 0.0}
You can find the pythonping library here: https://pypi.org/project/pythonping/
If you want to avoid implementing all the network communication details you could probably try to build something on top of fping:
fping is a like program which uses the
Internet Control Message Protocol
(ICMP) echo request to determine if a
target host is responding. fping
differs from ping in that you can
specify any number of targets on the
command line, or specify a file
containing the lists of targets to
ping. Instead of sending to one target
until it times out or replies, fping will send
out a ping packet and move on to the
next target in a round-robin fashion.
https://github.com/matthieu-lapeyre/network-benchmark My solution based on the work of FlipperPA: https://github.com/FlipperPA/latency-tester
import numpy
import pexpect
class WifiLatencyBenchmark(object):
def __init__(self, ip):
object.__init__(self)
self.ip = ip
self.interval = 0.5
ping_command = 'ping -i ' + str(self.interval) + ' ' + self.ip
self.ping = pexpect.spawn(ping_command)
self.ping.timeout = 1200
self.ping.readline() # init
self.wifi_latency = []
self.wifi_timeout = 0
def run_test(self, n_test):
for n in range(n_test):
p = self.ping.readline()
try:
ping_time = float(p[p.find('time=') + 5:p.find(' ms')])
self.wifi_latency.append(ping_time)
print 'test:', n + 1, '/', n_test, ', ping latency :', ping_time, 'ms'
except:
self.wifi_timeout = self.wifi_timeout + 1
print 'timeout'
self.wifi_timeout = self.wifi_timeout / float(n_test)
self.wifi_latency = numpy.array(self.wifi_delay)
def get_results(self):
print 'mean latency', numpy.mean(self.wifi_latency), 'ms'
print 'std latency', numpy.std(self.wifi_latency), 'ms'
print 'timeout', self.wifi_timeout * 100, '%'
if __name__ == '__main__':
ip = '192.168.0.1'
n_test = 100
my_wifi = WifiLatencyBenchmark(ip)
my_wifi.run_test(n_test)
my_wifi.get_results()
Github repository:
https://github.com/matthieu-lapeyre/network-benchmark
thanks from Jabba but that code doesn't work correctly for me so i change something like following
import shlex
from subprocess import Popen, PIPE, STDOUT
def get_simple_cmd_output(cmd, stderr=STDOUT):
"""
Execute a simple external command and get its output.
"""
args = shlex.split(cmd)
return Popen(args, stdout=PIPE, stderr=stderr).communicate()[0]
def get_ping_time(host):
host = host.split(':')[0]
cmd = "fping {host} -C 3 -q".format(host=host)
# result = str(get_simple_cmd_output(cmd)).replace('\\','').split(':')[-1].split() if x != '-']
result = str(get_simple_cmd_output(cmd)).replace('\\', '').split(':')[-1].replace("n'", '').replace("-",
'').replace(
"b''", '').split()
res = [float(x) for x in result]
if len(res) > 0:
return sum(res) / len(res)
else:
return 999999
def main():
# sample hard code for test
host = 'google.com'
print([host, get_ping_time(host)])
host = 'besparapp.com'
print([host, get_ping_time(host)])
if __name__ == '__main__':
main()

Categories