fn if_index_mtu()

in src/bsd.rs [317:378]


fn if_index_mtu(remote: IpAddr) -> Result<(u16, Option<usize>)> {
    // Open route socket.
    let mut fd = RouteSocket::new(PF_ROUTE, AF_UNSPEC)?;

    // Send route message.
    let query_seq = RouteSocket::new_seq();
    let query = RouteMessage::new(remote, query_seq)?;
    let query_version = query.version();
    let query_type = query.kind();
    fd.write_all((&query).into())?;

    // Read route messages.
    let pid = unsafe { getpid() };
    loop {
        let mut buf = vec![
            0u8;
            size_of::<rt_msghdr>() +
        // There will never be `RTAX_MAX` sockaddrs attached, but it's a safe upper bound.
         (RTAX_MAX as usize * size_of::<sockaddr_storage>())
        ];
        let len = fd.read(&mut buf[..])?;
        if len < size_of::<rt_msghdr>() {
            return Err(default_err());
        }
        let (reply, mut sa) = buf.split_at(size_of::<rt_msghdr>());
        let reply: rt_msghdr = reply.into();
        if !(reply.rtm_version == query_version
            && reply.rtm_pid == pid
            && reply.rtm_seq == query_seq)
        {
            continue;
        }
        if reply.rtm_type != query_type {
            return Err(default_err());
        }

        // This is a reply to our query.
        // This is the reply we are looking for.
        // Some BSDs let us get the interface index and MTU directly from the reply.
        let mtu = (reply.rtm_rmx.rmx_mtu != 0)
            .then(|| usize::try_from(reply.rtm_rmx.rmx_mtu))
            .transpose()
            .map_err(|e: TryFromIntError| unlikely_err(e.to_string()))?;
        if reply.rtm_index != 0 {
            // Some BSDs return the interface index directly.
            return Ok((reply.rtm_index, mtu));
        }
        // For others, we need to extract it from the sockaddrs.
        for i in 0..RTAX_MAX {
            if (reply.rtm_addrs & (1 << i)) == 0 {
                continue;
            }
            let saddr = unsafe { ptr::read_unaligned(sa.as_ptr().cast::<sockaddr>()) };
            if saddr.sa_family != AF_LINK {
                (_, sa) = sa.split_at(sockaddr_len(saddr.sa_family)?);
                continue;
            }
            let sdl = unsafe { ptr::read_unaligned(sa.as_ptr().cast::<sockaddr_dl>()) };
            return Ok((sdl.sdl_index, mtu));
        }
    }
}