Coverage Report

Created: 2026-09-28 07:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/ipsec-parser-0.7.0/src/ikev2.rs
Line
Count
Source
1
use crate::ikev2_notify::NotifyType;
2
use crate::ikev2_transforms::*;
3
use rusticata_macros::newtype_enum;
4
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
5
6
/// Payload exchange type: SA, Auth, CreateChildSA, etc.
7
#[derive(Copy, Clone, PartialEq, Eq)]
8
pub struct IkeExchangeType(pub u8);
9
10
newtype_enum! {
11
impl debug IkeExchangeType {
12
    IKE_SA_INIT     = 34,
13
    IKE_AUTH        = 35,
14
    CREATE_CHILD_SA = 36,
15
    INFORMATIONAL   = 37,
16
}
17
}
18
19
/// Protocol type: IKE, AH or ESP
20
///
21
/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.3.1
22
#[derive(Clone, Copy, PartialEq, Eq)]
23
pub struct ProtocolID(pub u8);
24
25
newtype_enum! {
26
impl debug ProtocolID {
27
    IKE = 1,
28
    AH  = 2,
29
    ESP = 3,
30
}
31
}
32
33
pub const IKEV2_FLAG_INITIATOR: u8 = 0b1000;
34
pub const IKEV2_FLAG_VERSION: u8 = 0b1_0000;
35
pub const IKEV2_FLAG_RESPONSE: u8 = 0b10_0000;
36
37
/// The IKE Header
38
///
39
/// IKE messages use UDP ports 500 and/or 4500, with one IKE message per
40
/// UDP datagram.  Information from the beginning of the packet through
41
/// the UDP header is largely ignored except that the IP addresses and
42
/// UDP ports from the headers are reversed and used for return packets.
43
/// When sent on UDP port 500, IKE messages begin immediately following
44
/// the UDP header.  When sent on UDP port 4500, IKE messages have
45
/// prepended four octets of zeros.  These four octets of zeros are not
46
/// part of the IKE message and are not included in any of the length
47
/// fields or checksums defined by IKE.  Each IKE message begins with the
48
/// IKE header, denoted HDR in this document.  Following the header are
49
/// one or more IKE payloads each identified by a Next Payload field in
50
/// the preceding payload.  Payloads are identified in the order in which
51
/// they appear in an IKE message by looking in the Next Payload field in
52
/// the IKE header, and subsequently according to the Next Payload field
53
/// in the IKE payload itself until a Next Payload field of zero
54
/// indicates that no payloads follow.  If a payload of type "Encrypted"
55
/// is found, that payload is decrypted and its contents parsed as
56
/// additional payloads.  An Encrypted payload MUST be the last payload
57
/// in a packet and an Encrypted payload MUST NOT contain another
58
/// Encrypted payload.
59
///
60
/// The responder's SPI in the header identifies an instance of an IKE
61
/// Security Association.  It is therefore possible for a single instance
62
/// of IKE to multiplex distinct sessions with multiple peers, including
63
/// multiple sessions per peer.
64
///
65
/// All multi-octet fields representing integers are laid out in big
66
/// endian order (also known as "most significant byte first", or
67
/// "network byte order").
68
///
69
/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.1
70
#[derive(Clone, Debug, PartialEq)]
71
pub struct IkeV2Header {
72
    pub init_spi: u64,
73
    pub resp_spi: u64,
74
    pub next_payload: IkePayloadType,
75
    pub maj_ver: u8,
76
    pub min_ver: u8,
77
    pub exch_type: IkeExchangeType,
78
    pub flags: u8,
79
    pub msg_id: u32,
80
    pub length: u32,
81
}
82
83
/// Payload type
84
#[derive(Clone, Copy, PartialEq, Eq)]
85
pub struct IkePayloadType(pub u8);
86
87
newtype_enum! {
88
impl debug IkePayloadType {
89
    NoNextPayload             = 0,
90
    SecurityAssociation       = 33,
91
    KeyExchange               = 34,
92
    IdentInitiator            = 35,
93
    IdentResponder            = 36,
94
    Certificate               = 37,
95
    CertificateRequest        = 38,
96
    Authentication            = 39,
97
    Nonce                     = 40,
98
    Notify                    = 41,
99
    Delete                    = 42,
100
    VendorID                  = 43,
101
    TrafficSelectorInitiator  = 44,
102
    TrafficSelectorResponder  = 45,
103
    EncryptedAndAuthenticated = 46,
104
    Configuration             = 47,
105
    ExtensibleAuthentication  = 48,
106
}
107
}
108
109
/// Generic (unparsed payload)
110
///
111
/// Defined in [RFC7296]
112
#[derive(Debug, PartialEq)]
113
pub struct IkeV2GenericPayload<'a> {
114
    pub hdr: IkeV2PayloadHeader,
