blob: 97177e9a89e62825c7cc85d9a3df141e30d2d708 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#![deny(warnings)]
#![feature(async_await, await_macro)]
use {
dhcp::protocol::{ConfigOption, Message, MessageType, OptionCode, CLIENT_PORT, SERVER_PORT},
failure::{Error, ResultExt},
fidl_fuchsia_hardware_ethernet_ext::MacAddress as MacAddr,
fuchsia_async::{net::UdpSocket, Executor},
std::net::SocketAddr,
};
const TEST_MAC: [u8; 6] = [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF];
fn main() -> Result<(), Error> {
println!("fake_client: starting...");
let mut exec = Executor::new().context("error creating executor")?;
let (sock, server) = build_and_bind_socket();
let disc = build_discover();
println!("Sending discover message: {:?}", disc);
let send_msgs = async move {
let serialized = disc.serialize();
await!(sock.send_to(&serialized, server))?;
let mut buf = vec![0u8; 1024];
let (bytes_recvd, _addr) = await!(sock.recv_from(&mut buf))?;
let offer = Message::from_buffer(&buf[0..bytes_recvd]).unwrap();
println!("fake_client: msg rcvd {:?}", offer);
let req = build_request(offer);
println!("fake_client: sending request msg {:?}", req);
let serialized = req.serialize();
await!(sock.send_to(&serialized, server))?;
let (bytes_recvd, _addr) = await!(sock.recv_from(&mut buf))?;
let ack = Message::from_buffer(&buf[0..bytes_recvd]).unwrap();
println!("fake_client: msg rcvd {:?}", ack);
Ok::<(), Error>(())
};
println!("fake_client: sending messages...");
exec.run_singlethreaded(send_msgs)
.context("could not run futures")?;
println!("fake_client: messages sent...");
Ok(())
}
fn build_and_bind_socket() -> (UdpSocket, SocketAddr) {
let addr = SocketAddr::new("127.0.0.1".parse().unwrap(), CLIENT_PORT);
let server = SocketAddr::new("127.0.0.1".parse().unwrap(), SERVER_PORT);
let udp_socket = UdpSocket::bind(&addr)
.context("error binding socket")
.unwrap();
(udp_socket, server)
}
fn build_discover() -> Message {
let mut disc = Message::new();
disc.xid = 42;
disc.chaddr = MacAddr { octets: TEST_MAC };
disc.options.push(ConfigOption {
code: OptionCode::DhcpMessageType,
value: vec![MessageType::DHCPDISCOVER.into()],
});
disc
}
fn build_request(offer: Message) -> Message {
let mut req = Message::new();
req.xid = 42;
req.ciaddr = offer.yiaddr;
req.chaddr = MacAddr { octets: TEST_MAC };
req.options.push(ConfigOption {
code: OptionCode::DhcpMessageType,
value: vec![MessageType::DHCPREQUEST.into()],
});
let server_id = offer
.get_config_option(OptionCode::ServerId)
.unwrap()
.clone();
req.options.push(server_id);
req
}