diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..ea8c4bf7f35f6f77f75d92ad8ce8349f6e81ddba --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000000000000000000000000000000000000..193a2033192341f48ba84a0741dee8ee2582383b --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,76 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "c_linked_list" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4964518bd3b4a8190e832886cdc0da9794f12e8e6c1613a9e90ff331c4c8724b" + +[[package]] +name = "gcc" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" + +[[package]] +name = "get_if_addrs" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abddb55a898d32925f3148bd281174a68eeb68bbfd9a5938a57b18f506ee4ef7" +dependencies = [ + "c_linked_list", + "get_if_addrs-sys", + "libc", + "winapi", +] + +[[package]] +name = "get_if_addrs-sys" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d04f9fb746cf36b191c00f3ede8bde9c8e64f9f4b05ae2694a9ccf5e3f5ab48" +dependencies = [ + "gcc", + "libc", +] + +[[package]] +name = "getaddrinfo" +version = "0.1.0" +dependencies = [ + "get_if_addrs", + "libc", + "objc", +] + +[[package]] +name = "libc" +version = "0.2.169" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..e8b696f0dea3061e1d65b96984aa92403cbbf07a --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "getaddrinfo" +version = "0.1.0" +edition = "2021" + +[dependencies] +get_if_addrs = "0.5.3" +libc = "0.2.169" +objc = "0.2.7" diff --git a/src/addr.rs b/src/addr.rs new file mode 100644 index 0000000000000000000000000000000000000000..51da6aac028e0d1154565b77ab12867de575278e --- /dev/null +++ b/src/addr.rs @@ -0,0 +1,16 @@ +#[derive(Debug)] +pub struct Addr { + pub name: String, + pub ipv4: String, + pub ipv6: String, +} + +impl Addr { + pub fn new(name: String) -> Self { + Addr { + name: name, + ipv4: String::from(""), + ipv6: String::from(""), + } + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000000000000000000000000000000000000..5df7311d97a6b702591c180d3989c97c4f7ac3c8 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,80 @@ +use addr::Addr; +use libc::{getifaddrs, ifaddrs, sockaddr, AF_INET, AF_INET6}; +use std::collections::HashMap; +use std::ffi::CStr; +use std::net::{Ipv4Addr, Ipv6Addr}; +use std::ptr; + +mod addr; + +fn main() { + // hash of address structure + let mut hash: HashMap<String, Addr> = HashMap::new(); + + unsafe { + let mut ifap: *mut ifaddrs = ptr::null_mut(); + + if getifaddrs(&mut ifap) != 0 { + eprintln!("Failed to get network interfaces."); + return; + } + + let mut cursor = ifap; + + while !cursor.is_null() { + let iface = &*cursor; + + if !iface.ifa_addr.is_null() { + let sockaddr = &*iface.ifa_addr; + + let name = CStr::from_ptr(iface.ifa_name).to_string_lossy().to_string(); + + let entry = hash + .entry(name.clone()) + .or_insert_with(|| Addr::new(name.clone())); + + match sockaddr.sa_family as i32 { + AF_INET => { + let addr = sockaddr as *const sockaddr as *const libc::sockaddr_in; + let ip = (*addr).sin_addr.s_addr.to_be(); + let ipv4 = Ipv4Addr::from(ip).to_string(); + entry.ipv4 = ipv4; + } + AF_INET6 => { + let addr = sockaddr as *const sockaddr as *const libc::sockaddr_in6; + let ip = (*addr).sin6_addr.s6_addr; + let ipv6 = Ipv6Addr::from(ip).to_string(); + entry.ipv6 = ipv6; + } + _ => {} + } + } + + cursor = iface.ifa_next; + } + + libc::freeifaddrs(ifap); + } + + // print get address + for addr in hash.values() { + let mut flag = false; + let mut res = addr.name.clone() + "\n"; + if !addr.ipv4.is_empty() { + res += "inet "; + res += &addr.ipv4; + res += "\n"; + flag = true; + } + if !addr.ipv6.is_empty() { + res += "inet6 "; + res += &addr.ipv6; + res += "\n"; + flag = true; + } + + if flag { + println!("{}", res); + } + } +}