115
    pub payload: &'a [u8],
116
}
117
118
/// Ciphersuite Proposal
119
///
120
/// The Proposal structure contains within it a Proposal Num and an IPsec
121
/// protocol ID.  Each structure MUST have a proposal number one (1)
122
/// greater than the previous structure.  The first Proposal in the
123
/// initiator's SA payload MUST have a Proposal Num of one (1).  One
124
/// reason to use multiple proposals is to propose both standard crypto
125
/// ciphers and combined-mode ciphers.  Combined-mode ciphers include
126
/// both integrity and encryption in a single encryption algorithm, and
127
/// MUST either offer no integrity algorithm or a single integrity
128
/// algorithm of "NONE", with no integrity algorithm being the
129
/// RECOMMENDED method.  If an initiator wants to propose both combined-
130
/// mode ciphers and normal ciphers, it must include two proposals: one
131
/// will have all the combined-mode ciphers, and the other will have all
132
/// the normal ciphers with the integrity algorithms.  For example, one
133
/// such proposal would have two proposal structures.  Proposal 1 is ESP
134
/// with AES-128, AES-192, and AES-256 bits in Cipher Block Chaining
135
/// (CBC) mode, with either HMAC-SHA1-96 or XCBC-96 as the integrity
136
/// algorithm; Proposal 2 is AES-128 or AES-256 in GCM mode with an
137
/// 8-octet Integrity Check Value (ICV).  Both proposals allow but do not
138
/// require the use of ESNs (Extended Sequence Numbers).  This can be
139
/// illustrated as:
140
///
141
/// ```ignore
142
/// SA Payload
143
///    |
144
///    +--- Proposal #1 ( Proto ID = ESP(3), SPI size = 4,
145
///    |     |            7 transforms,      SPI = 0x052357bb )
146
///    |     |
147
///    |     +-- Transform ENCR ( Name = ENCR_AES_CBC )
148
///    |     |     +-- Attribute ( Key Length = 128 )
149
///    |     |
150
///    |     +-- Transform ENCR ( Name = ENCR_AES_CBC )
151
///    |     |     +-- Attribute ( Key Length = 192 )
152
///    |     |
153
///    |     +-- Transform ENCR ( Name = ENCR_AES_CBC )
154
///    |     |     +-- Attribute ( Key Length = 256 )
155
///    |     |
156
///    |     +-- Transform INTEG ( Name = AUTH_HMAC_SHA1_96 )
157
///    |     +-- Transform INTEG ( Name = AUTH_AES_XCBC_96 )
158
///    |     +-- Transform ESN ( Name = ESNs )
159
///    |     +-- Transform ESN ( Name = No ESNs )
160
///    |
161
///    +--- Proposal #2 ( Proto ID = ESP(3), SPI size = 4,
162
///          |            4 transforms,      SPI = 0x35a1d6f2 )
163
///          |
164
///          +-- Transform ENCR ( Name = AES-GCM with a 8 octet ICV )
165
///          |     +-- Attribute ( Key Length = 128 )
166
///          |
167
///          +-- Transform ENCR ( Name = AES-GCM with a 8 octet ICV )
168
///          |     +-- Attribute ( Key Length = 256 )
169
///          |
170
///          +-- Transform ESN ( Name = ESNs )
171
///          +-- Transform ESN ( Name = No ESNs )
172
/// ```
173
///
174
/// Each Proposal/Protocol structure is followed by one or more transform
175
/// structures.  The number of different transforms is generally
176
/// determined by the Protocol.  AH generally has two transforms:
177
/// Extended Sequence Numbers (ESNs) and an integrity check algorithm.
178
/// ESP generally has three: ESN, an encryption algorithm, and an
179
/// integrity check algorithm.  IKE generally has four transforms: a
180
/// Diffie-Hellman group, an integrity check algorithm, a PRF algorithm,
181
/// and an encryption algorithm.  For each Protocol, the set of
182
/// permissible transforms is assigned Transform ID numbers, which appear
183
/// in the header of each transform.
184
///
185
/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.3.1
186
#[derive(Clone, Debug, PartialEq)]
187
pub struct IkeV2Proposal<'a> {
188
    pub last: u8,
