| use super::super::*; |
| |
| mod regression { |
| use super::*; |
| |
| #[test] |
| fn icmp6_echo_marshall_unmarshall() { |
| let icmp6 = Icmpv6Header { |
| icmp_type: Icmpv6Type::EchoRequest(IcmpEchoHeader { seq: 1, id: 2 }), |
| checksum: 0, |
| }; |
| // serialize |
| let mut buffer: Vec<u8> = Vec::with_capacity(256); |
| icmp6.write(&mut buffer).unwrap(); |
| let (new_icmp6, rest) = Icmpv6Header::from_slice(&buffer).unwrap(); |
| assert_eq!(icmp6, new_icmp6); |
| assert_eq!(rest.len(), 0); |
| } |
| |
| #[test] |
| fn ip6_echo_marshall_unmarshall() { |
| let builder = PacketBuilder::ipv6( |
| //source ip |
| [0xfe, 0x80, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], |
| //dst ip |
| [0xfe, 0x80, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 114], |
| //time to life |
| 20, |
| ) |
| .icmpv6_echo_request(1, 2); |
| let payload = [0xde, 0xad, 0xbe, 0xef]; |
| //get some memory to store the result |
| let mut result = Vec::<u8>::with_capacity(builder.size(payload.len())); |
| |
| //serialize |
| builder.write(&mut result, &payload).unwrap(); |
| |
| let new_ip = PacketHeaders::from_ip_slice(&result).unwrap(); |
| if let Some(TransportHeader::Icmpv6(hdr)) = new_ip.transport { |
| if let Icmpv6Type::EchoRequest(echo) = hdr.icmp_type { |
| assert_eq!(echo.id, 1); |
| assert_eq!(echo.seq, 2); |
| } else { |
| panic!("Not an EchoRequest!?"); |
| } |
| } else { |
| panic!("No transport header found!?") |
| } |
| } |
| const ICMP6_ECHO_REQUEST_BYTES: [u8; 118] = [ |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd, 0x60, |
| 0x00, 0xf3, 0xc2, 0x00, 0x40, 0x3a, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0xd5, 0x2f, 0x00, 0x05, |
| 0x00, 0x01, 0xe3, 0x58, 0xdb, 0x61, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x0d, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, |
| 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, |
| 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, |
| ]; |
| const ICMP6_ECHO_REPLY_BYTES: [u8; 118] = [ |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd, 0x60, |
| 0x00, 0xa3, 0xde, 0x00, 0x40, 0x3a, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x81, 0x00, 0xd4, 0x2f, 0x00, 0x05, |
| 0x00, 0x01, 0xe3, 0x58, 0xdb, 0x61, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x0d, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, |
| 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, |
| 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, |
| ]; |
| |
| #[test] |
| fn verify_icmp6_checksum() { |
| for (pkt, checksum) in [ |
| (ICMP6_ECHO_REQUEST_BYTES, 0xd52f), |
| (ICMP6_ECHO_REPLY_BYTES, 0xd42f), |
| ] { |
| // make sure we can unmarshall the correct checksum |
| let request = PacketHeaders::from_ethernet_slice(&pkt).unwrap(); |
| let mut icmp6 = request.transport.unwrap().icmpv6().unwrap(); |
| let valid_checksum = icmp6.checksum; |
| assert_ne!(valid_checksum, 0); |
| assert_eq!(valid_checksum, checksum); |
| // reset it and recalculate |
| icmp6.checksum = 0; |
| let iph = match request.net { |
| Some(NetHeaders::Ipv6(ipv6, _)) => ipv6, |
| _ => panic!("Failed to parse ipv6 part of packet?!"), |
| }; |
| assert_eq!( |
| icmp6 |
| .icmp_type |
| .calc_checksum(iph.source, iph.destination, request.payload.slice()), |
| Ok(valid_checksum) |
| ); |
| } |
| } |
| |
| #[test] |
| fn echo_request_slice() { |
| let echo = SlicedPacket::from_ethernet(&ICMP6_ECHO_REQUEST_BYTES).unwrap(); |
| use TransportSlice::*; |
| let icmp6 = match echo.transport.unwrap() { |
| Icmpv6(icmp6) => icmp6, |
| Icmpv4(_) | Udp(_) | Tcp(_) => panic!("Misparsed header!"), |
| }; |
| assert!(matches!( |
| icmp6.header().icmp_type, |
| Icmpv6Type::EchoRequest(_) |
| )); |
| } |
| } |