use crate::MacAddr;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum WpaCipher {
Unknown,
Ccmp128,
Tkip,
Gcmp128,
Gcmp256,
Ccmp256,
Unsupported(u32),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum WpaAkm {
Unknown,
Psk,
Enterprise,
Sae,
Unsupported(u32),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum WpaKeyKind {
Unknown,
Pairwise,
Group,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum WpaCredentialStatus {
Unknown,
NotConfigured,
Matched,
Mismatch,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum WpaHandshakeStatus {
NotStarted,
Observing,
Complete,
MicVerified,
Failed,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum WpaDecryptReason {
NotAttempted,
NetworkNotConfigured,
WaitingForHandshake,
UnsupportedCipher,
UnsupportedAkm,
MissingKeyMaterial,
MicFailed,
AuthenticationFailed,
ReplayDetected,
MalformedFrame,
Decrypted,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Hash)]
pub struct WpaMetadata {
bssid: Option<MacAddr>,
station: Option<MacAddr>,
cipher: Option<WpaCipher>,
akm: Option<WpaAkm>,
key_kind: Option<WpaKeyKind>,
key_id: Option<u8>,
packet_number: Option<u64>,
handshake_status: Option<WpaHandshakeStatus>,
decrypt_reason: Option<WpaDecryptReason>,
credential_status: Option<WpaCredentialStatus>,
}
impl WpaMetadata {
pub fn new() -> Self {
Self::default()
}
pub const fn bssid(&self) -> Option<MacAddr> {
self.bssid
}
pub const fn station(&self) -> Option<MacAddr> {
self.station
}
pub const fn cipher(&self) -> Option<WpaCipher> {
self.cipher
}
pub const fn akm(&self) -> Option<WpaAkm> {
self.akm
}
pub const fn key_kind(&self) -> Option<WpaKeyKind> {
self.key_kind
}
pub const fn key_id(&self) -> Option<u8> {
self.key_id
}
pub const fn packet_number(&self) -> Option<u64> {
self.packet_number
}
pub const fn handshake_status(&self) -> Option<WpaHandshakeStatus> {
self.handshake_status
}
pub const fn decrypt_reason(&self) -> Option<WpaDecryptReason> {
self.decrypt_reason
}
pub const fn credential_status(&self) -> Option<WpaCredentialStatus> {
self.credential_status
}
pub const fn credentials_matched(&self) -> Option<bool> {
match self.credential_status {
Some(WpaCredentialStatus::Matched) => Some(true),
Some(WpaCredentialStatus::Mismatch) => Some(false),
_ => None,
}
}
pub const fn with_bssid(mut self, bssid: MacAddr) -> Self {
self.bssid = Some(bssid);
self
}
pub const fn with_station(mut self, station: MacAddr) -> Self {
self.station = Some(station);
self
}
pub const fn with_cipher(mut self, cipher: WpaCipher) -> Self {
self.cipher = Some(cipher);
self
}
pub const fn with_akm(mut self, akm: WpaAkm) -> Self {
self.akm = Some(akm);
self
}
pub const fn with_key_kind(mut self, key_kind: WpaKeyKind) -> Self {
self.key_kind = Some(key_kind);
self
}
pub const fn with_key_id(mut self, key_id: u8) -> Self {
self.key_id = Some(key_id);
self
}
pub const fn with_packet_number(mut self, packet_number: u64) -> Self {
self.packet_number = Some(packet_number);
self
}
pub const fn with_handshake_status(mut self, handshake_status: WpaHandshakeStatus) -> Self {
self.handshake_status = Some(handshake_status);
self
}
pub const fn with_decrypt_reason(mut self, decrypt_reason: WpaDecryptReason) -> Self {
self.decrypt_reason = Some(decrypt_reason);
self
}
pub const fn with_credential_status(mut self, credential_status: WpaCredentialStatus) -> Self {
self.credential_status = Some(credential_status);
self
}
pub const fn with_credentials_matched(mut self, matched: bool) -> Self {
self.credential_status = Some(if matched {
WpaCredentialStatus::Matched
} else {
WpaCredentialStatus::Mismatch
});
self
}
}