189
    pub reserved: u8,
190
    pub proposal_length: u16,
191
    pub proposal_num: u8,
192
    pub protocol_id: ProtocolID,
193
    pub spi_size: u8,
194
    pub num_transforms: u8,
195
    pub spi: Option<&'a [u8]>,
196
    pub transforms: Vec<IkeV2RawTransform<'a>>,
197
}
198
199
/// Key Exchange Payload
200
///
201
/// The Key Exchange payload, denoted KE in this document, is used to
202
/// exchange Diffie-Hellman public numbers as part of a Diffie-Hellman
203
/// key exchange.  The Key Exchange payload consists of the IKE generic
204
/// payload header followed by the Diffie-Hellman public value itself.
205
///
206
/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.4
207
#[derive(Debug, PartialEq)]
208
pub struct KeyExchangePayload<'a> {
209
    pub dh_group: IkeTransformDHType,
210
    pub reserved: u16,
211
    pub kex_data: &'a [u8],
212
}
213
214
/// Identification Payloads
215
///
216
/// The Identification payloads, denoted IDi and IDr in this document,
217
/// allow peers to assert an identity to one another.  This identity may
218
/// be used for policy lookup, but does not necessarily have to match
219
/// anything in the CERT payload; both fields may be used by an
220
/// implementation to perform access control decisions.  When using the
221
/// ID_IPV4_ADDR/ID_IPV6_ADDR identity types in IDi/IDr payloads, IKEv2
222
/// does not require this address to match the address in the IP header
223
/// of IKEv2 packets, or anything in the TSi/TSr payloads.  The contents
224
/// of IDi/IDr are used purely to fetch the policy and authentication
225
/// data related to the other party.
226
///
227
/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.5
228
#[derive(Debug, PartialEq)]
229
pub struct IdentificationPayload<'a> {
230
    pub id_type: IdentificationType,
231
    pub reserved1: u8,
232
    pub reserved2: u16,
233
    pub ident_data: &'a [u8],
234
}
235
236
/// Type of Identification
237
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
238
pub struct IdentificationType(pub u8);
239
240
#[rustfmt::skip]
241
impl IdentificationType {
242
    /// A single four (4) octet IPv4 address.
243
    pub const ID_IPV4_ADDR   : IdentificationType = IdentificationType(1);
244
    /// A fully-qualified domain name string.  An example of an ID_FQDN
245
    /// is "example.com".  The string MUST NOT contain any terminators
246
    /// (e.g., NULL, CR, etc.).  All characters in the ID_FQDN are ASCII;
247
    /// for an "internationalized domain name", the syntax is as defined
248
    /// in [IDNA], for example "xn--tmonesimerkki-bfbb.example.net".
249
    pub const ID_FQDN        : IdentificationType = IdentificationType(2);
250
    /// A fully-qualified RFC 822 email address string.  An example of a
251
    /// ID_RFC822_ADDR is "jsmith@example.com".  The string MUST NOT
252
    /// contain any terminators.  Because of [EAI], implementations would
253
    /// be wise to treat this field as UTF-8 encoded text, not as
254
    /// pure ASCII.
255
    pub const ID_RFC822_ADDR : IdentificationType = IdentificationType(3);
256
    /// A single sixteen (16) octet IPv6 address.
257
    pub const ID_IPV6_ADDR   : IdentificationType = IdentificationType(5);
258
    /// The binary Distinguished Encoding Rules (DER) encoding of an ASN.1 X.500 Distinguished
259
    /// Name.
260
    pub const ID_DER_ASN1_DN : IdentificationType = IdentificationType(9);
261
    /// The binary DER encoding of an ASN.1 X.509 GeneralName.
262
    pub const ID_DER_ASN1_GN : IdentificationType = IdentificationType(10);
263
    /// An opaque octet stream that may be used to pass vendor-specific information necessary to do
264
    /// certain proprietary types of identification.
265
    pub const ID_KEY_ID      : IdentificationType = IdentificationType(11);
266
}
267
268
/// Certificate Payload
269
///
270
/// The Certificate payload, denoted CERT in this document, provides a
271
/// means to transport certificates or other authentication-related
272
/// information via IKE.  Certificate payloads SHOULD be included in an
273
/// exchange if certificates are available to the sender.  The Hash and
274
/// URL formats of the Certificate payloads should be used in case the
275
/// peer has indicated an ability to retrieve this information from
276
/// elsewhere using an HTTP_CERT_LOOKUP_SUPPORTED Notify payload.  Note
277
/// that the term "Certificate payload" is somewhat misleading, because
278
/// not all authentication mechanisms use certificates and data other
279
/// than certificates may be passed in this payload.
280
///
281
/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.6
282
#[derive(Debug, PartialEq)]
283
pub struct CertificatePayload<'a> {
284
    pub cert_encoding: CertificateEncoding,
