以前の記事では,Wiresharkを入れた後にipsendwinが起動しなくなり,Win10Pcapを追加して直した話を書きました.Windows 11ではどうなるか,Npcapで試し直しました.
DLL不足はNpcapのWinPcap API互換モードで解消しましたが,今度は「送信可能なインタフェースがありません。」で止まります.調べると,ipsendwinが先頭のNICだけを見て起動の可否を決めていました.列挙結果の並び順を変える互換DLLを挟むと起動し,同じPCの仮想Ethernetで送信フレームをキャプチャできました.
試した環境と,止まったところ
検証日は2026年11月4日です.
| OS | Windows 11 x64,ビルド26300.9711(DisplayVersion 26H2) |
|---|---|
| ipsendwin | Vector配布版2.4,32ビット |
| Npcap | 1.90,WinPcapCompatible=1,AdminOnly=0 |
| 送信に使ったNIC | Hyper-V Virtual Ethernet Adapter |
ipsendwinは配布MSIのProductVersionが2.4ですが,EXEのバージョン情報にはProductVersion 2.2/FileVersion 1.0.0.1が残っていました.今回使ったEXEのSHA-256は以下です.
7F5C507510CE5C44AB4497F6033D7E826C4282649ABCD3729A38AC5C7D34108D
最初はNpcapが入っておらず,起動時に「wpcap.dllが見つからない」と表示されました.公式サイトからNpcap 1.90を入れ,インストーラーの「Install Npcap in WinPcap API-compatible Mode」にチェックを入れています.このオプションでWinPcap互換アプリが読むDLLもシステム側に配置されます(Npcapのインストールオプション).
DLL不足のエラーは消えました.ただし,操作画面が出る前に次のメッセージで終了します.
送信可能なインタフェースがありません。
ここまでの変化を並べるとこうです.
| 状態 | 起動結果 |
|---|---|
| Npcapなし | wpcap.dllが見つからない |
| NpcapをWinPcap API互換モードで導入 | 送信可能なインタフェースがありません。 |
| 後述の互換DLLをEXEの隣に追加 | 操作画面が開き,NICを選択できる |
先頭がWAN Miniportだった
まず,ipsendwinとは別の32ビットプログラムからNpcapのpcap_findalldevs()を呼びました.NICは6つ列挙でき,Hyper-Vの仮想EthernetとRealtekの有線LANをpcap_open_live()で開くこともできました.Npcap側でNICが見えていないわけではありません.
返ってきた順番とアドレスファミリーは以下でした.デバイス固有のGUIDは省いています.
順番 Description Address families
1 WAN Miniport (Network Monitor) なし
2 WAN Miniport (IPv6) なし
3 WAN Miniport (IP) なし
4 Hyper-V Virtual Ethernet Adapter 2, 23
5 Realtek Gaming 2.5GbE Family Controller 2, 23
6 Adapter for loopback traffic capture 23, 2
2 = AF_INET(IPv4),23 = AF_INET6(IPv6)
pcap_findalldevs()はpcap_if_tの連結リストを返します.NIC間のnextとは別に,各NICのaddressesもpcap_addr_tの連結リストです.アドレスを持たないNICではaddressesがNULLになることがあり,アドレスがあってもIPv4とは限りません(APIの仕様).
ipsendwinの起動処理を逆アセンブルで追うと,先頭NICのaddressesをたどってsa_family == AF_INETを探していました.アドレスのリストは最後まで見ますが,見つからなかった場合に次のNICへ進む処理がありません.確認した分岐を擬似コードにするとこうなります.元のソースコードではありません.
// 列挙成功後の判定部分(エラー処理などは省略)
pcap_findalldevs(&devices, errbuf);
found_ipv4 = false;
for (address = devices->addresses; address; address = address->next) {
if (address->addr->sa_family == AF_INET) {
found_ipv4 = true;
break;
}
}
if (!found_ipv4) {
// 「送信可能なインタフェースがありません。」で終了
}
// devices->next に進む処理がない
今回の先頭は,アドレスを持たないWAN Miniportでした.後ろにIPv4を持つNICがあっても,そこまで調べずに終了していたわけです.
この結果からは,Windows 11そのものがipsendwinの送信を禁止したとは言えません.Windows 10との比較試験はしていませんが,今回の起動失敗はアプリ側の判定とNICの列挙順で説明できました.
ipsendwinの横に互換DLLを置く
IPv4を持つNICが先頭に来れば起動できそうなので,wpcap.dllという名前の32ビット互換DLLを作りました.ipsendwinからの呼び出しを受けて,実際の処理はインストール済みNpcapへ渡します.
- Vectorからipsendwin 2.4を入手します.
- NpcapをWinPcap API互換モードで導入します.今回試したのは1.90です.再起動を求められた場合は,再起動してから続けます.
- ipsendwinを閉じ,v0.1.1の配布ページから
ipsendwin-npcap-compat-win32-v0.1.1.zipをダウンロードして展開します. - ZIPの
wpcap.dllを,ipsendwin.exeと同じフォルダーに置きます.同名のDLLがすでにある場合は,元のファイルを別に保管してから置き換えます. - ipsendwinを起動し,使用するインタフェースを選びます.
ipsendwinを置いたフォルダー/
├─ ipsendwin.exe
└─ wpcap.dll ← 今回の互換DLL
これで操作画面が開きました.このDLLは自作の未署名DLLで,Npcap公式のDLLではありません.System32やSysWOW64,Npcapのインストール先には上書きしません.ZIPにipsendwin本体とNpcap本体は含めていません.
元に戻すときはipsendwinを閉じ,追加したwpcap.dllをフォルダーの外へ移します.元の同名ファイルを保管していた場合は,それを戻します.
互換DLLで変えているところ
実装はwpcap-compat.cにあります.今回の変更はpcap_findalldevs()が返したリストの先頭を入れ替えるところです.
- インストール済みNpcapの
pcap_findalldevs()を呼ぶ. - 先頭が「IPv4を持つ非ループバックNIC」なら,そのまま返す.
- そうでなければ後続を探し,最初に見つかった該当NICを元の位置から外して先頭につなぐ.
この環境では,先頭3つのWAN Miniportの後ろにあったHyper-V仮想Ethernetが先頭になります.残りのNICを削除したり,構造体を複製したりはしていません.リスト全体をNpcapのpcap_freealldevs()へ返して解放します.
中継する関数はpcap_findalldevs,pcap_freealldevs,pcap_open_live,pcap_sendpacket,pcap_close,pcap_lib_versionです.ipsendwinが序数で参照するエクスポートは,.defファイルで元の序数に合わせています.WinPcap API全体を実装した汎用の代替DLLではありません.
Npcap本体はGetSystemDirectoryW()で求めたシステムディレクトリのNpcapサブディレクトリから読み込みます.32ビットプロセスなので,使うのは32ビットのNpcapです.同名の自作DLLを再度読み込まないよう,本体には絶対パスを指定しています.パスをソースに固定する必要はありません.送信時のハンドルやフレームはNpcapへそのまま渡します.
この判定で見るのはIPv4アドレスの有無とループバックフラグです.リンク状態や送信先への疎通までは判定しないので,起動後に目的のNICを自分で選びます.IPv4を持つ非ループバックNICが1つもない環境や,Npcap自体を読み込めない状態は,並べ替えでは直りません.
1フレーム送って,別のプロセスで捕まえる
起動だけで終わらせず,Hyper-Vの仮想Ethernetへ1フレーム送ってみました.設定は以下です.送信元MACは選択した仮想NICに合わせ,送信先には検証用のローカルMACを指定しています.
| 設定項目 | 値 |
|---|---|
| フレーム構成 | MAC+その他 |
| Ethernetタイプ | 自動を外し,0x88B5 |
| ペイロード | 64バイト,すべて0x00 |
| 送信フレーム数 | 1 |

