im not sure what im changing
This commit is contained in:
Generated
+1
@@ -632,6 +632,7 @@ dependencies = [
|
||||
"rtnetlink",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_with",
|
||||
"strum",
|
||||
"thiserror 2.0.16",
|
||||
"tokio",
|
||||
|
||||
@@ -9,6 +9,7 @@ macaddr = { version = "1.0.1", features = ["serde", "serde_std"] }
|
||||
strum = { version = "0.27.2", features = ["derive", "strum_macros"] }
|
||||
serde_json = "1.0.143"
|
||||
serde = { version = "1.0.219", features = ["derive"] }
|
||||
serde_with = { version = "3.14.0", features = ["json"] }
|
||||
thiserror = "2.0.16"
|
||||
anyhow = "1.0.100"
|
||||
tokio = { version = "1.47.1", features = ["fs", "process", "rt-multi-thread", "io-util", "macros"] }
|
||||
|
||||
+2
-2
@@ -1,13 +1,13 @@
|
||||
//! low
|
||||
//!
|
||||
//! # lda-ipj
|
||||
//! # lda-ipjs
|
||||
//!
|
||||
//! this package will represent all my needs with the all the subcommands of ip -j.
|
||||
//!
|
||||
//! ## what i need
|
||||
//!
|
||||
//! ```console
|
||||
//! ip -j neigh
|
||||
//! ip -j neigh show
|
||||
//! ```
|
||||
//!
|
||||
//! i also need to see devices and idk MAYBE maybe not MAYBE UHHHHHH maybe broadcast
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// ip address [ show [ dev IFNAME ] [ scope SCOPE-ID ] [ master DEVICE ]
|
||||
// [ type TYPE ] [ to PREFIX ] [ FLAG-LIST ]
|
||||
// [ label LABEL ] [up] [ vrf NAME ] ]
|
||||
// fuck is this mean
|
||||
|
||||
// do i need all this? do i need anything but `ip -j a show dev br-lan`?
|
||||
|
||||
// TYPE := { vlan | veth | vcan | vxcan | dummy | ifb | macvlan | macvtap |
|
||||
// bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan | lowpan |
|
||||
// gre | gretap | erspan | ip6gre | ip6gretap | ip6erspan | vti |
|
||||
// nlmon | can | bond_slave | ipvlan | geneve | bridge_slave |
|
||||
// hsr | macsec | netdevsim }
|
||||
// FLAG-LIST := [ FLAG-LIST ] FLAG
|
||||
// FLAG := [ permanent | dynamic | secondary | primary |
|
||||
// [-]tentative | [-]deprecated | [-]dadfailed | temporary |
|
||||
// CONFFLAG-LIST ]
|
||||
// CONFFLAG-LIST := [ CONFFLAG-LIST ] CONFFLAG
|
||||
// CONFFLAG := [ home | nodad | mngtmpaddr | noprefixroute | autojoin ]
|
||||
|
||||
// prefix seems to be a cidr. both 6 and 4 works. idfk dog
|
||||
|
||||
use super::AddrInfo;
|
||||
|
||||
|
||||
|
||||
pub async fn get() -> Vec<AddrInfo> {
|
||||
todo!()
|
||||
}
|
||||
@@ -4,39 +4,38 @@
|
||||
//!
|
||||
//! lowk why its free but its indirection and its ass
|
||||
|
||||
use macaddr::MacAddr6;
|
||||
pub mod json;
|
||||
|
||||
use crate::utils::serialize::mac::option_mac;
|
||||
use macaddr::MacAddr;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// i dont include what i dont know about (almost all ts)
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct CommmonOutput {
|
||||
ifindex: u32,
|
||||
ifname: String,
|
||||
/// i imagine UP or DOWN, unknown
|
||||
operstate: String,
|
||||
// 6 has a serde and the enum doesnt? why.
|
||||
address: Option<MacAddr6>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Debug, Deserialize)]
|
||||
struct AddrOutput {
|
||||
#[serde(flatten)]
|
||||
c: CommmonOutput,
|
||||
addr_info: Vec<AddrInfo>,
|
||||
pub struct AddrOutput {
|
||||
pub ifindex: u32,
|
||||
pub ifname: String,
|
||||
/// i imagine UP or DOWN, unknown
|
||||
pub operstate: String,
|
||||
// 6 has a serde and the enum doesnt? why. (serializing ts is ass although... im not given an array. they string formatted ts)
|
||||
#[serde(with = "option_mac", default)]
|
||||
pub address: Option<MacAddr>,
|
||||
#[serde(default)] // i wish we have intellisense for this... fuck you metaprogramming
|
||||
pub addr_info: Vec<AddrInfo>,
|
||||
}
|
||||
|
||||
// i be copying
|
||||
// Raw JSON shape from ip -j -4 address show
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
struct AddrInfo {
|
||||
family: Option<String>,
|
||||
pub struct AddrInfo {
|
||||
pub family: Option<String>,
|
||||
|
||||
local: Option<String>,
|
||||
prefixlen: Option<u8>,
|
||||
pub local: Option<String>,
|
||||
pub prefixlen: Option<u8>,
|
||||
|
||||
broadcast: Option<String>,
|
||||
pub broadcast: Option<String>,
|
||||
|
||||
scope: Option<String>,
|
||||
label: Option<String>,
|
||||
pub scope: Option<String>,
|
||||
pub label: Option<String>,
|
||||
// many more exist; we only take what we need
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
pub mod json;
|
||||
pub mod nl;
|
||||
|
||||
use crate::utils::serialize::mac::{des_opm, ser_opm};
|
||||
use crate::utils::serialize::mac::option_mac;
|
||||
use std::net::IpAddr;
|
||||
|
||||
use macaddr::MacAddr;
|
||||
@@ -17,11 +17,11 @@ use strum::{Display, EnumString};
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)]
|
||||
pub struct NeighborInput {
|
||||
/// supports only the last item (ignore), `to` keyword is optional
|
||||
to: Option<IpAddr>,
|
||||
pub to: Option<IpAddr>,
|
||||
/// supports only one item (it complains if multiple)
|
||||
dev: Option<String>, // im all for simplicity
|
||||
pub dev: Option<String>, // im all for simplicity
|
||||
/// takes multiple, has to have `nud` before bro or it will think you `to`
|
||||
nud: Vec<NUDState>,
|
||||
pub nud: Vec<NUDState>,
|
||||
}
|
||||
|
||||
// as input this must be lowercase. as output it is uppercase
|
||||
@@ -64,21 +64,18 @@ pub enum NUDState {
|
||||
/// success, neighbor validation has ultimately
|
||||
/// failed.
|
||||
Failed,
|
||||
|
||||
Other(u16)
|
||||
}
|
||||
|
||||
/// everything i see
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)]
|
||||
pub struct NeighborItem {
|
||||
#[serde(rename(deserialize = "dst"))]
|
||||
ip: IpAddr,
|
||||
dev: String,
|
||||
#[serde(
|
||||
deserialize_with = "des_opm",
|
||||
serialize_with = "ser_opm",
|
||||
default,
|
||||
rename(deserialize = "lladdr")
|
||||
)]
|
||||
mac: Option<MacAddr>,
|
||||
pub ip: IpAddr,
|
||||
pub dev: String,
|
||||
#[serde(with = "option_mac", default, rename(deserialize = "lladdr"))]
|
||||
pub mac: Option<MacAddr>,
|
||||
#[serde(default)]
|
||||
state: Vec<NUDState>,
|
||||
pub state: Vec<NUDState>,
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ impl TryFrom<NeighbourState> for NUDState {
|
||||
NeighbourState::Noarp => Ok(Self::Noarp),
|
||||
NeighbourState::Permanent => Ok(Self::Permanent),
|
||||
NeighbourState::None => Ok(Self::None),
|
||||
NeighbourState::Other(e) => Err(e),
|
||||
NeighbourState::Other(e) => Ok(Self::Other(e)),
|
||||
_ => Err(u16::MAX), // idk
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ where
|
||||
}
|
||||
|
||||
/// Serialize a MacAddr as a string
|
||||
pub fn serialize_mac<S>(mac: &MacAddr, serializer: S) -> Result<S::Ok, S::Error>
|
||||
pub fn serialize<S>(mac: &MacAddr, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
@@ -19,7 +19,7 @@ where
|
||||
}
|
||||
|
||||
/// Deserialize a MacAddr from a string
|
||||
pub fn deserialize_mac<'de, D>(deserializer: D) -> Result<MacAddr, D::Error>
|
||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<MacAddr, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
@@ -27,18 +27,20 @@ where
|
||||
s.parse::<MacAddr>().map_err(DeError::custom)
|
||||
}
|
||||
|
||||
/// serialize an [`Option<MacAddr>`]
|
||||
pub fn ser_opm<S: Serializer>(bro: &Option<MacAddr>, ser: S) -> Result<S::Ok, S::Error> {
|
||||
pub mod option_mac {
|
||||
use super::*;
|
||||
/// serialize an [`Option<MacAddr>`]
|
||||
pub fn serialize<S: Serializer>(bro: &Option<MacAddr>, ser: S) -> Result<S::Ok, S::Error> {
|
||||
Option::<String>::serialize(&bro.as_ref().map(ToString::to_string), ser)
|
||||
}
|
||||
|
||||
/// deserialize an [`Option<MacAddr>`]
|
||||
pub fn des_opm<'de, D>(des: D) -> Result<Option<MacAddr>, D::Error>
|
||||
where
|
||||
}
|
||||
/// deserialize an [`Option<MacAddr>`]
|
||||
pub fn deserialize<'de, D>(des: D) -> Result<Option<MacAddr>, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
{
|
||||
Option::<&str>::deserialize(des)?
|
||||
.map(str::parse)
|
||||
.transpose()
|
||||
.map_err(de::Error::custom)
|
||||
}
|
||||
}
|
||||
|
||||
+9
-5
@@ -41,7 +41,7 @@ pub struct IpNeighLine {
|
||||
|
||||
// NUDState custom Deserialize now lives in arpparse/impl.rs; use serde_with OneOrMany for Vec
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, EnumString, Display, Clone, Copy, Hash, serde::Serialize)]
|
||||
#[derive(Debug, PartialEq, Eq, EnumString, Display, Clone, Copy, Hash, serde::Serialize, Default)]
|
||||
#[strum(serialize_all = "UPPERCASE", ascii_case_insensitive)]
|
||||
#[serde(rename_all = "UPPERCASE")]
|
||||
pub enum NUDState {
|
||||
@@ -63,10 +63,7 @@ pub enum NUDState {
|
||||
/// neighbour state if it was valid and the
|
||||
/// address is not changed by this command.
|
||||
Stale,
|
||||
/// this is a pseudo state used when initially
|
||||
/// creating a neighbour entry or after trying to
|
||||
/// remove it before it becomes free to do so.
|
||||
None,
|
||||
|
||||
|
||||
/// the neighbour entry has not (yet) been
|
||||
/// validated/resolved.
|
||||
@@ -80,6 +77,13 @@ pub enum NUDState {
|
||||
/// success, neighbor validation has ultimately
|
||||
/// failed.
|
||||
Failed,
|
||||
|
||||
/// this is a pseudo state used when initially
|
||||
/// creating a neighbour entry or after trying to
|
||||
/// remove it before it becomes free to do so.
|
||||
#[serde(other)]
|
||||
#[default]
|
||||
None,
|
||||
}
|
||||
|
||||
impl NUDState {
|
||||
|
||||
+3
-10
@@ -49,12 +49,10 @@ pub async fn status_smart_redirect(
|
||||
};
|
||||
match serde_html_form::to_string(query) {
|
||||
Ok(e) => Ok(Redirect::to(&format!("/api/status?{e}"))),
|
||||
Err(e) => Err((
|
||||
StatusCode::BAD_GATEWAY,
|
||||
Json(ApiError {
|
||||
Err(e) => Err(ApiError {
|
||||
error: e.to_string(),
|
||||
code: StatusCode::BAD_GATEWAY,
|
||||
}),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,12 +65,7 @@ pub async fn status_redirect(Path(NamePath { name }): Path<NamePath>) -> Redirec
|
||||
|
||||
pub async fn ip(Path(name): Path<String>) -> impl IntoResponse {
|
||||
get_ips(&name).await.map_or_else(
|
||||
|e| {
|
||||
ApiError {
|
||||
error: e.to_string(),
|
||||
}
|
||||
.into_response()
|
||||
},
|
||||
|e| ApiError::ise(e.to_string()).into_response(),
|
||||
|ips| Json(ips.collect::<Vec<_>>()).into_response(),
|
||||
)
|
||||
}
|
||||
|
||||
+3
-5
@@ -26,12 +26,10 @@ pub async fn get_dhcp_leases(Query(raw): Query<DhcpLeasesQueryRaw>) -> impl Into
|
||||
let out = enrich_leases_with_nud_state(leases_with_names).await;
|
||||
(StatusCode::OK, Json(out)).into_response()
|
||||
}
|
||||
Err(e) => (
|
||||
StatusCode::BAD_GATEWAY,
|
||||
Json(ApiError {
|
||||
Err(e) => ApiError {
|
||||
error: e.to_string(),
|
||||
}),
|
||||
)
|
||||
code: StatusCode::BAD_GATEWAY,
|
||||
}
|
||||
.into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
+13
-1
@@ -7,11 +7,23 @@ use serde::Serialize;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct ApiError {
|
||||
#[serde(skip_serializing, skip_deserializing)]
|
||||
pub code: StatusCode,
|
||||
pub error: String,
|
||||
}
|
||||
|
||||
impl ApiError {
|
||||
/// [StatusCode::INTERNAL_SERVER_ERROR]
|
||||
pub const fn ise(error: String) -> Self {
|
||||
Self {
|
||||
code: StatusCode::INTERNAL_SERVER_ERROR,
|
||||
error,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoResponse for ApiError {
|
||||
fn into_response(self) -> Response {
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, Json(self)).into_response()
|
||||
(self.code, Json(self)).into_response()
|
||||
}
|
||||
}
|
||||
|
||||
+3
-5
@@ -94,12 +94,10 @@ pub async fn get_status_json(
|
||||
)
|
||||
.into_response()
|
||||
}
|
||||
Err(error) => (
|
||||
StatusCode::BAD_GATEWAY,
|
||||
Json(ApiError {
|
||||
Err(error) => ApiError {
|
||||
code: StatusCode::BAD_GATEWAY,
|
||||
error: error.to_string(),
|
||||
}),
|
||||
)
|
||||
}
|
||||
.into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ pub async fn get_macs(
|
||||
let ip_m: HashSet<IpAddr> = futures::future::try_join_all(
|
||||
machine_names
|
||||
.iter()
|
||||
.map(|c| async { get_ips(c.as_ref()).await }),
|
||||
.map(|c| get_ips(c.as_ref())),
|
||||
)
|
||||
.await?
|
||||
.into_iter()
|
||||
|
||||
@@ -41,13 +41,13 @@ impl From<WakeTargetResult> for RouteWakeResult {
|
||||
}
|
||||
|
||||
impl RouteWakeTarget {
|
||||
pub fn to_incomplete(self) -> RouteWakeResult {
|
||||
pub const fn to_incomplete(self) -> RouteWakeResult {
|
||||
RouteWakeResult {
|
||||
target: self,
|
||||
status: RouteWakeStatus::Incomplete,
|
||||
}
|
||||
}
|
||||
pub fn is_incomplete(&self) -> bool {
|
||||
pub const fn is_incomplete(&self) -> bool {
|
||||
!matches!(
|
||||
self,
|
||||
Self {
|
||||
|
||||
@@ -22,21 +22,21 @@ pub enum WakeStatus {
|
||||
WrongSize,
|
||||
}
|
||||
impl WakeTarget {
|
||||
fn _new(ip: IpAddr, mac: MacAddr) -> Self {
|
||||
const fn _new(ip: IpAddr, mac: MacAddr) -> Self {
|
||||
Self { ip, mac }
|
||||
}
|
||||
fn good(self) -> WakeTargetResult {
|
||||
const fn good(self) -> WakeTargetResult {
|
||||
WakeTargetResult::new(self, WakeStatus::Success)
|
||||
}
|
||||
fn bad(self) -> WakeTargetResult {
|
||||
const fn bad(self) -> WakeTargetResult {
|
||||
WakeTargetResult::new(self, WakeStatus::WrongSize)
|
||||
}
|
||||
fn errored(self) -> WakeTargetResult {
|
||||
const fn errored(self) -> WakeTargetResult {
|
||||
WakeTargetResult::new(self, WakeStatus::NonexistentAddress)
|
||||
}
|
||||
}
|
||||
impl WakeTargetResult {
|
||||
fn new(target: WakeTarget, status: WakeStatus) -> Self {
|
||||
const fn new(target: WakeTarget, status: WakeStatus) -> Self {
|
||||
Self { target, status }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user