use crate::smb2::Smb2SessionSetupResp;
use crate::smb2::header::commands::{SMB2_NEGOTIATE_PROTOCOL, SMB2_SESSION_SETUP};
use crate::smb2::Smb2Header;
use crate::smb2::Smb2NegReq;
use crate::smb2::Smb2NegResp;
use crate::smb2::Smb2SessionSetupReq;
use crate::Error;
use crate::Result;
#[derive(Clone, Debug, PartialEq)]
pub enum Smb2Msg {
NegReq(Smb2NegReq),
NegResp(Smb2NegResp),
SessionSetupReq(Smb2SessionSetupReq),
SessionSetupResp(Smb2SessionSetupResp),
}
impl Smb2Msg {
pub fn build(&self) -> Vec<u8> {
match self {
Self::NegReq(b) => b.build(),
Self::NegResp(_) => todo!(),
Self::SessionSetupReq(b) => b.build(),
Self::SessionSetupResp(_) => todo!(),
}
}
pub fn parse(raw: &[u8]) -> Result<Self> {
let (_, header) = Smb2Header::parse(raw)?;
return Ok(match header.command {
SMB2_NEGOTIATE_PROTOCOL => {
if header.is_response() {
Self::NegResp(Smb2NegResp::parse(raw)?)
} else {
Self::NegReq(Smb2NegReq::parse(raw)?)
}
}
SMB2_SESSION_SETUP => {
if header.is_response() {
Self::SessionSetupResp(Smb2SessionSetupResp::parse(raw)?)
} else {
todo!()
}
}
_ => return Err(Error::Smb2UnknownCommand(header.command)),
});
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct Smb2Packet {
pub header: Smb2Header,
pub body: Smb2Body,
}
impl Smb2Packet {
pub fn new(header: Smb2Header, body: Smb2Body) -> Self {
return Self { header, body };
}
pub fn new_neg_req(header: Smb2Header, body: Smb2NegReq) -> Self {
return Self::new(header, Smb2Body::NegReq(body));
}
pub fn new_session_setup_req(
header: Smb2Header,
body: Smb2SessionSetupReq,
) -> Self {
return Self::new(header, Smb2Body::SessionSetupReq(body));
}
pub fn command(&self) -> u16 {
return self.header.command;
}
pub fn build(&self) -> Vec<u8> {
let mut raw = self.header.build();
raw.extend(self.body.build());
return raw;
}
pub fn parse(raw: &[u8]) -> Result<Self> {
let (raw, header) = Smb2Header::parse(raw)?;
let body = match header.command {
SMB2_NEGOTIATE_PROTOCOL => {
if header.is_response() {
Smb2Body::NegResp(Smb2NegResp::parse(raw)?)
} else {
Smb2Body::NegReq(Smb2NegReq::parse(raw)?)
}
}
SMB2_SESSION_SETUP => {
if header.is_response() {
Smb2Body::SessionSetupResp(Smb2SessionSetupResp::parse(raw)?)
} else {
todo!()
}
}
_ => return Err(Error::Smb2UnknownCommand(header.command)),
};
return Ok(Self { header, body });
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum Smb2Body {
NegReq(Smb2NegReq),
NegResp(Smb2NegResp),
SessionSetupReq(Smb2SessionSetupReq),
SessionSetupResp(Smb2SessionSetupResp),
}
impl Smb2Body {
pub fn build(&self) -> Vec<u8> {
match self {
Self::NegReq(b) => b.build(),
Self::NegResp(_) => todo!(),
Self::SessionSetupReq(b) => b.build(),
Self::SessionSetupResp(_) => todo!(),
}
}
}
impl Default for Smb2Body {
fn default() -> Self {
return Self::NegReq(Smb2NegReq::default());
}
}