starnix_core/vfs/socket/socket_generic_netlink/
messages.rs

1// Copyright 2022 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use netlink_packet_core::{NetlinkDeserializable, NetlinkHeader, NetlinkSerializable};
6use netlink_packet_generic::GenlMessage;
7use netlink_packet_generic::constants::GENL_ID_CTRL;
8use netlink_packet_generic::ctrl::GenlCtrl;
9use netlink_packet_utils::DecodeError;
10
11#[derive(Clone, Debug)]
12pub enum GenericMessage {
13    /// The default supported Netlink Control protocol.
14    Ctrl(GenlMessage<GenlCtrl>),
15    /// Any other Netlink protocol. Netlink family servers should perform their own
16    /// parsing on the given payload, likely also using GenlMessage/GenlFamily.
17    Other { family: u16, payload: Vec<u8> },
18}
19
20impl NetlinkDeserializable for GenericMessage {
21    type Error = DecodeError;
22
23    fn deserialize(header: &NetlinkHeader, payload: &[u8]) -> Result<Self, Self::Error> {
24        match header.message_type {
25            GENL_ID_CTRL => {
26                GenlMessage::<GenlCtrl>::deserialize(header, payload).map(GenericMessage::Ctrl)
27            }
28            family => Ok(GenericMessage::Other { family, payload: payload.to_vec() }),
29        }
30    }
31}
32
33impl NetlinkSerializable for GenericMessage {
34    fn message_type(&self) -> u16 {
35        match self {
36            GenericMessage::Ctrl(c) => NetlinkSerializable::message_type(c),
37            GenericMessage::Other { family, .. } => *family,
38        }
39    }
40    fn buffer_len(&self) -> usize {
41        match self {
42            GenericMessage::Ctrl(c) => NetlinkSerializable::buffer_len(c),
43            GenericMessage::Other { payload, .. } => payload.len(),
44        }
45    }
46    fn serialize(&self, buffer: &mut [u8]) {
47        match self {
48            GenericMessage::Ctrl(c) => NetlinkSerializable::serialize(c, buffer),
49            GenericMessage::Other { payload, .. } => buffer.copy_from_slice(&payload[..]),
50        }
51    }
52}