async-icmp 0.2.1

Async ICMP library
Documentation
use super::*;
use crate::message::echo::{EchoId, EchoSeq, IcmpEchoRequest};
use crate::Icmpv4;
use hex_literal::hex;

#[test]
fn echo_checksum_idempotent() {
    // Recalculating the checksum should produce the same answer, implying that it correctly
    // zeroes itself before recalculating
    let mut message = IcmpEchoRequest::from_fields(
        EchoId::from_be(100_u16),
        EchoSeq::from_be(200_u16),
        &hex::decode("DEADBEEF").unwrap(),
    );
    let expected = hex!("08005936006400C8DEADBEEF");

    let buffer = <IcmpEchoRequest as EncodeIcmpMessage<Icmpv4>>::encode(&mut message);
    buffer.calculate_icmpv4_checksum();
    assert_eq!(&expected, buffer.as_slice());
    buffer.calculate_icmpv4_checksum();
    assert_eq!(&expected, buffer.as_slice());
}

#[test]
fn checksum_over_odd_length() {
    let mut message = IcmpEchoRequest::from_fields(
        EchoId::from_be(100_u16),
        EchoSeq::from_be(200_u16),
        &[1, 2, 3],
    );
    let buffer = <IcmpEchoRequest as EncodeIcmpMessage<Icmpv4>>::encode(&mut message);
    buffer.calculate_icmpv4_checksum();

    assert_eq!(&hex!("0800F2D1006400C8010203"), buffer.as_slice());
}

#[test]
fn echo_encoded_checksum_no_data_matches_wireshark() {
    let mut message =
        IcmpEchoRequest::from_fields(EchoId::from_be(0x45AE), EchoSeq::from_be(0), &[]);

    let buffer = <IcmpEchoRequest as EncodeIcmpMessage<Icmpv4>>::encode(&mut message);
    buffer.calculate_icmpv4_checksum();
    assert_eq!(&hex!("B251"), &buffer.as_slice()[2..4])
}
#[test]
fn echo_encoded_checksum_with_data_matches_wireshark() {
    let mut message = IcmpEchoRequest::from_fields(
        EchoId::from_be(0xFA03),
        EchoSeq::from_be(0),
        &hex!("8a5382a2a36251117916d4efdd9c796095243a304848e58bab8b52091bd8a8ab"),
    );

    let buffer = <IcmpEchoRequest as EncodeIcmpMessage<Icmpv4>>::encode(&mut message);
    buffer.calculate_icmpv4_checksum();
    assert_eq!(&hex!("984C"), &buffer.as_slice()[2..4])
}

#[test]
fn echo_raw_checksum_no_data_matches_wireshark() {
    let mut message = hex!("0800af1748e80000");

    // checksum is calculated with 0 checksum
    message[2..4].fill(0);

    assert_eq!(
        &hex!("AF17"),
        &ones_complement_checksum(&message).to_be_bytes()
    );
}

#[test]
fn echo_raw_checksum_with_random_data_matches_wireshark() {
    let mut message =
        hex!("08009855fa0300008a5382a2a36251117916d4efdd9c796095243a304848e58bab8b52091bd8a8ab");

    // checksum is calculated with 0 checksum
    message[2..4].fill(0);

    assert_eq!(
        &hex!("984C"),
        &ones_complement_checksum(&message).to_be_bytes()
    );
}

#[test]
fn buffer_new() {
    let buf = IcmpMessageBuffer::new(0xAA, 0xBB, &[0xCC, 0xDD]);
    assert_eq!(hex!("AABB0000CCDD").as_slice(), buf.as_slice());
}

#[test]
fn buffer_checksum_idempotent() {
    let mut buf = IcmpMessageBuffer::new(0xAA, 0xBB, &[0xCC, 0xDD]);
    buf.calculate_icmpv4_checksum();
    assert_eq!(hex!("AABB8866CCDD").as_slice(), buf.as_slice());
    buf.calculate_icmpv4_checksum();
    assert_eq!(hex!("AABB8866CCDD").as_slice(), buf.as_slice());
}

#[test]
fn buffer_setters() {
    let mut buf = IcmpMessageBuffer::new(0xAA, 0xBB, &[0xCC, 0xDD]);
    buf.set_type(0xFA);
    buf.set_code(0xFB);
    buf.set_body([0xFC_u8, 0xFD, 0xFE]);
    assert_eq!(hex!("FAFB0000FCFDFE").as_slice(), buf.as_slice());
}

#[test]
fn buffer_body() {
    let mut buf = IcmpMessageBuffer::new(0xAA, 0xBB, &[0xCC, 0xDD]);
    buf.truncate_body(0);
    assert_eq!(hex!("AABB0000").as_slice(), buf.as_slice());
    buf.extend_body([1_u8, 2, 3]);
    assert_eq!(hex!("AABB0000010203").as_slice(), buf.as_slice());
    buf.extend_body([4_u8, 5, 6]);
    assert_eq!(hex!("AABB0000010203040506").as_slice(), buf.as_slice());
    buf.truncate_body(2);
    assert_eq!(hex!("AABB00000102").as_slice(), buf.as_slice());
    buf.body_mut()[0] = 0xEE;
    assert_eq!(hex!("AABB0000EE02").as_slice(), buf.as_slice());
}