diff options
author | HimbeerserverDE <himbeerserverde@gmail.com> | 2024-01-17 10:51:23 +0100 |
---|---|---|
committer | HimbeerserverDE <himbeerserverde@gmail.com> | 2024-01-17 10:51:23 +0100 |
commit | 00d865d82ec3e35532af74cc3daa78d16e9de2d0 (patch) | |
tree | 3525577412c15525cfefe405339bd5cea34ffe6c | |
parent | b278ff9010c60f8f9d7cdf5e9d0c42a78effbaf0 (diff) |
support clients that don't send a client identifier0.2.6
Uses the chaddr field to generate a client id based on the MAC address preceeded by 0x01. Increases compatibility with IoT devices.
-rw-r--r-- | Cargo.lock | 2 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | src/error.rs | 4 | ||||
-rw-r--r-- | src/main.rs | 32 | ||||
-rw-r--r-- | src/util.rs | 12 |
5 files changed, 25 insertions, 27 deletions
@@ -531,7 +531,7 @@ dependencies = [ [[package]] name = "rsdsl_dhcp4d" -version = "0.2.5" +version = "0.2.6" dependencies = [ "dhcproto", "ipnet", @@ -1,6 +1,6 @@ [package] name = "rsdsl_dhcp4d" -version = "0.2.5" +version = "0.2.6" authors = ["HimbeerserverDE <himbeerserverde@gmail.com>"] license = "MIT" edition = "2021" diff --git a/src/error.rs b/src/error.rs index baa97cb..8d149ee 100644 --- a/src/error.rs +++ b/src/error.rs @@ -5,16 +5,12 @@ use thiserror::Error; #[derive(Debug, Error)] pub enum Error { - #[error("empty client id")] - EmptyClientId, #[error("unhandled or unknown message type {0:?}")] InvalidMsgType(MessageType), #[error("unhandled or unknown opcode {0:?}")] InvalidOpcode(Opcode), #[error("missing ip address in dhcprequest")] NoAddrRequested, - #[error("missing client id")] - NoClientId, #[error("no ipv4 address on interface {0}")] NoIpv4Addr(String), #[error("missing message type")] diff --git a/src/main.rs b/src/main.rs index e3b0629..0de6529 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ use rsdsl_dhcp4d::lease::{LeaseFileManager, LeaseFileManagerConfig, LeaseManager}; -use rsdsl_dhcp4d::util::{format_client_id, local_ip, setsockopt}; +use rsdsl_dhcp4d::util::*; use rsdsl_dhcp4d::{Error, Result}; use std::ffi::CString; @@ -142,10 +142,8 @@ fn handle_request<T: LeaseManager>( match msg_type { MessageType::Discover => { - let client_id = match opts - .get(OptionCode::ClientIdentifier) - .ok_or(Error::NoClientId)? - { + let chid = gen_client_id(msg.chaddr()); + let client_id = match opts.get(OptionCode::ClientIdentifier).unwrap_or(&chid) { DhcpOption::ClientIdentifier(id) => id, _ => unreachable!(), }; @@ -193,7 +191,7 @@ fn handle_request<T: LeaseManager>( println!( "[info] offer {} client id {} lease time {:?} on {}", lease.address, - format_client_id(client_id)?, + format_client_id(client_id), lease.lease_time, link ); @@ -204,10 +202,8 @@ fn handle_request<T: LeaseManager>( MessageType::Request => { let mut lease_mgr = lease_mgr.lock().unwrap(); - let client_id = match opts - .get(OptionCode::ClientIdentifier) - .ok_or(Error::NoClientId)? - { + let chid = gen_client_id(msg.chaddr()); + let client_id = match opts.get(OptionCode::ClientIdentifier).unwrap_or(&chid) { DhcpOption::ClientIdentifier(id) => id, _ => unreachable!(), }; @@ -261,14 +257,14 @@ fn handle_request<T: LeaseManager>( println!( "[info] nak {} client id {} on {} (renew)", requested_addr, - format_client_id(client_id)?, + format_client_id(client_id), link ); } else { println!( "[info] nak {} client id {} on {}", requested_addr, - format_client_id(client_id)?, + format_client_id(client_id), link ); } @@ -303,7 +299,7 @@ fn handle_request<T: LeaseManager>( println!( "[info] ack {} client id {} lease time {:?} on {} (renew)", requested_addr, - format_client_id(client_id)?, + format_client_id(client_id), lease_time, link ); @@ -311,7 +307,7 @@ fn handle_request<T: LeaseManager>( println!( "[info] ack {} client id {} lease time {:?} on {}", requested_addr, - format_client_id(client_id)?, + format_client_id(client_id), lease_time, link ); @@ -325,10 +321,8 @@ fn handle_request<T: LeaseManager>( Ok(()) } MessageType::Release => { - let client_id = match opts - .get(OptionCode::ClientIdentifier) - .ok_or(Error::NoClientId)? - { + let chid = gen_client_id(msg.chaddr()); + let client_id = match opts.get(OptionCode::ClientIdentifier).unwrap_or(&chid) { DhcpOption::ClientIdentifier(id) => id, _ => unreachable!(), }; @@ -344,7 +338,7 @@ fn handle_request<T: LeaseManager>( println!( "[info] release {} client id {} on {}", released_pretty, - format_client_id(client_id)?, + format_client_id(client_id), link ); Ok(()) diff --git a/src/util.rs b/src/util.rs index 26ac950..cd595dd 100644 --- a/src/util.rs +++ b/src/util.rs @@ -4,6 +4,7 @@ use std::ffi::{c_char, c_int}; use std::io; use std::net::{IpAddr, Ipv4Addr}; +use dhcproto::v4::DhcpOption; use rsdsl_netlinklib::blocking::Connection; /// Helper macro to execute a system call that returns an `io::Result`. @@ -19,12 +20,19 @@ macro_rules! syscall { }}; } -pub fn format_client_id(client_id: &[u8]) -> Result<String> { +pub fn gen_client_id(hwaddr: &[u8]) -> DhcpOption { + let mut client_id = vec![0x01]; + client_id.extend_from_slice(hwaddr); + + DhcpOption::ClientIdentifier(client_id) +} + +pub fn format_client_id(client_id: &[u8]) -> String { client_id .iter() .map(|octet| format!("{:02x}", octet)) .reduce(|acc, octet| acc + ":" + &octet) - .ok_or(Error::EmptyClientId) + .unwrap_or(String::new()) } pub fn local_ip(conn: &Connection, link: String) -> Result<Ipv4Addr> { |