Skip to main content

rustsmb/io/
wire.rs

1//! Wire codecs and the response value: `Decode` (frame → typed request),
2//! `Encode` (typed body → bytes), and the `SmbResponse`/`ReplyHeader` a handler
3//! produces. Every response — solicited, interim, or unsolicited — is serialized
4//! through one place so signing/sealing lives in a single site.
5
6use smb_server_proto::types::Status;
7
8/// Decode one single-command SMB2 frame into a typed request. Implemented per
9/// command; dispatched statically by [`SmbRequest::parse`](super::SmbRequest).
10pub trait Decode: Sized {
11    /// The SMB2 command code this request decodes.
12    const COMMAND: u16;
13    /// Parse the request from its complete frame (header + body); the frame is
14    /// borrowed, so payloads stay zero-copy.
15    fn decode(frame: &[u8]) -> Result<Self, Status>;
16}
17
18/// Serialize a typed response body against a reply header.
19pub trait Encode {
20    /// Encode the response body (without the 64-byte SMB2 header).
21    fn encode(&self, hdr: &ReplyHeader) -> Vec<u8>;
22}
23
24/// Whether a response must be signed and/or sealed. Computed once at `accept`
25/// from the session/request so it is never threaded by hand.
26#[derive(Debug, Clone, Copy, Default)]
27pub struct SealIntent {
28    /// Sign the response ([MS-SMB2] §3.3.4.1.1).
29    pub sign: bool,
30    /// Encrypt (seal) the response ([MS-SMB2] §3.3.4.1.4).
31    pub seal: bool,
32}
33
34/// The header fields a reply echoes or sets, captured when the context is built.
35#[derive(Debug, Clone)]
36pub struct ReplyHeader {
37    /// SMB2 command code.
38    pub command: u16,
39    /// MessageId echoed from the request (0 for some server events).
40    pub message_id: u64,
41    /// SessionId echoed (0 for e.g. a lease break, [MS-SMB2] §3.3.4.6).
42    pub session_id: u64,
43    /// TreeId echoed.
44    pub tree_id: u32,
45    /// Credits granted on this reply.
46    pub credits: u16,
47    /// Signing/sealing intent.
48    pub seal: SealIntent,
49}
50
51/// A finished response: the status, the header it replies under, and the encoded
52/// body. Solicited, interim, and unsolicited replies all converge on this type.
53#[derive(Debug)]
54pub struct SmbResponse {
55    /// NT status of the reply.
56    pub status: Status,
57    /// Header this reply is framed with.
58    pub reply: ReplyHeader,
59    /// Encoded response body (without the 64-byte SMB2 header).
60    pub body: Vec<u8>,
61}