1 // Copyright 2024 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 use capture::pcap;
16 use std::io::Cursor;
17 use tokio::io::{AsyncSeekExt, BufReader};
18
timestamp(hdr: pcap::PacketHeader) -> f6419 fn timestamp(hdr: pcap::PacketHeader) -> f64 {
20 hdr.tv_sec as f64 + (hdr.tv_usec as f64 / 1_000_000.0)
21 }
22
23 // Read a file with a known number of records.
24 //
25 // Test magic numbers, record len, and timestamp fields
26 #[tokio::test]
read_file() -> Result<(), std::io::Error>27 async fn read_file() -> Result<(), std::io::Error> {
28 const DATA: &[u8] = include_bytes!("../data/dns.cap");
29 const RECORDS: i32 = 38;
30 let mut reader = BufReader::new(Cursor::new(DATA));
31 let header = pcap::read_file_header(&mut reader).await?;
32 assert_eq!(header.linktype, pcap::LinkType::Ethernet.into());
33 assert_eq!(header.snaplen, u16::MAX as u32);
34 let mut records = 0;
35 loop {
36 match pcap::read_record(&mut reader).await {
37 Ok((hdr, _record)) => {
38 records += 1;
39 if records == 1 {
40 assert_eq!(1112172466.496046000f64, timestamp(hdr));
41 } else if records == 38 {
42 assert_eq!(1112172745.375359000f64, timestamp(hdr));
43 }
44 }
45 Err(e) if e.kind() == std::io::ErrorKind::UnexpectedEof => {
46 assert_eq!(records, RECORDS);
47 assert_eq!(DATA.len() as u64, reader.stream_position().await?);
48 break;
49 }
50 _ => {
51 assert!(false, "Unexpected error");
52 }
53 }
54 }
55
56 Ok(())
57 }
58