use std::{
io::{Read, Write},
net::TcpStream,
};
use binrw::io::NoSeek;
use binrw::prelude::*;
use crate::packets::netbios::{NetBiosMessageContent, NetBiosTcpMessage, NetBiosTcpMessageHeader};
pub struct NetBiosClient {
connection: Option<TcpStream>,
}
impl NetBiosClient {
pub fn new() -> NetBiosClient {
NetBiosClient { connection: None }
}
pub fn connect(&mut self, address: &str) -> Result<(), Box<dyn std::error::Error>> {
self.connection = Some(TcpStream::connect(address)?);
Ok(())
}
pub fn send(&mut self, data: NetBiosMessageContent) -> Result<(), Box<dyn std::error::Error>> {
let raw_message = NetBiosTcpMessage::from_content(&data)?;
self.send_raw(raw_message)
}
pub fn send_raw(&mut self, data: NetBiosTcpMessage) -> Result<(), Box<dyn std::error::Error>> {
self.connection
.as_ref()
.ok_or("NetBiosClient is not connected")?
.write_all(&data.to_bytes()?)?;
Ok(())
}
pub fn recieve_bytes(&mut self) -> Result<NetBiosTcpMessage, Box<dyn std::error::Error>> {
let mut tcp = self
.connection
.as_ref()
.ok_or("NetBiosClient is not connected")?;
let header_receiver = &mut NoSeek::new(&mut tcp);
let header = NetBiosTcpMessageHeader::read(header_receiver)?;
if header.stream_protocol_length.value > 2u32.pow(3 * 8) - 1 {
return Err("Stream protocol length is too large".into());
}
let mut data = vec![0; header.stream_protocol_length.value as usize];
tcp.read_exact(&mut data)?;
Ok(NetBiosTcpMessage { content: data })
}
}