Bottle Python ping check 5 pings - python

I am trying to write a script to print a ping check to the browser with 5 pings.
This script:
from bottle import route, run, template
import subprocess
#route('/pings/<ip>')
def ping(ip):
param = '-c 1'
command = ['ping', param, ip]
num = 0
while (num < 6):
return subprocess.check_output(command)
num += 1
run(host='0.0.0.0', port=8080)
Currently outputs to the browser as follows:
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data. 64 bytes from 8.8.8.8:
icmp_seq=1 ttl=54 time=17.7 ms --- 8.8.8.8 ping statistics --- 1
packets transmitted, 1 received, 0% packet loss, time 0ms rtt
min/avg/max/mdev = 17.756/17.756/17.756/0.000 ms
But it doesn't print out 5 pings like I expect it to. It only prints out the one ping, is it for some reason only printing out the last one? How can I print out 5 pings like it would look if you ran it from a shell command.
Thanks.

The loop is only running once because return is executed during the first iteration of the loop therefore you're only getting the first result. You can get the ping result and append that to a list then once the loop is complete you can just return that list.
def ping(ip):
param = '-c 1'
command = ['ping', param, ip]
num = 0
output = []
while (num < 6):
output.append(subprocess.check_output(command))
num += 1
return output // or return "\n".join(output)

Related

Is .apply_on_packets 's timeout unpredictable?

The following code gives unpredictable results with the following advice in use:
import pyshark
import pandas as pd
import asyncio
def ProcessPackets(packet):
global packet_list
packet_version = packet.layers[1].version
layer_name = packet.layers[2].layer_name
packet_list.append([packet_version, layer_name, packet.length, packet.sniff_time])
def Capture(timeOrPath):
global packet_list
packet_list=[]
try:
timeout=int(timeOrPath)
capture = pyshark.LiveCapture()
capture.apply_on_packets(ProcessPackets, timeout=timeout)
except asyncio.TimeoutError:
pass
except ValueError:
capture = pyshark.FileCapture(timeOrPath)
capture.load_packets()
capture.apply_on_packets(ProcessPackets)
data = pd.DataFrame(packet_list, columns=['vIP', 'protocol', 'length','timestamp'])
print(data['timestamp'].iloc[-1]-data['timestamp'].iloc[0])
def main():
Capture(6)
if __name__ == '__main__':
main()
Sometimes the calculated time exceeds the timeout given.
(timestamp is packet.sniff_time)
UPDATED 06-03-2021
After doing some research into this capture latency issue, I have determined that the problem likely is linked to pyshark waiting for dumpcap to load. dumpcap is loaded in LiveCapture mode
def _get_dumpcap_parameters(self):
# Don't report packet counts.
params = ["-q"]
if self._get_tshark_version() < LooseVersion("2.5.0"):
# Tshark versions older than 2.5 don't support pcapng. This flag forces dumpcap to output pcap.
params += ["-P"]
if self.bpf_filter:
params += ["-f", self.bpf_filter]
if self.monitor_mode:
params += ["-I"]
for interface in self.interfaces:
params += ["-i", interface]
# Write to STDOUT
params += ["-w", "-"]
return params
async def _get_tshark_process(self, packet_count=None, stdin=None):
read, write = os.pipe()
dumpcap_params = [get_process_path(process_name="dumpcap", tshark_path=self.tshark_path)] + self._get_dumpcap_parameters()
self._log.debug("Creating Dumpcap subprocess with parameters: %s" % " ".join(dumpcap_params))
dumpcap_process = await asyncio.create_subprocess_exec(*dumpcap_params, stdout=write,
stderr=self._stderr_output())
self._created_new_process(dumpcap_params, dumpcap_process, process_name="Dumpcap")
tshark = await super(LiveCapture, self)._get_tshark_process(packet_count=packet_count, stdin=read)
return tshark
The code above launches this on my system:
/usr/local/bin/dumpcap -q -i en0 -w -
and this:
/usr/local/bin/tshark -l -n -T pdml -r -
I have attempted to pass in some custom parameters to LiveCapture
capture = pyshark.LiveCapture(interface='en0', custom_parameters=["-q", "--no-promiscuous-mode", "-l"])
but there is still around a 1/2 of a second delay.
10.015577793121338
0 days 00:00:09.371264
In the dumpcap documentation there is a -a mode, which allows for a duration timeout, but I cannot pass that parameter into pyshark without causing an error.
Tshark also has a -a mode, but it also causes an error within pyshark
capture = pyshark.LiveCapture(interface='en0', override_prefs={'': '-r'}, custom_parameters={'': '-a duration:20'})
There might be way to modify the timeout parameters within pyshark code base, to allow the -a mode. To do this would require some testing, which I don't have the time to do at the moment.
I opened an issue on this problem with the developers of pyshark.
ORIGINAL POST 06-02-2021
I reworked your code to write the extracted items to a pandas dataframe. If this isn't what you wanted please update your questions with your exact requirements.
import pyshark
import asyncio
import pandas as pd
packet_list = []
def process_packets(packet):
global packet_list
try:
packet_version = packet.layers[1].version
layer_name = packet.layers[2].layer_name
packet_list.append([packet_version, layer_name, packet.length, str(packet.sniff_time)])
except AttributeError:
pass
def capture_packets(timeout):
capture = pyshark.LiveCapture(interface='en0')
try:
capture.apply_on_packets(process_packets, timeout=timeout)
except asyncio.TimeoutError:
pass
finally:
return packet_list
def main():
capture_packets(6)
df = pd.DataFrame(packet_list, columns=['packet version', 'layer type', 'length', 'capture time'])
print(df)
# output
packet version layer type length capture time
0 4 udp 75 2021-06-02 16:22:36.463805
1 4 udp 67 2021-06-02 16:22:36.517076
2 4 udp 1388 2021-06-02 16:22:36.706240
3 4 udp 1392 2021-06-02 16:22:36.706245
4 4 udp 1392 2021-06-02 16:22:36.706246
truncated...
if __name__ == '__main__':
main()

