Compare commits
No commits in common. "1ea4715b59723cb077357249c02ffaa504b1f3ed" and "b3ec1bf1bf9879de2ea514e119fd3f7c64af1b27" have entirely different histories.
1ea4715b59
...
b3ec1bf1bf
44
Cargo.lock
generated
44
Cargo.lock
generated
@ -75,12 +75,6 @@ dependencies = [
|
|||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "anyhow"
|
|
||||||
version = "1.0.86"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-trait"
|
name = "async-trait"
|
||||||
version = "0.1.81"
|
version = "0.1.81"
|
||||||
@ -211,13 +205,10 @@ checksum = "a7993efb860416547839c115490d4951c6d0f8ec04a3594d9dd99d50ed7ec170"
|
|||||||
name = "dhcpv6stateless"
|
name = "dhcpv6stateless"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
|
||||||
"clap",
|
"clap",
|
||||||
"dhcproto",
|
"dhcproto",
|
||||||
"env_logger",
|
|
||||||
"hex",
|
"hex",
|
||||||
"ipnetwork",
|
"ipnetwork",
|
||||||
"log",
|
|
||||||
"pnet",
|
"pnet",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
@ -234,29 +225,6 @@ dependencies = [
|
|||||||
"syn 1.0.109",
|
"syn 1.0.109",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "env_filter"
|
|
||||||
version = "0.1.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab"
|
|
||||||
dependencies = [
|
|
||||||
"log",
|
|
||||||
"regex",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "env_logger"
|
|
||||||
version = "0.11.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d"
|
|
||||||
dependencies = [
|
|
||||||
"anstream",
|
|
||||||
"anstyle",
|
|
||||||
"env_filter",
|
|
||||||
"humantime",
|
|
||||||
"log",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "form_urlencoded"
|
name = "form_urlencoded"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
@ -353,12 +321,6 @@ version = "0.4.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "humantime"
|
|
||||||
version = "2.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "idna"
|
name = "idna"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
@ -413,12 +375,6 @@ version = "0.2.158"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
|
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "log"
|
|
||||||
version = "0.4.22"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "matches"
|
name = "matches"
|
||||||
version = "0.1.10"
|
version = "0.1.10"
|
||||||
|
@ -4,12 +4,9 @@ version = "0.1.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.86"
|
|
||||||
clap = { version = "4.5.16", features = ["derive"] }
|
clap = { version = "4.5.16", features = ["derive"] }
|
||||||
dhcproto = "0.12.0"
|
dhcproto = "0.12.0"
|
||||||
env_logger = "0.11.5"
|
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
ipnetwork = "0.20.0"
|
ipnetwork = "0.20.0"
|
||||||
log = "0.4.22"
|
|
||||||
pnet = "0.35.0"
|
pnet = "0.35.0"
|
||||||
tokio = { version = "1.39.3", features = ["macros", "net", "rt-multi-thread"] }
|
tokio = { version = "1.39.3", features = ["macros", "net", "rt-multi-thread"] }
|
||||||
|
12
README.md
12
README.md
@ -2,18 +2,6 @@
|
|||||||
|
|
||||||
This -thing- is doing a DHCPv6 INFORMATION-REQUEST, waits for a response and displays it.
|
This -thing- is doing a DHCPv6 INFORMATION-REQUEST, waits for a response and displays it.
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Pass the interface name as the first parameter:
|
|
||||||
|
|
||||||
```
|
|
||||||
dhcpv6stateless wlp3s0
|
|
||||||
```
|
|
||||||
|
|
||||||
## Logging
|
|
||||||
|
|
||||||
Logging is handled by [Rust env_logger](https://docs.rs/env_logger/latest/env_logger/).
|
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
- <https://datatracker.ietf.org/doc/html/rfc8415#section-6.1>
|
- <https://datatracker.ietf.org/doc/html/rfc8415#section-6.1>
|
||||||
|
44
src/main.rs
44
src/main.rs
@ -1,7 +1,3 @@
|
|||||||
use anyhow::{
|
|
||||||
Context,
|
|
||||||
Result,
|
|
||||||
};
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use dhcproto::{
|
use dhcproto::{
|
||||||
Decodable,
|
Decodable,
|
||||||
@ -17,12 +13,6 @@ use dhcproto::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
use ipnetwork;
|
use ipnetwork;
|
||||||
use log::{
|
|
||||||
debug,
|
|
||||||
log_enabled,
|
|
||||||
info,
|
|
||||||
Level,
|
|
||||||
};
|
|
||||||
use pnet;
|
use pnet;
|
||||||
use std::net::SocketAddrV6;
|
use std::net::SocketAddrV6;
|
||||||
use tokio::net::UdpSocket;
|
use tokio::net::UdpSocket;
|
||||||
@ -40,16 +30,14 @@ struct Cli {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()>{
|
async fn main() {
|
||||||
env_logger::init();
|
|
||||||
|
|
||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
|
|
||||||
let all_interfaces = pnet::datalink::interfaces();
|
let all_interfaces = pnet::datalink::interfaces();
|
||||||
let selected_interface = all_interfaces
|
let selected_interface = all_interfaces
|
||||||
.iter()
|
.iter()
|
||||||
.find(|i| i.name == cli.interface)
|
.find(|i| i.name == cli.interface)
|
||||||
.with_context(|| format!("No interface found with name: {}", cli.interface))?;
|
.expect(format!("No interface found with name: {}", cli.interface).as_str());
|
||||||
|
|
||||||
let ipv6_addresses = selected_interface.ips
|
let ipv6_addresses = selected_interface.ips
|
||||||
.iter()
|
.iter()
|
||||||
@ -62,14 +50,10 @@ async fn main() -> Result<()>{
|
|||||||
|
|
||||||
// Just take the first address found on the interface
|
// Just take the first address found on the interface
|
||||||
let selected_address = ipv6_link_local_addresses.next()
|
let selected_address = ipv6_link_local_addresses.next()
|
||||||
.context("No IPv6 link local address assigned to this interface")?;
|
.expect("No IPv6 link local address assigned to this interface");
|
||||||
|
|
||||||
let socket_addr = SocketAddrV6::new(selected_address.ip(), DHCP_CLIENT_PORT, 0, selected_interface.index.clone());
|
let socket_addr = SocketAddrV6::new(selected_address.ip(), DHCP_CLIENT_PORT, 0, selected_interface.index.clone());
|
||||||
let sock = UdpSocket::bind(socket_addr).await
|
let sock = UdpSocket::bind(socket_addr).await.unwrap();
|
||||||
.context("Unable to bind UDP socket")?;
|
|
||||||
|
|
||||||
info!("Listening on {}", sock.local_addr()
|
|
||||||
.context("Failed to fetch address socket bound to")?);
|
|
||||||
|
|
||||||
let remote_addr = SocketAddrV6::new(ALL_DHCP_RELAY_AGENTS_AND_SERVERS.parse().unwrap(), DHCP_RELAY_AGENT_AND_SERVER_PORT, 0, selected_interface.index.clone());
|
let remote_addr = SocketAddrV6::new(ALL_DHCP_RELAY_AGENTS_AND_SERVERS.parse().unwrap(), DHCP_RELAY_AGENT_AND_SERVER_PORT, 0, selected_interface.index.clone());
|
||||||
|
|
||||||
@ -86,28 +70,20 @@ async fn main() -> Result<()>{
|
|||||||
|
|
||||||
let mut msg_buf = Vec::new();
|
let mut msg_buf = Vec::new();
|
||||||
let mut msg_encoder = Encoder::new(&mut msg_buf);
|
let mut msg_encoder = Encoder::new(&mut msg_buf);
|
||||||
msg.encode(&mut msg_encoder)
|
msg.encode(&mut msg_encoder).unwrap(); // Serializes msg to msg_buf
|
||||||
.context("Unable to serialize DHCP options for message to send")?; // Serializes msg to msg_buf
|
|
||||||
|
|
||||||
sock.send_to(&msg_buf, remote_addr).await
|
sock.send_to(&msg_buf, remote_addr).await.unwrap();
|
||||||
.context("Failed to send DHCPv6 INFORMATION-REQUEST message")?;
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut recv_buf = [0; 1024];
|
let mut recv_buf = [0; 1024];
|
||||||
let (len, recv_addr) = sock.recv_from(&mut recv_buf).await
|
let (len, recv_addr) = sock.recv_from(&mut recv_buf).await.unwrap();
|
||||||
.context("Failed to receive DHCPv6 response")?;
|
let recv_msg = Message::decode(&mut Decoder::new(&recv_buf)).unwrap();
|
||||||
let recv_msg = Message::decode(&mut Decoder::new(&recv_buf))
|
|
||||||
.context("Unable to parse DHCPv6 response message")?;
|
|
||||||
|
|
||||||
if recv_msg.xid() == msg.xid() {
|
if recv_msg.xid() == msg.xid() {
|
||||||
info!("{:?} bytes received from {:?}", len, recv_addr);
|
println!("{:?} bytes received from {:?}", len, recv_addr);
|
||||||
if log_enabled!(Level::Debug) {
|
println!("{}", &recv_buf[..len].escape_ascii().to_string());
|
||||||
debug!("Received packet: {}", hex::encode(&recv_buf[..len]));
|
|
||||||
}
|
|
||||||
println!("{}", &recv_msg);
|
println!("{}", &recv_msg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user