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 = 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::::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(_) )); } }