MTU計測バッチファイル:Windowsバッチファイルでハマる
こちらの「Linux版MTU計測スクリプト」の続きで、Windowsバッチファイルを作ることにした。WindowsとLinuxのpingでは、DF(Don't fragment)ビット用のオプション指定が異なる、バッチ(スクリプト)の文法が異なるだけなのだが、バッチファイル作成時に少々はまったので、記録することにした。すべて基本的なことかもしれない。
はまった内容
てこずった内容が下記。部分的に説明。
@echo off
rem if 条件1 or 条件2 .... が存在しない
if "%~1"=="" (
echo IPアドレスを指定してください
exit /b
) else if "%~2"=="" (
echo 送信サイズを指定してください
exit /b
)
まず、バッチファイルでは、if文内に条件を複数記載できず、、、らしい。なので、if elseが多数発生する。
set ip=%1%
set /a first=%2%
rem echo %1% -f -l %2% -n 2 引数をそのまま使うとNG
echo %1% -f -l %2% -n 2
rem echo %ip% -f -l %first% -n 2 引数を変数に代入するとOK
echo %ip% -f -l %first% -n 2
IPアドレスや最初にトライするPayloadサイズを引数(%1、%2)として渡すのであるが、そのまま実行するとNGとなる。ここのechoの結果は下記となる(calcMtu00がバッチファイル)。
I:\>calcMtu00 8.8.8.8 1440
8.8.8.82 -n 2
8.8.8.8 -f -l 1440 -n 2
Windowsでは、”-f”がDFビットオプション、”-l”がPayloadサイズ指定オプションである。
set /a try=first
set /a okMTU=first
:doWhileLoop
ping %ip% -f -l %try% -n 2
set /a mtu=okMTU+28
if %errorlevel% == 1 (
rem 1回目の実行時に変数testに正しい価が設定されない
set /a test=okMTU+28
echo.
if %okMTU% == %first% (
echo ### MTU is less than %mtu% ###
echo test = %test%
) else (
echo ### MTU is %mtu% ###
echo test = %test%
)
rem endlocal
) else (
set /a okMTU=try
set /a try=try+1
goto doWhileLoop
)
pingの実行結果を変数%errorlevel%で判断しており、エラー時にMTU値を計算して(IPヘッダ20バイト+ICMPヘッダサイズ8バイトを付加)処理を終了する。%errorlevel%の前後で計算した値が、1回目の実行時では異なっていた。下記は1回目の結果。
I:\>calcMtu00 8.8.8.8 1440
8.8.8.8 に ping を送信しています 1440 バイトのデータ:
要求がタイムアウトしました。
要求がタイムアウトしました。
8.8.8.8 の ping 統計:
パケット数: 送信 = 2、受信 = 0、損失 = 2 (100% の損失)、
### MTU is less than 1468 ###
test = 1518
前者の値が正しい。後者の値(test)は、前回実行時の結果(かもしれない)。2回目の結果は下記。
I:\>calcMtu00 8.8.8.8 1440
8.8.8.8 に ping を送信しています 1440 バイトのデータ:
要求がタイムアウトしました。
要求がタイムアウトしました。
8.8.8.8 の ping 統計:
パケット数: 送信 = 2、受信 = 0、損失 = 2 (100% の損失)、
### MTU is less than 1468 ###
test = 1468
2回目以降は同じ値となった(同じ引数を与えた場合)。
正式版
こちらが確実に動作するもの(今のところ)。
@echo off
if "%~1"=="" (
echo IPアドレスを指定してください
exit /b
) else if "%~2"=="" (
echo 最初にトライする送信サイズを指定してください
exit /b
)
set ip=%1%
set /a first=%2%
set /a try=first
set /a okMTU=first
:doWhileLoop
ping %ip% -f -l %try% -n 2
set /a mtu=okMTU+28
if %errorlevel% == 1 (
echo.
if %okMTU% == %first% (
echo ### MTU is less than %mtu% ###
) else (
echo ### MTU is %mtu% ###
)
) else (
set /a okMTU=try
set /a try=try+1
goto doWhileLoop
)
VPNなし
ある環境下での、VPN接続なし(通常ネットワーク接続時)の結果は下記となる。
C:\>calcMtu1 8.8.8.8 1424
8.8.8.8 に ping を送信しています 1424 バイトのデータ:
8.8.8.8 からの応答: バイト数 =1424 時間 =10ms TTL=116
8.8.8.8 からの応答: バイト数 =1424 時間 =8ms TTL=116
8.8.8.8 の ping 統計:
パケット数: 送信 = 2、受信 = 2、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
最小 = 8ms、最大 = 10ms、平均 = 9ms
8.8.8.8 に ping を送信しています 1425 バイトのデータ:
8.8.8.8 からの応答: バイト数 =1425 時間 =14ms TTL=116
8.8.8.8 からの応答: バイト数 =1425 時間 =7ms TTL=116
8.8.8.8 の ping 統計:
パケット数: 送信 = 2、受信 = 2、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
最小 = 7ms、最大 = 14ms、平均 = 10ms
8.8.8.8 に ping を送信しています 1426 バイトのデータ:
8.8.8.8 からの応答: バイト数 =1426 時間 =5ms TTL=116
8.8.8.8 からの応答: バイト数 =1426 時間 =7ms TTL=116
8.8.8.8 の ping 統計:
パケット数: 送信 = 2、受信 = 2、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
最小 = 5ms、最大 = 7ms、平均 = 6ms
8.8.8.8 に ping を送信しています 1427 バイトのデータ:
パケットの断片化が必要ですが、DF が設定されています。
パケットの断片化が必要ですが、DF が設定されています。
8.8.8.8 の ping 統計:
パケット数: 送信 = 2、受信 = 0、損失 = 2 (100% の損失)、
### MTU is 1454 ###
VPNあり
同じ環境下での、あるVPN経由の結果は下記となる。
C:\>calcMtu1 8.8.8.8 1344
8.8.8.8 に ping を送信しています 1344 バイトのデータ:
8.8.8.8 からの応答: バイト数 =1344 時間 =20ms TTL=56
8.8.8.8 からの応答: バイト数 =1344 時間 =14ms TTL=56
8.8.8.8 の ping 統計:
パケット数: 送信 = 2、受信 = 2、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
最小 = 14ms、最大 = 20ms、平均 = 17ms
8.8.8.8 に ping を送信しています 1345 バイトのデータ:
8.8.8.8 からの応答: バイト数 =1345 時間 =13ms TTL=56
8.8.8.8 からの応答: バイト数 =1345 時間 =15ms TTL=56
8.8.8.8 の ping 統計:
パケット数: 送信 = 2、受信 = 2、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
最小 = 13ms、最大 = 15ms、平均 = 14ms
8.8.8.8 に ping を送信しています 1346 バイトのデータ:
8.8.8.8 からの応答: バイト数 =1346 時間 =16ms TTL=56
8.8.8.8 からの応答: バイト数 =1346 時間 =22ms TTL=56
8.8.8.8 の ping 統計:
パケット数: 送信 = 2、受信 = 2、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
最小 = 16ms、最大 = 22ms、平均 = 19ms
8.8.8.8 に ping を送信しています 1347 バイトのデータ:
要求がタイムアウトしました。
要求がタイムアウトしました。
8.8.8.8 の ping 統計:
パケット数: 送信 = 2、受信 = 0、損失 = 2 (100% の損失)、
### MTU is 1374 ###
VPN経由の場合、相当量のヘッダが追加され、MTU値が小さくなるのがわかる。
EOF