dhcpv4: Emit DNS servers in repr

This commit is contained in:
Anton Romanov 2021-06-28 20:03:39 +02:00 committed by Dario Nieuwenhuis
parent 3782d6425e
commit 7a83e7d69b
1 changed files with 51 additions and 0 deletions

View File

@ -727,6 +727,10 @@ impl<'a> Repr<'a> {
if self.lease_duration.is_some() {
len += 6;
}
if let Some(dns_servers) = self.dns_servers {
len += 2;
len += dns_servers.iter().flatten().count() * core::mem::size_of::<u32>();
}
if let Some(list) = self.parameter_request_list {
len += list.len() + 2;
}
@ -892,6 +896,25 @@ impl<'a> Repr<'a> {
if let Some(duration) = self.lease_duration {
options = DhcpOption::IpLeaseTime(duration).emit(options);
}
if let Some(dns_servers) = self.dns_servers {
const IP_SIZE: usize = core::mem::size_of::<u32>();
let mut servers = [0; MAX_DNS_SERVER_COUNT * IP_SIZE];
let data_len = dns_servers
.iter()
.flatten()
.enumerate()
.inspect(|(i, ip)| {
servers[(i * IP_SIZE)..((i + 1) * IP_SIZE)].copy_from_slice(ip.as_bytes());
})
.count()
* IP_SIZE;
let option = DhcpOption::Other {
kind: field::OPT_DOMAIN_NAME_SERVER,
data: &servers[..data_len],
};
options = option.emit(options);
}
if let Some(list) = self.parameter_request_list {
options = DhcpOption::Other {
kind: field::OPT_PARAMETER_REQUEST_LIST,
@ -1151,6 +1174,34 @@ 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];