aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHimbeerserverDE <himbeerserverde@gmail.com>2024-01-17 10:51:23 +0100
committerHimbeerserverDE <himbeerserverde@gmail.com>2024-01-17 10:51:23 +0100
commit00d865d82ec3e35532af74cc3daa78d16e9de2d0 (patch)
tree3525577412c15525cfefe405339bd5cea34ffe6c
parentb278ff9010c60f8f9d7cdf5e9d0c42a78effbaf0 (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.lock2
-rw-r--r--Cargo.toml2
-rw-r--r--src/error.rs4
-rw-r--r--src/main.rs32
-rw-r--r--src/util.rs12
5 files changed, 25 insertions, 27 deletions
diff --git a/Cargo.lock b/Cargo.lock
index ddc116e..e411266 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -531,7 +531,7 @@ dependencies = [
[[package]]
name = "rsdsl_dhcp4d"
-version = "0.2.5"
+version = "0.2.6"
dependencies = [
"dhcproto",
"ipnet",
diff --git a/Cargo.toml b/Cargo.toml
index a35ebcf..f731b2e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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> {