Add module for network interfaces

This commit is contained in:
Eugen Wissner 2018-09-01 09:56:44 +02:00
parent 41878cde50
commit aa12aa9014
8 changed files with 233 additions and 6 deletions

View File

@ -11,10 +11,11 @@ The returned value is placed in %rax.
*/ */
.text .text
.globl syscall1 // 1 parameter.
.type syscall1, @function .globl _D5tanya3sys5linux7syscallQiFNbNillZl
.type _D5tanya3sys5linux7syscallQiFNbNillZl, @function
syscall1: _D5tanya3sys5linux7syscallQiFNbNillZl:
movq %rsi, %rax // Syscall number. movq %rsi, %rax // Syscall number.
syscall syscall

View File

@ -34,5 +34,7 @@
} }
], ],
"libs-windows": ["advapi32"] "libs-windows": ["advapi32"],
"libs-windows-x86_mscoff": ["iphlpapi"],
"libs-windows-x86_64": ["iphlpapi"]
} }

141
source/tanya/net/iface.d Normal file
View File

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

View File

@ -14,6 +14,9 @@ module tanya.sys.linux.syscall;
version (TanyaNative): version (TanyaNative):
extern ptrdiff_t syscall(ptrdiff_t, ptrdiff_t)
@nogc nothrow @system;
extern ptrdiff_t syscall(ptrdiff_t, ptrdiff_t, ptrdiff_t) extern ptrdiff_t syscall(ptrdiff_t, ptrdiff_t, ptrdiff_t)
@nogc nothrow @system; @nogc nothrow @system;
@ -37,14 +40,18 @@ private template getOverloadMangling(size_t n)
} }
pragma(mangle, getOverloadMangling!0) 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; @nogc nothrow pure @system;
pragma(mangle, getOverloadMangling!1) 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; @nogc nothrow pure @system;
pragma(mangle, getOverloadMangling!2) 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, extern ptrdiff_t syscall_(ptrdiff_t,
ptrdiff_t, ptrdiff_t,
ptrdiff_t, ptrdiff_t,

View File

@ -30,6 +30,7 @@ version (Windows):
alias BYTE = ubyte; alias BYTE = ubyte;
alias TBYTE = wchar; // If Unicode, otherwise char. alias TBYTE = wchar; // If Unicode, otherwise char.
alias CHAR = char; // Signed or unsigned char. alias CHAR = char; // Signed or unsigned char.
alias WCHAR = wchar;
alias TCHAR = wchar; // If Unicode, otherwise char. alias TCHAR = wchar; // If Unicode, otherwise char.
alias SHORT = short; alias SHORT = short;
alias USHORT = ushort; alias USHORT = ushort;
@ -52,6 +53,10 @@ enum HANDLE INVALID_HANDLE_VALUE = cast(HANDLE) -1;
enum TRUE = 1; enum TRUE = 1;
enum FALSE = 0; enum FALSE = 0;
alias PSTR = CHAR*;
alias PWSTR = WCHAR*;
alias PTSTR = TCHAR*;
align(1) struct GUID align(1) struct GUID
{ {
uint Data1; uint Data1;

View File

@ -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;

View File

@ -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;

View File

@ -15,5 +15,7 @@ module tanya.sys.windows;
version (Windows): version (Windows):
public import tanya.sys.windows.def; 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.winbase;
public import tanya.sys.windows.winsock2; public import tanya.sys.windows.winsock2;