diff --git a/src/lib.rs b/src/lib.rs index 45c6982..4715ae2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,9 @@ #![allow(unused)] -use std::{net::Ipv4Addr, path::Path}; +#![feature(ip_in_core)] +#![feature(error_in_core)] +mod options; +extern crate alloc; + //#![no_std] use alloc::vec::Vec; use core::net::Ipv4Addr; @@ -25,8 +29,15 @@ struct Dhcpv4Message<'a> { server_address: Ipv4Addr, gateway_address: Ipv4Addr, client_hardware_address: &'a [u8], - server_name: &'a str, - file_name: &'a Path, + server_name: Option<&'a str>, + file_name: Option<&'a str>, + options: Vec>, +} + +impl<'a> Dhcpv4Message<'_> { + fn get_option(&self) -> Option> + where + T: DhcpOption, { let opt = self.options.iter().find(|a| a.code == T::CODE)?; Some(T::parse(opt)) @@ -70,6 +81,7 @@ impl From for HardwareType { } } +fn parse_operation(i: &[u8]) -> IResult<&[u8], Operation> { be_u8(i).map(|(i, v)| (i, v.into())) } @@ -101,9 +113,6 @@ fn parse_server_name(i: &[u8]) -> IResult<&[u8], &str> { Ok((i, val)) } -fn parse_file(i: &[u8]) -> IResult<&[u8], &Path> { - let nullbyte_position = i.iter().position(|v| *v == b'\0').unwrap_or(128); - let val = unsafe { std::str::from_utf8_unchecked(&i[..nullbyte_position]) }; fn parse_option(i: &[u8]) -> IResult<&[u8], RawDhcpOption> { let (i, code) = be_u8(i)?; let (i, length) = be_u8(i)?; @@ -114,8 +123,10 @@ fn parse_option(i: &[u8]) -> IResult<&[u8], RawDhcpOption> { fn parse_file(i: &[u8]) -> IResult<&[u8], &str> { let (i, val) = take(128usize)(i)?; + let nullbyte_position = val.iter().position(|v| *v == b'\0').unwrap_or(128); + let val = unsafe { core::str::from_utf8_unchecked(&val[..nullbyte_position]) }; - Ok((i, Path::new(val))) + Ok((i, val)) } fn parse_dhcp_packet(packet: &[u8]) -> IResult<&[u8], Dhcpv4Message> { @@ -134,8 +145,9 @@ fn parse_dhcp_packet(packet: &[u8]) -> IResult<&[u8], Dhcpv4Message> { let (packet, server_name_bytes) = take(64usize)(packet)?; let (packet, file_name_bytes) = take(128usize)(packet)?; - let (_, server_name) = parse_server_name(server_name_bytes)?; - let (_, file_name) = parse_file(file_name_bytes)?; + let mut options = Vec::new(); + let mut server_name = None; + let mut file_name = None; if let Ok((mut packet, magic)) = take::<_, _, ()>(4usize)(packet) { while !packet.is_empty() && packet[0] != 0xff { let (remaining, option) = parse_option(packet)?; @@ -164,6 +176,7 @@ fn parse_dhcp_packet(packet: &[u8]) -> IResult<&[u8], Dhcpv4Message> { client_hardware_address, server_name, file_name, + options, }, )) }