70 lines
2.8 KiB
Rust
70 lines
2.8 KiB
Rust
use rs_tcp::*;
|
|
use std::{
|
|
collections::{hash_map::Entry, HashMap},
|
|
io,
|
|
};
|
|
|
|
fn main() -> io::Result<()> {
|
|
let mut nic = tun_tap::Iface::without_packet_info("mytun0", tun_tap::Mode::Tun)?;
|
|
let mut buffer = vec![0; 1500];
|
|
// 保存所有连接对应的状态
|
|
let mut connections: HashMap<Quad, Connection> = HashMap::new();
|
|
|
|
loop {
|
|
let nbytes = nic.recv(&mut buffer).unwrap();
|
|
// 忽略非TCP数据包
|
|
match etherparse::Ipv4HeaderSlice::from_slice(&buffer) {
|
|
Ok(iph) => {
|
|
let src = iph.source_addr();
|
|
let dst = iph.destination_addr();
|
|
let proto = iph.protocol();
|
|
if proto != etherparse::IpNumber(0x06) {
|
|
continue;
|
|
}
|
|
match etherparse::TcpHeaderSlice::from_slice(&buffer[iph.slice().len()..nbytes]) {
|
|
Ok(tcph) => {
|
|
let payload_offset = iph.slice().len() + tcph.slice().len();
|
|
let mut payload = &buffer[payload_offset..nbytes];
|
|
|
|
let recv_quad = Quad {
|
|
src: (src, tcph.source_port()),
|
|
dst: (dst, tcph.destination_port()),
|
|
};
|
|
// 这里我们需要处理接收到的Tcp数据包
|
|
match connections.entry(recv_quad) {
|
|
Entry::Occupied(mut occupied_entry) => {
|
|
// 已经存在的连接
|
|
occupied_entry.get_mut().on_packet(iph, tcph, &payload);
|
|
},
|
|
Entry::Vacant(vacant_entry) => {
|
|
eprintln!(
|
|
"{}:{} -> {}:{} first handpacket syn: {}, seq: {}",
|
|
src,
|
|
tcph.source_port(),
|
|
dst,
|
|
tcph.destination_port(),
|
|
tcph.syn(),
|
|
tcph.sequence_number()
|
|
);
|
|
// 第一次接受的包
|
|
if let Some(c) = Connection::accept(&mut nic, iph, tcph)?{
|
|
vacant_entry.insert(c);
|
|
}
|
|
},
|
|
}
|
|
}
|
|
Err(e) => {
|
|
// 这不是一个TCP包 但是协议是TCP
|
|
eprintln!("ignoring weird packet: {:?}", e)
|
|
}
|
|
}
|
|
}
|
|
Err(_) => {
|
|
// 非IP标准包 忽略
|
|
continue;
|
|
}
|
|
};
|
|
}
|
|
Ok(())
|
|
}
|