/// Send an IP packet to a remote host over a specific device.
///
/// `send_ip_packet_from_device` accepts a device, a source and destination IP
/// address, a next hop IP address, and a serializer. It computes
/// the routing information and serializes the request in a new IP packet and
/// sends it. `mtu` will optionally impose an MTU constraint on the whole IP
/// packet. This is useful for cases where some packets are being sent out
/// which must not exceed some size (ICMPv6 Error Responses).
///
/// # Panics
///
/// Since `send_ip_packet_from_device` specifies a physical device, it cannot
/// send to or from a loopback IP address. If either `src_ip` or `dst_ip` are in
/// the loopback subnet, `send_ip_packet_from_device` will panic.
Send an IP packet to a remote host over a specific device.
`send_ip_packet_from_device` accepts a device, a source and destination IP
address, a next hop IP address, and a serializer. It computes
the routing information and serializes the request in a new IP packet and
sends it. `mtu` will optionally impose an MTU constraint on the whole IP
packet. This is useful for cases where some packets are being sent out
which must not exceed some size (ICMPv6 Error Responses).
Send an IP packet to a remote host over a specific device . ` send_ip_packet_from_device ` accepts a device a source and destination IP address a next hop IP address and a serializer . It computes the routing information and serializes the request in a new IP packet and sends it . ` mtu ` will optionally impose an MTU constraint on the whole IP packet . This is useful for cases where some packets are being sent out which must not exceed some size ( ICMPv6 Error Responses ) .
pub(crate) fn send_ip_packet_from_device<B: BufferMut, D: BufferDispatcher<B>, A, S>(
    ctx: &mut Ctx<D>,
    device: DeviceId,
    src_ip: A,
    dst_ip: A,
    next_hop: SpecifiedAddr<A>,
    proto: <A::Version as packet_formats::ip::IpExt>::Proto,
    body: S,
    mtu: Option<u32>,
) -> Result<(), S>
where
    A: IpAddress,
    S: Serializer<Buffer = B>,
{
    assert!(!A::Version::LOOPBACK_SUBNET.contains(&src_ip));
    assert!(!A::Version::LOOPBACK_SUBNET.contains(&dst_ip));
    // Tentative addresses are not considered bound to an interface in the
    // traditional sense, therefore, no packet should have a source IP set to a
    // tentative address.
    debug_assert!(!SpecifiedAddr::new(src_ip).map_or(false, |src_ip| {
        crate::device::is_addr_tentative_on_device(ctx, &src_ip, device)
    }));
    let builder = <A::Version as packet_formats::ip::IpExt>::PacketBuilder::new(
        src_ip,
        dst_ip,
        get_hop_limit::<_, A::Version>(ctx, device),
        proto,
    );
    let body = body.encapsulate(builder);
    if let Some(mtu) = mtu {
        let body = body.with_mtu(mtu as usize);
        crate::device::send_ip_frame(ctx, device, next_hop, body)
            .map_err(|ser| ser.into_inner().into_inner())
    } else {
        crate::device::send_ip_frame(ctx, device, next_hop, body).map_err(|ser| ser.into_inner())
    }
}
pub ( crate ) fn send_ip_packet_from_device < B : BufferMut , D : BufferDispatcher < B > , A , S > ( ctx : & mut Ctx < D > , device : DeviceId , src_ip : A , dst_ip : A , next_hop : SpecifiedAddr < A > , proto : < A :: Version as packet_formats :: ip :: IpExt > :: Proto , body : S , mtu : Option < u32 > , ) -> Result < ( ) , S > where A : IpAddress , S : Serializer < Buffer = B > , { assert ! ( A Version LOOPBACK_SUBNET contains ( src_ip ) ) ; assert ! ( A Version LOOPBACK_SUBNET contains ( dst_ip ) ) ; // Tentative addresses are not considered bound to an interface in the // traditional sense, therefore, no packet should have a source IP set to a // tentative address. debug_assert ! ( SpecifiedAddr new ( src_ip ) map_or ( false src_ip { crate device is_addr_tentative_on_device ( ctx src_ip device ) } ) ) ; let builder = < A :: Version as packet_formats :: ip :: IpExt > :: PacketBuilder :: new ( src_ip , dst_ip , get_hop_limit :: < _ , A :: Version > ( ctx , device ) , proto , ) ; let body = body . encapsulate ( builder ) ; if let Some ( mtu ) = mtu { let body = body . with_mtu ( mtu as usize ) ; crate :: device :: send_ip_frame ( ctx , device , next_hop , body ) . map_err ( | ser | ser . into_inner ( ) . into_inner ( ) ) } else { crate :: device :: send_ip_frame ( ctx , device , next_hop , body ) . map_err ( | ser | ser . into_inner ( ) ) } }
Send an IP packet to a remote host over a specific device.
Send an IP packet to a remote host over a specific device .
ctx
&mut Ctx<D>
device
DeviceId
src_ip
A
dst_ip
A
next_hop
SpecifiedAddr<A>
proto
<A::Version as packet_formats::ip::IpExt>::Proto
body
S
mtu
Option<u32>
panics
Since `send_ip_packet_from_device` specifies a physical device, it cannot
send to or from a loopback IP address. If either `src_ip` or `dst_ip` are in
the loopback subnet, `send_ip_packet_from_device` will panic.
Since ` send_ip_packet_from_device ` specifies a physical device it cannot send to or from a loopback IP address . If either ` src_ip ` or ` dst_ip ` are in the loopback subnet ` send_ip_packet_from_device ` will panic .