#!/usr/bin/perl -w # # mtufinder - test different sized HTTP requests to a web server, # highlighting MTU size problems. Perl, Unix/Linux/Windows... # # 25-Jan-2006, ver 1.05 # # USAGE: mtufinder [-h] | [-p proxy:port] hostname # eg, # mtufinder science.nasa.gov # mtufinder -p proxy1:8080 science.nasa.gov # # Sometimes firewalls on the Internet are misconfigured to block ICMP, # and in doing so they block the ICMP can't fragment requests that # are returned when a too large MTU was used. This program can help # identify the case. # # COPYRIGHT: Copyright (c) 2005 Brendan Gregg. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # (http://www.gnu.org/copyleft/gpl.html) # # 24-Mar-2004 Brendan Gregg Created this. # 25-Jan-2006 " " Tweaked style. use strict; use IO::Socket; use Getopt::Std; # # Command line arguments # usage() if @ARGV == 0 or $ARGV[0] eq "--help"; getopts('hp:'); usage() if $main::opt_h; $main::opt_h = 0; my ($hostname, $proxy, $port, $website); if (defined $main::opt_p) { $main::opt_p =~ s|^http://||; ($hostname, $port) = split /:/, $main::opt_p; $port = 8080 if $port eq ""; # default proxy port $proxy = 1; $website = $ARGV[0]; } else { $hostname = $ARGV[0]; $hostname =~ s|^http://||; $port = 80; # default port $website = "/"; } # # Variables # my $string = "Accept-Language: en\n"; # This has a length of 20 bytes, # and is used as a padding string. my $count = 0; my $inc = 25; # multiple of $string increment $| = 1; # # Main # if ($proxy) { print "website, $website via proxy, $hostname:$port\n"; } else { print "website, $hostname\n"; } while ((16 + 20 * $count) < 1600) { ### Connect to host my $remote = IO::Socket::INET->new( Proto => "tcp", PeerAddr => "$hostname", PeerPort => "$port" ); if ($remote) { ### Send test request my $bytes = 16 + 20 * $count; print "trying $bytes bytes... "; print $remote "GET $website HTTP/1.0\n"; print $remote $string x $count . "\n"; ### Read reply my $reply = ""; $reply .= $_ while (<$remote>); ### Check reply was ok print length($reply) > 10 ? "connected ok\n" : "failed\n"; close $remote; } else { ### Initial connection failed print STDERR "ERROR1: Connection to $hostname failed\n"; } $count += $inc; } # usage - print usage message and exit # sub usage { print STDERR "USAGE: mtufinder [-h] | [-p proxy:port] hostname\n"; print STDERR " eg, mtufinder science.nasa.gov\n"; print STDERR " mtufinder -p proxy1:8080 science.nasa.gov\n"; exit 1; }