netlink-packet-core
provides a generic netlink message
NetlinkMessage<T>
that is independant of the sub-protocol. Such
messages are not very useful by themselves, since they are just
used to carry protocol-dependant messages. That is what the T
represent: T
is the NetlinkMessage
's protocol-dependant
message. This can be any type that implements
NetlinkSerializable
and NetlinkDeserializable
.
For instance, the netlink-packet-route
crate provides rtnetlink
messages via netlink_packet_route::RtnlMessage
, and
netlink-packet-audit
provides audit messages via
netlink_packet_audit::AuditMessage
.
By itself, the netlink-packet-core
crate is not very
useful. However, it is used in netlink-proto
to provide an
asynchronous implementation of the netlink protocol for any
sub-protocol. Thus, a crate that defines messages for a given
netlink sub-protocol could integrate with netlink-packet-core
and would get an asynchronous implementation for free. See the
second example below for such an integration, via the
NetlinkSerializable
and NetlinkDeserializable
traits.
Example: usage with netlink-packet-route
This example shows how to serialize and deserialize netlink packet
for the rtnetlink sub-protocol. It requires
netlink-packet-route
.
use ;
use ;
Example: adding messages for new netlink sub-protocol
Let's assume we have a netlink protocol called "ping pong" that defines two types of messages: "ping" messages, which payload can be any sequence of bytes, and "pong" message, which payload is also a sequence of bytes. The protocol works as follow: when an enpoint receives a "ping" message, it answers with a "pong", with the payload of the "ping" it's answering to.
"ping" messages have type 18 and "pong" have type "20". Here is
what a "ping" message that would look like if its payload is [0, 1, 2, 3]
:
0 8 16 24 32
+----------------+----------------+----------------+----------------+
| packet length (including header) = 16 + 4 = 20 |
+----------------+----------------+----------------+----------------+
| message type = 18 (ping) | flags |
+----------------+----------------+----------------+----------------+
| sequence number |
+----------------+----------------+----------------+----------------+
| port number |
+----------------+----------------+----------------+----------------+
| 0 | 1 | 2 | 3 |
+----------------+----------------+----------------+----------------+
And the "pong" response would be:
0 8 16 24 32
+----------------+----------------+----------------+----------------+
| packet length (including header) = 16 + 4 = 20 |
+----------------+----------------+----------------+----------------+
| message type = 20 (pong) | flags |
+----------------+----------------+----------------+----------------+
| sequence number |
+----------------+----------------+----------------+----------------+
| port number |
+----------------+----------------+----------------+----------------+
| 0 | 1 | 2 | 3 |
+----------------+----------------+----------------+----------------+
Here is how we could implement the messages for such a protocol
and integrate this implementation with netlink-packet-core
:
use ;
use Error;
use fmt;
// PingPongMessage represent the messages for the "ping-pong" netlink
// protocol. There are only two types of messages.
// The netlink header contains a "message type" field that identifies
// the message it carries. Some values are reserved, and we
// arbitrarily decided that "ping" type is 18 and "pong" type is 20.
pub const PING_MESSAGE: u16 = 18;
pub const PONG_MESSAGE: u16 = 20;
// A custom error type for when deserialization fails. This is
// required because `NetlinkDeserializable::Error` must implement
// `std::error::Error`, so a simple `String` won't cut it.
;
// NetlinkDeserializable implementation
// NetlinkSerializable implementation
// It can be convenient to be able to create a NetlinkMessage directly
// from a PingPongMessage. Since NetlinkMessage<T> already implements
// From<NetlinkPayload<T>>, we just need to implement
// From<NetlinkPayload<PingPongMessage>> for this to work.