()
| 779 | |
| 780 | #[test] |
| 781 | fn test_read() { |
| 782 | let tap_ip_guard = TAP_IP_LOCK.lock().unwrap(); |
| 783 | |
| 784 | let mut tap = Tap::new(1).unwrap(); |
| 785 | let ip_addr = IpAddr::V4((*tap_ip_guard).parse().unwrap()); |
| 786 | let netmask = IpAddr::V4(SUBNET_MASK.parse().unwrap()); |
| 787 | tap.set_ip_addr(ip_addr, Some(netmask)).unwrap(); |
| 788 | tap.enable().unwrap(); |
| 789 | |
| 790 | // Send a packet to the interface. We expect to be able to receive it on the associated fd. |
| 791 | pnet_send_packet(tap.if_name_as_str()); |
| 792 | |
| 793 | let mut buf = [0u8; 4096]; |
| 794 | |
| 795 | let mut found_packet_sz = None; |
| 796 | |
| 797 | // In theory, this could actually loop forever if something keeps sending data through the |
| 798 | // tap interface, but it's highly unlikely. |
| 799 | while found_packet_sz.is_none() { |
| 800 | let size = tap.read(&mut buf).unwrap(); |
| 801 | |
| 802 | // We skip the first 10 bytes because the IFF_VNET_HDR flag is set when the interface |
| 803 | // is created, and the legacy header is 10 bytes long without a certain flag which |
| 804 | // is not set in Tap::new(). |
| 805 | let eth_bytes = &buf[10..size]; |
| 806 | |
| 807 | let packet = EthernetPacket::new(eth_bytes).unwrap(); |
| 808 | if packet.get_ethertype() != EtherTypes::Ipv4 { |
| 809 | // not an IPv4 packet |
| 810 | continue; |
| 811 | } |
| 812 | |
| 813 | let ipv4_bytes = ð_bytes[14..]; |
| 814 | let packet = Ipv4Packet::new(ipv4_bytes).unwrap(); |
| 815 | |
| 816 | // Our packet should carry an UDP payload, and not contain IP options. |
| 817 | if packet.get_next_level_protocol() != IpNextHeaderProtocols::Udp |
| 818 | && packet.get_header_length() != 5 |
| 819 | { |
| 820 | continue; |
| 821 | } |
| 822 | |
| 823 | let udp_bytes = &ipv4_bytes[20..]; |
| 824 | |
| 825 | let udp_len = UdpPacket::new(udp_bytes).unwrap().get_length() as usize; |
| 826 | |
| 827 | // Skip the header bytes. |
| 828 | let inner_string = str::from_utf8(&udp_bytes[8..udp_len]).unwrap(); |
| 829 | |
| 830 | if inner_string.eq(DATA_STRING) { |
| 831 | found_packet_sz = Some(size); |
| 832 | break; |
| 833 | } |
| 834 | } |
| 835 | |
| 836 | assert!(found_packet_sz.is_some()); |
| 837 | } |
| 838 |
nothing calls this directly
no test coverage detected