Reputation: 95
I have a list of IP's (Generated from a traceroute in Python Scapy) which I need to send 3 ping's to measure the average time to each hop. My first methord was building a ICMP request using sockets and measuring the time for response. But it is inaccurate and slow when pinging multiple hosts. I did try and use normal Linux ping, but my for i
loop was being blocked while waiting for the response, obviously I want all the ping requests to be send out at the same time.
So I'm looking for a way to use fping
in Linux which I give a list of IP's and then let that do the work of building packets. But I'm not sure how to pass a list of arguments to a shell command or get the data back into an array for further processing after it has completed.
Any pointers appreciated!
Upvotes: 1
Views: 8537
Reputation: 309
The following function parses fping
's output and returns a dictionary containing the availability for every host:
import subprocess
from typing import List, Dict
def ping(hosts: List[str], timeout: int = 500) -> Dict[str, bool]:
command = ["fping", "-t", str(timeout)] + hosts
proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
parse = lambda stream: [
line.split(" ")
for line
in stream.read().decode("UTF-8").split("\n")
if len(line) != 0
]
lines = parse(proc.stdout) + parse(proc.stderr)
return {p[0]: p[-1] == "alive" for p in lines if p[1] == 'is'}
print(ping(["google.com", "asdfasdfasdf1234.com", "stackoverflow.com"]))
# {'google.com': True, 'stackoverflow.com': True, 'asdfasdfasdf1234.com:': False}
Upvotes: 0
Reputation: 41950
I don't know much about fping
, but something like this...
import subprocess
CMD = ['fping', 'param1', 'param2']
result = subprocess.check_output(CMD)
...will run fping param1 param2
, and put the output as a string into the result
variable, once the fping
process has terminated.
You can split the output into lines with result.splitlines()
.
Here's quick one-liner example using ping
to grab three ping times to localhost...
>>> [line.rpartition('=')[-1] for line in subprocess.check_output(['ping', '-c', '3', 'localhost']).splitlines()[1:-4]]
['0.028 ms', '0.023 ms', '0.025 ms']
Upvotes: 3