Skip to main content

ipfix_parser/registry/
mod.rs

1//! IANA IPFIX registries
2//!
3//! Constants and types mirroring the IANA
4//! [IP Flow Information Export (IPFIX) Entities](https://www.iana.org/assignments/ipfix/ipfix.xhtml)
5//! registries. The Information Element table [`INFORMATION_ELEMENTS`] is
6//! generated from the IANA registry (`make registry-update`) and validated
7//! against it by `make specs-validate`.
8
9mod information_elements;
10
11pub use information_elements::INFORMATION_ELEMENTS;
12
13/// IPFIX Version Number (IANA "IPFIX Version Numbers" registry)
14pub const IPFIX_VERSION: u16 = 10;
15
16/// Set ID of Template Sets (IANA "IPFIX Set IDs" registry)
17pub const TEMPLATE_SET_ID: u16 = 2;
18
19/// Set ID of Options Template Sets (IANA "IPFIX Set IDs" registry)
20pub const OPTIONS_TEMPLATE_SET_ID: u16 = 3;
21
22/// First Set ID reserved for Data Sets (IANA "IPFIX Set IDs" registry)
23pub const MIN_DATA_SET_ID: u16 = 256;
24
25/// Private Enterprise Number signifying "IPFIX Reverse Information Element"
26/// (RFC 5103 Section 6.1)
27pub const REVERSE_INFORMATION_ELEMENT_PEN: u32 = 29305;
28
29/// Information Elements of an Information Element type record
30/// (RFC 5610 Section 3.9, Table 4). Validated against the RFC by
31/// `make specs-validate`.
32pub mod type_records {
33    /// `informationElementId` (RFC 5477), a Scope Field
34    pub const INFORMATION_ELEMENT_ID: u16 = 303;
35    /// `privateEnterpriseNumber` (RFC 5610 Section 3.8), a Scope Field
36    pub const PRIVATE_ENTERPRISE_NUMBER: u16 = 346;
37    /// `informationElementDataType` (RFC 5610 Section 3.1)
38    pub const INFORMATION_ELEMENT_DATA_TYPE: u16 = 339;
39    /// `informationElementDescription` (RFC 5610 Section 3.2)
40    pub const INFORMATION_ELEMENT_DESCRIPTION: u16 = 340;
41    /// `informationElementName` (RFC 5610 Section 3.3)
42    pub const INFORMATION_ELEMENT_NAME: u16 = 341;
43    /// `informationElementRangeBegin` (RFC 5610 Section 3.4)
44    pub const INFORMATION_ELEMENT_RANGE_BEGIN: u16 = 342;
45    /// `informationElementRangeEnd` (RFC 5610 Section 3.5)
46    pub const INFORMATION_ELEMENT_RANGE_END: u16 = 343;
47    /// `informationElementSemantics` (RFC 5610 Section 3.6)
48    pub const INFORMATION_ELEMENT_SEMANTICS: u16 = 344;
49    /// `informationElementUnits` (RFC 5610 Section 3.7)
50    pub const INFORMATION_ELEMENT_UNITS: u16 = 345;
51
52    /// The Scope Fields that identify a type record
53    pub const SCOPE_ELEMENTS: [u16; 2] = [INFORMATION_ELEMENT_ID, PRIVATE_ENTERPRISE_NUMBER];
54
55    /// All Information Elements read from a type record
56    pub const ELEMENTS: [u16; 9] = [
57        INFORMATION_ELEMENT_ID,
58        PRIVATE_ENTERPRISE_NUMBER,
59        INFORMATION_ELEMENT_DATA_TYPE,
60        INFORMATION_ELEMENT_SEMANTICS,
61        INFORMATION_ELEMENT_UNITS,
62        INFORMATION_ELEMENT_RANGE_BEGIN,
63        INFORMATION_ELEMENT_RANGE_END,
64        INFORMATION_ELEMENT_NAME,
65        INFORMATION_ELEMENT_DESCRIPTION,
66    ];
67}
68
69/// IPFIX abstract data type - RFC 7012 Section 3.1
70///
71/// IANA "IPFIX Information Element Data Types" registry. The discriminant is
72/// the IANA registry value.
73#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
74#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
75#[repr(u8)]
76pub enum DataType {
77    OctetArray = 0,
78    Unsigned8 = 1,
79    Unsigned16 = 2,
80    Unsigned32 = 3,
81    Unsigned64 = 4,
82    Signed8 = 5,
83    Signed16 = 6,
84    Signed32 = 7,
85    Signed64 = 8,
86    Float32 = 9,
87    Float64 = 10,
88    Boolean = 11,
89    MacAddress = 12,
90    String = 13,
91    DateTimeSeconds = 14,
92    DateTimeMilliseconds = 15,
93    DateTimeMicroseconds = 16,
94    DateTimeNanoseconds = 17,
95    Ipv4Address = 18,
96    Ipv6Address = 19,
97    BasicList = 20,
98    SubTemplateList = 21,
99    SubTemplateMultiList = 22,
100    Unsigned256 = 23,
101}
102
103impl DataType {
104    /// All data types, in IANA registry order
105    pub const ALL: [DataType; 24] = [
106        DataType::OctetArray,
107        DataType::Unsigned8,
108        DataType::Unsigned16,
109        DataType::Unsigned32,
110        DataType::Unsigned64,
111        DataType::Signed8,
112        DataType::Signed16,
113        DataType::Signed32,
114        DataType::Signed64,
115        DataType::Float32,
116        DataType::Float64,
117        DataType::Boolean,
118        DataType::MacAddress,
119        DataType::String,
120        DataType::DateTimeSeconds,
121        DataType::DateTimeMilliseconds,
122        DataType::DateTimeMicroseconds,
123        DataType::DateTimeNanoseconds,
124        DataType::Ipv4Address,
125        DataType::Ipv6Address,
126        DataType::BasicList,
127        DataType::SubTemplateList,
128        DataType::SubTemplateMultiList,
129        DataType::Unsigned256,
130    ];
131
132    /// The data type with this IANA registry value
133    pub fn from_value(value: u8) -> Option<DataType> {
134        DataType::ALL.get(value as usize).copied()
135    }
136
137    /// The IANA name of the data type (e.g. `unsigned32`)
138    pub fn name(&self) -> &'static str {
139        match self {
140            DataType::OctetArray => "octetArray",
141            DataType::Unsigned8 => "unsigned8",
142            DataType::Unsigned16 => "unsigned16",
143            DataType::Unsigned32 => "unsigned32",
144            DataType::Unsigned64 => "unsigned64",
145            DataType::Signed8 => "signed8",
146            DataType::Signed16 => "signed16",
147            DataType::Signed32 => "signed32",
148            DataType::Signed64 => "signed64",
149            DataType::Float32 => "float32",
150            DataType::Float64 => "float64",
151            DataType::Boolean => "boolean",
152            DataType::MacAddress => "macAddress",
153            DataType::String => "string",
154            DataType::DateTimeSeconds => "dateTimeSeconds",
155            DataType::DateTimeMilliseconds => "dateTimeMilliseconds",
156            DataType::DateTimeMicroseconds => "dateTimeMicroseconds",
157            DataType::DateTimeNanoseconds => "dateTimeNanoseconds",
158            DataType::Ipv4Address => "ipv4Address",
159            DataType::Ipv6Address => "ipv6Address",
160            DataType::BasicList => "basicList",
161            DataType::SubTemplateList => "subTemplateList",
162            DataType::SubTemplateMultiList => "subTemplateMultiList",
163            DataType::Unsigned256 => "unsigned256",
164        }
165    }
166
167    /// The default (non-reduced) encoded length in octets, or `None` for
168    /// variable-length types
169    pub fn default_length(&self) -> Option<u16> {
170        match self {
171            DataType::Unsigned8 | DataType::Signed8 | DataType::Boolean => Some(1),
172            DataType::Unsigned16 | DataType::Signed16 => Some(2),
173            DataType::Unsigned32
174            | DataType::Signed32
175            | DataType::Float32
176            | DataType::DateTimeSeconds
177            | DataType::Ipv4Address => Some(4),
178            DataType::MacAddress => Some(6),
179            DataType::Unsigned64
180            | DataType::Signed64
181            | DataType::Float64
182            | DataType::DateTimeMilliseconds
183            | DataType::DateTimeMicroseconds
184            | DataType::DateTimeNanoseconds => Some(8),
185            DataType::Ipv6Address => Some(16),
186            DataType::Unsigned256 => Some(32),
187            DataType::OctetArray
188            | DataType::String
189            | DataType::BasicList
190            | DataType::SubTemplateList
191            | DataType::SubTemplateMultiList => None,
192        }
193    }
194}
195
196/// Data type semantics - RFC 7012 Section 3.2
197///
198/// IANA "IPFIX Information Element Semantics" registry. The discriminant is
199/// the IANA registry value.
200#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
201#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
202#[repr(u8)]
203pub enum DataTypeSemantics {
204    Default = 0,
205    Quantity = 1,
206    TotalCounter = 2,
207    DeltaCounter = 3,
208    Identifier = 4,
209    Flags = 5,
210    List = 6,
211    SnmpCounter = 7,
212    SnmpGauge = 8,
213}
214
215impl DataTypeSemantics {
216    /// All semantics, in IANA registry order
217    pub const ALL: [DataTypeSemantics; 9] = [
218        DataTypeSemantics::Default,
219        DataTypeSemantics::Quantity,
220        DataTypeSemantics::TotalCounter,
221        DataTypeSemantics::DeltaCounter,
222        DataTypeSemantics::Identifier,
223        DataTypeSemantics::Flags,
224        DataTypeSemantics::List,
225        DataTypeSemantics::SnmpCounter,
226        DataTypeSemantics::SnmpGauge,
227    ];
228
229    /// The semantics with this IANA registry value
230    pub fn from_value(value: u8) -> Option<DataTypeSemantics> {
231        DataTypeSemantics::ALL.get(value as usize).copied()
232    }
233
234    /// The IANA name of the semantics (e.g. `deltaCounter`)
235    pub fn name(&self) -> &'static str {
236        match self {
237            DataTypeSemantics::Default => "default",
238            DataTypeSemantics::Quantity => "quantity",
239            DataTypeSemantics::TotalCounter => "totalCounter",
240            DataTypeSemantics::DeltaCounter => "deltaCounter",
241            DataTypeSemantics::Identifier => "identifier",
242            DataTypeSemantics::Flags => "flags",
243            DataTypeSemantics::List => "list",
244            DataTypeSemantics::SnmpCounter => "snmpCounter",
245            DataTypeSemantics::SnmpGauge => "snmpGauge",
246        }
247    }
248}
249
250/// Registration status of an Information Element (RFC 7013 Section 5.2)
251#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
252#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
253pub enum Status {
254    Current,
255    Deprecated,
256    Obsolete,
257}
258
259/// An IANA-registered Information Element
260#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
261pub struct InformationElement {
262    /// ElementID
263    pub id: u16,
264    /// Name (e.g. `sourceIPv4Address`)
265    pub name: &'static str,
266    /// Abstract Data Type
267    pub data_type: DataType,
268    /// Data Type Semantics, if specified
269    pub semantics: Option<DataTypeSemantics>,
270    /// Status
271    pub status: Status,
272    /// Units, if specified
273    pub units: Option<&'static str>,
274}
275
276/// Look up an IANA Information Element by identifier
277pub fn lookup(id: u16) -> Option<&'static InformationElement> {
278    INFORMATION_ELEMENTS
279        .binary_search_by_key(&id, |ie| ie.id)
280        .ok()
281        .map(|idx| &INFORMATION_ELEMENTS[idx])
282}
283
284/// Look up an IANA Information Element by name
285pub fn lookup_by_name(name: &str) -> Option<&'static InformationElement> {
286    INFORMATION_ELEMENTS.iter().find(|ie| ie.name == name)
287}