285
    pub cert_data: &'a [u8],
286
}
287
288
/// Certificate Encoding
289
///
290
/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.6
291
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
292
pub struct CertificateEncoding(pub u8);
293
294
#[allow(non_upper_case_globals)]
295
#[rustfmt::skip]
296
impl CertificateEncoding {
297
    /// PKCS #7 wrapped X.509 certificate
298
    pub const Pkcs7_X509                  : CertificateEncoding = CertificateEncoding(1);
299
    /// PGP Certificate
300
    pub const PgpCert                     : CertificateEncoding = CertificateEncoding(2);
301
    /// DNS Signed Key
302
    pub const DnsKey                      : CertificateEncoding = CertificateEncoding(3);
303
    /// X.509 Certificate - Signature
304
    pub const X509Sig                     : CertificateEncoding = CertificateEncoding(4);
305
    /// Kerberos Token
306
    pub const Kerberos                    : CertificateEncoding = CertificateEncoding(6);
307
    /// Certificate Revocation List (CRL)
308
    pub const Crl                         : CertificateEncoding = CertificateEncoding(7);
309
    /// Authority Revocation List (ARL)
310
    pub const Arl                         : CertificateEncoding = CertificateEncoding(8);
311
    /// SPKI Certificate
312
    pub const SpkiCert                    : CertificateEncoding = CertificateEncoding(9);
313
    /// X.509 Certificate - Attribute
314
    pub const X509CertAttr                : CertificateEncoding = CertificateEncoding(10);
315
    /// Deprecated (was Raw RSA Key)
316
    pub const OldRsaKey                   : CertificateEncoding = CertificateEncoding(11);
317
    /// Hash and URL of X.509 certificate
318
    pub const X509Cert_HashUrl            : CertificateEncoding = CertificateEncoding(12);
319
    /// Hash and URL of X.509 bundle
320
    pub const X509Bundle_HashUrl          : CertificateEncoding = CertificateEncoding(13);
321
    /// OCSP Content ([RFC4806](https://tools.ietf.org/html/rfc4806))
322
    pub const OCSPContent                 : CertificateEncoding = CertificateEncoding(14);
323
    /// Raw Public Key ([RFC7670](https://tools.ietf.org/html/rfc7670))
324
    pub const RawPublicKey                : CertificateEncoding = CertificateEncoding(15);
325
}
326
327
/// Certificate Request Payload
328
///
329
/// The Certificate Request payload, denoted CERTREQ in this document,
330
/// provides a means to request preferred certificates via IKE and can
331
/// appear in the IKE_INIT_SA response and/or the IKE_AUTH request.
332
/// Certificate Request payloads MAY be included in an exchange when the
333
/// sender needs to get the certificate of the receiver.
334
///
335
/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.7
336
#[derive(Debug, PartialEq)]
337
pub struct CertificateRequestPayload<'a> {
338
    pub cert_encoding: CertificateEncoding,
339
    pub ca_data: &'a [u8],
340
}
341
342
/// Authentication Payload
343
///
344
/// The Authentication payload, denoted AUTH in this document, contains
345
/// data used for authentication purposes.
346
///
347
/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.8
348
#[derive(Debug, PartialEq)]
349
pub struct AuthenticationPayload<'a> {
350
    pub auth_method: AuthenticationMethod,
351
    pub auth_data: &'a [u8],
