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/// IPFIX abstract data type - RFC 7012 Section 3.1
30///
31/// IANA "IPFIX Information Element Data Types" registry. The discriminant is
32/// the IANA registry value.
33#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
34#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
35#[repr(u8)]
36pub enum DataType {
37    OctetArray = 0,
38    Unsigned8 = 1,
39    Unsigned16 = 2,
40    Unsigned32 = 3,
41    Unsigned64 = 4,
42    Signed8 = 5,
43    Signed16 = 6,
44    Signed32 = 7,
45    Signed64 = 8,
46    Float32 = 9,
47    Float64 = 10,
48    Boolean = 11,
49    MacAddress = 12,
50    String = 13,
51    DateTimeSeconds = 14,
52    DateTimeMilliseconds = 15,
53    DateTimeMicroseconds = 16,
54    DateTimeNanoseconds = 17,
55    Ipv4Address = 18,
56    Ipv6Address = 19,
57    BasicList = 20,
58    SubTemplateList = 21,
59    SubTemplateMultiList = 22,
60    Unsigned256 = 23,
61}
62
63impl DataType {
64    /// All data types, in IANA registry order
65    pub const ALL: [DataType; 24] = [
66        DataType::OctetArray,
67        DataType::Unsigned8,
68        DataType::Unsigned16,
69        DataType::Unsigned32,
70        DataType::Unsigned64,
71        DataType::Signed8,
72        DataType::Signed16,
73        DataType::Signed32,
74        DataType::Signed64,
75        DataType::Float32,
76        DataType::Float64,
77        DataType::Boolean,
78        DataType::MacAddress,
79        DataType::String,
80        DataType::DateTimeSeconds,
81        DataType::DateTimeMilliseconds,
82        DataType::DateTimeMicroseconds,
83        DataType::DateTimeNanoseconds,
84        DataType::Ipv4Address,
85        DataType::Ipv6Address,
86        DataType::BasicList,
87        DataType::SubTemplateList,
88        DataType::SubTemplateMultiList,
89        DataType::Unsigned256,
90    ];
91
92    /// The IANA name of the data type (e.g. `unsigned32`)
93    pub fn name(&self) -> &'static str {
94        match self {
95            DataType::OctetArray => "octetArray",
96            DataType::Unsigned8 => "unsigned8",
97            DataType::Unsigned16 => "unsigned16",
98            DataType::Unsigned32 => "unsigned32",
99            DataType::Unsigned64 => "unsigned64",
100            DataType::Signed8 => "signed8",
101            DataType::Signed16 => "signed16",
102            DataType::Signed32 => "signed32",
103            DataType::Signed64 => "signed64",
104            DataType::Float32 => "float32",
105            DataType::Float64 => "float64",
106            DataType::Boolean => "boolean",
107            DataType::MacAddress => "macAddress",
108            DataType::String => "string",
109            DataType::DateTimeSeconds => "dateTimeSeconds",
110            DataType::DateTimeMilliseconds => "dateTimeMilliseconds",
111            DataType::DateTimeMicroseconds => "dateTimeMicroseconds",
112            DataType::DateTimeNanoseconds => "dateTimeNanoseconds",
113            DataType::Ipv4Address => "ipv4Address",
114            DataType::Ipv6Address => "ipv6Address",
115            DataType::BasicList => "basicList",
116            DataType::SubTemplateList => "subTemplateList",
117            DataType::SubTemplateMultiList => "subTemplateMultiList",
118            DataType::Unsigned256 => "unsigned256",
119        }
120    }
121
122    /// The default (non-reduced) encoded length in octets, or `None` for
123    /// variable-length types
124    pub fn default_length(&self) -> Option<u16> {
125        match self {
126            DataType::Unsigned8 | DataType::Signed8 | DataType::Boolean => Some(1),
127            DataType::Unsigned16 | DataType::Signed16 => Some(2),
128            DataType::Unsigned32
129            | DataType::Signed32
130            | DataType::Float32
131            | DataType::DateTimeSeconds
132            | DataType::Ipv4Address => Some(4),
133            DataType::MacAddress => Some(6),
134            DataType::Unsigned64
135            | DataType::Signed64
136            | DataType::Float64
137            | DataType::DateTimeMilliseconds
138            | DataType::DateTimeMicroseconds
139            | DataType::DateTimeNanoseconds => Some(8),
140            DataType::Ipv6Address => Some(16),
141            DataType::Unsigned256 => Some(32),
142            DataType::OctetArray
143            | DataType::String
144            | DataType::BasicList
145            | DataType::SubTemplateList
146            | DataType::SubTemplateMultiList => None,
147        }
148    }
149}
150
151/// Data type semantics - RFC 7012 Section 3.2
152///
153/// IANA "IPFIX Information Element Semantics" registry. The discriminant is
154/// the IANA registry value.
155#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
156#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
157#[repr(u8)]
158pub enum DataTypeSemantics {
159    Default = 0,
160    Quantity = 1,
161    TotalCounter = 2,
162    DeltaCounter = 3,
163    Identifier = 4,
164    Flags = 5,
165    List = 6,
166    SnmpCounter = 7,
167    SnmpGauge = 8,
168}
169
170impl DataTypeSemantics {
171    /// All semantics, in IANA registry order
172    pub const ALL: [DataTypeSemantics; 9] = [
173        DataTypeSemantics::Default,
174        DataTypeSemantics::Quantity,
175        DataTypeSemantics::TotalCounter,
176        DataTypeSemantics::DeltaCounter,
177        DataTypeSemantics::Identifier,
178        DataTypeSemantics::Flags,
179        DataTypeSemantics::List,
180        DataTypeSemantics::SnmpCounter,
181        DataTypeSemantics::SnmpGauge,
182    ];
183
184    /// The IANA name of the semantics (e.g. `deltaCounter`)
185    pub fn name(&self) -> &'static str {
186        match self {
187            DataTypeSemantics::Default => "default",
188            DataTypeSemantics::Quantity => "quantity",
189            DataTypeSemantics::TotalCounter => "totalCounter",
190            DataTypeSemantics::DeltaCounter => "deltaCounter",
191            DataTypeSemantics::Identifier => "identifier",
192            DataTypeSemantics::Flags => "flags",
193            DataTypeSemantics::List => "list",
194            DataTypeSemantics::SnmpCounter => "snmpCounter",
195            DataTypeSemantics::SnmpGauge => "snmpGauge",
196        }
197    }
198}
199
200/// Registration status of an Information Element (RFC 7013 Section 5.2)
201#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
202#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
203pub enum Status {
204    Current,
205    Deprecated,
206    Obsolete,
207}
208
209/// An IANA-registered Information Element
210#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
211pub struct InformationElement {
212    /// ElementID
213    pub id: u16,
214    /// Name (e.g. `sourceIPv4Address`)
215    pub name: &'static str,
216    /// Abstract Data Type
217    pub data_type: DataType,
218    /// Data Type Semantics, if specified
219    pub semantics: Option<DataTypeSemantics>,
220    /// Status
221    pub status: Status,
222    /// Units, if specified
223    pub units: Option<&'static str>,
224}
225
226/// Look up an IANA Information Element by identifier
227pub fn lookup(id: u16) -> Option<&'static InformationElement> {
228    INFORMATION_ELEMENTS
229        .binary_search_by_key(&id, |ie| ie.id)
230        .ok()
231        .map(|idx| &INFORMATION_ELEMENTS[idx])
232}
233
234/// Look up an IANA Information Element by name
235pub fn lookup_by_name(name: &str) -> Option<&'static InformationElement> {
236    INFORMATION_ELEMENTS.iter().find(|ie| ie.name == name)
237}