mirror of
https://github.com/cubixle/radius-rs.git
synced 2026-04-24 23:04:43 +01:00
Support RFC3162
This commit is contained in:
@@ -15,6 +15,7 @@ This supports the following RFC dictionaries at the moment:
|
||||
- [RFC2867](https://tools.ietf.org/html/rfc2867)
|
||||
- [RFC2868](https://tools.ietf.org/html/rfc2868)
|
||||
- [RFC2869](https://tools.ietf.org/html/rfc2869)
|
||||
- [RFC3162](https://tools.ietf.org/html/rfc3162)
|
||||
- [RFC3576](https://tools.ietf.org/html/rfc3576)
|
||||
- [RFC4072](https://tools.ietf.org/html/rfc4072)
|
||||
- [RFC5090](https://tools.ietf.org/html/rfc5090)
|
||||
@@ -33,7 +34,6 @@ Simple example implementations are here:
|
||||
|
||||
- retransmission feature on the client
|
||||
- Support the following RFC dictionaries:
|
||||
- rfc3162
|
||||
- rfc3580
|
||||
- rfc4372
|
||||
- rfc4603
|
||||
|
||||
@@ -48,6 +48,9 @@ enum RadiusAttributeValueType {
|
||||
TunnelPassword,
|
||||
Octets,
|
||||
IpAddr,
|
||||
Ipv6Addr,
|
||||
Ipv6Prefix,
|
||||
IfId,
|
||||
Date,
|
||||
Integer,
|
||||
VSA,
|
||||
@@ -60,6 +63,9 @@ impl FromStr for RadiusAttributeValueType {
|
||||
"string" => Ok(RadiusAttributeValueType::String),
|
||||
"octets" => Ok(RadiusAttributeValueType::Octets),
|
||||
"ipaddr" => Ok(RadiusAttributeValueType::IpAddr),
|
||||
"ipv6addr" => Ok(RadiusAttributeValueType::Ipv6Addr),
|
||||
"ipv6prefix" => Ok(RadiusAttributeValueType::Ipv6Prefix),
|
||||
"ifid" => Ok(RadiusAttributeValueType::IfId),
|
||||
"date" => Ok(RadiusAttributeValueType::Date),
|
||||
"integer" => Ok(RadiusAttributeValueType::Integer),
|
||||
"vsa" => Ok(RadiusAttributeValueType::VSA),
|
||||
@@ -118,7 +124,7 @@ fn main() {
|
||||
fn generate_header(w: &mut BufWriter<File>) {
|
||||
let code = b"// Code generated by machine generator; DO NOT EDIT.
|
||||
|
||||
use std::net::Ipv4Addr;
|
||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||
|
||||
use chrono::{DateTime, Utc};
|
||||
|
||||
@@ -228,6 +234,23 @@ fn generate_attribute_code(
|
||||
true => unimplemented!("tagged-ip-addr"),
|
||||
false => generate_ipaddr_attribute_code(w, &method_identifier, &type_identifier),
|
||||
},
|
||||
RadiusAttributeValueType::Ipv6Addr => match attr.has_tag {
|
||||
true => unimplemented!("tagged-ip-v6-addr"),
|
||||
false => generate_ipv6addr_attribute_code(w, &method_identifier, &type_identifier),
|
||||
},
|
||||
RadiusAttributeValueType::Ipv6Prefix => match attr.has_tag {
|
||||
true => unimplemented!("tagged-ipv6-prefix"),
|
||||
false => generate_ipv6_prefix_attribute_code(w, &method_identifier, &type_identifier),
|
||||
},
|
||||
RadiusAttributeValueType::IfId => match attr.has_tag {
|
||||
true => unimplemented!("tagged-ifid"),
|
||||
false => generate_fixed_length_octets_attribute_code(
|
||||
w,
|
||||
&method_identifier,
|
||||
&type_identifier,
|
||||
8,
|
||||
),
|
||||
},
|
||||
RadiusAttributeValueType::Date => match attr.has_tag {
|
||||
true => unimplemented!("tagged-date"),
|
||||
false => generate_date_attribute_code(w, &method_identifier, &type_identifier),
|
||||
@@ -505,6 +528,59 @@ pub fn lookup_all_{method_identifier}(packet: &Packet) -> Result<Vec<Ipv4Addr>,
|
||||
w.write_all(code.as_bytes()).unwrap();
|
||||
}
|
||||
|
||||
fn generate_ipv6addr_attribute_code(
|
||||
w: &mut BufWriter<File>,
|
||||
method_identifier: &str,
|
||||
type_identifier: &str,
|
||||
) {
|
||||
let code = format!(
|
||||
"pub fn add_{method_identifier}(packet: &mut Packet, value: &Ipv6Addr) {{
|
||||
packet.add(AVP::from_ipv6({type_identifier}, value));
|
||||
}}
|
||||
pub fn lookup_{method_identifier}(packet: &Packet) -> Option<Result<Ipv6Addr, AVPError>> {{
|
||||
packet.lookup({type_identifier}).map(|v| v.encode_ipv6())
|
||||
}}
|
||||
pub fn lookup_all_{method_identifier}(packet: &Packet) -> Result<Vec<Ipv6Addr>, AVPError> {{
|
||||
let mut vec = Vec::new();
|
||||
for avp in packet.lookup_all({type_identifier}) {{
|
||||
vec.push(avp.encode_ipv6()?)
|
||||
}}
|
||||
Ok(vec)
|
||||
}}
|
||||
",
|
||||
method_identifier = method_identifier,
|
||||
type_identifier = type_identifier,
|
||||
);
|
||||
w.write_all(code.as_bytes()).unwrap();
|
||||
}
|
||||
|
||||
fn generate_ipv6_prefix_attribute_code(
|
||||
w: &mut BufWriter<File>,
|
||||
method_identifier: &str,
|
||||
type_identifier: &str,
|
||||
) {
|
||||
let code = format!(
|
||||
"pub fn add_{method_identifier}(packet: &mut Packet, value: &[u8]) -> Result<(), AVPError> {{
|
||||
packet.add(AVP::from_ipv6_prefix({type_identifier}, value)?);
|
||||
Ok(())
|
||||
}}
|
||||
pub fn lookup_{method_identifier}(packet: &Packet) -> Option<Result<Vec<u8>, AVPError>> {{
|
||||
packet.lookup({type_identifier}).map(|v| v.encode_ipv6_prefix())
|
||||
}}
|
||||
pub fn lookup_all_{method_identifier}(packet: &Packet) -> Result<Vec<Vec<u8>>, AVPError> {{
|
||||
let mut vec = Vec::new();
|
||||
for avp in packet.lookup_all({type_identifier}) {{
|
||||
vec.push(avp.encode_ipv6_prefix()?)
|
||||
}}
|
||||
Ok(vec)
|
||||
}}
|
||||
",
|
||||
method_identifier = method_identifier,
|
||||
type_identifier = type_identifier,
|
||||
);
|
||||
w.write_all(code.as_bytes()).unwrap();
|
||||
}
|
||||
|
||||
fn generate_date_attribute_code(
|
||||
w: &mut BufWriter<File>,
|
||||
method_identifier: &str,
|
||||
|
||||
16
dicts/dictionary.rfc3162
Normal file
16
dicts/dictionary.rfc3162
Normal file
@@ -0,0 +1,16 @@
|
||||
# -*- text -*-
|
||||
# Copyright (C) 2020 The FreeRADIUS Server project and contributors
|
||||
# This work is licensed under CC-BY version 4.0 https://creativecommons.org/licenses/by/4.0
|
||||
# Version $Id$
|
||||
#
|
||||
# Attributes and values defined in RFC 3162.
|
||||
# http://www.ietf.org/rfc/rfc3162.txt
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
ATTRIBUTE NAS-Ipv6-Address 95 ipv6addr
|
||||
ATTRIBUTE Framed-Interface-Id 96 ifid
|
||||
ATTRIBUTE Framed-Ipv6-Prefix 97 ipv6prefix
|
||||
ATTRIBUTE Login-Ipv6-Host 98 ipv6addr
|
||||
ATTRIBUTE Framed-Ipv6-Route 99 string
|
||||
ATTRIBUTE Framed-Ipv6-Pool 100 string
|
||||
@@ -103,6 +103,18 @@ impl AVP {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_ipv6_prefix(typ: AVPType, prefix: &[u8]) -> Result<Self, AVPError> {
|
||||
let prefix_len = prefix.len();
|
||||
if prefix_len > 16 {
|
||||
return Err(AVPError::InvalidAttributeLengthError(prefix_len));
|
||||
}
|
||||
|
||||
Ok(AVP {
|
||||
typ,
|
||||
value: [vec![0x00, prefix_len as u8], prefix.to_vec()].concat::<u8>(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn from_user_password(
|
||||
typ: AVPType,
|
||||
plain_text: &[u8],
|
||||
@@ -374,6 +386,13 @@ impl AVP {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn encode_ipv6_prefix(&self) -> Result<Vec<u8>, AVPError> {
|
||||
match self.value.len() > 2 {
|
||||
true => Ok(self.value[2..].to_owned()),
|
||||
false => Err(AVPError::InvalidAttributeLengthError(self.value.len())),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn encode_user_password(
|
||||
&self,
|
||||
secret: &[u8],
|
||||
|
||||
@@ -8,6 +8,7 @@ pub mod rfc2866;
|
||||
pub mod rfc2867;
|
||||
pub mod rfc2868;
|
||||
pub mod rfc2869;
|
||||
pub mod rfc3162;
|
||||
pub mod rfc3576;
|
||||
pub mod rfc4072;
|
||||
pub mod rfc5090;
|
||||
|
||||
131
radius/src/rfc3162.rs
Normal file
131
radius/src/rfc3162.rs
Normal file
@@ -0,0 +1,131 @@
|
||||
// Code generated by machine generator; DO NOT EDIT.
|
||||
|
||||
use std::net::Ipv6Addr;
|
||||
|
||||
use crate::avp::{AVPError, AVPType, AVP};
|
||||
use crate::packet::Packet;
|
||||
|
||||
pub const NAS_IPV_6_ADDRESS_TYPE: AVPType = 95;
|
||||
pub fn delete_nas_ipv_6_address(packet: &mut Packet) {
|
||||
packet.delete(NAS_IPV_6_ADDRESS_TYPE);
|
||||
}
|
||||
pub fn add_nas_ipv_6_address(packet: &mut Packet, value: &Ipv6Addr) {
|
||||
packet.add(AVP::from_ipv6(NAS_IPV_6_ADDRESS_TYPE, value));
|
||||
}
|
||||
pub fn lookup_nas_ipv_6_address(packet: &Packet) -> Option<Result<Ipv6Addr, AVPError>> {
|
||||
packet
|
||||
.lookup(NAS_IPV_6_ADDRESS_TYPE)
|
||||
.map(|v| v.encode_ipv6())
|
||||
}
|
||||
pub fn lookup_all_nas_ipv_6_address(packet: &Packet) -> Result<Vec<Ipv6Addr>, AVPError> {
|
||||
let mut vec = Vec::new();
|
||||
for avp in packet.lookup_all(NAS_IPV_6_ADDRESS_TYPE) {
|
||||
vec.push(avp.encode_ipv6()?)
|
||||
}
|
||||
Ok(vec)
|
||||
}
|
||||
|
||||
pub const FRAMED_INTERFACE_ID_TYPE: AVPType = 96;
|
||||
pub fn delete_framed_interface_id(packet: &mut Packet) {
|
||||
packet.delete(FRAMED_INTERFACE_ID_TYPE);
|
||||
}
|
||||
pub fn add_framed_interface_id(packet: &mut Packet, value: &[u8]) -> Result<(), AVPError> {
|
||||
if value.len() != 8 {
|
||||
return Err(AVPError::InvalidAttributeLengthError(8));
|
||||
}
|
||||
packet.add(AVP::from_bytes(FRAMED_INTERFACE_ID_TYPE, value));
|
||||
Ok(())
|
||||
}
|
||||
pub fn lookup_framed_interface_id(packet: &Packet) -> Option<Vec<u8>> {
|
||||
packet
|
||||
.lookup(FRAMED_INTERFACE_ID_TYPE)
|
||||
.map(|v| v.encode_bytes())
|
||||
}
|
||||
pub fn lookup_all_framed_interface_id(packet: &Packet) -> Vec<Vec<u8>> {
|
||||
let mut vec = Vec::new();
|
||||
for avp in packet.lookup_all(FRAMED_INTERFACE_ID_TYPE) {
|
||||
vec.push(avp.encode_bytes())
|
||||
}
|
||||
vec
|
||||
}
|
||||
|
||||
pub const FRAMED_IPV_6_PREFIX_TYPE: AVPType = 97;
|
||||
pub fn delete_framed_ipv_6_prefix(packet: &mut Packet) {
|
||||
packet.delete(FRAMED_IPV_6_PREFIX_TYPE);
|
||||
}
|
||||
pub fn add_framed_ipv_6_prefix(packet: &mut Packet, value: &[u8]) -> Result<(), AVPError> {
|
||||
packet.add(AVP::from_ipv6_prefix(FRAMED_IPV_6_PREFIX_TYPE, value)?);
|
||||
Ok(())
|
||||
}
|
||||
pub fn lookup_framed_ipv_6_prefix(packet: &Packet) -> Option<Result<Vec<u8>, AVPError>> {
|
||||
packet
|
||||
.lookup(FRAMED_IPV_6_PREFIX_TYPE)
|
||||
.map(|v| v.encode_ipv6_prefix())
|
||||
}
|
||||
pub fn lookup_all_framed_ipv_6_prefix(packet: &Packet) -> Result<Vec<Vec<u8>>, AVPError> {
|
||||
let mut vec = Vec::new();
|
||||
for avp in packet.lookup_all(FRAMED_IPV_6_PREFIX_TYPE) {
|
||||
vec.push(avp.encode_ipv6_prefix()?)
|
||||
}
|
||||
Ok(vec)
|
||||
}
|
||||
|
||||
pub const LOGIN_IPV_6_HOST_TYPE: AVPType = 98;
|
||||
pub fn delete_login_ipv_6_host(packet: &mut Packet) {
|
||||
packet.delete(LOGIN_IPV_6_HOST_TYPE);
|
||||
}
|
||||
pub fn add_login_ipv_6_host(packet: &mut Packet, value: &Ipv6Addr) {
|
||||
packet.add(AVP::from_ipv6(LOGIN_IPV_6_HOST_TYPE, value));
|
||||
}
|
||||
pub fn lookup_login_ipv_6_host(packet: &Packet) -> Option<Result<Ipv6Addr, AVPError>> {
|
||||
packet
|
||||
.lookup(LOGIN_IPV_6_HOST_TYPE)
|
||||
.map(|v| v.encode_ipv6())
|
||||
}
|
||||
pub fn lookup_all_login_ipv_6_host(packet: &Packet) -> Result<Vec<Ipv6Addr>, AVPError> {
|
||||
let mut vec = Vec::new();
|
||||
for avp in packet.lookup_all(LOGIN_IPV_6_HOST_TYPE) {
|
||||
vec.push(avp.encode_ipv6()?)
|
||||
}
|
||||
Ok(vec)
|
||||
}
|
||||
|
||||
pub const FRAMED_IPV_6_ROUTE_TYPE: AVPType = 99;
|
||||
pub fn delete_framed_ipv_6_route(packet: &mut Packet) {
|
||||
packet.delete(FRAMED_IPV_6_ROUTE_TYPE);
|
||||
}
|
||||
pub fn add_framed_ipv_6_route(packet: &mut Packet, value: &str) {
|
||||
packet.add(AVP::from_string(FRAMED_IPV_6_ROUTE_TYPE, value));
|
||||
}
|
||||
pub fn lookup_framed_ipv_6_route(packet: &Packet) -> Option<Result<String, AVPError>> {
|
||||
packet
|
||||
.lookup(FRAMED_IPV_6_ROUTE_TYPE)
|
||||
.map(|v| v.encode_string())
|
||||
}
|
||||
pub fn lookup_all_framed_ipv_6_route(packet: &Packet) -> Result<Vec<String>, AVPError> {
|
||||
let mut vec = Vec::new();
|
||||
for avp in packet.lookup_all(FRAMED_IPV_6_ROUTE_TYPE) {
|
||||
vec.push(avp.encode_string()?)
|
||||
}
|
||||
Ok(vec)
|
||||
}
|
||||
|
||||
pub const FRAMED_IPV_6_POOL_TYPE: AVPType = 100;
|
||||
pub fn delete_framed_ipv_6_pool(packet: &mut Packet) {
|
||||
packet.delete(FRAMED_IPV_6_POOL_TYPE);
|
||||
}
|
||||
pub fn add_framed_ipv_6_pool(packet: &mut Packet, value: &str) {
|
||||
packet.add(AVP::from_string(FRAMED_IPV_6_POOL_TYPE, value));
|
||||
}
|
||||
pub fn lookup_framed_ipv_6_pool(packet: &Packet) -> Option<Result<String, AVPError>> {
|
||||
packet
|
||||
.lookup(FRAMED_IPV_6_POOL_TYPE)
|
||||
.map(|v| v.encode_string())
|
||||
}
|
||||
pub fn lookup_all_framed_ipv_6_pool(packet: &Packet) -> Result<Vec<String>, AVPError> {
|
||||
let mut vec = Vec::new();
|
||||
for avp in packet.lookup_all(FRAMED_IPV_6_POOL_TYPE) {
|
||||
vec.push(avp.encode_string()?)
|
||||
}
|
||||
Ok(vec)
|
||||
}
|
||||
Reference in New Issue
Block a user