1#![recursion_limit = "1024"]
23
24#[macro_use]
25extern crate custom_derive;
26#[macro_use]
27extern crate conv;
28#[macro_use]
29extern crate log;
30extern crate byteorder;
31
32use protocol::{ReadBytes, ConstPackedSizeBytes, WriteBytes};
33use std::io;
34use std::net::{ToSocketAddrs, UdpSocket};
35use std::time::Duration;
36
37pub mod protocol;
38pub mod unix_time;
39
40pub fn request<A: ToSocketAddrs>(addr: A) -> io::Result<protocol::Packet> {
47 let mut packet = {
49 let leap_indicator = protocol::LeapIndicator::default();
50 let version = protocol::Version::V4;
51 let mode = protocol::Mode::Client;
52 let poll = 0;
53 let precision = 0;
54 let root_delay = protocol::ShortFormat::default();
55 let root_dispersion = protocol::ShortFormat::default();
56 let transmit_timestamp = unix_time::Instant::now().into();
57 let stratum = protocol::Stratum::UNSPECIFIED;
58 let src = protocol::PrimarySource::Null;
59 let reference_id = protocol::ReferenceIdentifier::PrimarySource(src);
60 let reference_timestamp = protocol::TimestampFormat::default();
61 let receive_timestamp = protocol::TimestampFormat::default();
62 let origin_timestamp = protocol::TimestampFormat::default();
63 protocol::Packet {
64 leap_indicator,
65 version,
66 mode,
67 stratum,
68 poll,
69 precision,
70 root_delay,
71 root_dispersion,
72 reference_id,
73 reference_timestamp,
74 origin_timestamp,
75 receive_timestamp,
76 transmit_timestamp,
77 }
78 };
79
80 let mut bytes = [0u8; protocol::Packet::PACKED_SIZE_BYTES];
82 (&mut bytes[..]).write_bytes(&packet)?;
83
84 let sock = UdpSocket::bind("0.0.0.0:0")?;
86 sock.set_read_timeout(Some(Duration::from_secs(5)))?;
87 sock.set_write_timeout(Some(Duration::from_secs(5)))?;
88
89 let sz = sock.send_to(&bytes, addr)?;
91 debug!("{:?}", sock.local_addr());
92 debug!("sent: {}", sz);
93
94 let res = sock.recv(&mut bytes[..])?;
96 debug!("recv: {:?}", res);
97 debug!("{:?}", &bytes[..]);
98
99 packet = (&bytes[..]).read_bytes()?;
101 Ok(packet)
102}
103
104#[test]
105fn test_request_ntp_org() {
106 let res = request("0.pool.ntp.org:123");
107 let _ = res.expect("Failed to get a ntp packet from ntp.org");
108}
109
110#[test]
111fn test_request_google() {
112 let res = request("time.google.com:123");
113 let _ = res.expect("Failed to get a ntp packet from time.google.com");
114}