diff --git a/README.md b/README.md index 5e2b1a4..d29e950 100644 --- a/README.md +++ b/README.md @@ -54,18 +54,27 @@ Now UDPping will generate outputs as a normal ping, but the protocol used is `UD # Advanced Usage ``` -root@raspberrypi:~# ./udpping.py - usage: - this_program - this_program "" - - options: - LEN the length of payload, unit:byte - INTERVAL the seconds waited between sending each packet, as well as the timeout for reply packet, unit: ms - - examples: - ./udpping.py 44.55.66.77 4000 - ./udpping.py 44.55.66.77 4000 "LEN=400;INTERVAL=2000" - ./udpping.py fe80::5400:ff:aabb:ccdd 4000 +$ ./udpping.py -h +usage: udpping.py [-h] [-l LEN] [-i INTERVAL] [-c COUNT] dest_ip dest_port + +ping with UDP protocol + +positional arguments: + dest_ip destination IP address(IPv4/IPv6) + dest_port destination port + +options: + -h, --help show this help message and exit + -l LEN, --len LEN payload length, unit:byte, default is 64 + -i INTERVAL, --interval INTERVAL + interval between each packet, unit: ms, default is 1000 + -c COUNT, --count COUNT + number of packets, default is unlimited + +examples: + ./udpping.py 44.55.66.77 4000 -l 400 -i 2000 + ./udpping.py fe80::5400:ff:aabb:ccdd 4000 + ./udpping.py 44.55.66.77 4000 -l 400 -i 2000 -c 100') + ``` diff --git a/udpping.py b/udpping.py index caffa5f..df0a8f4 100755 --- a/udpping.py +++ b/udpping.py @@ -1,20 +1,14 @@ #!/usr/bin/env python -from __future__ import print_function +from __future__ import print_function import socket -import sys import time import string import random import signal import sys -import os - -INTERVAL = 1000 #unit ms -LEN =64 -IP="" -PORT=0 +import argparse count=0 count_of_received=0 @@ -30,48 +24,61 @@ def signal_handler(signal, frame): print('%d packets transmitted, %d received, %.2f%% packet loss'%(count,count_of_received, (count-count_of_received)*100.0/count)) if count_of_received!=0: print('rtt min/avg/max = %.2f/%.2f/%.2f ms'%(rtt_min,rtt_sum/count_of_received,rtt_max)) - os._exit(0) + sys.exit(0) -def random_string(length): - return ''.join(random.choice(string.ascii_letters+ string.digits ) for m in range(length)) - -if len(sys.argv) != 3 and len(sys.argv)!=4 : - print(""" usage:""") - print(""" this_program """) - print(""" this_program "" """) +def print_result(): + if count!=0 and count_of_received!=0: + print('') + print('--- ping statistics ---') + if count!=0: + print('%d packets transmitted, %d received, %.2f%% packet loss'%(count,count_of_received, (count-count_of_received)*100.0/count)) + if count_of_received!=0: + print('rtt min/avg/max = %.2f/%.2f/%.2f ms'%(rtt_min,rtt_sum/count_of_received,rtt_max)) + sys.exit(0) - print() - print(""" options:""") - print(""" LEN the length of payload, unit:byte""") - print(""" INTERVAL the seconds waited between sending each packet, as well as the timeout for reply packet, unit: ms""") +def random_string(length): + return ''.join(random.choice(string.ascii_letters+ string.digits ) for _ in range(length)) - print() - print(" examples:") - print(" ./udpping.py 44.55.66.77 4000") - print(' ./udpping.py 44.55.66.77 4000 "LEN=400;INTERVAL=2000"') - print(" ./udpping.py fe80::5400:ff:aabb:ccdd 4000") - print() +epilog_txt = ''' +examples: + ./udpping.py 44.55.66.77 4000 -l 400 -i 2000 + ./udpping.py fe80::5400:ff:aabb:ccdd 4000 + ./udpping.py 44.55.66.77 4000 -l 400 -i 2000 -c 100') +''' +args = argparse.ArgumentParser(description='ping with UDP protocol', epilog= epilog_txt, formatter_class=argparse.RawTextHelpFormatter) +args.add_argument("dest_ip", type=str, help="destination IP address(IPv4/IPv6)") +args.add_argument("dest_port", type=int, help="destination port") +args.add_argument("-l", "--len", type=int, dest="len", help="payload length, unit:byte, default is 64", default=64) +args.add_argument("-i", "--interval", type=int, dest="interval", help="interval between each packet, unit: ms, default is 1000", default=1000) +args.add_argument("-c", "--count", type=int, dest="count", help="number of packets, default is unlimited", default=0) - exit() +args = args.parse_args() -IP=sys.argv[1] -PORT=int(sys.argv[2]) +IP=args.dest_ip +PORT=args.dest_port -is_ipv6=0; +is_ipv6=0 if IP.find(":")!=-1: - is_ipv6=1; + is_ipv6=1 -if len(sys.argv)==4: - exec(sys.argv[3]) - +LEN = args.len if args.len else 64 if LEN<5: print("LEN must be >=5") exit() + +INTERVAL = args.interval if args.interval else 1000 if INTERVAL<50: print("INTERVAL must be >=50") exit() +if args.count: + COUNT = args.count + HAS_COUNT = True +else: + COUNT = 0 + HAS_COUNT = False + signal.signal(signal.SIGINT, signal_handler) if not is_ipv6: @@ -83,22 +90,28 @@ def random_string(length): sys.stdout.flush() while True: + + if (HAS_COUNT and COUNT == count): + print_result() + payload= random_string(LEN) sock.sendto(payload.encode(), (IP, PORT)) time_of_send=time.time() deadline = time.time() + INTERVAL/1000.0 received=0 rtt=0.0 - + while True: timeout=deadline - time.time() if timeout <0: break #print "timeout=",timeout - sock.settimeout(timeout); + sock.settimeout(timeout) try: recv_data,addr = sock.recvfrom(65536) - if recv_data== payload.encode() and addr[0]==IP and addr[1]==PORT: + if recv_data== payload.encode() and \ + (addr[0]==IP or (is_ipv6 and (socket.inet_pton(socket.AF_INET6, addr[0]) == socket.inet_pton(socket.AF_INET6, IP)))) and \ + addr[1]==PORT: rtt=((time.time()-time_of_send)*1000) print("Reply from",IP,"seq=%d"%count, "time=%.2f"%(rtt),"ms") sys.stdout.flush()