제목에서 알 수 있듯이 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 클라이언트와 같은 원시 소켓을 사용하는 대신 SLAAC 및 DHCPv6 패킷(각각 ICMPv6 및 UDP)을 일반적인 방식으로 전송할 수 있습니다.
초기 패킷은 OS가 링크 로컬 주소를 할당함으로써 발생하는 "중복 주소 감지" 패킷이거나 SLAAC 자동 구성을 시작하는 "라우터 요청"일 가능성이 있다고 의심됩니다.
귀하의 경우에는 특히 네트워크 스택이 처리해야 하는 정상적인 상황이므로 이 기능을 비활성화하지 않는 것이 좋습니다.~ 일지라도IPv6을 지원하지 않습니다. 실제 이더넷 네트워크에 연결된 실제 장치에 대해 TCP/IP를 구현하는 경우 다른 장치가 보내는 내용을 선택할 수 없습니다.회의IPv6뿐만 아니라 모든 종류의 이상하고 원치 않는 프레임을 수신합니다(예: 실제적인 예를 들자면 이더넷용 LLDP, STP, RoMON, CTP).
즉, OS가 Tap 인터페이스에서 IPv6과 통신하는 것을 방지하더라도가능한,이로 인해 운동이 비실용적이 되고 종종 잘못된 접근 방식이 됩니다.
대신 네트워크 스택은 조용히 있어야 합니다.소홀히 하다IPv6, DECnet 또는 IPX 등 인식할 수 없는 이더넷 유형의 모든 이더넷 프레임입니다. (즉, 여기서는 특수한 경우인 0x86DD가 필요하지 않으며, 0x0800/0x0806 이외의 것은 안전하게 삭제할 수 있습니다.)