新しく作成されたTAPデバイスの設定時にIPv6パケットを取得する

新しく作成されたTAPデバイスの設定時にIPv6パケットを取得する

タイトルが示すように、TCP / IPスタックを作成してTCPがどのように機能するかを学びたいと思います。以下のようにプログラムでRustでTAPデバイスを作成しています。

pub struct Tap {
    fd: i32,
}

#[repr(C)]
struct IFreq {
    name: [c_char; IFNAMSIZ],
    flags: c_short,
}

impl Tap {
    pub fn new(name: &CStr) -> Result<Tap, TapError> {
        let fd = unsafe {
            let fd = libc::open(b"/dev/net/tun\0".as_ptr() as *const _, libc::O_RDWR);
            if fd < 0 {
                Err(TapError::OpenFD(std::io::Error::last_os_error()))
            } else {
                Ok(fd)
            }
        }?;

        let mut ifr = IFreq {
            name: [0; IFNAMSIZ],
            flags: (libc::IFF_TAP | libc::IFF_NO_PI) as c_short,
        };

        for (dst, src) in ifr.name[0..IFNAMSIZ - 1]
            .iter_mut()
            .zip(name.to_bytes().iter())
        {
            *dst = *src as i8;
        }

        unsafe {
            let err = libc::ioctl(fd, TUNSETIFF, &mut ifr as *mut _);
            if err == -1 {
                return Err(TapError::IOCTL(std::io::Error::last_os_error()));
            }
        }

        Ok(Tap { fd })
    }
}

ただし、これを使用しip link set dev <tap name> upてイーサネットフレームを読み始めると、IPv6フレーム(イーサネットタイプ0x86DD)のみが得られるようです。これは普通ですか?これが起こらないようにするにはどうすればよいですか?私は現在IPv4の実装に専念しており、IPv6トラフィックは処理したくありません。

ベストアンサー1

ただし、ip link set dev upを使用して起動してイーサネットフレームを読み始めると、IPv6フレーム(イーサネットタイプ0x86DD)しか取得されないようです。これは普通ですか?これが起こらないようにするにはどうすればよいですか?私は現在IPv4の実装に専念しており、IPv6トラフィックは処理したくありません。

IPv6をサポートするシステムでは、各インターフェイスは自動的にローカルリンクプレフィックスのIPv6アドレスfe80::/64。これは主にインフラストラクチャの目的に使用されます。たとえば、DHCPv4クライアントなどのrawソケットを使用する代わりに、SLAACおよびDHCPv6パケット(それぞれICMPv6およびUDP)を一般的な方法で送信できます。

初期パケットは、OSがリンクローカルアドレスを割り当てることによって発生する「冗長アドレス検出」パケット、またはSLAAC自動設定を開始する「ルータ要求」である可能性があると疑われます。

お客様の場合、特にネットワークスタックが処理する必要がある通常の状況なので、この機能を無効にしないことをお勧めします。〜でもIPv6をサポートしていません。物理イーサネットネットワークに接続されている物理デバイスにTCP / IPを実装している場合、他のデバイスが送信するものを選択することはできません。会議IPv6だけでなく、あらゆる種類の奇妙で不要なフレームを受信します(例:実際の例では、イーサネット用のLLDP、STP、RoMON、CTP)。

つまり、OSがTapインターフェイスでIPv6と通信するのを防いでいても可能、これは運動が実用的ではなく、しばしば誤ったアプローチになります。

代わりに、ネットワークスタックは静かにする必要があります。無視するIPv6、DECnet、IPXなど、認識できないイーサネットタイプのすべてのイーサネットフレーム。 (つまり、ここでは特別なケースである0x86DDは必要ありません。0x0800 / 0x0806以外は安全に削除できます。)

おすすめ記事