summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x64/linux/syscall.S7
-rw-r--r--dub.json4
-rw-r--r--source/tanya/net/iface.d141
-rw-r--r--source/tanya/sys/linux/syscall.d11
-rw-r--r--source/tanya/sys/windows/def.d5
-rw-r--r--source/tanya/sys/windows/ifdef.d30
-rw-r--r--source/tanya/sys/windows/iphlpapi.d39
-rw-r--r--source/tanya/sys/windows/package.d2
8 files changed, 233 insertions, 6 deletions
diff --git a/arch/x64/linux/syscall.S b/arch/x64/linux/syscall.S
index e69bd30..a9c5437 100644
--- a/arch/x64/linux/syscall.S
+++ b/arch/x64/linux/syscall.S
@@ -11,10 +11,11 @@ The returned value is placed in %rax.
*/
.text
- .globl syscall1
- .type syscall1, @function
+// 1 parameter.
+ .globl _D5tanya3sys5linux7syscallQiFNbNillZl
+ .type _D5tanya3sys5linux7syscallQiFNbNillZl, @function
-syscall1:
+_D5tanya3sys5linux7syscallQiFNbNillZl:
movq %rsi, %rax // Syscall number.
syscall
diff --git a/dub.json b/dub.json
index 63774fe..e52bbfd 100644
--- a/dub.json
+++ b/dub.json
@@ -34,5 +34,7 @@
}
],
- "libs-windows": ["advapi32"]
+ "libs-windows": ["advapi32"],
+ "libs-windows-x86_mscoff": ["iphlpapi"],
+ "libs-windows-x86_64": ["iphlpapi"]
}
diff --git a/source/tanya/net/iface.d b/source/tanya/net/iface.d
new file mode 100644
index 0000000..abb5c42
--- /dev/null
+++ b/source/tanya/net/iface.d
@@ -0,0 +1,141 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * Network interfaces.
+ *
+ * Copyright: Eugene Wissner 2018.
+ * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
+ * Mozilla Public License, v. 2.0).
+ * Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
+ * Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/net/iface.d,
+ * tanya/net/iface.d)
+ */
+module tanya.net.iface;
+
+import tanya.algorithm.mutation;
+import tanya.meta.trait;
+import tanya.meta.transform;
+import tanya.range;
+
+version (TanyaNative)
+{
+ import mir.linux._asm.unistd;
+ import tanya.sys.linux.syscall;
+ import tanya.sys.posix.ioctl;
+ import tanya.sys.posix.net.if_;
+ import tanya.sys.posix.socket;
+}
+else version (Windows)
+{
+ import tanya.sys.windows.ifdef;
+ import tanya.sys.windows.iphlpapi;
+}
+else version (Posix)
+{
+ import core.sys.posix.net.if_;
+}
+
+/**
+ * Converts the name of a network interface to its index.
+ *
+ * If an interface with the name $(D_PARAM name) cannot be found or another
+ * error occurres, returns 0.
+ *
+ * Params:
+ * name = Interface name.
+ *
+ * Returns: Returns interface index or 0.
+ */
+uint nameToIndex(R)(R name) @trusted
+if (isInputRange!R && is(Unqual!(ElementType!R) == char) && hasLength!R)
+{
+ version (TanyaNative)
+ {
+ if (name.length >= IF_NAMESIZE)
+ {
+ return 0;
+ }
+ ifreq ifreq_ = void;
+ ifreq_.ifr_ifindex = 8;
+
+ copy(name, ifreq_.ifr_name[]);
+ ifreq_.ifr_name[name.length] = '\0';
+
+ auto socket = syscall(AF_INET,
+ SOCK_DGRAM | SOCK_CLOEXEC,
+ 0,
+ NR_socket);
+ if (socket <= 0)
+ {
+ return 0;
+ }
+ scope (exit)
+ {
+ syscall(socket, NR_close);
+ }
+ if (syscall(socket,
+ SIOCGIFINDEX,
+ cast(ptrdiff_t) &ifreq_,
+ NR_ioctl) == 0)
+ {
+ return ifreq_.ifr_ifindex;
+ }
+ return 0;
+ }
+ else version (Windows)
+ {
+ if (name.length > IF_MAX_STRING_SIZE)
+ {
+ return 0;
+ }
+ char[IF_MAX_STRING_SIZE + 1] buffer;
+ NET_LUID luid;
+
+ copy(name, buffer[]);
+ buffer[name.length] = '\0';
+
+ if (ConvertInterfaceNameToLuidA(buffer.ptr, &luid) != 0)
+ {
+ return 0;
+ }
+ NET_IFINDEX index;
+ if (ConvertInterfaceLuidToIndex(&luid, &index) == 0)
+ {
+ return index;
+ }
+ return 0;
+ }
+ else version (Posix)
+ {
+ if (name.length >= IF_NAMESIZE)
+ {
+ return 0;
+ }
+ char[IF_NAMESIZE] buffer;
+
+ copy(name, buffer[]);
+ buffer[name.length] = '\0';
+
+ return if_nametoindex(buffer.ptr);
+ }
+}
+
+///
+@nogc nothrow @safe unittest
+{
+ version (linux)
+ {
+ assert(nameToIndex("lo") == 1);
+ }
+ else version (Windows)
+ {
+ assert(nameToIndex("loopback_0") == 1);
+ }
+ else
+ {
+ assert(nameToIndex("lo0") == 1);
+ }
+ assert(nameToIndex("ecafretni") == 0);
+}
diff --git a/source/tanya/sys/linux/syscall.d b/source/tanya/sys/linux/syscall.d
index fab77cf..e70f75a 100644
--- a/source/tanya/sys/linux/syscall.d
+++ b/source/tanya/sys/linux/syscall.d
@@ -14,6 +14,9 @@ module tanya.sys.linux.syscall;
version (TanyaNative):
+extern ptrdiff_t syscall(ptrdiff_t, ptrdiff_t)
+@nogc nothrow @system;
+
extern ptrdiff_t syscall(ptrdiff_t, ptrdiff_t, ptrdiff_t)
@nogc nothrow @system;
@@ -37,14 +40,18 @@ private template getOverloadMangling(size_t n)
}
pragma(mangle, getOverloadMangling!0)
-extern ptrdiff_t syscall_(ptrdiff_t, ptrdiff_t, ptrdiff_t)
+extern ptrdiff_t syscall_(ptrdiff_t, ptrdiff_t)
@nogc nothrow pure @system;
pragma(mangle, getOverloadMangling!1)
-extern ptrdiff_t syscall(ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t)
+extern ptrdiff_t syscall_(ptrdiff_t, ptrdiff_t, ptrdiff_t)
@nogc nothrow pure @system;
pragma(mangle, getOverloadMangling!2)
+extern ptrdiff_t syscall_(ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t)
+@nogc nothrow pure @system;
+
+pragma(mangle, getOverloadMangling!3)
extern ptrdiff_t syscall_(ptrdiff_t,
ptrdiff_t,
ptrdiff_t,
diff --git a/source/tanya/sys/windows/def.d b/source/tanya/sys/windows/def.d
index 6fe920e..ea37266 100644
--- a/source/tanya/sys/windows/def.d
+++ b/source/tanya/sys/windows/def.d
@@ -30,6 +30,7 @@ version (Windows):
alias BYTE = ubyte;
alias TBYTE = wchar; // If Unicode, otherwise char.
alias CHAR = char; // Signed or unsigned char.
+alias WCHAR = wchar;
alias TCHAR = wchar; // If Unicode, otherwise char.
alias SHORT = short;
alias USHORT = ushort;
@@ -52,6 +53,10 @@ enum HANDLE INVALID_HANDLE_VALUE = cast(HANDLE) -1;
enum TRUE = 1;
enum FALSE = 0;
+alias PSTR = CHAR*;
+alias PWSTR = WCHAR*;
+alias PTSTR = TCHAR*;
+
align(1) struct GUID
{
uint Data1;
diff --git a/source/tanya/sys/windows/ifdef.d b/source/tanya/sys/windows/ifdef.d
new file mode 100644
index 0000000..89e1c3f
--- /dev/null
+++ b/source/tanya/sys/windows/ifdef.d
@@ -0,0 +1,30 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * Copyright: Eugene Wissner 2018.
+ * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
+ * Mozilla Public License, v. 2.0).
+ * Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
+ * Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/sys/windows/ifdef.d,
+ * tanya/sys/windows/ifdef.d)
+ */
+module tanya.sys.windows.ifdef;
+
+version (Windows):
+
+import tanya.sys.windows.def;
+
+union NET_LUID_LH
+{
+ ulong Value;
+ ulong Info;
+}
+
+alias NET_LUID = NET_LUID_LH;
+alias IF_LUID = NET_LUID_LH;
+
+alias NET_IFINDEX = ULONG;
+
+enum size_t IF_MAX_STRING_SIZE = 256;
diff --git a/source/tanya/sys/windows/iphlpapi.d b/source/tanya/sys/windows/iphlpapi.d
new file mode 100644
index 0000000..002d2f5
--- /dev/null
+++ b/source/tanya/sys/windows/iphlpapi.d
@@ -0,0 +1,39 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * Copyright: Eugene Wissner 2018.
+ * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
+ * Mozilla Public License, v. 2.0).
+ * Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
+ * Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/sys/windows/iphlpapi.d,
+ * tanya/sys/windows/iphlpapi.d)
+ */
+module tanya.sys.windows.iphlpapi;
+
+version (Windows):
+
+import tanya.sys.windows.def;
+import tanya.sys.windows.ifdef;
+
+extern(Windows)
+DWORD ConvertInterfaceNameToLuidA(const(CHAR)* InterfaceName,
+ NET_LUID* InterfaceLuid)
+@nogc nothrow @system;
+
+extern(Windows)
+DWORD ConvertInterfaceLuidToIndex(const(NET_LUID)* InterfaceLuid,
+ NET_IFINDEX* InterfaceIndex)
+@nogc nothrow @system;
+
+extern(Windows)
+DWORD ConvertInterfaceIndexToLuid(NET_IFINDEX InterfaceIndex,
+ NET_LUID* InterfaceLuid)
+@nogc nothrow @system;
+
+extern(Windows)
+DWORD ConvertInterfaceLuidToNameA(const(NET_LUID)* InterfaceLuid,
+ PSTR InterfaceName,
+ size_t Length)
+@nogc nothrow @system;
diff --git a/source/tanya/sys/windows/package.d b/source/tanya/sys/windows/package.d
index a09f0c1..120013f 100644
--- a/source/tanya/sys/windows/package.d
+++ b/source/tanya/sys/windows/package.d
@@ -15,5 +15,7 @@ module tanya.sys.windows;
version (Windows):
public import tanya.sys.windows.def;
+public import tanya.sys.windows.ifdef;
+public import tanya.sys.windows.iphlpapi;
public import tanya.sys.windows.winbase;
public import tanya.sys.windows.winsock2;