smb_server_proto_smb2/
session_setup.rs1#[allow(dead_code)]
9mod req_off {
10 pub const STRUCT: usize = 0;
12 pub const FLAGS: usize = 2;
14 pub const SECURITY_MODE: usize = 3;
16 pub const CAPABILITIES: usize = 4;
18 pub const CHANNEL: usize = 8;
20 pub const BLOB_OFFSET: usize = 12;
22 pub const BLOB_LENGTH: usize = 14;
24 pub const PREV_SESSION_ID: usize = 16;
26 pub const FIXED_END: usize = 24;
28}
29
30fn g16(b: &[u8], o: usize) -> u16 {
31 match b.get(o..o + 2) {
32 Some(s) => u16::from_le_bytes([s[0], s[1]]),
33 None => 0,
34 }
35}
36
37#[derive(Debug)]
39pub struct Request {
40 pub flags: u8,
42 pub security_mode: u16,
44 pub capabilities: u32,
46 pub prev_session_id: u64,
48 pub blob: Vec<u8>,
50}
51
52pub const FLAG_BINDING: u8 = 0x01;
55
56impl Request {
57 pub fn parse(frame: &[u8]) -> Option<Request> {
60 const HDR: usize = 64;
61 let b = frame.get(HDR..)?;
62 if g16(b, req_off::STRUCT) != 25 && g16(b, req_off::STRUCT) != 24 {
63 return None;
64 }
65 let blob_off = g16(b, req_off::BLOB_OFFSET) as usize;
66 let blob_len = g16(b, req_off::BLOB_LENGTH) as usize;
67 let (start, end) = if blob_off >= HDR {
70 (blob_off, blob_off.saturating_add(blob_len))
71 } else {
72 (HDR + req_off::FIXED_END, frame.len())
73 };
74 let blob = frame.get(start..end.min(frame.len())).unwrap_or(&[]).to_vec();
75 Some(Request {
76 flags: *b.get(req_off::FLAGS).unwrap_or(&0),
77 security_mode: *b.get(req_off::SECURITY_MODE).unwrap_or(&0) as u16,
78 capabilities: u32::from_le_bytes(
79 b.get(req_off::CAPABILITIES..req_off::CAPABILITIES + 4)
80 .map(|s| s.try_into().unwrap())
81 .unwrap_or([0; 4]),
82 ),
83 prev_session_id: u64::from_le_bytes(
84 b.get(req_off::PREV_SESSION_ID..req_off::PREV_SESSION_ID + 8)
85 .map(|s| s.try_into().unwrap())
86 .unwrap_or([0; 8]),
87 ),
88 blob,
89 })
90 }
91}
92
93pub fn build_response(session_flags: u16, blob: &[u8]) -> Vec<u8> {
99 let mut b = Vec::with_capacity(8 + blob.len());
100 b.extend_from_slice(&9u16.to_le_bytes()); b.extend_from_slice(&session_flags.to_le_bytes());
102 b.extend_from_slice(&(72u16).to_le_bytes()); b.extend_from_slice(&(blob.len() as u16).to_le_bytes());
104 b.extend_from_slice(blob);
105 b
106}
107
108pub mod cmd {
110 pub const NEGOTIATE: u16 = 0;
112 pub const SESSION_SETUP: u16 = 1;
114 pub const LOGOFF: u16 = 2;
116 pub const TREE_CONNECT: u16 = 3;
118 pub const TREE_DISCONNECT: u16 = 4;
120 pub const CREATE: u16 = 5;
122 pub const CLOSE: u16 = 6;
124 pub const FLUSH: u16 = 7;
126 pub const READ: u16 = 8;
128 pub const WRITE: u16 = 9;
130 pub const LOCK: u16 = 10;
132 pub const IOCTL: u16 = 11;
134 pub const CANCEL: u16 = 12;
136 pub const ECHO: u16 = 13;
138 pub const QUERY_DIRECTORY: u16 = 14;
140 pub const CHANGE_NOTIFY: u16 = 15;
142 pub const QUERY_INFO: u16 = 16;
144 pub const SET_INFO: u16 = 17;
146 pub const OPLOCK_BREAK: u16 = 18;
148}