summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--lib/pure/net.nim20
-rw-r--r--tests/untestable/network/README.md8
-rw-r--r--tests/untestable/network/stdlib/tnet.nim16
3 files changed, 44 insertions, 0 deletions
diff --git a/lib/pure/net.nim b/lib/pure/net.nim
index f468e1c5d..f55d5d900 100644
--- a/lib/pure/net.nim
+++ b/lib/pure/net.nim
@@ -1662,3 +1662,23 @@ proc connect*(socket: Socket, address: string, port = Port(0),
         socket.fd.setBlocking(true)
         doAssert socket.gotHandshake()
   socket.fd.setBlocking(true)
+
+proc getPrimaryIPAddr*(dest = parseIpAddress("8.8.8.8")): IpAddress =
+  ## Finds the local IP address, usually assigned to eth0 on LAN or wlan0 on WiFi,
+  ## used to reach an external address. Useful to run local services.
+  ##
+  ## No traffic is sent.
+  ##
+  ## Supports IPv4 and v6.
+  ## Raises OSError if external networking is not set up.
+  ##
+  ## .. code-block:: Nim
+  ##   echo $getPrimaryIPAddr()  # "192.168.1.2"
+
+  let socket =
+    if dest.family == IpAddressFamily.IPv4:
+      newSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
+    else:
+      newSocket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)
+  socket.connect($dest, 80.Port)
+  socket.getLocalAddr()[0].parseIpAddress()
diff --git a/tests/untestable/network/README.md b/tests/untestable/network/README.md
new file mode 100644
index 000000000..173cf105f
--- /dev/null
+++ b/tests/untestable/network/README.md
@@ -0,0 +1,8 @@
+This directory contains tests that require networking and cannot be run in CI.
+
+The tests can be run manually during development using:
+```nim
+./koch tests cat untestable/network/stdlib
+```
+
+The directory structure mimics tests/
diff --git a/tests/untestable/network/stdlib/tnet.nim b/tests/untestable/network/stdlib/tnet.nim
new file mode 100644
index 000000000..cb0f38944
--- /dev/null
+++ b/tests/untestable/network/stdlib/tnet.nim
@@ -0,0 +1,16 @@
+discard """
+outputsub: ""
+"""
+
+import net, nativesockets
+import unittest
+
+suite "getPrimaryIPAddr":
+  test "localhost v4":
+    check getPrimaryIPAddr(parseIpAddress("127.0.0.1")) == parseIpAddress("127.0.0.1")
+
+  test "localhost v6":
+    check getPrimaryIPAddr(parseIpAddress("::1")) == parseIpAddress("::1")
+
+  test "v4":
+    check getPrimaryIPAddr() != parseIpAddress("127.0.0.1")