diff options
| -rw-r--r-- | arch/x64/linux/syscall.S | 7 | ||||
| -rw-r--r-- | dub.json | 4 | ||||
| -rw-r--r-- | source/tanya/net/iface.d | 141 | ||||
| -rw-r--r-- | source/tanya/sys/linux/syscall.d | 11 | ||||
| -rw-r--r-- | source/tanya/sys/windows/def.d | 5 | ||||
| -rw-r--r-- | source/tanya/sys/windows/ifdef.d | 30 | ||||
| -rw-r--r-- | source/tanya/sys/windows/iphlpapi.d | 39 | ||||
| -rw-r--r-- | source/tanya/sys/windows/package.d | 2 |
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 @@ -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; |
