IPフラグメンテーションが起こる様子をWiresharkで確認する

はじめに

大きいデータを送信すると、経路上でデータが複数に分割されることがある(IPフラグメンテーション)。これをWiresharkで実際に確かめたい。

手順

  1. Wiresharkを起動して、パケットをキャプチャする。フィルタリングは以下のようにすればいい。
ip.addr==<任意のIPアドレス>
  1. 以下のPythonコードを実行して、UDPパケットを送信する。
import socket

# 送信先のIPアドレスとポート番号
UDP_IP = "任意のIPアドレス"  # ※ループバックアドレスは使わないこと
UDP_PORT = 5005

# 65,000バイトのデータを作成
MESSAGE = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ" * 1000

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))
print(f"Sent {len(MESSAGE)} bytes to {UDP_IP}:{UDP_PORT}")

※注意点

  • udp.port==5005とフィルタリングするとうまくいかない
    今回見たいのは、送信するUDPデータグラムとそれらが分割されてできた複数のIPパケットである。そのため、UDPポートでフィルタリングしてしまうと、portフィールドがあるUDPデータグラムしか表示されない。IPパケットはUDPのヘッダがないので、フィルタリングで弾かれてしまう。

  • ループバックアドレスだとうまくいかない
    最初はsenderとreceiverを用意してデータグラムを送受信させるプログラムを書いたが、この場合だとうまくいかなかった。ループバックアドレスはルーターを経由しないため、そもそもIPパケットが分割されないという可能性がある。

結果

以下のようにいくつかのIPパケットとそれらが構成されてできたUDPデータグラムが表示される。 Wiresharkのキャプチャ結果
今回は送信側のキャプチャ結果を示しているので、IPパケットの順序は基本的にオフセットの小さい順になっている。ちなみにオフセットの間隔は1480バイトとなっているが、これは一度に送れるIPパケットの最大サイズ(MTU)が1500バイトで、そこからIPヘッダのサイズを引いた値である。

まとめ

本当は受信側でやりたかったが、ループバックアドレスを使うとIPフラグメンテーションが起きないため、ひとまず送信側でやった。 受信側でやるとIPパケットの到着順序がばらばらになったり、そこから送信時の順序通りに正しく再構築されることを確認できるので面白いと思う。気が向いたらやってみたい。

参考

Wireshark Fragmented Packet Capturing
https://youtu.be/1gX_-DqGNxA?si=cG_gh3P9YuzK1k5L