キャプチャには,切り分けで使った別の32ビットプログラムを使いました.source/pcap-probe.csです.互換DLLとは別のフォルダーで実行し,通常のNpcapを呼び出します.pcap_open_live()で同じ仮想NICを開き,BPFフィルターをether proto 0x88b5にして待ち受けました.
取得できたフレームは78バイトで,Ethernetヘッダー14バイトとペイロード64バイトが設定と一致しました.この78バイトにはFCSを含みません.v0.1.1のDLLでも同じ内容を確認し,アプリの保存先を変えて設定ファイルを読み直した後も,再度送信・キャプチャできました.
同じ確認をする場合は,リポジトリのルートから次のようにプローブをビルドできます..NET FrameworkのC#コンパイラーを使い,/platform:x86を指定します.
New-Item -ItemType Directory -Path .\probe -Force | Out-Null
& "$env:WINDIR\Microsoft.NET\Framework\v4.0.30319\csc.exe" /nologo /platform:x86 /out:probe\pcap-probe.exe source\pcap-probe.cs
.\probe\pcap-probe.exe
引数なしではNIC一覧を表示します.出力されたデバイス名を指定すると,そのNICを開いてデータリンク種別を表示します.さらに未作成の出力ファイル名を渡すと,EtherType 0x88B5の最初の1フレームを最大30秒待ち,生のフレームバイト列を保存します.PCAP形式ではありません.
# 一覧に表示されたデバイス名をコピーして入力する
$deviceName = Read-Host 'キャプチャするデバイス名'
.\probe\pcap-probe.exe $deviceName
.\probe\pcap-probe.exe $deviceName .\probe\test-frame.bin
キャプチャを開始してから,ipsendwinで1フレーム送ります.正常に取れればData link type: 1とCaptured test frame: 78 bytesが表示されます.このプローブはEthernet用で,既存の出力ファイルは上書きしません.NIC名を渡す段階で開けない場合は,並び順とは別にNpcapの導入状態やアクセス権を確認する必要があります.
今回確認したのは,同じPC上の仮想Ethernetで送信したフレームを別プロセスで取得できるところまでです.Wiresharkはこの検証環境に入れていないので,Wiresharkとの同時動作と,物理LAN上の別端末への到達は未検証です.
ソースと配布ファイル
GitHubのリポジトリにソースとビルドスクリプトを置いています.配布DLLはGitHub Releasesのv0.1.1です.
互換DLLを自分でビルドする場合は,32ビットPEを生成できるMinGWのGCCとbinutilsを用意し,リポジトリのルートで実行します.
$toolchainBin = Read-Host 'GCCとdlltoolがあるbinフォルダー'
.\source\build.ps1 -ToolchainBin $toolchainBin
出力はリポジトリ直下のwpcap.dllです.Windowsが64ビットでも,ipsendwinに合わせて-m32で生成します.ビルドスクリプトが外部ファイルをダウンロードする処理はありません.
配布DLLのSHA-256:
968E261DCF4D627F3402AD98E89C3B39CC155257C64D10FE51892C2DA1B1F8FC
v0.1.1 ZIPのSHA-256:
8DD2B7B93E7C28C70354C8CDABC438CD7050EF3F9F78C1A907A7DA9EB81D7D83