352
}
353
354
/// Method of authentication used.
355
///
356
/// See also [IKEV2IANA](https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml) for the latest values.
357
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
358
pub struct AuthenticationMethod(pub u8);
359
360
#[allow(non_upper_case_globals)]
361
#[rustfmt::skip]
362
impl AuthenticationMethod {
363
    /// RSA Digital Signature
364
    pub const RsaSig          : AuthenticationMethod = AuthenticationMethod(1);
365
    /// Shared Key Message Integrity Code
366
    pub const SharedKeyMIC    : AuthenticationMethod = AuthenticationMethod(2);
367
    /// DSS Digital Signature
368
    pub const DssSig          : AuthenticationMethod = AuthenticationMethod(3);
369
    /// ECDSA with SHA-256 on the P-256 curve
370
    pub const EcdsaSha256P256 : AuthenticationMethod = AuthenticationMethod(9);
371
    /// ECDSA with SHA-384 on the P-384 curve
372
    pub const EcdsaSha384P384 : AuthenticationMethod = AuthenticationMethod(10);
373
    /// ECDSA with SHA-512 on the P-512 curve
374
    pub const EcdsaSha512P512 : AuthenticationMethod = AuthenticationMethod(11);
375
    /// Generic Secure Password Authentication Method
376
    pub const GenericPass     : AuthenticationMethod = AuthenticationMethod(12);
377
    /// NULL Authentication
378
    pub const Null            : AuthenticationMethod = AuthenticationMethod(13);
379
    /// Digital Signature
380
    pub const DigitalSig      : AuthenticationMethod = AuthenticationMethod(14);
381
382
    /// Test if value is in unassigned range
383
0
    pub fn is_unassigned(self) -> bool {
384
0
        (self.0 >= 4 && self.0 <= 8) ||
385
0
        (self.0 >= 15 && self.0 <= 200)
386
0
    }
Unexecuted instantiation: <ipsec_parser::ikev2::AuthenticationMethod>::is_unassigned
Unexecuted instantiation: <ipsec_parser::ikev2::AuthenticationMethod>::is_unassigned
387
388
    /// Test if value is in private use range
389
0
    pub fn is_private_use(self) -> bool {
390
0
        self.0 >= 201
391
0
    }
Unexecuted instantiation: <ipsec_parser::ikev2::AuthenticationMethod>::is_private_use
Unexecuted instantiation: <ipsec_parser::ikev2::AuthenticationMethod>::is_private_use
392
}
393
394
/// Nonce Payload
395
///
396
/// The Nonce payload, denoted as Ni and Nr in this document for the
397
/// initiator's and responder's nonce, respectively, contains random data used to guarantee
398
/// liveness during an exchange and protect against replay attacks.
399
///
400
/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.9
401
#[derive(PartialEq)]
402
pub struct NoncePayload<'a> {
403
    pub nonce_data: &'a [u8],
404
}
405
406
/// Notify Payload
407
///
408
/// The Notify payload, denoted N in this document, is used to transmit informational data, such as
409
/// error conditions and state transitions, to an IKE peer.  A Notify payload may appear in a
410
/// response message (usually specifying why a request was rejected), in an INFORMATIONAL exchange
411
/// (to report an error not in an IKE request), or in any other message to indicate sender
412
/// capabilities or to modify the meaning of the request.
413
///
414
/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.10
415
#[derive(PartialEq)]
416
pub struct NotifyPayload<'a> {
417
    pub protocol_id: ProtocolID,
418
    pub spi_size: u8,
419
    pub notify_type: NotifyType,
420
    pub spi: Option<&'a [u8]>,
421
    pub notify_data: Option<&'a [u8]>,
422
}
423
424
/// Delete Payload
425
///
426
/// The Delete payload, denoted D in this document, contains a
427
/// protocol-specific Security Association identifier that the sender has
428
/// removed from its Security Association database and is, therefore, no
429
/// longer valid.  Figure 17 shows the format of the Delete payload.  It
430
/// is possible to send multiple SPIs in a Delete payload; however, each
431
/// SPI MUST be for the same protocol.  Mixing of protocol identifiers
432
/// MUST NOT be performed in the Delete payload.  It is permitted,
433
/// however, to include multiple Delete payloads in a single
434
/// INFORMATIONAL exchange where each Delete payload lists SPIs for a
435
/// different protocol.
436
///
437
/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.11
438
#[derive(Debug, PartialEq)]
439
pub struct DeletePayload<'a> {
440
    pub protocol_id: ProtocolID,
441
    pub spi_size: u8,
