mirror of
https://github.com/aramperes/onetun.git
synced 2025-09-08 23:58:31 -04:00
WIP
This commit is contained in:
parent
65032b2311
commit
f3976be852
3 changed files with 172 additions and 25 deletions
86
Cargo.lock
generated
86
Cargo.lock
generated
|
@ -277,6 +277,15 @@ dependencies = [
|
|||
"quick-error",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hwaddr"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e414433a9e4338f4e87fa29d0670c883a5e73e7955c45f4a49130c0aa992c85b"
|
||||
dependencies = [
|
||||
"phf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.11"
|
||||
|
@ -367,6 +376,12 @@ dependencies = [
|
|||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "managed"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c75de51135344a4f8ed3cfe2720dc27736f7711989703a0b43aadf3753c55577"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.4.1"
|
||||
|
@ -425,7 +440,21 @@ dependencies = [
|
|||
"boringtun",
|
||||
"clap",
|
||||
"log",
|
||||
"packet",
|
||||
"pretty_env_logger",
|
||||
"smoltcp",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "packet"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c136c7ad0619ed4f88894aecf66ad86c80683e7b5d707996e6a3a7e0e3916944"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"byteorder",
|
||||
"hwaddr",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -453,6 +482,24 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12"
|
||||
dependencies = [
|
||||
"phf_shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7"
|
||||
dependencies = [
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pretty_env_logger"
|
||||
version = "0.3.1"
|
||||
|
@ -566,6 +613,12 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "533494a8f9b724d33625ab53c6c4800f7cc445895924a8ef649222dcb76e938b"
|
||||
|
||||
[[package]]
|
||||
name = "slog"
|
||||
version = "2.7.0"
|
||||
|
@ -591,6 +644,19 @@ version = "1.7.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
|
||||
|
||||
[[package]]
|
||||
name = "smoltcp"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e4a069bef843d170df47e7c0a8bf8d037f217d9f5b325865acc3e466ffe40d3"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"byteorder",
|
||||
"libc",
|
||||
"log",
|
||||
"managed",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
|
@ -643,6 +709,26 @@ dependencies = [
|
|||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.3"
|
||||
|
|
|
@ -11,3 +11,5 @@ clap = { version = "2.33", default-features = false, features = ["suggestions"]
|
|||
log = "0.4"
|
||||
pretty_env_logger = "0.3"
|
||||
anyhow = "1"
|
||||
smoltcp = "0.7.5"
|
||||
packet = "0.1.4"
|
||||
|
|
109
src/main.rs
109
src/main.rs
|
@ -1,7 +1,7 @@
|
|||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
use std::net::{IpAddr, SocketAddr, UdpSocket};
|
||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket};
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::{Arc, Barrier};
|
||||
use std::thread;
|
||||
|
@ -12,6 +12,9 @@ use boringtun::crypto::{X25519PublicKey, X25519SecretKey};
|
|||
use boringtun::device::peer::Peer;
|
||||
use boringtun::noise::{Tunn, TunnResult};
|
||||
use clap::{App, Arg};
|
||||
use packet::ip::Protocol;
|
||||
use packet::Builder;
|
||||
use smoltcp::wire::Ipv4Packet;
|
||||
|
||||
use crate::config::Config;
|
||||
|
||||
|
@ -46,7 +49,8 @@ fn main() -> anyhow::Result<()> {
|
|||
|
||||
let endpoint_addr = config.endpoint_addr;
|
||||
|
||||
let peer_ip = config.source_peer_ip;
|
||||
let source_peer_addr = SocketAddr::new(config.source_peer_ip, 1234);
|
||||
let destination_addr = config.dest_addr;
|
||||
|
||||
let close = Arc::new(AtomicBool::new(false));
|
||||
|
||||
|
@ -74,23 +78,15 @@ fn main() -> anyhow::Result<()> {
|
|||
}
|
||||
};
|
||||
|
||||
debug!("Got packet from endpoint sock: {} bytes", n);
|
||||
|
||||
match peer.decapsulate(None, &recv_buf[..n], &mut send_buf) {
|
||||
let data = &recv_buf[..n];
|
||||
match peer.decapsulate(None, data, &mut send_buf) {
|
||||
TunnResult::WriteToNetwork(packet) => {
|
||||
send_mocked_packet(packet, endpoint_sock.clone(), endpoint_addr, peer_ip)
|
||||
.unwrap();
|
||||
send_packet(packet, endpoint_sock.clone(), endpoint_addr).unwrap();
|
||||
loop {
|
||||
let mut send_buf = [0u8; MAX_PACKET];
|
||||
match peer.decapsulate(None, &[], &mut send_buf) {
|
||||
TunnResult::WriteToNetwork(packet) => {
|
||||
send_mocked_packet(
|
||||
packet,
|
||||
endpoint_sock.clone(),
|
||||
endpoint_addr,
|
||||
peer_ip,
|
||||
)
|
||||
.unwrap();
|
||||
send_packet(packet, endpoint_sock.clone(), endpoint_addr).unwrap();
|
||||
}
|
||||
_ => {
|
||||
break;
|
||||
|
@ -130,14 +126,25 @@ fn main() -> anyhow::Result<()> {
|
|||
}
|
||||
};
|
||||
|
||||
debug!("Got packet from source sock: {} bytes", n);
|
||||
let data = &recv_buf[..n];
|
||||
|
||||
match peer.encapsulate(&recv_buf[..n], &mut send_buf) {
|
||||
// TODO: Support TCP
|
||||
let ip_packet =
|
||||
wrap_data_packet(Protocol::Udp, data, source_peer_addr, destination_addr)
|
||||
.expect("Failed to wrap data packet");
|
||||
|
||||
debug!("Crafted IP packet: {:#?}", ip_packet);
|
||||
|
||||
match peer.encapsulate(ip_packet.as_slice(), &mut send_buf) {
|
||||
TunnResult::WriteToNetwork(packet) => {
|
||||
send_mocked_packet(packet, endpoint_sock.clone(), endpoint_addr, peer_ip)
|
||||
.unwrap();
|
||||
send_packet(packet, endpoint_sock.clone(), endpoint_addr).unwrap();
|
||||
}
|
||||
TunnResult::Err(e) => {
|
||||
error!("Failed to encapsulate: {:?}", e);
|
||||
}
|
||||
other => {
|
||||
error!("Unexpected TunnResult during encapsulation: {:?}", other);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
@ -156,8 +163,7 @@ fn main() -> anyhow::Result<()> {
|
|||
let mut send_buf = [0u8; MAX_PACKET];
|
||||
match peer.update_timers(&mut send_buf) {
|
||||
TunnResult::WriteToNetwork(packet) => {
|
||||
send_mocked_packet(packet, endpoint_sock.clone(), endpoint_addr, peer_ip)
|
||||
.unwrap();
|
||||
send_packet(packet, endpoint_sock.clone(), endpoint_addr).unwrap();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -178,14 +184,67 @@ fn main() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn send_mocked_packet(
|
||||
// wraps a UDP packet with an IP layer packet with the wanted source & destination addresses
|
||||
fn wrap_data_packet(
|
||||
proto: Protocol,
|
||||
data: &[u8],
|
||||
source: SocketAddr,
|
||||
destination: SocketAddr,
|
||||
) -> anyhow::Result<Vec<u8>> {
|
||||
match source {
|
||||
SocketAddr::V4(source) => {
|
||||
let mut builder = packet::ip::v4::Builder::default();
|
||||
|
||||
builder = builder
|
||||
.source(*source.ip())
|
||||
.with_context(|| "Failed to set packet source")?;
|
||||
builder = builder
|
||||
.payload(data)
|
||||
.with_context(|| "Failed to set packet payload")?;
|
||||
builder = builder
|
||||
.protocol(proto)
|
||||
.with_context(|| "Failed to set packet protocol")?;
|
||||
builder = builder
|
||||
.dscp(0)
|
||||
.with_context(|| "Failed to set packet dcsp")?;
|
||||
builder = builder
|
||||
.id(12345)
|
||||
.with_context(|| "Failed to set packet ID")?;
|
||||
builder = builder
|
||||
.ttl(16)
|
||||
.with_context(|| "Failed to set packet TTL")?;
|
||||
|
||||
match destination {
|
||||
SocketAddr::V4(destination) => {
|
||||
builder = builder
|
||||
.destination(*destination.ip())
|
||||
.with_context(|| "Failed to set packet destination")?;
|
||||
}
|
||||
SocketAddr::V6(_) => {
|
||||
return Err(anyhow::anyhow!(
|
||||
"cannot use ipv6 destination with ipv4 source"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
builder
|
||||
.build()
|
||||
.with_context(|| "Failed to build ipv4 packet")
|
||||
}
|
||||
SocketAddr::V6(_) => {
|
||||
todo!("ipv6 support")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn send_packet(
|
||||
packet: &[u8],
|
||||
endpoint_socket: Arc<UdpSocket>,
|
||||
endpoint_addr: SocketAddr,
|
||||
peer_addr: IpAddr,
|
||||
) -> anyhow::Result<usize> {
|
||||
// todo: replace addr with peer_addr
|
||||
endpoint_socket
|
||||
let size = endpoint_socket
|
||||
.send_to(packet, endpoint_addr)
|
||||
.with_context(|| "Failed to send mocked packet")
|
||||
.with_context(|| "Failed to send packet")?;
|
||||
Ok(size)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue