1 use super::super::*;
2 
3 mod regression {
4     use super::*;
5 
6     #[test]
icmp6_echo_marshall_unmarshall()7     fn icmp6_echo_marshall_unmarshall() {
8         let icmp6 = Icmpv6Header {
9             icmp_type: Icmpv6Type::EchoRequest(IcmpEchoHeader { seq: 1, id: 2 }),
10             checksum: 0,
11         };
12         // serialize
13         let mut buffer: Vec<u8> = Vec::with_capacity(256);
14         icmp6.write(&mut buffer).unwrap();
15         let (new_icmp6, rest) = Icmpv6Header::from_slice(&buffer).unwrap();
16         assert_eq!(icmp6, new_icmp6);
17         assert_eq!(rest.len(), 0);
18     }
19 
20     #[test]
ip6_echo_marshall_unmarshall()21     fn ip6_echo_marshall_unmarshall() {
22         let builder = PacketBuilder::ipv6(
23             //source ip
24             [0xfe, 0x80, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14],
25             //dst ip
26             [0xfe, 0x80, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 114],
27             //time to life
28             20,
29         )
30         .icmpv6_echo_request(1, 2);
31         let payload = [0xde, 0xad, 0xbe, 0xef];
32         //get some memory to store the result
33         let mut result = Vec::<u8>::with_capacity(builder.size(payload.len()));
34 
35         //serialize
36         builder.write(&mut result, &payload).unwrap();
37 
38         let new_ip = PacketHeaders::from_ip_slice(&result).unwrap();
39         if let Some(TransportHeader::Icmpv6(hdr)) = new_ip.transport {
40             if let Icmpv6Type::EchoRequest(echo) = hdr.icmp_type {
41                 assert_eq!(echo.id, 1);
42                 assert_eq!(echo.seq, 2);
43             } else {
44                 panic!("Not an EchoRequest!?");
45             }
46         } else {
47             panic!("No transport header found!?")
48         }
49     }
50     const ICMP6_ECHO_REQUEST_BYTES: [u8; 118] = [
51         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd, 0x60,
52         0x00, 0xf3, 0xc2, 0x00, 0x40, 0x3a, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0xd5, 0x2f, 0x00, 0x05,
55         0x00, 0x01, 0xe3, 0x58, 0xdb, 0x61, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x0d, 0x00, 0x00,
56         0x00, 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
57         0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
58         0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
59     ];
60     const ICMP6_ECHO_REPLY_BYTES: [u8; 118] = [
61         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd, 0x60,
62         0x00, 0xa3, 0xde, 0x00, 0x40, 0x3a, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x81, 0x00, 0xd4, 0x2f, 0x00, 0x05,
65         0x00, 0x01, 0xe3, 0x58, 0xdb, 0x61, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x0d, 0x00, 0x00,
66         0x00, 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
67         0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
68         0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
69     ];
70 
71     #[test]
verify_icmp6_checksum()72     fn verify_icmp6_checksum() {
73         for (pkt, checksum) in [
74             (ICMP6_ECHO_REQUEST_BYTES, 0xd52f),
75             (ICMP6_ECHO_REPLY_BYTES, 0xd42f),
76         ] {
77             // make sure we can unmarshall the correct checksum
78             let request = PacketHeaders::from_ethernet_slice(&pkt).unwrap();
79             let mut icmp6 = request.transport.unwrap().icmpv6().unwrap();
80             let valid_checksum = icmp6.checksum;
81             assert_ne!(valid_checksum, 0);
82             assert_eq!(valid_checksum, checksum);
83             // reset it and recalculate
84             icmp6.checksum = 0;
85             let iph = match request.net {
86                 Some(NetHeaders::Ipv6(ipv6, _)) => ipv6,
87                 _ => panic!("Failed to parse ipv6 part of packet?!"),
88             };
89             assert_eq!(
90                 icmp6
91                     .icmp_type
92                     .calc_checksum(iph.source, iph.destination, request.payload.slice()),
93                 Ok(valid_checksum)
94             );
95         }
96     }
97 
98     #[test]
echo_request_slice()99     fn echo_request_slice() {
100         let echo = SlicedPacket::from_ethernet(&ICMP6_ECHO_REQUEST_BYTES).unwrap();
101         use TransportSlice::*;
102         let icmp6 = match echo.transport.unwrap() {
103             Icmpv6(icmp6) => icmp6,
104             Icmpv4(_) | Udp(_) | Tcp(_) => panic!("Misparsed header!"),
105         };
106         assert!(matches!(
107             icmp6.header().icmp_type,
108             Icmpv6Type::EchoRequest(_)
109         ));
110     }
111 }
112