Created
August 14, 2019 17:29
-
-
Save richardeoin/b562e79d0d499e00a8bf4944f00594d9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#[macro_use] | |
extern crate log; | |
extern crate env_logger; | |
extern crate getopts; | |
extern crate smoltcp; | |
mod utils; | |
use smoltcp::iface::{EthernetInterfaceBuilder, NeighborCache}; | |
use smoltcp::phy::wait as phy_wait; | |
use smoltcp::socket::SocketSet; | |
use smoltcp::socket::{TcpSocket, TcpSocketBuffer}; | |
use smoltcp::socket::{UdpPacketMetadata, UdpSocket, UdpSocketBuffer}; | |
use smoltcp::time::Instant; | |
use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr}; | |
use std::fmt::Write; | |
use std::os::unix::io::AsRawFd; | |
use std::str; | |
fn main() { | |
utils::setup_logging(""); | |
let (mut opts, mut free) = utils::create_options(); | |
utils::add_tap_options(&mut opts, &mut free); | |
utils::add_middleware_options(&mut opts, &mut free); | |
let mut matches = utils::parse_options(&opts, free); | |
let device = utils::parse_tap_options(&mut matches); | |
let fd = device.as_raw_fd(); | |
let device = utils::parse_middleware_options(&mut matches, device, /*loopback=*/ false); | |
let mut neighbor_cache_storage = [None; 8]; | |
let neighbor_cache = NeighborCache::new(&mut neighbor_cache_storage[..]); | |
// UDP | |
let mut udp_rx_meta_storage = [UdpPacketMetadata::EMPTY; 1]; | |
let mut udp_tx_meta_storage = [UdpPacketMetadata::EMPTY; 1]; | |
let mut udp_rx_storage = [0; 64]; | |
let mut udp_tx_storage = [0; 128]; | |
let udp_rx_buffer = UdpSocketBuffer::new(&mut udp_rx_meta_storage[..], &mut udp_rx_storage[..]); | |
let udp_tx_buffer = UdpSocketBuffer::new(&mut udp_tx_meta_storage[..], &mut udp_tx_storage[..]); | |
let udp_socket = UdpSocket::new(udp_rx_buffer, udp_tx_buffer); | |
let mut tcp_rx_storage = [0; 64]; | |
let mut tcp_tx_storage = [0; 128]; | |
let tcp1_rx_buffer = TcpSocketBuffer::new(&mut tcp_rx_storage[..]); | |
let tcp1_tx_buffer = TcpSocketBuffer::new(&mut tcp_tx_storage[..]); | |
let tcp1_socket = TcpSocket::new(tcp1_rx_buffer, tcp1_tx_buffer); | |
let ethernet_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]); | |
let ip_addrs = [ | |
IpCidr::new(IpAddress::v4(192, 168, 69, 1), 24), | |
IpCidr::new(IpAddress::v6(0xfdaa, 0, 0, 0, 0, 0, 0, 1), 64), | |
IpCidr::new(IpAddress::v6(0xfe80, 0, 0, 0, 0, 0, 0, 1), 64), | |
]; | |
let mut iface = EthernetInterfaceBuilder::new(device) | |
.ethernet_addr(ethernet_addr) | |
.neighbor_cache(neighbor_cache) | |
.ip_addrs(ip_addrs) | |
.finalize(); | |
let mut socket_set_entries: [_; 8] = Default::default(); | |
let mut sockets = SocketSet::new(&mut socket_set_entries[..]); | |
let udp_handle = sockets.add(udp_socket); | |
let tcp1_handle = sockets.add(tcp1_socket); | |
loop { | |
let timestamp = Instant::now(); | |
match iface.poll(&mut sockets, timestamp) { | |
Ok(_) => {} | |
Err(e) => { | |
debug!("poll error: {}", e); | |
} | |
} | |
// udp:6969: respond "hello" | |
{ | |
let mut socket = sockets.get::<UdpSocket>(udp_handle); | |
if !socket.is_open() { | |
socket.bind(6969).unwrap() | |
} | |
let client = match socket.recv() { | |
Ok((data, endpoint)) => { | |
debug!( | |
"udp:6969 recv data: {:?} from {}", | |
str::from_utf8(data.as_ref()).unwrap(), | |
endpoint | |
); | |
Some(endpoint) | |
} | |
Err(_) => None, | |
}; | |
if let Some(endpoint) = client { | |
let data = b"hello\n"; | |
debug!( | |
"udp:6969 send data: {:?}", | |
str::from_utf8(data.as_ref()).unwrap() | |
); | |
socket.send_slice(data, endpoint).unwrap(); | |
} | |
} | |
// tcp:6969: respond "hello" | |
{ | |
let mut socket = sockets.get::<TcpSocket>(tcp1_handle); | |
if !socket.is_open() { | |
socket.listen(6969).unwrap(); | |
} | |
if socket.can_send() { | |
debug!("tcp:6969 send greeting"); | |
write!(socket, "hello\n").unwrap(); | |
debug!("tcp:6969 close"); | |
socket.close(); | |
} | |
} | |
phy_wait(fd, iface.poll_delay(&sockets, timestamp)).expect("wait error"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment