From 579aa40befb6b0ebd3384dda5ca0515255ef5c19 Mon Sep 17 00:00:00 2001 From: yanpj1992 Date: Sat, 22 Jul 2023 14:26:27 +0800 Subject: [PATCH 1/4] Add COUNT option to set the number of packets to send --- udpping.py | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/udpping.py b/udpping.py index caffa5f..c9c48f9 100755 --- a/udpping.py +++ b/udpping.py @@ -16,6 +16,9 @@ IP="" PORT=0 +COUNT = 0 +HAS_COUNT = False + count=0 count_of_received=0 rtt_sum=0.0 @@ -32,8 +35,18 @@ def signal_handler(signal, frame): print('rtt min/avg/max = %.2f/%.2f/%.2f ms'%(rtt_min,rtt_sum/count_of_received,rtt_max)) os._exit(0) +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)) + os._exit(0) + def random_string(length): - return ''.join(random.choice(string.ascii_letters+ string.digits ) for m in range(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:""") @@ -44,12 +57,14 @@ def random_string(length): 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""") + print(""" COUNT the count of packet, default is unlimited""") 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(' ./udpping.py 44.55.66.77 4000 "LEN=400;INTERVAL=2000;COUNT=100"') print() exit() @@ -57,10 +72,10 @@ def random_string(length): IP=sys.argv[1] PORT=int(sys.argv[2]) -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]) @@ -72,6 +87,9 @@ def random_string(length): print("INTERVAL must be >=50") exit() +if COUNT != 0: + HAS_COUNT = True + signal.signal(signal.SIGINT, signal_handler) if not is_ipv6: @@ -83,19 +101,23 @@ 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: From cfee7bfdd7639a3f901c2e3b6333f964092d6217 Mon Sep 17 00:00:00 2001 From: PeiJia Yan Date: Tue, 1 Aug 2023 20:43:30 +0800 Subject: [PATCH 2/4] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5e2b1a4..2f925cf 100644 --- a/README.md +++ b/README.md @@ -62,10 +62,11 @@ root@raspberrypi:~# ./udpping.py 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 + COUNT the count of packets, default is unlimited examples: ./udpping.py 44.55.66.77 4000 - ./udpping.py 44.55.66.77 4000 "LEN=400;INTERVAL=2000" + ./udpping.py 44.55.66.77 4000 "LEN=400;INTERVAL=2000;COUNT=100" ./udpping.py fe80::5400:ff:aabb:ccdd 4000 ``` From 8810b1f977c84561cde486bf0f681f20ce3c213e Mon Sep 17 00:00:00 2001 From: yanpj1992 Date: Tue, 22 Aug 2023 22:11:53 +0800 Subject: [PATCH 3/4] fix ipv6 address check. --- udpping.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/udpping.py b/udpping.py index c9c48f9..3a9bac8 100755 --- a/udpping.py +++ b/udpping.py @@ -120,7 +120,9 @@ def random_string(length): 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() From 36ce0a277ba6366945f9df94914f530903debe20 Mon Sep 17 00:00:00 2001 From: yanpj1992 Date: Wed, 1 May 2024 21:11:31 +0800 Subject: [PATCH 4/4] use argparse and update readme --- README.md | 36 ++++++++++++++++----------- udpping.py | 73 +++++++++++++++++++++++------------------------------- 2 files changed, 53 insertions(+), 56 deletions(-) diff --git a/README.md b/README.md index 2f925cf..d29e950 100644 --- a/README.md +++ b/README.md @@ -54,19 +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 - COUNT the count of packets, default is unlimited - - examples: - ./udpping.py 44.55.66.77 4000 - ./udpping.py 44.55.66.77 4000 "LEN=400;INTERVAL=2000;COUNT=100" - ./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 3a9bac8..df0a8f4 100755 --- a/udpping.py +++ b/udpping.py @@ -1,23 +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 - -COUNT = 0 -HAS_COUNT = False +import argparse count=0 count_of_received=0 @@ -33,7 +24,7 @@ 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 print_result(): if count!=0 and count_of_received!=0: @@ -43,52 +34,50 @@ def print_result(): 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 "" """) - - 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""") - print(""" COUNT the count of packet, default is unlimited""") - - 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(' ./udpping.py 44.55.66.77 4000 "LEN=400;INTERVAL=2000;COUNT=100"') - print() - - exit() - -IP=sys.argv[1] -PORT=int(sys.argv[2]) + return ''.join(random.choice(string.ascii_letters+ string.digits ) for _ in range(length)) + +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) + +args = args.parse_args() + +IP=args.dest_ip +PORT=args.dest_port is_ipv6=0 if IP.find(":")!=-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 COUNT != 0: +if args.count: + COUNT = args.count HAS_COUNT = True +else: + COUNT = 0 + HAS_COUNT = False signal.signal(signal.SIGINT, signal_handler)