summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorache <ache@ache.one>2019-08-29 02:13:14 +0200
committerache <ache@ache.one>2019-08-29 02:13:14 +0200
commit93e1ba1e2b9852376cce8bf4b03f260598d5ca6c (patch)
treeb5420d9d9f23da705331c96908a81ad47c55d548
parentInit commit (diff)
Detect DHCP Message Type
-rw-r--r--src/main.rs104
1 files changed, 76 insertions, 28 deletions
diff --git a/src/main.rs b/src/main.rs
index f514adf..712b2d9 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -2,19 +2,22 @@ use std::net::UdpSocket;
use std::net;
use std::str;
use std::fmt;
+use std::mem;
const BUFFER_SIZE: usize = 5000;
const SERVER_PORT: u16 = 67;
-enum DHCP_MESSAGE_TYPE {
- DHCPDISCOVER = 1,
- DHCPOFFER = 2,
- DHCPREQUEST = 3,
- DHCPDECLINE,
- DHCPPACK,
- DHCPNAK,
- DHCPRELEASE,
- DHCPINFORM
+const IP_SERVER: net::Ipv4Addr = net::Ipv4Addr::new(10, 2, 0, 11);
+
+enum DhcpMessageType {
+ DHCPDISCOVER = 1, // Send by client
+ DHCPOFFER = 2, // Send by server
+ DHCPREQUEST = 3, // Send by client
+ DHCPDECLINE, // Send by client
+ DHCPPACK, // Send by server
+ DHCPNAK, // Send by server
+ DHCPRELEASE, // Send by client
+ DHCPINFORM // Not send
}
const OPTIONS_NAME : [&str;77] = ["Pad", // 0
@@ -113,6 +116,31 @@ struct DhcpMessage {
file: [u8; 128],
options: [u8; 312]
}
+impl DhcpMessage {
+ fn request_type( &self ) -> Option<DhcpMessageType> {
+ let mut i = 4; // Magic cookie ! 🍪
+ loop {
+ if i >= 312 {
+ return None;
+ }
+ let i_tmp : usize = usize::from(i);
+ if self.options[i_tmp] == 53 {
+ if self.options[i_tmp+2] > 0 && self.options[i_tmp+2] < 9 {
+ print!("Type: {}\n", self.options[i_tmp+2]);
+ return Some(unsafe { mem::transmute(self.options[i_tmp+2]) });
+ } else {
+ return None
+ }
+ } else if self.options[i_tmp] == 0 || self.options[i_tmp] == 255 {
+ i += 1
+ } else if self.options[i_tmp] < 77 {
+ i += u16::from(self.options[i_tmp+1]);
+ } else {
+ return None;
+ }
+ }
+ }
+}
impl fmt::Display for DhcpMessage {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -150,25 +178,39 @@ impl fmt::Display for DhcpMessage {
self.siaddr, self.giaddr, self.chaddr[0],
self.chaddr[1], self.chaddr[2], self.chaddr[3],
self.chaddr[4], self.chaddr[5], name,
- if is_file_empty { "empty" } else {"not empty"});
- write!(f, "options :\n");
+ if is_file_empty { "empty" } else {"not empty"})?;
+ write!(f, "options :\n(\n")?;
let mut i: u16 = 0;
+ { // Check for Magic Cookie 🍪
+ let i_tmp : usize = usize::from(i);
+ if self.options[i_tmp] == 0x63 &&
+ self.options[i_tmp+1] == 0x82 &&
+ self.options[i_tmp+2] == 0x53 &&
+ self.options[i_tmp+3] == 0x63 {
+ write!(f, " MAGIC COOKIE 0x63825363\n")?;
+ i += 4
+ }
+ }
loop {
if i >= 312 {
break;
}
- let I : usize = usize::from(i);
- if self.options[I] == 0xFF {
- write!(f, " End Option(0xFF)");
+ let i_tmp : usize = usize::from(i);
+ if self.options[i_tmp] == 0xFF {
+ write!(f, " End Option(0xFF)\n")?;
break;
- } else if self.options[I] == 0 {
- write!(f, " Pad Option(0x00)");
- i += 1;
- } else if self.options[I] < 77 {
- write!(f, " {} Option({:02x})\n", OPTIONS_NAME[usize::from(self.options[I])], self.options[I]);
- i += u16::from(self.options[I+1]);
+ } else if self.options[i_tmp] == 0 {
+ let mut times: u16= 1;
+ while i_tmp + usize::from(times) < 312 && self.options[i_tmp+usize::from(times)] == 0 {
+ times += 1;
+ }
+ write!(f, " Pad Option(0x00) x{}\n", times)?;
+ i += times;
+ } else if self.options[i_tmp] < 77 {
+ write!(f, " {} Option({:02x})\n", OPTIONS_NAME[usize::from(self.options[i_tmp])], self.options[i_tmp])?;
+ i += u16::from(self.options[i_tmp+1]);
} else {
- write!(f, " Unknow Option({:02x})", self.options[I]);
+ write!(f, " Unknow Option({:02x})\n", self.options[i_tmp])?;
break;
}
}
@@ -210,22 +252,22 @@ fn fill_dhcp_message( dhcp_message: &mut DhcpMessage, buf : &[u8; BUFFER_SIZE],
dhcp_message.siaddr = u32::from_be_bytes([buf[20], buf[21], buf[22], buf[23]]);
dhcp_message.giaddr = u32::from_be_bytes([buf[24], buf[25], buf[26], buf[27]]);
dhcp_message.chaddr = [buf[28], buf[29], buf[30], buf[31], buf[32], buf[33]];
+
for i in 0..64 {
- dhcp_message.sname[i] = buf[i+34]
+ dhcp_message.sname[i] = buf[i+34];
}
for i in 0..128 {
- dhcp_message.file[i] = buf[i+98]
+ dhcp_message.file[i] = buf[i+98];
}
- let size = if size > 226 + 538 { 538 } else { size };
- for i in 226..size {
- dhcp_message.options[i-226] = buf[i+98]
+ let size = if size > 538 { 538 } else { size };
+ for i in 236..size {
+ dhcp_message.options[i-236] = buf[i];
}
-
-
true
}
+
fn main() -> std::io::Result<()> {
{
let addrs = [
@@ -234,6 +276,7 @@ fn main() -> std::io::Result<()> {
let socket = UdpSocket::bind(&addrs[..])?;
loop {
+ print!("Ready to listen ! 🦊\n");
// Receives a single datagram message on the socket. If `buf` is too small to hold
// the message, it will be cut off.
let mut buf = [0; BUFFER_SIZE];
@@ -252,6 +295,11 @@ fn main() -> std::io::Result<()> {
if dhcp_message.xid == 42 {
break
}
+ if let Some(DhcpMessageType::DHCPDISCOVER) = dhcp_message.request_type() {
+ print!("It's a discovery !\n");
+ } else {
+ print!("It's not a discovery !\n");
+ }
}
} // the socket is closed here
Ok(())