Skip to content

Commit

Permalink
feat: add types and de/encoding for SCMP messages
Browse files Browse the repository at this point in the history
  • Loading branch information
mlegner committed Dec 22, 2023
1 parent 76ee823 commit 2c56fe6
Show file tree
Hide file tree
Showing 6 changed files with 1,222 additions and 0 deletions.
1 change: 1 addition & 0 deletions crates/scion-proto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub mod datagram;
pub mod packet;
pub mod path;
pub mod reliable;
pub mod scmp;
pub(crate) mod utils;
pub mod wire_encoding;

Expand Down
8 changes: 8 additions & 0 deletions crates/scion-proto/src/packet/headers/address_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ impl From<ByEndpoint<SocketAddr>> for AddressHeader {
}
}
}
impl From<ByEndpoint<ScionAddr>> for AddressHeader {
fn from(value: ByEndpoint<ScionAddr>) -> Self {
AddressHeader {
ia: value.map(ScionAddr::isd_asn),
host: value.map(|e| MaybeEncoded::Decoded(e.host())),
}
}
}

impl<T: Buf> WireDecodeWithContext<T> for AddressHeader {
type Error = DecodeError;
Expand Down
52 changes: 52 additions & 0 deletions crates/scion-proto/src/scmp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//! Types and conversion for the SCION Control Message Protocol.
//!
//! This implements the specification at the [SCION documentation page][scion-doc-scmp] but currently
//! does not cover DRKey-based authentication.
//!
//! [scion-doc-scmp]: https://docs.scion.org/en/latest/protocols/scmp.html
mod error;
pub use error::ScmpDecodeError;

mod messages;
pub use messages::*;

mod raw;
pub use raw::ScmpMessageRaw;

use crate::packet::AddressHeader;

/// Trait implemented by all SCMP messages.
pub trait ScmpMessageBase {
/// Returns the SCMP type of this message.
fn get_type(&self) -> ScmpType;

/// Returns the additional SCMP code of this message.
fn code(&self) -> u8 {
0
}
}

/// Trait implemented by all SCMP messages to handle checksums.
pub trait ScmpMessageChecksum: ScmpMessageBase {
/// Returns the currently stored checksum of the message.
fn checksum(&self) -> u16;

/// Clears then sets the checksum to the value returned by [`Self::calculate_checksum()`].
fn set_checksum(&mut self, address_header: &AddressHeader);

/// Compute the checksum for this SCMP message using the provided address header.
fn calculate_checksum(&self, address_header: &AddressHeader) -> u16;

/// Returns true if the checksum successfully verifies, otherwise false.
fn verify_checksum(&self, address_header: &AddressHeader) -> bool {
self.calculate_checksum(address_header) == 0
}
}

/// SCION protocol number for SCMP.
///
/// See the [IETF SCION-dataplane RFC draft][rfc] for possible values.
///
///[rfc]: https://www.ietf.org/archive/id/draft-dekater-scion-dataplane-00.html#protnum
pub const SCMP_PROTOCOL_NUMBER: u8 = 202;
23 changes: 23 additions & 0 deletions crates/scion-proto/src/scmp/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//! Errors encountered when handling SCMP messages.
/// Error encountered when attempting to decode an SCMP message.
#[derive(Debug, thiserror::Error)]
pub enum ScmpDecodeError {
/// The data is shorter than the minimum length of the corresponding SCMP message.
#[error("message is empty or was truncated")]
MessageEmptyOrTruncated,
/// When attempting to decode a specific message type and the data contains a different message
/// type.
#[error("the type of the message does not match the type being decoded")]
MessageTypeMismatch,
/// Informational messages of unknown types need to be dropped.
#[error("unknown info message type {0}")]
UnknownInfoMessage(u8),
/// Depending on the type of SCMP message, only specific values of the `code` field are allowed.
#[error("invalid code for this message type")]
InvalidCode,
/// When decoding a SCION packet presumably containing an SCMP message but the next-header value
/// of the SCION header doesn't match [`SCMP_PROTOCOL_NUMBER`][super::SCMP_PROTOCOL_NUMBER].
#[error("next-header value of SCION header is not correct")]
WrongProtocolNumber(u8),
}
Loading

0 comments on commit 2c56fe6

Please sign in to comment.