dhcp: remove 0.0.0.0s from the DNS serevr list.

tp-link routers pad the DNS server list with 0.0.0.0 to a fixed size :(
master
Dario Nieuwenhuis 2021-04-08 01:33:04 +02:00
parent b1f2bcb678
commit 53b62cfbad
3 changed files with 23 additions and 6 deletions

View File

@ -2,7 +2,7 @@ use crate::{Error, Result};
use crate::wire::{EthernetAddress, IpProtocol, IpAddress,
Ipv4Cidr, Ipv4Address, Ipv4Repr,
UdpRepr, UDP_HEADER_LEN,
DhcpPacket, DhcpRepr, DhcpMessageType, DHCP_CLIENT_PORT, DHCP_SERVER_PORT};
DhcpPacket, DhcpRepr, DhcpMessageType, DHCP_CLIENT_PORT, DHCP_SERVER_PORT, DHCP_MAX_DNS_SERVER_COUNT};
use crate::wire::dhcpv4::{field as dhcpv4_field};
use crate::socket::SocketMeta;
use crate::time::{Instant, Duration};
@ -36,7 +36,7 @@ pub struct Config {
/// match the DHCP server's address.
pub router: Option<Ipv4Address>,
/// DNS servers
pub dns_servers: [Option<Ipv4Address>; 3],
pub dns_servers: [Option<Ipv4Address>; DHCP_MAX_DNS_SERVER_COUNT],
}
/// Information on how to reach a DHCP server.
@ -256,10 +256,25 @@ impl Dhcpv4Socket {
let lease_duration = dhcp_repr.lease_duration.unwrap_or(DEFAULT_LEASE_DURATION);
// Cleanup the DNS servers list, keeping only unicasts/
// TP-Link TD-W8970 sends 0.0.0.0 as second DNS server if there's only one configured :(
let mut dns_servers = [None; DHCP_MAX_DNS_SERVER_COUNT];
if let Some(received) = dhcp_repr.dns_servers {
let mut i = 0;
for addr in received.iter() {
if let Some(addr) = addr{
if addr.is_unicast() {
// This can never be out-of-bounds since both arrays have length DHCP_MAX_DNS_SERVER_COUNT
dns_servers[i] = Some(*addr);
i += 1;
}
}
}
}
let config = Config{
address: Ipv4Cidr::new(dhcp_repr.your_ip, prefix_len),
router: dhcp_repr.router,
dns_servers: dhcp_repr.dns_servers.unwrap_or([None; 3]),
dns_servers: dns_servers
};
// RFC 2131 indicates clients should renew a lease halfway through its expiration.

View File

@ -8,6 +8,7 @@ use crate::wire::arp::Hardware;
pub const SERVER_PORT: u16 = 67;
pub const CLIENT_PORT: u16 = 68;
pub const MAX_DNS_SERVER_COUNT: usize = 3;
const DHCP_MAGIC_NUMBER: u32 = 0x63825363;
@ -686,7 +687,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_SERVER_COUNT]>,
/// The maximum size dhcp packet the interface can receive
pub max_size: Option<u16>,
/// The DHCP IP lease duration, specified in seconds.
@ -780,7 +781,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_SERVER_COUNT];
for (server, chunk) in servers.iter_mut().zip(data.chunks(4)) {
*server = Some(Ipv4Address::from_bytes(chunk));
}

View File

@ -225,4 +225,5 @@ pub use self::dhcpv4::{Packet as DhcpPacket,
Repr as DhcpRepr,
MessageType as DhcpMessageType,
CLIENT_PORT as DHCP_CLIENT_PORT,
SERVER_PORT as DHCP_SERVER_PORT};
SERVER_PORT as DHCP_SERVER_PORT,
MAX_DNS_SERVER_COUNT as DHCP_MAX_DNS_SERVER_COUNT};