mirror of
https://github.com/cubixle/radius-rs.git
synced 2026-04-30 11:58:44 +01:00
Support to generate code for fixed length octets
This commit is contained in:
@@ -29,6 +29,7 @@ struct RadiusAttribute {
|
|||||||
name: String,
|
name: String,
|
||||||
typ: u8,
|
typ: u8,
|
||||||
value_type: RadiusAttributeValueType,
|
value_type: RadiusAttributeValueType,
|
||||||
|
fixed_octets_length: Option<usize>,
|
||||||
has_tag: bool,
|
has_tag: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,7 +203,15 @@ fn generate_attribute_code(
|
|||||||
},
|
},
|
||||||
RadiusAttributeValueType::Octets => match attr.has_tag {
|
RadiusAttributeValueType::Octets => match attr.has_tag {
|
||||||
true => unimplemented!("tagged-octets"),
|
true => unimplemented!("tagged-octets"),
|
||||||
false => generate_octets_attribute_code(w, &method_identifier, &type_identifier),
|
false => match attr.fixed_octets_length {
|
||||||
|
Some(fixed_octets_length) => generate_fixed_length_octets_attribute_code(
|
||||||
|
w,
|
||||||
|
&method_identifier,
|
||||||
|
&type_identifier,
|
||||||
|
fixed_octets_length,
|
||||||
|
),
|
||||||
|
None => generate_octets_attribute_code(w, &method_identifier, &type_identifier),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
RadiusAttributeValueType::IpAddr => match attr.has_tag {
|
RadiusAttributeValueType::IpAddr => match attr.has_tag {
|
||||||
true => unimplemented!("tagged-ip-addr"),
|
true => unimplemented!("tagged-ip-addr"),
|
||||||
@@ -396,6 +405,38 @@ pub fn lookup_all_{method_identifier}(packet: &Packet) -> Vec<Vec<u8>> {{
|
|||||||
w.write_all(code.as_bytes()).unwrap();
|
w.write_all(code.as_bytes()).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn generate_fixed_length_octets_attribute_code(
|
||||||
|
w: &mut BufWriter<File>,
|
||||||
|
method_identifier: &str,
|
||||||
|
type_identifier: &str,
|
||||||
|
fixed_octets_length: usize,
|
||||||
|
) {
|
||||||
|
let code = format!(
|
||||||
|
"pub fn add_{method_identifier}(packet: &mut Packet, value: &[u8]) -> Result<(), AVPError> {{
|
||||||
|
if value.len() != {fixed_octets_length} {{
|
||||||
|
return Err(AVPError::InvalidAttributeLengthError({fixed_octets_length}));
|
||||||
|
}}
|
||||||
|
packet.add(AVP::from_bytes({type_identifier}, value));
|
||||||
|
Ok(())
|
||||||
|
}}
|
||||||
|
pub fn lookup_{method_identifier}(packet: &Packet) -> Option<Vec<u8>> {{
|
||||||
|
packet.lookup({type_identifier}).map(|v| v.encode_bytes())
|
||||||
|
}}
|
||||||
|
pub fn lookup_all_{method_identifier}(packet: &Packet) -> Vec<Vec<u8>> {{
|
||||||
|
let mut vec = Vec::new();
|
||||||
|
for avp in packet.lookup_all({type_identifier}) {{
|
||||||
|
vec.push(avp.encode_bytes())
|
||||||
|
}}
|
||||||
|
vec
|
||||||
|
}}
|
||||||
|
",
|
||||||
|
method_identifier = method_identifier,
|
||||||
|
type_identifier = type_identifier,
|
||||||
|
fixed_octets_length = fixed_octets_length,
|
||||||
|
);
|
||||||
|
w.write_all(code.as_bytes()).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
fn generate_ipaddr_attribute_code(
|
fn generate_ipaddr_attribute_code(
|
||||||
w: &mut BufWriter<File>,
|
w: &mut BufWriter<File>,
|
||||||
method_identifier: &str,
|
method_identifier: &str,
|
||||||
@@ -570,6 +611,7 @@ fn parse_dict_file(dict_file_path: &Path) -> Result<DictParsed, String> {
|
|||||||
let line_filter_re = Regex::new(r"^(?:#.*|)$").unwrap();
|
let line_filter_re = Regex::new(r"^(?:#.*|)$").unwrap();
|
||||||
let tabs_re = Regex::new(r"\t+").unwrap();
|
let tabs_re = Regex::new(r"\t+").unwrap();
|
||||||
let trailing_comment_re = Regex::new(r"\s*?#.+?$").unwrap();
|
let trailing_comment_re = Regex::new(r"\s*?#.+?$").unwrap();
|
||||||
|
let fixed_length_octets_re = Regex::new(r"^octets\[(\d+)]$").unwrap();
|
||||||
|
|
||||||
let mut radius_attributes: Vec<RadiusAttribute> = Vec::new();
|
let mut radius_attributes: Vec<RadiusAttribute> = Vec::new();
|
||||||
let mut radius_attribute_to_values: BTreeMap<String, Vec<RadiusValue>> = BTreeMap::new();
|
let mut radius_attribute_to_values: BTreeMap<String, Vec<RadiusValue>> = BTreeMap::new();
|
||||||
@@ -611,31 +653,49 @@ fn parse_dict_file(dict_file_path: &Path) -> Result<DictParsed, String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let typ = match RadiusAttributeValueType::from_str(items[3]) {
|
let (typ, fixed_octets_length) = match RadiusAttributeValueType::from_str(items[3])
|
||||||
|
{
|
||||||
Ok(t) => {
|
Ok(t) => {
|
||||||
if t == RadiusAttributeValueType::String {
|
if t == RadiusAttributeValueType::String {
|
||||||
match encryption_type {
|
match encryption_type {
|
||||||
Some(EncryptionType::UserPassword) => {
|
Some(EncryptionType::UserPassword) => {
|
||||||
RadiusAttributeValueType::UserPassword
|
(RadiusAttributeValueType::UserPassword, None)
|
||||||
}
|
}
|
||||||
Some(EncryptionType::TunnelPassword) => {
|
Some(EncryptionType::TunnelPassword) => {
|
||||||
RadiusAttributeValueType::TunnelPassword
|
(RadiusAttributeValueType::TunnelPassword, None)
|
||||||
}
|
}
|
||||||
None => t,
|
None => (t, None),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
t
|
(t, None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
|
// XXX ad-hoc
|
||||||
|
let cap = fixed_length_octets_re.captures(items[3]);
|
||||||
|
if cap.is_some() {
|
||||||
|
(
|
||||||
|
RadiusAttributeValueType::Octets,
|
||||||
|
Some(
|
||||||
|
cap.unwrap()
|
||||||
|
.get(1)
|
||||||
|
.unwrap()
|
||||||
|
.as_str()
|
||||||
|
.parse::<usize>()
|
||||||
|
.unwrap(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
return Err(format!("invalid type has come => {}", items[3]));
|
return Err(format!("invalid type has come => {}", items[3]));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
radius_attributes.push(RadiusAttribute {
|
radius_attributes.push(RadiusAttribute {
|
||||||
name: items[1].to_string(),
|
name: items[1].to_string(),
|
||||||
typ: items[2].parse().unwrap(),
|
typ: items[2].parse().unwrap(),
|
||||||
value_type: typ,
|
value_type: typ,
|
||||||
|
fixed_octets_length,
|
||||||
has_tag,
|
has_tag,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user