#[macro_use]
extern crate log;
use env_logger::Env;
use sntp::{
net::iface::{EthernetInterfaceBuilder, NeighborCache, Routes},
net::phy::{wait as phy_wait, TapInterface},
net::socket::{SocketSet, UdpPacketMetadata, UdpSocketBuffer},
net::time::Instant,
net::wire::{EthernetAddress, IpAddress, IpCidr, Ipv4Address},
Client,
};
use std::collections::BTreeMap;
use std::os::unix::io::AsRawFd;
use std::str::FromStr;
fn main() {
env_logger::from_env(Env::default().default_filter_or("info")).init();
let device = TapInterface::new("tap0").unwrap();
let fd = device.as_raw_fd();
let server = IpAddress::from_str("62.112.134.4").expect("invalid address format");
let neighbor_cache = NeighborCache::new(BTreeMap::new());
let sntp_rx_buffer = UdpSocketBuffer::new([UdpPacketMetadata::EMPTY; 1], vec![0; 900]);
let sntp_tx_buffer = UdpSocketBuffer::new([UdpPacketMetadata::EMPTY; 1], vec![0; 600]);
let mut sockets = SocketSet::new(vec![]);
let ethernet_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x02]);
let ip_addrs = [IpCidr::new(IpAddress::v4(192, 168, 69, 1), 24)];
let default_v4_gw = Ipv4Address::new(192, 168, 69, 100);
let mut routes_storage = [None; 1];
let mut routes = Routes::new(&mut routes_storage[..]);
routes.add_default_ipv4_route(default_v4_gw).unwrap();
let mut iface = EthernetInterfaceBuilder::new(device)
.ethernet_addr(ethernet_addr)
.neighbor_cache(neighbor_cache)
.ip_addrs(ip_addrs)
.routes(routes)
.finalize();
let mut sntp = Client::new(
&mut sockets,
sntp_rx_buffer,
sntp_tx_buffer,
server,
Instant::now(),
);
loop {
let timestamp = Instant::now();
iface.poll(&mut sockets, timestamp).map(|_| ()).ok();
let network_time = sntp.poll(&mut sockets, timestamp).unwrap_or_else(|e| {
error!("SNTP error: {}", e);
None
});
if let Some(t) = network_time {
info!("SNTP timestamp received: {:?}", t);
}
let mut timeout = sntp.next_poll(timestamp);
iface
.poll_delay(&sockets, timestamp)
.map(|sockets_timeout| timeout = sockets_timeout);
phy_wait(fd, Some(timeout)).unwrap_or_else(|e| error!("Wait error: {}", e));
}
}