Reading from txt file and executing an os command

What i want to achieve would be reading the IP/Domain from the TXT file and executing an OS import command then adding the IP/Domain when pinging.
However the problem is that for some reason it's placing a period at the end of the IP/Domain that it read from the TXT file, resulting in an invalid request when pining (the code works the only problem would be the period at the end)
for example: when the pinging line executes on the compiler it's telling me "bad parameters google.com." however on the txt file it self there is only one period which is the one for the .com it self.
def scanlist():
ipopen = open("IPlist.txt")
#Opens the IPlist.txt file and strips each of the lines so that we can read individually.
with open("IPlist.txt", "r+") as ips_file:
ips = [ip.strip() for ip in ips_file.readlines()]
#Read each line from the IPlist.txt file
with open("IPlist.txt", "r") as available_ips_file:
for ip in ips:
#Pings each line from the IPlist.txt file
response = os.system('ping -a 1 {}'.format(ip))
if response == 0: # 512/DOWN value - 0/UP value
# Up
print("- Ip Address:", ip, 'is up!')
elif response == 512:
#down
print("- IP Address:", ip, 'is down!')
else:
#other error
print("- Bad parameters or other error!")
For the entire code visit the github: https://github.com/Hontiris1/IPPing/blob/master/Ping.py
the issue was in the paramter you were passing to the ping the 1 after -a is not a valid parameter
import os
def scanlist():
#Opens the IPlist.txt file and strips each of the lines so that we can read individually.
with open("IPlist.txt") as ips_file:
ips = list(map(str.strip,ips_file.readlines()))
#Read each line from the IPlist.txt file
for ip in ips:
#Pings each line from the IPlist.txt file
response = os.system('ping {} -a -n 1'.format(ip)) # to send only one request
if response == 0: # 512/DOWN value - 0/UP value
# Up
print("- Ip Address:", ip, 'is up!')
elif response == 1: # if it's time out
#down
print("- IP Address:", ip, 'is down!')
else:
#other error
print("- Bad parameters or other error!")
scanlist()
output
Pinging 8.8.8.8 with 32 bytes of data:
Reply from 8.8.8.8: bytes=32 time=55ms TTL=56
Ping statistics for 8.8.8.8:
Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 55ms, Maximum = 55ms, Average = 55ms
- Ip Address: 8.8.8.8 is up!
Pinging stackoverflowll.com [218.93.250.18] with 32 bytes of data:
Request timed out.
Ping statistics for 218.93.250.18:
Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),
- IP Address: stackoverflowll.com is down!

Add multiple entries of text to specific lines of code in Python

I would like to add the flag
-c 4
to my line of code at
hostname = "216.58.223.3 -c 4"
The way it currently works:
#staticmethod
def valve_southafrica_two():
print("Pinging Valve South Africa 2")
hostname = "155.133.238.163"
response = os.system("ping " + hostname)
if response == 0:
pingstatus = "Active"
else:
pingstatus = "Error"
print("Ping Test Complete")
return pingstatus
and the way I want it to work is so:
#staticmethod
def valve_southafrica_two():
print("Pinging Valve South Africa 2")
hostname = "155.133.238.163 -c 4"
response = os.system("ping " + hostname)
if response == 0:
pingstatus = "Active"
else:
pingstatus = "Error"
print("Ping Test Complete")
return pingstatus
for Linux +/ MacOS Pinging, is there any way to bulk add the -c 4 flag next to the xxx.xxx.xxx.xxx (IP) or is the only solution to manually add the -c 4 next to each line?
Use subprocess,call
By which we can send the commands as a list of arguments so we just need to specify -c 4 as an argument
import subprocess
#import os
def valve_southafrica_two():
print("Pinging Valve South Africa 2")
hostname = "155.133.238.163"
response =subprocess.call(["ping",hostname,"-c 4"])
if response == 0:
pingstatus = "Active"
else:
pingstatus = "Error"
print("Ping Test Complete")
return pingstatus
valve_southafrica_two()
OUTPUT
Pinging Valve South Africa 2
PING 155.133.238.163 (155.133.238.163) 56(84) bytes of data.
64 bytes from 155.133.238.163: icmp_seq=1 ttl=47 time=327 ms
64 bytes from 155.133.238.163: icmp_seq=2 ttl=47 time=325 ms
64 bytes from 155.133.238.163: icmp_seq=3 ttl=47 time=326 ms
64 bytes from 155.133.238.163: icmp_seq=4 ttl=47 time=325 ms
--- 155.133.238.163 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3003ms
rtt min/avg/max/mdev = 325.113/326.192/327.601/0.992 ms
Ping Test Complete
You can use string formatting or f-strings like below
flag = '-c 4'
# python 3.6
hostname = f'155.133.238.163 {flag}'
# python 2.7
hostname = '155.133.238.163 {0}'.format(flag)
Output
155.133.238.163 -c 4

Cannot receive echo replies from others

Only "destination unreachable" replies are received while using given snippet(handler is pyicmp.handler.Handler from https://github.com/volftomas/pyicmp):
def IPScanner(handler, ip, file, lock):
for ttl in (32,):
# putting 32 in a tuple was necessary here,
# otherwise do_ping() acts as a noop
ctr = 0
for j in range(0,4):
t = PrintThread(str("Dest:" + ip + " TTL" + str(ttl)), lock)
t.start()
ping_result = handler.do_ping(ip, ttl)
if ping_result['packet_loss'] == 0:
ping_result['packet_loss'] = j
break
else:
ping_result['packet_loss'] = 0
d = DumpFileThread(file, ping_result, lock)
d.start()
Some hosts send destination unreachable and others block echo request, I cannot share dumpfile because dumpfile I have now has IP mappings of a corporate institution. I can ping the IPs passed to this function via Windows's ping. Why can I not receive pings from pyicmp library. ICMP echo is not blocked on my host.

Reconstruct HTTP Webpage from libpcap python script

I am trying to reconstruct a webpage from a libpcap file from a python script. I have all the packets so the goal I guess is to have a libpcap file as input and you find all the necessary packets and somehow have a webpage file as output with all pictures and data from that page. Can anyone get me started off in the right direction. I think I will need dkpt and/or scaPY.
Update 1: Code is below! Here is the code I have come up so far with in Python. It is suppose to grab the first set of packets from a single HTTP session beginning with a packet with the SYN and ACK flags set to 1 and ends with a packet that has the FIN flag set to 1.
Assuming there is only one website visited during the packet capture does this code append all the necessary packets needed to reconstruct the visited webpage?
Assuming I have all the necessary packets how do I reconstruct the webpage?
import scaPy
pktList = list() #create a list to store the packets we want to keep
pcap = rdpcap('myCapture.pcap') #returns a packet list with every packet in the pcap
count = 0 #will store the index of the syn-ack packet in pcap
for pkt in pcap: #loops through packet list named pcap one packet at a time
count = count + 1 #increments by 1
if pkt[TCP].flags == 0x12 and pkt[TCP].sport == 80: #if it is a SYN-ACK packet session has been initiated as http
break #breaks out of the for loop
currentPkt = count #loop from here
while pcap[currentPkt].flags&0x01 != 0x01: #while the FIN bit is set to 0 keep loops stop when it is a 1
if pcap[currentPkt].sport == 80 and pcap[currentPkt].dport == pcap[count].dport and pcap[currentPkt].src == pcap[count].src and pcap[currentPkt].dst == pcap[count].dst:
#if the src, dst ports and IP's are the same as the SYN-ACK packet then the http packets belong to this session and we want to keep them
pktList.append(pcap[currentPkt])
#once the loop exits we have hit the packet with the FIN flag set and now we need to reconstruct the packets from this list.
currentPkt = currentPkt + 1
Perhaps something like tcpick -r your.pcap -wRS does the job for you.
http://tcpick.sourceforge.net/?t=1&p=OPTIONS
This python script will extract all unencrypted HTTP webpages that are in a PCAP File and output them as HTML Files. It uses scaPY to work with the individual packets (another good python module is dpkt).
from scapy.all import *
from operator import *
import sys
def sorting(pcap):
newerList = list()
#remove everything not HTTP (anything not TCP or anything TCP and not HTTP (port 80)
#count = 0 #dont need this it was for testing
for x in pcap:
if x.haslayer(TCP) and x.sport == 80 and bin(x[TCP].flags)!="0b10100":
newerList.append(x);
newerList = sorted(newerList, key=itemgetter("IP.src","TCP.dport"))
wrpcap("sorted.pcap", newerList)
return newerList
def extract(pcap,num, count):
listCounter = count
counter = 0
#print listCounter
#Exit if we have reached the end of the the list of packets
if count >= len(pcap):
sys.exit()
#Create a new file and find the packet with the payload containing the beginning HTML code and write it to file
while listCounter != len(pcap):
thisFile = "file" + str(num) + ".html"
file = open(thisFile,"a")
s = str(pcap[listCounter][TCP].payload)
#print "S is: ", s
x,y,z = s.partition("<")
s = x + y + z #before was y+z
if s.find("<html") != -1:
file.write(s)
listCounter = listCounter + 1
break
listCounter = listCounter + 1
#Continue to loop through packets and write their contents until we find the close HTML tag and
#include that packet as well
counter = listCounter
while counter != len(pcap):
s = str(pcap[counter][TCP].payload)
if s.find("</html>") != -1:
file.write(s)
file.close
break
else:
file.write(s)
counter = counter + 1
#Recursively call the function incrementing the file name by 1
#and giving it the last spot in the PCAP we were in so we continue
#at the next PCAP
extract(pcap, num+1, counter)
if __name__ == "__main__":
#Read in file from user
f = raw_input("Please enter the name of your pcap file in this directory. Example: myFile.pcap")
pcapFile = rdpcap(f)
print "Filtering Pcap File of non HTTP Packets and then sorting packets"
#Sort and Filter the PCAP
pcapFile = sorting(pcapFile)
print "Sorting Complete"
print "Extracting Data"
#Extract the Data
extract(pcapFile,1,0)
Print "Extracting Complete"

Categories

Resources