From dabbf02109541d437507e9bdc2e2e0902a33e9dc Mon Sep 17 00:00:00 2001 From: moznion Date: Sun, 6 Dec 2020 16:54:42 +0900 Subject: [PATCH] Support RFC6572 and ipv4prefix type --- README.md | 2 +- code-generator/src/main.rs | 33 +++ dicts/dictionary.rfc6572 | 29 +++ radius/src/avp.rs | 21 +- radius/src/lib.rs | 1 + radius/src/rfc6572.rs | 415 +++++++++++++++++++++++++++++++++++++ 6 files changed, 499 insertions(+), 2 deletions(-) create mode 100644 dicts/dictionary.rfc6572 create mode 100644 radius/src/rfc6572.rs diff --git a/README.md b/README.md index 2f958cf..133b82a 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ This supports the following RFC dictionaries at the moment: - [RFC5607](https://tools.ietf.org/html/rfc5607) - [RFC5904](https://tools.ietf.org/html/rfc5904) - [RFC6519](https://tools.ietf.org/html/rfc6519) +- [RFC6572](https://tools.ietf.org/html/rfc6572) - [RFC6677](https://tools.ietf.org/html/rfc6677) - [RFC6911](https://tools.ietf.org/html/rfc6911) - [RFC7055](https://tools.ietf.org/html/rfc7055) @@ -48,7 +49,6 @@ Simple example implementations are here: - rfc4679 - rfc5447 - rfc5580 - - rfc6572 - rfc6929 - rfc6930 - rfc7268 diff --git a/code-generator/src/main.rs b/code-generator/src/main.rs index 55b2a25..cd0b326 100644 --- a/code-generator/src/main.rs +++ b/code-generator/src/main.rs @@ -48,6 +48,7 @@ enum RadiusAttributeValueType { TunnelPassword, Octets, IpAddr, + Ipv4Prefix, Ipv6Addr, Ipv6Prefix, IfId, @@ -64,6 +65,7 @@ impl FromStr for RadiusAttributeValueType { "string" => Ok(RadiusAttributeValueType::String), "octets" => Ok(RadiusAttributeValueType::Octets), "ipaddr" => Ok(RadiusAttributeValueType::IpAddr), + "ipv4prefix" => Ok(RadiusAttributeValueType::Ipv4Prefix), "ipv6addr" => Ok(RadiusAttributeValueType::Ipv6Addr), "ipv6prefix" => Ok(RadiusAttributeValueType::Ipv6Prefix), "ifid" => Ok(RadiusAttributeValueType::IfId), @@ -236,6 +238,10 @@ fn generate_attribute_code( true => unimplemented!("tagged-ip-addr"), false => generate_ipaddr_attribute_code(w, &method_identifier, &type_identifier), }, + RadiusAttributeValueType::Ipv4Prefix => match attr.has_tag { + true => unimplemented!("tagged-ip-addr"), + false => generate_ipv4_prefix_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), @@ -534,6 +540,33 @@ pub fn lookup_all_{method_identifier}(packet: &Packet) -> Result, w.write_all(code.as_bytes()).unwrap(); } +fn generate_ipv4_prefix_attribute_code( + w: &mut BufWriter, + 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_ipv4_prefix({type_identifier}, value)?); + Ok(()) +}} +pub fn lookup_{method_identifier}(packet: &Packet) -> Option, AVPError>> {{ + packet.lookup({type_identifier}).map(|v| v.encode_ipv4_prefix()) +}} +pub fn lookup_all_{method_identifier}(packet: &Packet) -> Result>, AVPError> {{ + let mut vec = Vec::new(); + for avp in packet.lookup_all({type_identifier}) {{ + vec.push(avp.encode_ipv4_prefix()?) + }} + Ok(vec) +}} +", + method_identifier = method_identifier, + type_identifier = type_identifier, + ); + w.write_all(code.as_bytes()).unwrap(); +} + fn generate_ipv6addr_attribute_code( w: &mut BufWriter, method_identifier: &str, diff --git a/dicts/dictionary.rfc6572 b/dicts/dictionary.rfc6572 new file mode 100644 index 0000000..0b1d98e --- /dev/null +++ b/dicts/dictionary.rfc6572 @@ -0,0 +1,29 @@ +# -*- 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 6572. +# http://www.ietf.org/rfc/rfc6572.txt +# +# $Id$ +# + +ATTRIBUTE Mobile-Node-Identifier 145 octets +ATTRIBUTE Service-Selection 146 string +ATTRIBUTE PMIP6-Home-LMA-IPv6-Address 147 ipv6addr +ATTRIBUTE PMIP6-Visited-LMA-IPv6-Address 148 ipv6addr +ATTRIBUTE PMIP6-Home-LMA-IPv4-Address 149 ipaddr +ATTRIBUTE PMIP6-Visited-LMA-IPv4-Address 150 ipaddr +ATTRIBUTE PMIP6-Home-HN-Prefix 151 ipv6prefix +ATTRIBUTE PMIP6-Visited-HN-Prefix 152 ipv6prefix +ATTRIBUTE PMIP6-Home-Interface-ID 153 ifid +ATTRIBUTE PMIP6-Visited-Interface-ID 154 ifid +ATTRIBUTE PMIP6-Home-IPv4-HoA 155 ipv4prefix +ATTRIBUTE PMIP6-Visited-IPv4-HoA 156 ipv4prefix +ATTRIBUTE PMIP6-Home-DHCP4-Server-Address 157 ipaddr +ATTRIBUTE PMIP6-Visited-DHCP4-Server-Address 158 ipaddr +ATTRIBUTE PMIP6-Home-DHCP6-Server-Address 159 ipv6addr +ATTRIBUTE PMIP6-Visited-DHCP6-Server-Address 160 ipv6addr +ATTRIBUTE PMIP6-Home-IPv4-Gateway 161 ipaddr +ATTRIBUTE PMIP6-Visited-IPv4-Gateway 162 ipaddr diff --git a/radius/src/avp.rs b/radius/src/avp.rs index 30f1c35..c9c7c5a 100644 --- a/radius/src/avp.rs +++ b/radius/src/avp.rs @@ -103,6 +103,18 @@ impl AVP { } } + pub fn from_ipv4_prefix(typ: AVPType, prefix: &[u8]) -> Result { + let prefix_len = prefix.len(); + if prefix_len != 4 { + return Err(AVPError::InvalidAttributeLengthError(prefix_len)); + } + + Ok(AVP { + typ, + value: [vec![0x00, prefix_len as u8 & 0b00111111], prefix.to_vec()].concat::(), + }) + } + pub fn from_ipv6(typ: AVPType, value: &Ipv6Addr) -> Self { AVP { typ, @@ -118,7 +130,7 @@ impl AVP { Ok(AVP { typ, - value: [vec![0x00, prefix_len as u8], prefix.to_vec()].concat::(), + value: [vec![0x00, (prefix_len * 8) as u8], prefix.to_vec()].concat::(), }) } @@ -393,6 +405,13 @@ impl AVP { } } + pub fn encode_ipv4_prefix(&self) -> Result, AVPError> { + match self.value.len() == 6 { + true => Ok(self.value[2..].to_owned()), + false => Err(AVPError::InvalidAttributeLengthError(self.value.len())), + } + } + pub fn encode_ipv6(&self) -> Result { const IPV6_SIZE: usize = std::mem::size_of::(); if self.value.len() != IPV6_SIZE { diff --git a/radius/src/lib.rs b/radius/src/lib.rs index c1febb9..91eeeeb 100644 --- a/radius/src/lib.rs +++ b/radius/src/lib.rs @@ -22,6 +22,7 @@ pub mod rfc5176; pub mod rfc5607; pub mod rfc5904; pub mod rfc6519; +pub mod rfc6572; pub mod rfc6677; pub mod rfc6911; pub mod rfc7055; diff --git a/radius/src/rfc6572.rs b/radius/src/rfc6572.rs new file mode 100644 index 0000000..08d5830 --- /dev/null +++ b/radius/src/rfc6572.rs @@ -0,0 +1,415 @@ +// Code generated by machine generator; DO NOT EDIT. + +use std::net::{Ipv4Addr, Ipv6Addr}; + +use crate::avp::{AVPError, AVPType, AVP}; +use crate::packet::Packet; + +pub const MOBILE_NODE_IDENTIFIER_TYPE: AVPType = 145; +pub fn delete_mobile_node_identifier(packet: &mut Packet) { + packet.delete(MOBILE_NODE_IDENTIFIER_TYPE); +} +pub fn add_mobile_node_identifier(packet: &mut Packet, value: &[u8]) { + packet.add(AVP::from_bytes(MOBILE_NODE_IDENTIFIER_TYPE, value)); +} +pub fn lookup_mobile_node_identifier(packet: &Packet) -> Option> { + packet + .lookup(MOBILE_NODE_IDENTIFIER_TYPE) + .map(|v| v.encode_bytes()) +} +pub fn lookup_all_mobile_node_identifier(packet: &Packet) -> Vec> { + let mut vec = Vec::new(); + for avp in packet.lookup_all(MOBILE_NODE_IDENTIFIER_TYPE) { + vec.push(avp.encode_bytes()) + } + vec +} + +pub const SERVICE_SELECTION_TYPE: AVPType = 146; +pub fn delete_service_selection(packet: &mut Packet) { + packet.delete(SERVICE_SELECTION_TYPE); +} +pub fn add_service_selection(packet: &mut Packet, value: &str) { + packet.add(AVP::from_string(SERVICE_SELECTION_TYPE, value)); +} +pub fn lookup_service_selection(packet: &Packet) -> Option> { + packet + .lookup(SERVICE_SELECTION_TYPE) + .map(|v| v.encode_string()) +} +pub fn lookup_all_service_selection(packet: &Packet) -> Result, AVPError> { + let mut vec = Vec::new(); + for avp in packet.lookup_all(SERVICE_SELECTION_TYPE) { + vec.push(avp.encode_string()?) + } + Ok(vec) +} + +pub const PMIP6_HOME_LMA_I_PV_6_ADDRESS_TYPE: AVPType = 147; +pub fn delete_pmip6_home_lma_i_pv_6_address(packet: &mut Packet) { + packet.delete(PMIP6_HOME_LMA_I_PV_6_ADDRESS_TYPE); +} +pub fn add_pmip6_home_lma_i_pv_6_address(packet: &mut Packet, value: &Ipv6Addr) { + packet.add(AVP::from_ipv6(PMIP6_HOME_LMA_I_PV_6_ADDRESS_TYPE, value)); +} +pub fn lookup_pmip6_home_lma_i_pv_6_address(packet: &Packet) -> Option> { + packet + .lookup(PMIP6_HOME_LMA_I_PV_6_ADDRESS_TYPE) + .map(|v| v.encode_ipv6()) +} +pub fn lookup_all_pmip6_home_lma_i_pv_6_address( + packet: &Packet, +) -> Result, AVPError> { + let mut vec = Vec::new(); + for avp in packet.lookup_all(PMIP6_HOME_LMA_I_PV_6_ADDRESS_TYPE) { + vec.push(avp.encode_ipv6()?) + } + Ok(vec) +} + +pub const PMIP6_VISITED_LMA_I_PV_6_ADDRESS_TYPE: AVPType = 148; +pub fn delete_pmip6_visited_lma_i_pv_6_address(packet: &mut Packet) { + packet.delete(PMIP6_VISITED_LMA_I_PV_6_ADDRESS_TYPE); +} +pub fn add_pmip6_visited_lma_i_pv_6_address(packet: &mut Packet, value: &Ipv6Addr) { + packet.add(AVP::from_ipv6(PMIP6_VISITED_LMA_I_PV_6_ADDRESS_TYPE, value)); +} +pub fn lookup_pmip6_visited_lma_i_pv_6_address( + packet: &Packet, +) -> Option> { + packet + .lookup(PMIP6_VISITED_LMA_I_PV_6_ADDRESS_TYPE) + .map(|v| v.encode_ipv6()) +} +pub fn lookup_all_pmip6_visited_lma_i_pv_6_address( + packet: &Packet, +) -> Result, AVPError> { + let mut vec = Vec::new(); + for avp in packet.lookup_all(PMIP6_VISITED_LMA_I_PV_6_ADDRESS_TYPE) { + vec.push(avp.encode_ipv6()?) + } + Ok(vec) +} + +pub const PMIP6_HOME_LMA_I_PV_4_ADDRESS_TYPE: AVPType = 149; +pub fn delete_pmip6_home_lma_i_pv_4_address(packet: &mut Packet) { + packet.delete(PMIP6_HOME_LMA_I_PV_4_ADDRESS_TYPE); +} +pub fn add_pmip6_home_lma_i_pv_4_address(packet: &mut Packet, value: &Ipv4Addr) { + packet.add(AVP::from_ipv4(PMIP6_HOME_LMA_I_PV_4_ADDRESS_TYPE, value)); +} +pub fn lookup_pmip6_home_lma_i_pv_4_address(packet: &Packet) -> Option> { + packet + .lookup(PMIP6_HOME_LMA_I_PV_4_ADDRESS_TYPE) + .map(|v| v.encode_ipv4()) +} +pub fn lookup_all_pmip6_home_lma_i_pv_4_address( + packet: &Packet, +) -> Result, AVPError> { + let mut vec = Vec::new(); + for avp in packet.lookup_all(PMIP6_HOME_LMA_I_PV_4_ADDRESS_TYPE) { + vec.push(avp.encode_ipv4()?) + } + Ok(vec) +} + +pub const PMIP6_VISITED_LMA_I_PV_4_ADDRESS_TYPE: AVPType = 150; +pub fn delete_pmip6_visited_lma_i_pv_4_address(packet: &mut Packet) { + packet.delete(PMIP6_VISITED_LMA_I_PV_4_ADDRESS_TYPE); +} +pub fn add_pmip6_visited_lma_i_pv_4_address(packet: &mut Packet, value: &Ipv4Addr) { + packet.add(AVP::from_ipv4(PMIP6_VISITED_LMA_I_PV_4_ADDRESS_TYPE, value)); +} +pub fn lookup_pmip6_visited_lma_i_pv_4_address( + packet: &Packet, +) -> Option> { + packet + .lookup(PMIP6_VISITED_LMA_I_PV_4_ADDRESS_TYPE) + .map(|v| v.encode_ipv4()) +} +pub fn lookup_all_pmip6_visited_lma_i_pv_4_address( + packet: &Packet, +) -> Result, AVPError> { + let mut vec = Vec::new(); + for avp in packet.lookup_all(PMIP6_VISITED_LMA_I_PV_4_ADDRESS_TYPE) { + vec.push(avp.encode_ipv4()?) + } + Ok(vec) +} + +pub const PMIP6_HOME_HN_PREFIX_TYPE: AVPType = 151; +pub fn delete_pmip6_home_hn_prefix(packet: &mut Packet) { + packet.delete(PMIP6_HOME_HN_PREFIX_TYPE); +} +pub fn add_pmip6_home_hn_prefix(packet: &mut Packet, value: &[u8]) -> Result<(), AVPError> { + packet.add(AVP::from_ipv6_prefix(PMIP6_HOME_HN_PREFIX_TYPE, value)?); + Ok(()) +} +pub fn lookup_pmip6_home_hn_prefix(packet: &Packet) -> Option, AVPError>> { + packet + .lookup(PMIP6_HOME_HN_PREFIX_TYPE) + .map(|v| v.encode_ipv6_prefix()) +} +pub fn lookup_all_pmip6_home_hn_prefix(packet: &Packet) -> Result>, AVPError> { + let mut vec = Vec::new(); + for avp in packet.lookup_all(PMIP6_HOME_HN_PREFIX_TYPE) { + vec.push(avp.encode_ipv6_prefix()?) + } + Ok(vec) +} + +pub const PMIP6_VISITED_HN_PREFIX_TYPE: AVPType = 152; +pub fn delete_pmip6_visited_hn_prefix(packet: &mut Packet) { + packet.delete(PMIP6_VISITED_HN_PREFIX_TYPE); +} +pub fn add_pmip6_visited_hn_prefix(packet: &mut Packet, value: &[u8]) -> Result<(), AVPError> { + packet.add(AVP::from_ipv6_prefix(PMIP6_VISITED_HN_PREFIX_TYPE, value)?); + Ok(()) +} +pub fn lookup_pmip6_visited_hn_prefix(packet: &Packet) -> Option, AVPError>> { + packet + .lookup(PMIP6_VISITED_HN_PREFIX_TYPE) + .map(|v| v.encode_ipv6_prefix()) +} +pub fn lookup_all_pmip6_visited_hn_prefix(packet: &Packet) -> Result>, AVPError> { + let mut vec = Vec::new(); + for avp in packet.lookup_all(PMIP6_VISITED_HN_PREFIX_TYPE) { + vec.push(avp.encode_ipv6_prefix()?) + } + Ok(vec) +} + +pub const PMIP6_HOME_INTERFACE_ID_TYPE: AVPType = 153; +pub fn delete_pmip6_home_interface_id(packet: &mut Packet) { + packet.delete(PMIP6_HOME_INTERFACE_ID_TYPE); +} +pub fn add_pmip6_home_interface_id(packet: &mut Packet, value: &[u8]) -> Result<(), AVPError> { + if value.len() != 8 { + return Err(AVPError::InvalidAttributeLengthError(8)); + } + packet.add(AVP::from_bytes(PMIP6_HOME_INTERFACE_ID_TYPE, value)); + Ok(()) +} +pub fn lookup_pmip6_home_interface_id(packet: &Packet) -> Option> { + packet + .lookup(PMIP6_HOME_INTERFACE_ID_TYPE) + .map(|v| v.encode_bytes()) +} +pub fn lookup_all_pmip6_home_interface_id(packet: &Packet) -> Vec> { + let mut vec = Vec::new(); + for avp in packet.lookup_all(PMIP6_HOME_INTERFACE_ID_TYPE) { + vec.push(avp.encode_bytes()) + } + vec +} + +pub const PMIP6_VISITED_INTERFACE_ID_TYPE: AVPType = 154; +pub fn delete_pmip6_visited_interface_id(packet: &mut Packet) { + packet.delete(PMIP6_VISITED_INTERFACE_ID_TYPE); +} +pub fn add_pmip6_visited_interface_id(packet: &mut Packet, value: &[u8]) -> Result<(), AVPError> { + if value.len() != 8 { + return Err(AVPError::InvalidAttributeLengthError(8)); + } + packet.add(AVP::from_bytes(PMIP6_VISITED_INTERFACE_ID_TYPE, value)); + Ok(()) +} +pub fn lookup_pmip6_visited_interface_id(packet: &Packet) -> Option> { + packet + .lookup(PMIP6_VISITED_INTERFACE_ID_TYPE) + .map(|v| v.encode_bytes()) +} +pub fn lookup_all_pmip6_visited_interface_id(packet: &Packet) -> Vec> { + let mut vec = Vec::new(); + for avp in packet.lookup_all(PMIP6_VISITED_INTERFACE_ID_TYPE) { + vec.push(avp.encode_bytes()) + } + vec +} + +pub const PMIP6_HOME_I_PV_4_HO_A_TYPE: AVPType = 155; +pub fn delete_pmip6_home_i_pv_4_ho_a(packet: &mut Packet) { + packet.delete(PMIP6_HOME_I_PV_4_HO_A_TYPE); +} +pub fn add_pmip6_home_i_pv_4_ho_a(packet: &mut Packet, value: &[u8]) -> Result<(), AVPError> { + packet.add(AVP::from_ipv4_prefix(PMIP6_HOME_I_PV_4_HO_A_TYPE, value)?); + Ok(()) +} +pub fn lookup_pmip6_home_i_pv_4_ho_a(packet: &Packet) -> Option, AVPError>> { + packet + .lookup(PMIP6_HOME_I_PV_4_HO_A_TYPE) + .map(|v| v.encode_ipv4_prefix()) +} +pub fn lookup_all_pmip6_home_i_pv_4_ho_a(packet: &Packet) -> Result>, AVPError> { + let mut vec = Vec::new(); + for avp in packet.lookup_all(PMIP6_HOME_I_PV_4_HO_A_TYPE) { + vec.push(avp.encode_ipv4_prefix()?) + } + Ok(vec) +} + +pub const PMIP6_VISITED_I_PV_4_HO_A_TYPE: AVPType = 156; +pub fn delete_pmip6_visited_i_pv_4_ho_a(packet: &mut Packet) { + packet.delete(PMIP6_VISITED_I_PV_4_HO_A_TYPE); +} +pub fn add_pmip6_visited_i_pv_4_ho_a(packet: &mut Packet, value: &[u8]) -> Result<(), AVPError> { + packet.add(AVP::from_ipv4_prefix( + PMIP6_VISITED_I_PV_4_HO_A_TYPE, + value, + )?); + Ok(()) +} +pub fn lookup_pmip6_visited_i_pv_4_ho_a(packet: &Packet) -> Option, AVPError>> { + packet + .lookup(PMIP6_VISITED_I_PV_4_HO_A_TYPE) + .map(|v| v.encode_ipv4_prefix()) +} +pub fn lookup_all_pmip6_visited_i_pv_4_ho_a(packet: &Packet) -> Result>, AVPError> { + let mut vec = Vec::new(); + for avp in packet.lookup_all(PMIP6_VISITED_I_PV_4_HO_A_TYPE) { + vec.push(avp.encode_ipv4_prefix()?) + } + Ok(vec) +} + +pub const PMIP6_HOME_DHCP4_SERVER_ADDRESS_TYPE: AVPType = 157; +pub fn delete_pmip6_home_dhcp4_server_address(packet: &mut Packet) { + packet.delete(PMIP6_HOME_DHCP4_SERVER_ADDRESS_TYPE); +} +pub fn add_pmip6_home_dhcp4_server_address(packet: &mut Packet, value: &Ipv4Addr) { + packet.add(AVP::from_ipv4(PMIP6_HOME_DHCP4_SERVER_ADDRESS_TYPE, value)); +} +pub fn lookup_pmip6_home_dhcp4_server_address( + packet: &Packet, +) -> Option> { + packet + .lookup(PMIP6_HOME_DHCP4_SERVER_ADDRESS_TYPE) + .map(|v| v.encode_ipv4()) +} +pub fn lookup_all_pmip6_home_dhcp4_server_address( + packet: &Packet, +) -> Result, AVPError> { + let mut vec = Vec::new(); + for avp in packet.lookup_all(PMIP6_HOME_DHCP4_SERVER_ADDRESS_TYPE) { + vec.push(avp.encode_ipv4()?) + } + Ok(vec) +} + +pub const PMIP6_VISITED_DHCP4_SERVER_ADDRESS_TYPE: AVPType = 158; +pub fn delete_pmip6_visited_dhcp4_server_address(packet: &mut Packet) { + packet.delete(PMIP6_VISITED_DHCP4_SERVER_ADDRESS_TYPE); +} +pub fn add_pmip6_visited_dhcp4_server_address(packet: &mut Packet, value: &Ipv4Addr) { + packet.add(AVP::from_ipv4( + PMIP6_VISITED_DHCP4_SERVER_ADDRESS_TYPE, + value, + )); +} +pub fn lookup_pmip6_visited_dhcp4_server_address( + packet: &Packet, +) -> Option> { + packet + .lookup(PMIP6_VISITED_DHCP4_SERVER_ADDRESS_TYPE) + .map(|v| v.encode_ipv4()) +} +pub fn lookup_all_pmip6_visited_dhcp4_server_address( + packet: &Packet, +) -> Result, AVPError> { + let mut vec = Vec::new(); + for avp in packet.lookup_all(PMIP6_VISITED_DHCP4_SERVER_ADDRESS_TYPE) { + vec.push(avp.encode_ipv4()?) + } + Ok(vec) +} + +pub const PMIP6_HOME_DHCP6_SERVER_ADDRESS_TYPE: AVPType = 159; +pub fn delete_pmip6_home_dhcp6_server_address(packet: &mut Packet) { + packet.delete(PMIP6_HOME_DHCP6_SERVER_ADDRESS_TYPE); +} +pub fn add_pmip6_home_dhcp6_server_address(packet: &mut Packet, value: &Ipv6Addr) { + packet.add(AVP::from_ipv6(PMIP6_HOME_DHCP6_SERVER_ADDRESS_TYPE, value)); +} +pub fn lookup_pmip6_home_dhcp6_server_address( + packet: &Packet, +) -> Option> { + packet + .lookup(PMIP6_HOME_DHCP6_SERVER_ADDRESS_TYPE) + .map(|v| v.encode_ipv6()) +} +pub fn lookup_all_pmip6_home_dhcp6_server_address( + packet: &Packet, +) -> Result, AVPError> { + let mut vec = Vec::new(); + for avp in packet.lookup_all(PMIP6_HOME_DHCP6_SERVER_ADDRESS_TYPE) { + vec.push(avp.encode_ipv6()?) + } + Ok(vec) +} + +pub const PMIP6_VISITED_DHCP6_SERVER_ADDRESS_TYPE: AVPType = 160; +pub fn delete_pmip6_visited_dhcp6_server_address(packet: &mut Packet) { + packet.delete(PMIP6_VISITED_DHCP6_SERVER_ADDRESS_TYPE); +} +pub fn add_pmip6_visited_dhcp6_server_address(packet: &mut Packet, value: &Ipv6Addr) { + packet.add(AVP::from_ipv6( + PMIP6_VISITED_DHCP6_SERVER_ADDRESS_TYPE, + value, + )); +} +pub fn lookup_pmip6_visited_dhcp6_server_address( + packet: &Packet, +) -> Option> { + packet + .lookup(PMIP6_VISITED_DHCP6_SERVER_ADDRESS_TYPE) + .map(|v| v.encode_ipv6()) +} +pub fn lookup_all_pmip6_visited_dhcp6_server_address( + packet: &Packet, +) -> Result, AVPError> { + let mut vec = Vec::new(); + for avp in packet.lookup_all(PMIP6_VISITED_DHCP6_SERVER_ADDRESS_TYPE) { + vec.push(avp.encode_ipv6()?) + } + Ok(vec) +} + +pub const PMIP6_HOME_I_PV_4_GATEWAY_TYPE: AVPType = 161; +pub fn delete_pmip6_home_i_pv_4_gateway(packet: &mut Packet) { + packet.delete(PMIP6_HOME_I_PV_4_GATEWAY_TYPE); +} +pub fn add_pmip6_home_i_pv_4_gateway(packet: &mut Packet, value: &Ipv4Addr) { + packet.add(AVP::from_ipv4(PMIP6_HOME_I_PV_4_GATEWAY_TYPE, value)); +} +pub fn lookup_pmip6_home_i_pv_4_gateway(packet: &Packet) -> Option> { + packet + .lookup(PMIP6_HOME_I_PV_4_GATEWAY_TYPE) + .map(|v| v.encode_ipv4()) +} +pub fn lookup_all_pmip6_home_i_pv_4_gateway(packet: &Packet) -> Result, AVPError> { + let mut vec = Vec::new(); + for avp in packet.lookup_all(PMIP6_HOME_I_PV_4_GATEWAY_TYPE) { + vec.push(avp.encode_ipv4()?) + } + Ok(vec) +} + +pub const PMIP6_VISITED_I_PV_4_GATEWAY_TYPE: AVPType = 162; +pub fn delete_pmip6_visited_i_pv_4_gateway(packet: &mut Packet) { + packet.delete(PMIP6_VISITED_I_PV_4_GATEWAY_TYPE); +} +pub fn add_pmip6_visited_i_pv_4_gateway(packet: &mut Packet, value: &Ipv4Addr) { + packet.add(AVP::from_ipv4(PMIP6_VISITED_I_PV_4_GATEWAY_TYPE, value)); +} +pub fn lookup_pmip6_visited_i_pv_4_gateway(packet: &Packet) -> Option> { + packet + .lookup(PMIP6_VISITED_I_PV_4_GATEWAY_TYPE) + .map(|v| v.encode_ipv4()) +} +pub fn lookup_all_pmip6_visited_i_pv_4_gateway(packet: &Packet) -> Result, AVPError> { + let mut vec = Vec::new(); + for avp in packet.lookup_all(PMIP6_VISITED_I_PV_4_GATEWAY_TYPE) { + vec.push(avp.encode_ipv4()?) + } + Ok(vec) +}