Skip to content

Commit

Permalink
don't use broadcast, use last address instead
Browse files Browse the repository at this point in the history
  • Loading branch information
t-aleksander committed Dec 23, 2024
1 parent 2244772 commit 040f9a8
Showing 1 changed file with 20 additions and 10 deletions.
30 changes: 20 additions & 10 deletions src/handlers/network_devices.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use std::{net::IpAddr, str::FromStr};
use std::{
net::{IpAddr, Ipv4Addr, Ipv6Addr},
str::FromStr,
};

use axum::{
extract::{Json, Path, State},
Expand Down Expand Up @@ -702,24 +705,31 @@ pub async fn modify_network_device(
/// The network part is the part that can't be changed by the user.
/// This is to display an IP address in the UI like this: 192.168.(1.1)/16, where the part in the parenthesis can be changed by the user.
// The algorithm works as follows:
// 1. Get the network address, broadcast address and IP address segments, e.g. 192.1.1.1 would be [192, 1, 1, 1]
// 2. Iterate over the segments and compare the broadcast and network segments, as long as the current segments are equal, append the segment to the network part.
// If they are not equal, we found the modifiable segment (one of the segments of an address that may change between hosts in the same network),
// 1. Get the network address, last address and IP address segments, e.g. 192.1.1.1 would be [192, 1, 1, 1]
// 2. Iterate over the segments and compare the last address and network segments, as long as the current segments are equal, append the segment to the network part.
// If they are not equal, we found the first modifiable segment (one of the segments of an address that may change between hosts in the same network),
// append the rest of the segments to the modifiable part.
// 3. Join the segments with the delimiter and return the network part, modifiable part and the network prefix
fn split_ip(ip: &IpAddr, network: &IpNetwork) -> (String, String, String) {
let network_addr = network.network();
let network_prefix = network.prefix();
let network_broadcast = network.broadcast();

let ip_segments = match ip {
IpAddr::V4(ip) => ip.octets().iter().map(|x| *x as u16).collect(),
IpAddr::V6(ip) => ip.segments().to_vec(),
};

let broadcast_segments = match network_broadcast {
IpAddr::V4(ip) => ip.octets().iter().map(|x| *x as u16).collect(),
IpAddr::V6(ip) => ip.segments().to_vec(),
let last_addr_segments = match network {
IpNetwork::V4(net) => {
let last_ip = u32::from(net.ip()) | (!u32::from(net.mask()));
let last_ip: Ipv4Addr = last_ip.into();
last_ip.octets().iter().map(|x| *x as u16).collect()
}
IpNetwork::V6(net) => {
let last_ip = u128::from(net.ip()) | (!u128::from(net.mask()));
let last_ip: Ipv6Addr = last_ip.into();
last_ip.segments().to_vec()
}
};

let network_segments = match network_addr {
Expand All @@ -738,13 +748,13 @@ fn split_ip(ip: &IpAddr, network: &IpNetwork) -> (String, String, String) {
}
};

for (i, ((broadcast_segment, network_segment), ip_segment)) in broadcast_segments
for (i, ((last_addr_segment, network_segment), ip_segment)) in last_addr_segments
.iter()
.zip(network_segments.iter())
.zip(ip_segments.iter())
.enumerate()
{
if broadcast_segment != network_segment {
if last_addr_segment != network_segment {
let parts = ip_segments.split_at(i).1;
let joined = parts
.iter()
Expand Down

0 comments on commit 040f9a8

Please sign in to comment.