someip_parse/
lib.rs

1//! A Rust library for parsing the SOME/IP network protocol (without payload interpretation).
2//!
3//! # Usage
4//!
5//! Add the following to your `Cargo.toml`:
6//!
7//! ```toml
8//! [dependencies]
9//! someip_parse = "0.6.1"
10//! ```
11//!
12//! # Example
13//! [examples/print_messages.rs](https://github.com/JulianSchmid/someip-parse-rs/blob/0.2.0/examples/print_messages.rs):
14//! ```
15//! # let mut udp_payload = Vec::<u8>::new();
16//! # {
17//! #     use someip_parse::*;
18//! #     let header = SomeIpHeader{
19//! #         message_id: 0x1234_8234,
20//! #         length: SOMEIP_LEN_OFFSET_TO_PAYLOAD + 4,
21//! #         request_id: 1,
22//! #         interface_version: 1,
23//! #         message_type: MessageType::Notification,
24//! #         return_code: ReturnCode::Ok.into(),
25//! #         tp_header: None
26//! #     };/*
27//! #     header.write_raw(&mut udp_payload).unwrap();
28//! #     udp_payload.extend_from_slice(&[1,2,3,4]);*/
29//! # }
30//! use someip_parse::SomeipMsgsIterator;
31//!
32//! //trying parsing some ip messages located in a udp payload
33//! for someip_message in SomeipMsgsIterator::new(&udp_payload) {
34//!     match someip_message {
35//!         Ok(value) => {
36//!             if value.is_someip_sd() {
37//!                 println!("someip service discovery packet");
38//!             } else {
39//!                 println!("0x{:x} (service id: 0x{:x}, method/event id: 0x{:x})",
40//!                          value.message_id(),
41//!                          value.service_id(),
42//!                          value.event_or_method_id());
43//!             }
44//!             println!("  with payload {:?}", value.payload())
45//!         },
46//!         Err(_) => {} //error reading a someip packet (based on size, protocol version value or message type value)
47//!     }
48//! }
49//! ```
50//!
51//! # References
52//! * [AUTOSAR Foundation](https://www.autosar.org/standards/foundation) \(contains SOMEIP Protocol Specification & SOME/IP Service Discovery Protocol Specification\)
53//! * [SOME/IP Protocol Specification R22-11](https://www.autosar.org/fileadmin/standards/R22-11/FO/AUTOSAR_PRS_SOMEIPProtocol.pdf)
54//! * [SOME/IP Service Discovery Protocol Specification R22-11](https://www.autosar.org/fileadmin/standards/R22-11/FO/AUTOSAR_PRS_SOMEIPServiceDiscoveryProtocol.pdf)
55
56// # Reason for 'bool_comparison' disable:
57//
58// Clippy triggers triggers errors like the following if the warning stays enabled:
59//
60//   warning: equality checks against false can be replaced by a negation
61//     --> src/packet_decoder.rs:131:20
62//      |
63//  131 |                 if false == fragmented {
64//      |                    ^^^^^^^^^^^^^^^^^^^ help: try simplifying it as shown: `!fragmented`
65//
66//
67// I prefer to write `false == value` instead of `!value` as it
68// is more visually striking and is not as easy to overlook as the single
69// character '!'.
70#![allow(clippy::bool_comparison)]
71
72#[cfg(test)]
73mod proptest_generators;
74
75/// Error types of someip_parse.
76pub mod err;
77
78mod message_type;
79pub use message_type::*;
80
81mod return_code;
82pub use return_code::*;
83
84mod sd;
85pub use sd::*;
86
87mod tp_range;
88pub use tp_range::*;
89
90mod someip_msgs_iterator;
91pub use someip_msgs_iterator::*;
92
93mod someip_header;
94pub use someip_header::*;
95
96mod someip_msg_slice;
97pub use someip_msg_slice::*;
98
99mod tp_buf_config;
100pub use tp_buf_config::*;
101
102mod tp_buf;
103pub use tp_buf::*;
104
105mod tp_header;
106pub use tp_header::*;
107
108mod tp_pool;
109pub use tp_pool::*;
110
111/// Maximum allowed TP segment length.
112pub const TP_UDP_MAX_SEGMENT_LEN: usize = 1400;
113
114/// Maximum allowed TP aligned segment length.
115///
116/// All packets except for the last packet (where
117/// the "more segments" flag is set to 0) are required
118/// to have a len of multiple of 16 bytes.
119pub const TP_UDP_MAX_SEGMENT_LEN_ALIGNED: usize = 1392;
120
121///The currently supported protocol version.
122pub const SOMEIP_PROTOCOL_VERSION: u8 = 1;
123
124///Offset that must be substracted from the length field to determine the length of the actual payload.
125pub const SOMEIP_LEN_OFFSET_TO_PAYLOAD: u32 = 4 * 2; // 2x 32bits
126
127///Maximum payload length supported by some ip. This is NOT the maximum length that is supported when
128///sending packets over UDP. This constant is based on the limitation of the length field data type (uint32).
129pub const SOMEIP_MAX_PAYLOAD_LEN: u32 = u32::MAX - SOMEIP_LEN_OFFSET_TO_PAYLOAD;
130
131/// The maximum payload size of an SOMEIP UDP message.
132///
133/// This value comes directly from the SOMEIP specification,
134/// which states the following:
135///
136/// > The size of the SOME/IP payload field depends on the transport
137/// > protocol used. With UDP the SOME/IP payload shall be between 0
138/// > and 1400 Bytes. The limitation to 1400 Bytes is needed in order
139/// > to allow for future changes to protocol stack (e.g. changing to
140/// > IPv6 or adding security means). Since TCP supports segmentation
141/// > of payloads, larger sizes are automatically supported.
142pub const SOMEIP_MAX_PAYLOAD_LEN_UDP: u32 = 1400;
143
144///Length of a someip header.
145pub const SOMEIP_HEADER_LENGTH: usize = 4 * 4;
146
147///Length of the tp header that follows a someip header if a someip packet has been flaged as tp.
148pub const TP_HEADER_LENGTH: usize = 4;
149
150///Flag in the message type field marking the package a as tp message (transporting large SOME/IP messages of UDP).
151pub const SOMEIP_HEADER_MESSAGE_TYPE_TP_FLAG: u8 = 0x20;
152
153///Message id of SOMEIP service discovery messages
154pub const SOMEIP_SD_MESSAGE_ID: u32 = 0xffff_8100;
155
156/// Helper function for reading big endian u32 values from a ptr unchecked.
157///
158/// # Safety
159///
160/// It is in the responsibility of the caller to ensure there are at least 4
161/// bytes accessable via the ptr. If this is not the case undefined behavior
162/// will be triggered.
163#[inline]
164unsafe fn get_unchecked_be_u32(ptr: *const u8) -> u32 {
165    u32::from_be_bytes([*ptr, *ptr.add(1), *ptr.add(2), *ptr.add(3)])
166}
167
168/// Helper function for reading big endian u16 values from a ptr unchecked.
169///
170/// # Safety
171///
172/// It is in the responsibility of the caller to ensure there are at least 2
173/// bytes accessable via the ptr. If this is not the case undefined behavior
174/// will be triggered.
175#[inline]
176unsafe fn get_unchecked_be_u16(ptr: *const u8) -> u16 {
177    u16::from_be_bytes([*ptr, *ptr.add(1)])
178}