]> git.feebdaed.xyz Git - linuxyz.git/commitdiff
ncat rust working
authorseantywork <seantywork@gmail.com>
Sat, 26 Apr 2025 10:51:12 +0000 (10:51 +0000)
committerseantywork <seantywork@gmail.com>
Sat, 26 Apr 2025 10:51:12 +0000 (10:51 +0000)
0xetc/0xrs/ncat/Cargo.toml
0xetc/0xrs/ncat/src/main.rs
0xetc/0xrs/ncat/src/ncat/ncat.rs

index 4d3b459f4bb8983b1cea7d7a14f70ddd53f0c420..e75be910a919a2f33852f0b3054ed25aa3cdb147 100644 (file)
@@ -5,4 +5,5 @@ edition = "2024"
 
 [dependencies]
 ctrlc = "3.4"
-pipe = "0.4.0"
\ No newline at end of file
+tokio = { version = "1.44.2", features = ["full"] }
+byteorder = "1.5.0"
\ No newline at end of file
index 06a0887a20afd806e782c56df47f25a3f5909d1f..686d0a423cb0047a45b43d10d8adf97add8fe496 100644 (file)
@@ -1,13 +1,15 @@
 mod ncat;
 
 use std::{
-    env, fs, net::{TcpListener, TcpStream}, ops::Deref, process::{self, ExitCode}, thread
+    env, ops::Deref, process::{self, ExitCode}, thread
 };
 
-use ncat::ncat::{self as NCAT, NcatOptions};
+use tokio;
 
+use ncat::ncat::{self as NCAT, NcatOptions};
 
-fn main() -> process::ExitCode {
+#[tokio::main]
+async fn main() -> process::ExitCode {
     
     let args: Vec<String> = env::args().collect();
 
@@ -62,8 +64,11 @@ fn main() -> process::ExitCode {
         }
     }
 
+    tokio::spawn(NCAT::runner(ncat_opts.clone()));
 
+    loop {
 
+    }
 
     return process::ExitCode::from(0u8);
 }
index d28604d0f0d9528997d8e3075c454757713a1854..36d357aa1dc12991d49dab873a8ad01b9bda256a 100644 (file)
@@ -1,22 +1,19 @@
 
 use std::{
-    fmt::Error, ops::Deref, process, sync::Arc
+    fs, io::{self, BufRead, Read, Write}, net::{TcpListener, TcpStream}, process, sync::{mpsc::{self, Receiver, Sender}, Arc}, thread, time::Duration
 };
 
-use pipe::{PipeReader, PipeWriter};
+use byteorder::{LittleEndian, BigEndian, ByteOrder, ReadBytesExt};
 
 
 #[derive(Clone)]
 pub struct NcatOptions {
 
-    pub _server_sig_tx: PipeWriter,
-    pub _server_sig_rx: PipeReader,
     pub mode_client: bool,
     pub mode_listen: bool, 
-    pub _client_sock_ready: bool,
-    pub _client_sockfd: i32,
     pub host: String,
     pub port: String, 
+    pub serve_content: String
 
 }
 
