use super::*;
use mac_address::MacAddress;
use std::net::Ipv4Addr;
#[derive(Debug, PartialEq)]
pub struct Message {
pub op: Ops,
pub htype: HTypes,
pub hlen: u8,
pub hops: u8,
pub xid: u32,
pub secs: u16,
pub flags: Flags,
pub ciaddr: Ipv4Addr,
pub yiaddr: Ipv4Addr,
pub siaddr: Ipv4Addr,
pub giaddr: Ipv4Addr,
pub chaddr: [u8; 16],
pub sname: SName,
pub file: File,
pub magic: MagicBuffer,
pub options: MessageOptionsList,
}
impl Encodable for Message {}
impl Decodable for Message {}
impl MessageHelpers for Message {
fn find_option(&self, tag: u8) -> Option<&MessageOptions> {
self.options.find_option(tag)
}
fn add_option(&mut self, option: MessageOptions) {
self.options.add_option(option);
}
fn get_mac_address(&self) -> MacAddress {
MacAddress::new([
self.chaddr[0],
self.chaddr[1],
self.chaddr[2],
self.chaddr[3],
self.chaddr[4],
self.chaddr[5],
])
}
}
impl DecodeMessage for Message {
type Op = Ops;
type Htype = HTypes;
type Hlen = u8;
type Hops = u8;
type Xid = u32;
type Secs = u16;
type Flags = Flags;
type Ciaddr = Ipv4Addr;
type Yiaddr = Ipv4Addr;
type Siaddr = Ipv4Addr;
type Giaddr = Ipv4Addr;
type Chaddr = [u8; 16];
type Sname = SName;
type File = File;
type Magic = MagicBuffer;
type Options = MessageOptionsList;
type Output = Self;
fn decode_op(undecoded: &UndecodedMessage) -> Self::Op {
Self::Op::from(undecoded.slice_op())
}
fn decode_htype(undecoded: &UndecodedMessage) -> Self::Htype {
Self::Htype::from(undecoded.slice_htype())
}
fn decode_hlen(undecoded: &UndecodedMessage) -> Self::Hlen {
undecoded.slice_hlen()
}
fn decode_hops(undecoded: &UndecodedMessage) -> Self::Hops {
undecoded.slice_hops()
}
fn decode_xid(undecoded: &UndecodedMessage) -> Self::Xid {
let bytes = undecoded.slice_xid();
u32::from_be_bytes(bytes)
}
fn decode_secs(undecoded: &UndecodedMessage) -> Self::Secs {
let bytes = undecoded.slice_secs();
u16::from_be_bytes(bytes)
}
fn decode_flags(undecoded: &UndecodedMessage) -> Self::Flags {
Self::Flags::from(undecoded.slice_flags_temporary())
}
fn decode_ciaddr(undecoded: &UndecodedMessage) -> Self::Ciaddr {
let bytes = undecoded.slice_ciaddr();
Ipv4Addr::from(bytes)
}
fn decode_yiaddr(undecoded: &UndecodedMessage) -> Self::Yiaddr {
let bytes = undecoded.slice_yiaddr();
Ipv4Addr::from(bytes)
}
fn decode_siaddr(undecoded: &UndecodedMessage) -> Self::Siaddr {
let bytes = undecoded.slice_siaddr();
Ipv4Addr::from(bytes)
}
fn decode_giaddr(undecoded: &UndecodedMessage) -> Self::Giaddr {
let bytes = undecoded.slice_giaddr();
Ipv4Addr::from(bytes)
}
fn decode_chaddr(undecoded: &UndecodedMessage) -> Self::Chaddr {
undecoded.slice_chaddr()
}
fn decode_sname(undecoded: &UndecodedMessage) -> Self::Sname {
SName::from_array(undecoded.slice_sname())
}
fn decode_file(undecoded: &UndecodedMessage) -> Self::File {
File::from_array(undecoded.slice_file())
}
fn decode_magic(_magic: &UndecodedMessage) -> Self::Magic {
MAGIC
}
fn decode_options(undecoded: &UndecodedMessage) -> Self::Options {
MessageOptionsList::from_bytes(&undecoded.slice_options())
}
fn from_bytes(undecoded: &UndecodedMessage) -> Self::Output {
Message {
op: Self::decode_op(undecoded),
htype: Self::decode_htype(undecoded),
hlen: Self::decode_hlen(undecoded),
hops: Self::decode_hops(undecoded),
xid: Self::decode_xid(undecoded),
secs: Self::decode_secs(undecoded),
flags: Self::decode_flags(undecoded),
ciaddr: Self::decode_ciaddr(undecoded),
yiaddr: Self::decode_yiaddr(undecoded),
siaddr: Self::decode_siaddr(undecoded),
giaddr: Self::decode_giaddr(undecoded),
chaddr: Self::decode_chaddr(undecoded),
sname: Self::decode_sname(undecoded),
file: Self::decode_file(undecoded),
magic: Self::decode_magic(undecoded),
options: Self::decode_options(undecoded),
}
}
}
impl EncodeMessage for Message {
#[inline]
fn encode_op(&self) -> u8 {
(&self.op).into()
}
#[inline]
fn encode_htype(&self) -> u8 {
(&self.htype).into()
}
#[inline]
fn encode_hlen(&self) -> u8 {
self.hlen
}
#[inline]
fn encode_hops(&self) -> u8 {
self.hops
}
#[inline]
fn encode_xid(&self) -> [u8; 4] {
self.xid.to_be_bytes()
}
#[inline]
fn encode_secs(&self) -> [u8; 2] {
self.secs.to_be_bytes()
}
#[inline]
fn encode_flags(&self) -> [u8; 2] {
self.flags.temporary_to_bytes()
}
#[inline]
fn encode_ciaddr(&self) -> [u8; 4] {
self.ciaddr.octets()
}
#[inline]
fn encode_yiaddr(&self) -> [u8; 4] {
self.yiaddr.octets()
}
#[inline]
fn encode_siaddr(&self) -> [u8; 4] {
self.siaddr.octets()
}
#[inline]
fn encode_giaddr(&self) -> [u8; 4] {
self.giaddr.octets()
}
#[inline]
fn encode_chaddr(&self) -> [u8; 16] {
self.chaddr
}
#[inline]
fn encode_sname(&self) -> [u8; 64] {
(&self.sname).into()
}
#[inline]
fn encode_file(&self) -> [u8; 128] {
(&self.file).into()
}
#[inline]
fn encode_options(&self) -> Vec<u8> {
(&self.options).into()
}
}