@@ -850,8 +850,8 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> {
850850 match raw_socket. process ( & ip_repr, ip_payload, & checksum_caps) {
851851 // The packet is valid and handled by socket.
852852 Ok ( ( ) ) => handled_by_raw_socket = true ,
853- // The socket buffer is full.
854- Err ( Error :: Exhausted ) => ( ) ,
853+ // The socket buffer is full or the packet was truncated
854+ Err ( Error :: Exhausted ) | Err ( Error :: Truncated ) => ( ) ,
855855 // Raw sockets don't validate the packets in any way.
856856 Err ( _) => unreachable ! ( ) ,
857857 }
@@ -2667,6 +2667,67 @@ mod test {
26672667 Ok ( Packet :: None ) ) ;
26682668 }
26692669
2670+ #[ test]
2671+ #[ cfg( all( feature = "proto-ipv4" , feature = "socket-raw" ) ) ]
2672+ fn test_raw_socket_truncated_packet ( ) {
2673+ use socket:: { RawSocket , RawSocketBuffer , RawPacketMetadata } ;
2674+ use wire:: { IpVersion , Ipv4Packet , UdpPacket , UdpRepr } ;
2675+
2676+ let ( mut iface, mut socket_set) = create_loopback ( ) ;
2677+
2678+ let packets = 1 ;
2679+ let rx_buffer = RawSocketBuffer :: new ( vec ! [ RawPacketMetadata :: EMPTY ; packets] , vec ! [ 0 ; 48 * 1 ] ) ;
2680+ let tx_buffer = RawSocketBuffer :: new ( vec ! [ RawPacketMetadata :: EMPTY ; packets] , vec ! [ 0 ; 48 * packets] ) ;
2681+ let raw_socket = RawSocket :: new ( IpVersion :: Ipv4 , IpProtocol :: Udp , rx_buffer, tx_buffer) ;
2682+ socket_set. add ( raw_socket) ;
2683+
2684+ let src_addr = Ipv4Address ( [ 127 , 0 , 0 , 2 ] ) ;
2685+ let dst_addr = Ipv4Address ( [ 127 , 0 , 0 , 1 ] ) ;
2686+
2687+ let udp_repr = UdpRepr {
2688+ src_port : 67 ,
2689+ dst_port : 68 ,
2690+ payload : & [ 0x2a ; 49 ] // 49 > 48, hence packet will be truncated
2691+ } ;
2692+ let mut bytes = vec ! [ 0xff ; udp_repr. buffer_len( ) ] ;
2693+ let mut packet = UdpPacket :: new_unchecked ( & mut bytes[ ..] ) ;
2694+ udp_repr. emit ( & mut packet, & src_addr. into ( ) , & dst_addr. into ( ) , & ChecksumCapabilities :: default ( ) ) ;
2695+ let ipv4_repr = Ipv4Repr {
2696+ src_addr : src_addr,
2697+ dst_addr : dst_addr,
2698+ protocol : IpProtocol :: Udp ,
2699+ hop_limit : 64 ,
2700+ payload_len : udp_repr. buffer_len ( )
2701+ } ;
2702+
2703+ // Emit to ethernet frame
2704+ let mut eth_bytes = vec ! [ 0u8 ;
2705+ EthernetFrame :: <& [ u8 ] >:: header_len( ) +
2706+ ipv4_repr. buffer_len( ) + udp_repr. buffer_len( )
2707+ ] ;
2708+ let frame = {
2709+ let mut frame = EthernetFrame :: new_unchecked ( & mut eth_bytes) ;
2710+ ipv4_repr. emit (
2711+ & mut Ipv4Packet :: new_unchecked ( frame. payload_mut ( ) ) ,
2712+ & ChecksumCapabilities :: default ( ) ) ;
2713+ udp_repr. emit (
2714+ & mut UdpPacket :: new_unchecked (
2715+ & mut frame. payload_mut ( ) [ ipv4_repr. buffer_len ( ) ..] ) ,
2716+ & src_addr. into ( ) ,
2717+ & dst_addr. into ( ) ,
2718+ & ChecksumCapabilities :: default ( ) ) ;
2719+ EthernetFrame :: new_unchecked ( & * frame. into_inner ( ) )
2720+ } ;
2721+
2722+ let frame = iface. inner . process_ipv4 ( & mut socket_set, Instant :: from_millis ( 0 ) , & frame) ;
2723+
2724+ // because the packet could not be handled we should send an Icmp message
2725+ assert ! ( match frame {
2726+ Ok ( Packet :: Icmpv4 ( _) ) => true ,
2727+ _ => false ,
2728+ } ) ;
2729+ }
2730+
26702731 #[ test]
26712732 #[ cfg( all( feature = "proto-ipv4" , feature = "socket-raw" , feature = "socket-udp" ) ) ]
26722733 fn test_raw_socket_with_udp_socket ( ) {
0 commit comments