@@ -24,17 +21,12 @@ impl NcatOptions {
 
     pub fn new() -> Self {
 
-        let (mut read, mut write) = pipe::pipe();
-
         Self { 
             mode_client: false, 
             mode_listen: false, 
-            _client_sock_ready: false, 
-            _client_sockfd: 0, 
-            _server_sig_rx: read,
-            _server_sig_tx: write,
             host: "".to_string(), 
-            port: "".to_string() 
+            port: "".to_string(),
+            serve_content: "".to_string()
         }
 
     }
@@ -112,28 +104,278 @@ pub fn parse_args(args: &Vec<String>) -> Result<Arc<NcatOptions>, String>{
     
 }
 
-pub fn runner(ncat_opts: &mut NcatOptions) -> Result<(), String> {
+pub async fn runner(mut ncat_opts: NcatOptions) -> Result<(), String> {
+
+    let (tx, rx) = mpsc::channel::<NcatOptions>();
+
+    let (txStream, rxStream) = mpsc::channel::<TcpStream>();
+
+
+    if ncat_opts.mode_client {
+
+        tokio::spawn(get_thread(ncat_opts.clone(), tx, rxStream));
+
+        let result = client(ncat_opts.clone(), txStream);
+
+        return result;
+
+    }
 
-    let mut status = 0;
 
     if ncat_opts.mode_listen {
 
+        tokio::spawn(get_thread(ncat_opts.clone(), tx, rxStream));
+
+        let mut ncat_opts_updated: NcatOptions = NcatOptions::new();
+
+        let timeout = Duration::new(0, 500000000);
 
+        match rx.recv_timeout(timeout) {
+
+            Ok(received) => {
+
+                ncat_opts_updated = received;
+
+            }
+
+            Err(e) => {
+
+                ncat_opts_updated = ncat_opts.clone();
+            }
+        };
+
+
+        let result = listen_and_serve(ncat_opts_updated.clone());
+        
+        return result;
 
     }
 
+    return Err("unsupported mode".to_string());
 
-    return Ok(());
 }
 
 
-fn client(ncat_opts: &mut NcatOptions) -> Result<(), String> {
+fn client(mut ncat_opts: NcatOptions, tx: Sender<TcpStream>) -> Result<(), String> {
+
+    let mut stream = TcpStream::connect((ncat_opts.host.as_str(), ncat_opts.port.to_string().parse::<u16>().unwrap())).unwrap();
+
+    let mut io_stream = stream.try_clone().unwrap();
+
+    let mut io_stream_reader = io_stream.try_clone().unwrap();
+
+    match tx.send(io_stream_reader) {
+
+        Ok(())=> {
+
+        }
+
+        Err(e) => {
+
+            println!("terrible channel send error: {}", e);
+
+
+        }
+
+    };
+
+    let stdin = io::stdin();
+    for line in stdin.lock().lines() {
+        
+        let message = line.unwrap();
+        
+        if message == "exit".to_string() {
+
+            break;
+
+        }
+
+        let mut header = [0u8; 4];
+
+        let mut message_size = [0u32];
+
+        message_size[0] = message.len() as u32;
+
+        BigEndian::write_u32_into(&message_size, &mut header);
+
+        let mut wbuff_vec = header.to_vec();
+
+        let mut message_vec = message.as_bytes().to_vec();
+
+        wbuff_vec.append(&mut message_vec);
+
+        //let wbuff = wbuff_vec.as_slice();
+
+        let wsize = io_stream.write(&wbuff_vec).unwrap();
+
+        if wsize <= 0 {
+
+            println!("failed to write: {}", wsize);
+        }
+    }
 
     return Ok(());
 }
 
 
-fn listen_and_serve(ncat_opts: &mut NcatOptions) -> Result<(), String> {
+fn listen_and_serve(mut ncat_opts: NcatOptions) -> Result<(), String> {
+
+    let mut listenaddr = ncat_opts.host.clone();
+
+    listenaddr += &":";
+
+    listenaddr += ncat_opts.port.as_str();
+
+    let listener = TcpListener::bind(listenaddr).unwrap();
+
+    for stream in listener.incoming() {
+
+        match stream {
+
+            Ok(mut io_stream) =>{
+
+                let mut header = [0u8; 4];
+
+                loop {
+            
+                    let mut valread = 0;
+            
+            
+                    loop {
+            
+                        let mut n = io_stream.read(&mut header[valread..]).unwrap();
+            
+                        if n == 0 {
+            
+                            println!("read header error");
+            
+                            break;
+                        }
+            
+                        valread += n;
+            
+                        if valread == 4 {
+            
+                            break;
+                        }
+                    }
+            
+            
+                    let mut datalen = LittleEndian::read_u32(&mut header);
+                    
+                    println!("datalen: {}", datalen);
+
+                    let mut data = Vec::<u8>::with_capacity(datalen as usize);
+            
+                    valread = 0;
+            
+                    loop {
+            
+                        let mut n = io_stream.read(&mut data[valread..]).unwrap();
+            
+                        if n == 0 {
+            
+                            println!("read data error");
+            
+                            break;
+                        }
+            
+                        valread += n;
+            
+                        if valread == datalen as usize {
+            
+                            break;
+                        }
+            
+                    }
+            
+                    println!("{}", String::from_utf8(data).unwrap());
+                }
+            
+
+            }
+            Err(e) => {
+                println!("accept error: {}", e);
+            }
+
+        }
+
+    }
 
     return Ok(());
+}
+
+
+async fn get_thread(mut ncat_opts: NcatOptions, tx: Sender<NcatOptions>, rx: Receiver<TcpStream>) {
+
+    if(ncat_opts.mode_client) {
+
+        let mut io_stream = rx.recv().unwrap();
+
+        let mut header = [0u8; 4];
+
+        loop {
+
+            let mut valread = 0;
+
+
+            loop {
+
+                let mut n = io_stream.read(&mut header[valread..]).unwrap();
+
+                if n == 0 {
+    
+                    println!("read header error");
+    
+                    break;
+                }
+
+                valread += n;
+
+                if valread == 4 {
+
+                    break;
+                }
+            }
+
+
+            let mut datalen = BigEndian::read_u32(&mut header);
+
+            let mut data = Vec::<u8>::with_capacity(datalen as usize);
+
+            valread = 0;
+
+            loop {
+
+                let mut n = io_stream.read(&mut data[valread..]).unwrap();
+
+                if n == 0 {
+    
+                    println!("read data error");
+    
+                    break;
+                }
+
+                valread += n;
+
+                if valread == datalen as usize {
+
+                    break;
+                }
+
+            }
+
+            println!("{}", String::from_utf8(data).unwrap());
+
+        }
+
+    } else if (ncat_opts.mode_listen) {
+
+
+
+
+
+    }
+
+
 }
\ No newline at end of file