442
    pub num_spi: u16,
443
    pub spi: &'a [u8],
444
}
445
446
/// Vendor ID Payload
447
///
448
/// The Vendor ID payload, denoted V in this document, contains a vendor-
449
/// defined constant.  The constant is used by vendors to identify and
450
/// recognize remote instances of their implementations.  This mechanism
451
/// allows a vendor to experiment with new features while maintaining
452
/// backward compatibility.
453
///
454
/// A Vendor ID payload MAY announce that the sender is capable of
455
/// accepting certain extensions to the protocol, or it MAY simply
456
/// identify the implementation as an aid in debugging.  A Vendor ID
457
/// payload MUST NOT change the interpretation of any information defined
458
/// in this specification (i.e., the critical bit MUST be set to 0).
459
/// Multiple Vendor ID payloads MAY be sent.  An implementation is not
460
/// required to send any Vendor ID payload at all.
461
///
462
/// A Vendor ID payload may be sent as part of any message.  Reception of
463
/// a familiar Vendor ID payload allows an implementation to make use of
464
/// private use numbers described throughout this document, such as
465
/// private payloads, private exchanges, private notifications, etc.
466
/// Unfamiliar Vendor IDs MUST be ignored.
467
///
468
/// Writers of documents who wish to extend this protocol MUST define a
469
/// Vendor ID payload to announce the ability to implement the extension
470
/// in the document.  It is expected that documents that gain acceptance
471
/// and are standardized will be given "magic numbers" out of the Future
472
/// Use range by IANA, and the requirement to use a Vendor ID will go
473
/// away.
474
///
475
/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.12
476
#[derive(Debug, PartialEq)]
477
pub struct VendorIDPayload<'a> {
478
    pub vendor_id: &'a [u8],
479
}
480
481
/// Type of Traffic Selector
482
///
483
/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.13.1
484
///
485
/// See also [IKEV2IANA](https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml) for the latest values.
486
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
487
pub struct TSType(pub u8);
488
489
#[allow(non_upper_case_globals)]
490
impl TSType {
491
    /// A range of IPv4 addresses
492
    pub const IPv4AddrRange: TSType = TSType(7);
493
    /// A range of IPv6 addresses
494
    pub const IPv6AddrRange: TSType = TSType(8);
495
    /// Fibre Channel Traffic Selectors ([RFC4595](https://tools.ietf.org/html/rfc4595))
496
    pub const FcAddrRange: TSType = TSType(9);
497
}
498
499
/// Traffic Selector
500
///
501
/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.13.1
502
#[derive(Debug, PartialEq)]
503
pub struct TrafficSelector<'a> {
504
    pub ts_type: TSType,
505
    pub ip_proto_id: u8,
506
    pub sel_length: u16,
507
    pub start_port: u16,
508
    pub end_port: u16,
509
    pub start_addr: &'a [u8],
510
    pub end_addr: &'a [u8],
