diff --git a/Cargo.lock b/Cargo.lock index c3ac678..a033bf0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -157,6 +157,12 @@ version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytes" version = "1.5.0" @@ -180,6 +186,7 @@ dependencies = [ "clap", "clap-verbosity-flag", "cloudflare", + "local-ip-address", "log", "pretty_env_logger", "public-ip", @@ -423,6 +430,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + [[package]] name = "encoding_rs" version = "0.8.33" @@ -893,6 +906,18 @@ version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +[[package]] +name = "local-ip-address" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66357e687a569abca487dc399a9c9ac19beb3f13991ed49f00c144e02cbd42ab" +dependencies = [ + "libc", + "neli", + "thiserror", + "windows-sys", +] + [[package]] name = "lock_api" version = "0.4.10" @@ -965,6 +990,31 @@ dependencies = [ "tempfile", ] +[[package]] +name = "neli" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1100229e06604150b3becd61a4965d5c70f3be1759544ea7274166f4be41ef43" +dependencies = [ + "byteorder", + "libc", + "log", + "neli-proc-macros", +] + +[[package]] +name = "neli-proc-macros" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c168194d373b1e134786274020dae7fc5513d565ea2ebb9bc9ff17ffb69106d4" +dependencies = [ + "either", + "proc-macro2", + "quote", + "serde", + "syn 1.0.109", +] + [[package]] name = "nibble_vec" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index dcb1538..565f773 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ tokio = { version = "^1", features = ["rt-multi-thread", "macros"] } cloudflare = "^0.10" anyhow = "^1" clap-verbosity-flag = "^2.0" +local-ip-address = "^0.5.0" [dependencies.clap] version = "^4.4" diff --git a/src/api.rs b/src/api.rs index b813c35..5fa7348 100644 --- a/src/api.rs +++ b/src/api.rs @@ -55,6 +55,10 @@ pub struct Cli { )] pub email: Option, + /// Use local network ip + #[clap(short, long)] + pub local: bool, + #[clap(flatten)] pub verbose: Verbosity, /// set an AAAA record to the host's ipv6 address diff --git a/src/ip.rs b/src/ip.rs index 2530adc..91b6ff6 100644 --- a/src/ip.rs +++ b/src/ip.rs @@ -1,7 +1,9 @@ +use crate::api::Cli; use crate::dns::{Fqdn, Requests, ZoneId}; use anyhow::Result; use cloudflare::endpoints::dns::{DnsContent, DnsRecord}; use cloudflare::framework::async_api::{ApiClient, Client}; +use local_ip_address as local; use public_ip::{http, Version}; use std::net::IpAddr; use std::sync::Arc; @@ -58,11 +60,15 @@ impl DynDns for Option { } } -pub async fn get_ips() -> Result { - let (ipv4, ipv6) = tokio::join!( - public_ip::addr_with(http::ALL, Version::V4), - public_ip::addr_with(public_ip::ALL, Version::V6) - ); +pub async fn get_ips(cli: &Cli) -> Result { + let (ipv4, ipv6) = if cli.local { + (local::local_ip().ok(), local::local_ipv6().ok()) + } else { + tokio::join!( + public_ip::addr_with(http::ALL, Version::V4), + public_ip::addr_with(public_ip::ALL, Version::V6) + ) + }; if (None, None) == (ipv4, ipv6) { Err(anyhow::anyhow!( diff --git a/src/main.rs b/src/main.rs index ad62e1e..d6fb564 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,7 +18,7 @@ async fn main() -> Result<()> { .filter_level(cli.verbose.log_level_filter()) .init(); - let (public_ipv4, public_ipv6) = ip::get_ips().await?; + let (public_ipv4, public_ipv6) = ip::get_ips(&cli).await?; let api_client = Arc::new(api::get_client(&cli)?); let records = dns::get_records(&cli, api_client.clone()).await?; let mut handles: Vec>> =