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);
+        }
+    }
+}