Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions radius/src/core/packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,11 @@ impl Packet {
pub fn lookup_all(&self, typ: AVPType) -> Vec<&AVP> {
self.attributes.lookup_all(typ)
}

/// Returns all attributes
pub fn attributes(&self) -> Vec<&AVP> {
self.attributes.0.iter().collect()
}
}

impl Debug for Packet {
Expand Down
99 changes: 99 additions & 0 deletions radius/src/core/vsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,45 @@ impl StringVSA {
value: value.as_bytes().to_vec(),
}
}

/// Decode from AVP bytes
pub fn from_message(b: &[u8]) -> Option<StringVSA> {
if b.len()<6 {
None
} else {
let vendor_id = b[0..4].to_vec();
let vendor_type = b[4];
let length = b[5];
let value = b[6..].to_vec();
Some(StringVSA{vendor_id,vendor_type,length,value})
}
}

/// Vendor ID slice
pub fn vendor_id(&self) -> &[u8] {
&self.vendor_id
}

/// Vendor ID as i32 or 0
pub fn vendor_id_i32(&self) -> i32 {
if self.vendor_id.len()==4 {
let mut b = [0u8;4];
b.clone_from_slice(&self.vendor_id[0..4]);
i32::from_be_bytes(b)
} else {
0
}
}

/// Vendor type
pub fn vendor_type(&self) -> u8 {
self.vendor_type
}

/// Value as bytes
pub fn as_bytes(&self) -> &[u8] {
&self.value
}
}

impl VSA for StringVSA {
Expand Down Expand Up @@ -110,6 +149,52 @@ impl TaggedStringVSA {
value: value.as_bytes().to_vec(),
}
}

/// Decode from AVP bytes
pub fn from_message(b: &[u8]) -> Option<TaggedStringVSA> {
if b.len()<7 {
None
} else {
let vendor_id = b[0..4].to_vec();
let vendor_type = b[4];
let length = b[5];
let tag = b[6];
let value = b[7..].to_vec();
Some(TaggedStringVSA{vendor_id,vendor_type,length,tag,value})
}
}

/// Vendor ID slice
pub fn vendor_id(&self) -> &[u8] {
&self.vendor_id
}

/// Vendor ID as i32 or 0
pub fn vendor_id_i32(&self) -> i32 {
if self.vendor_id.len()==4 {
let mut b = [0u8;4];
b.clone_from_slice(&self.vendor_id[0..4]);
i32::from_be_bytes(b)
} else {
0
}
}

/// Vendor type
pub fn vendor_type(&self) -> u8 {
self.vendor_type
}

/// Tag
pub fn tag(&self) -> u8 {
self.tag
}

/// Value as bytes
pub fn as_bytes(&self) -> &[u8] {
&self.value
}

}

impl VSA for TaggedStringVSA {
Expand Down Expand Up @@ -173,6 +258,13 @@ mod string_vsa_tests {
[0, 0, 19, 10, 65, 16, 98, 97, 114, 40, 49, 48, 48, 48, 44, 53, 52, 52, 49, 41]
)
}

#[test]
fn decode_encode() {
let vsa = StringVSA::new(1,2,"test");
let vsa2 = StringVSA::from_message(&vsa.message()).unwrap();
assert_eq!(vsa,vsa2);
}
}

#[cfg(test)]
Expand Down Expand Up @@ -203,4 +295,11 @@ mod tagged_string_vsa_tests {
[0, 0, 19, 10, 65, 17, 5, 98, 97, 114, 40, 49, 48, 48, 48, 44, 53, 52, 52, 49, 41]
)
}

#[test]
fn decode_encode() {
let vsa = TaggedStringVSA::new(1,2,3,"test");
let vsa2 = TaggedStringVSA::from_message(&vsa.message()).unwrap();
assert_eq!(vsa,vsa2);
}
}