Created
May 30, 2020 16:31
-
-
Save hleroy/9fd589a243a978caa001c8b58ee6a6ca to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# -*- coding: utf-8 -*- | |
''' | |
check_mtu.py -- Check link MTU by sending UDP packets with increasing payload size | |
positional arguments: | |
host host to send packet to. If omitted, defaults to | |
www.google.com | |
optional arguments: | |
-h, --help show this help message and exit | |
-p PORT, --port PORT port to send packet to. If omitted, defaults to 80 | |
-l PAYLOADS, --payloads PAYLOADS | |
range of payloads to test. If omitted, defaults to | |
1420-1480 | |
-v, --verbose print the result of each test | |
@author: Hervé Le Roy | |
@contact: hleroy@hleroy.com | |
''' | |
import socket | |
from argparse import ArgumentParser | |
def payload_range(string): | |
val_list = string.split('-') | |
return range(int(val_list[0]), int(val_list[1]) + 1) | |
def main(): | |
"Check link MTU by sending UDP packets with increasing payload size" | |
# Defaults | |
DEFAULT_HOST = "www.google.com" | |
DEFAULT_PORT = 80 | |
DEFAULT_PAYLOADS = "1420-1480" | |
# Setup argument parser | |
parser = ArgumentParser( | |
description="Check link MTU by sending UDP packets with increasing payload size") | |
parser.add_argument("host", nargs="?", default=DEFAULT_HOST, | |
help="host to send packet to. If omitted, defaults to www.google.com") | |
parser.add_argument("-p", "--port", type=int, default=DEFAULT_PORT, | |
help="port to send packet to. If omitted, defaults to 80") | |
parser.add_argument('-l', '--payloads', type=payload_range, default=DEFAULT_PAYLOADS, | |
help="range of payloads to test. If omitted, defaults to 1420-1480") | |
parser.add_argument('-v', '--verbose', action='store_true', | |
help="print the result of each test") | |
args = parser.parse_args() | |
# Initialize max payloads | |
max_payload = 0 | |
# Open socket | |
IP_MTU_DISCOVER = 10 # MTU discover | |
IP_PMTUDISC_DO = 2 # Always set DF (don't fragment) bit | |
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) | |
for payload in args.payloads: | |
s.connect((args.host, args.port)) | |
s.setsockopt(socket.IPPROTO_IP, IP_MTU_DISCOVER, IP_PMTUDISC_DO) | |
try: | |
s.send(b'#' * payload) | |
except socket.error: | |
if args.verbose: | |
print('Failed to sent UDP packet with a payload of {} bytes'.format( | |
payload)) | |
else: | |
max_payload = payload | |
if args.verbose: | |
print('Succesfully sent UDP packet with a payload of {} bytes'.format( | |
payload)) | |
if max_payload == 0: | |
print('No packet went through. Try decreasing payload size.') | |
exit() | |
if max_payload == args.payloads[-1]: | |
print('All packets went through. Try increasing payload size.') | |
exit() | |
# MTU = max_payload + 20 (IP header) + 8 (UDP header) | |
print('Path MTU to {} is {}'.format(args.host, max_payload + 28)) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment