This commit is contained in:
fuckwit 2023-05-29 22:47:09 +02:00
parent 43a0c5926c
commit 2639aeca24

View File

@ -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<RawDhcpOption<'a>>,
}
impl<'a> Dhcpv4Message<'_> {
fn get_option<T>(&self) -> Option<Result<T::Item, DhcpOptionError>>
where
T: DhcpOption,
{
let opt = self.options.iter().find(|a| a.code == T::CODE)?;
Some(T::parse(opt))
@ -70,6 +81,7 @@ impl From<u8> 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,
},
))
}