Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Emit dns servers in DHCPv4 repr. Fixes #504 #505

Merged
merged 5 commits into from
Jun 27, 2021
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 46 additions & 2 deletions src/wire/dhcpv4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ use crate::wire::arp::Hardware;

const DHCP_MAGIC_NUMBER: u32 = 0x63825363;

pub const MAX_DNS_SERVERS: usize = 3;

enum_with_unknown! {
/// The possible opcodes of a DHCP packet.
pub enum OpCode(u8) {
Expand Down Expand Up @@ -680,7 +682,7 @@ pub struct Repr<'a> {
/// the client is interested in.
pub parameter_request_list: Option<&'a [u8]>,
/// DNS servers
pub dns_servers: Option<[Option<Ipv4Address>; 3]>,
pub dns_servers: Option<[Option<Ipv4Address>; MAX_DNS_SERVERS]>,
/// The maximum size dhcp packet the interface can receive
pub max_size: Option<u16>,
/// The DHCP IP lease duration, specified in seconds.
Expand All @@ -700,6 +702,11 @@ impl<'a> Repr<'a> {
if self.router.is_some() { len += 6; }
if self.subnet_mask.is_some() { len += 6; }
if self.lease_duration.is_some() { len += 6; }
if let Some(dns_servers) = self.dns_servers {
len += 2;
len += dns_servers.iter()
theli-ua marked this conversation as resolved.
Show resolved Hide resolved
.filter(|d| d.is_some()).map(|_| 4).sum::<usize>();
}
if let Some(list) = self.parameter_request_list { len += list.len() + 2; }

len
Expand Down Expand Up @@ -777,7 +784,7 @@ impl<'a> Repr<'a> {
parameter_request_list = Some(data);
}
DhcpOption::Other {kind: field::OPT_DOMAIN_NAME_SERVER, data} => {
let mut servers = [None; 3];
let mut servers = [None; MAX_DNS_SERVERS];
for (server, chunk) in servers.iter_mut().zip(data.chunks(4)) {
*server = Some(Ipv4Address::from_bytes(chunk));
}
Expand Down Expand Up @@ -842,6 +849,20 @@ impl<'a> Repr<'a> {
if let Some(duration) = self.lease_duration {
let tmp = options; options = DhcpOption::IpLeaseTime(duration).emit(tmp);
}
if let Some(dns_servers) = self.dns_servers {
const IP_SIZE: usize = core::mem::size_of::<u32>();
let mut servers = [0; MAX_DNS_SERVERS * IP_SIZE];

let data_len = dns_servers.iter().filter(|o| o.is_some())
.enumerate()
.map(|(i, ip)| {
theli-ua marked this conversation as resolved.
Show resolved Hide resolved
servers[(i * IP_SIZE)..((i + 1) * IP_SIZE)]
.copy_from_slice(ip.unwrap().as_bytes());
theli-ua marked this conversation as resolved.
Show resolved Hide resolved
i + 1
}).last().unwrap_or(0);
theli-ua marked this conversation as resolved.
Show resolved Hide resolved
let option = DhcpOption::Other{ kind: field::OPT_DOMAIN_NAME_SERVER, data: &servers[..IP_SIZE * data_len] };
let tmp = options; options = option.emit(tmp);
}
if let Some(list) = self.parameter_request_list {
let option = DhcpOption::Other{ kind: field::OPT_PARAMETER_REQUEST_LIST, data: list };
let tmp = options; options = option.emit(tmp);
Expand Down Expand Up @@ -1088,6 +1109,29 @@ mod test {
repr.emit(&mut packet).unwrap();
}

#[test]
fn test_emit_offer_dns() {
let repr = {
let mut repr = offer_repr();
repr.dns_servers = Some([
Some(Ipv4Address([163, 1, 74, 6])),
Some(Ipv4Address([163, 1, 74, 7])),
Some(Ipv4Address([163, 1, 74, 3]))]);
repr
};
let mut bytes = vec![0xa5; repr.buffer_len()];
let mut packet = Packet::new_unchecked(&mut bytes);
repr.emit(&mut packet).unwrap();

let packet = Packet::new_unchecked(&bytes);
let repr_parsed = Repr::parse(&packet).unwrap();

assert_eq!(repr_parsed.dns_servers, Some([
Some(Ipv4Address([163, 1, 74, 6])),
Some(Ipv4Address([163, 1, 74, 7])),
Some(Ipv4Address([163, 1, 74, 3]))]));
}

#[test]
fn test_emit_dhcp_option() {
static DATA: &[u8] = &[1, 3, 6];
Expand Down