511
}
512
513
0
fn ipv4_from_slice(b: &[u8]) -> Ipv4Addr {
514
0
    Ipv4Addr::new(b[0], b[1], b[2], b[3])
515
0
}
Unexecuted instantiation: ipsec_parser::ikev2::ipv4_from_slice
Unexecuted instantiation: ipsec_parser::ikev2::ipv4_from_slice
516
517
0
fn ipv6_from_slice(b: &[u8]) -> Ipv6Addr {
518
0
    Ipv6Addr::new(
519
0
        (b[0] as u16) << 8 | (b[1] as u16),
520
0
        (b[2] as u16) << 8 | (b[3] as u16),
521
0
        (b[4] as u16) << 8 | (b[5] as u16),
522
0
        (b[6] as u16) << 8 | (b[7] as u16),
523
0
        (b[8] as u16) << 8 | (b[9] as u16),
524
0
        (b[10] as u16) << 8 | (b[11] as u16),
525
0
        (b[12] as u16) << 8 | (b[13] as u16),
526
0
        (b[14] as u16) << 8 | (b[15] as u16),
527
    )
528
0
}
Unexecuted instantiation: ipsec_parser::ikev2::ipv6_from_slice
Unexecuted instantiation: ipsec_parser::ikev2::ipv6_from_slice
529
530
impl<'a> TrafficSelector<'a> {
531
0
    pub fn get_ts_type(&self) -> TSType {
532
0
        self.ts_type
533
0
    }
Unexecuted instantiation: <ipsec_parser::ikev2::TrafficSelector>::get_ts_type
Unexecuted instantiation: <ipsec_parser::ikev2::TrafficSelector>::get_ts_type
534
535
0
    pub fn get_start_addr(&self) -> Option<IpAddr> {
536
0
        match self.ts_type {
537
0
            TSType::IPv4AddrRange => Some(IpAddr::V4(ipv4_from_slice(self.start_addr))),
538
0
            TSType::IPv6AddrRange => Some(IpAddr::V6(ipv6_from_slice(self.start_addr))),
539
0
            _ => None,
540
        }
541
0
    }
Unexecuted instantiation: <ipsec_parser::ikev2::TrafficSelector>::get_start_addr
Unexecuted instantiation: <ipsec_parser::ikev2::TrafficSelector>::get_start_addr
542
543
0
    pub fn get_end_addr(&self) -> Option<IpAddr> {
544
0
        match self.ts_type {
545
0
            TSType::IPv4AddrRange => Some(IpAddr::V4(ipv4_from_slice(self.end_addr))),
546
0
            TSType::IPv6AddrRange => Some(IpAddr::V6(ipv6_from_slice(self.end_addr))),
547
0
            _ => None,
548
        }
549
0
    }
Unexecuted instantiation: <ipsec_parser::ikev2::TrafficSelector>::get_end_addr
Unexecuted instantiation: <ipsec_parser::ikev2::TrafficSelector>::get_end_addr
550
}
551
552
/// Traffic Selector Payload
553
///
554
/// The Traffic Selector payload, denoted TS in this document, allows
555
/// peers to identify packet flows for processing by IPsec security
556
/// services.  The Traffic Selector payload consists of the IKE generic
557
/// payload header followed by individual Traffic Selectors.
558
///
559
/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.13
560
#[derive(Debug, PartialEq)]
561
pub struct TrafficSelectorPayload<'a> {
562
    pub num_ts: u8,
563
    pub reserved: &'a [u8], // 3 bytes
564
    pub ts: Vec<TrafficSelector<'a>>,
565
}
566
567
/// Encrypted Payload
568
///
569
/// The Encrypted payload, denoted SK {...} in this document, contains
570
/// other payloads in encrypted form.  The Encrypted payload, if present
571
/// in a message, MUST be the last payload in the message.  Often, it is
572
/// the only payload in the message.  This payload is also called the
573
/// "Encrypted and Authenticated" payload.
574
#[derive(Debug, PartialEq)]
575
pub struct EncryptedPayload<'a>(pub &'a [u8]);
576
577
/// IKE Message Payload Content
578
///
579
/// The content of an IKE message is one of the defined payloads.
580
///
581
/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.2
582
#[derive(Debug, PartialEq)]
583
pub enum IkeV2PayloadContent<'a> {
584
    SA(Vec<IkeV2Proposal<'a>>),
585
    KE(KeyExchangePayload<'a>),
586
    IDi(IdentificationPayload<'a>),
587
    IDr(IdentificationPayload<'a>),
588
    Certificate(CertificatePayload<'a>),
589
    CertificateRequest(CertificateRequestPayload<'a>),
590
    Authentication(AuthenticationPayload<'a>),
591
    Nonce(NoncePayload<'a>),
592
    Notify(NotifyPayload<'a>),
593
    Delete(DeletePayload<'a>),
594
    VendorID(VendorIDPayload<'a>),
595
    TSi(TrafficSelectorPayload<'a>),
596
    TSr(TrafficSelectorPayload<'a>),
597
    Encrypted(EncryptedPayload<'a>),
598
599
    Unknown(&'a [u8]),
600
601
    Dummy,
602
}
603
604
/// Generic Payload Header
605
///
606
/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.2
607
#[derive(Clone, Debug, PartialEq)]
608
pub struct IkeV2PayloadHeader {
609
    pub next_payload_type: IkePayloadType,
610
    pub critical: bool,
611
    pub reserved: u8,
612
    pub payload_length: u16,
613
}
614
615
/// IKE Message Payload
616
///
617
/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3
618
#[derive(Debug, PartialEq)]
619
pub struct IkeV2Payload<'a> {
620
    pub hdr: IkeV2PayloadHeader,
621
    pub content: IkeV2PayloadContent<'a>,
622
}