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}