2021-07-18 17:46:08 +01:00
|
|
|
module libtun.adapter;
|
|
|
|
|
|
|
|
extern (C) int ioctl(int fd, ulong request, void* data);
|
|
|
|
extern (C) int open(char* path, int flags);
|
|
|
|
|
2021-07-18 18:45:17 +01:00
|
|
|
import core.stdc.stdio;
|
2021-07-18 18:26:15 +01:00
|
|
|
|
2021-07-18 17:46:08 +01:00
|
|
|
|
|
|
|
/**
|
2021-07-18 22:10:11 +01:00
|
|
|
* TUN maintenance routines in `tunctl.c`
|
2021-07-18 17:46:08 +01:00
|
|
|
*/
|
2021-07-18 18:23:16 +01:00
|
|
|
extern (C) int createTun(char* interfaceName, int iffFlags);
|
2021-07-18 17:46:08 +01:00
|
|
|
extern (C) int destroyTun(int fd);
|
2021-07-18 18:45:17 +01:00
|
|
|
extern (C) int tunWrite(int fd, char* data, int length);
|
2021-07-18 22:10:11 +01:00
|
|
|
extern (C) int tunRead(int fd, char* data);
|
2021-07-18 17:46:08 +01:00
|
|
|
|
|
|
|
public class TUNAdapter
|
|
|
|
{
|
2021-07-18 18:45:17 +01:00
|
|
|
/* Tunnel device descriptor */
|
|
|
|
private int tunFD;
|
2021-07-18 22:10:11 +01:00
|
|
|
private bool isClosed;
|
2021-07-18 18:45:17 +01:00
|
|
|
|
2021-07-18 22:10:11 +01:00
|
|
|
this(string interfaceName, AdapterType adapterType = AdapterType.TAP)
|
2021-07-18 17:46:08 +01:00
|
|
|
{
|
2021-07-18 18:45:17 +01:00
|
|
|
init(interfaceName);
|
2021-07-18 17:46:08 +01:00
|
|
|
}
|
|
|
|
|
2021-07-18 18:45:17 +01:00
|
|
|
private void init(string interfaceName)
|
2021-07-18 17:46:08 +01:00
|
|
|
{
|
2021-07-18 18:45:17 +01:00
|
|
|
tunFD = createTun(cast(char*)interfaceName, 1);
|
2021-07-18 18:26:15 +01:00
|
|
|
if(tunFD < 0)
|
|
|
|
{
|
|
|
|
throw new TUNException("Error creating tun device");
|
|
|
|
}
|
2021-07-18 17:46:08 +01:00
|
|
|
}
|
|
|
|
|
2021-07-18 22:10:11 +01:00
|
|
|
private void sanityCheck()
|
2021-07-18 17:46:08 +01:00
|
|
|
{
|
2021-07-18 22:10:11 +01:00
|
|
|
if(isClosed)
|
|
|
|
{
|
|
|
|
throw new TUNException("Cannot operate on closed tunnel device");
|
|
|
|
}
|
|
|
|
}
|
2021-07-18 17:46:08 +01:00
|
|
|
|
2021-07-18 22:10:11 +01:00
|
|
|
public void close()
|
|
|
|
{
|
|
|
|
sanityCheck();
|
|
|
|
|
|
|
|
isClosed = true;
|
|
|
|
destroyTun(tunFD);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void receive(ref byte[] buffer)
|
|
|
|
{
|
|
|
|
sanityCheck();
|
|
|
|
|
|
|
|
/* TODO: Get amount read */
|
|
|
|
/* FIXME: For now set it length to 20 */
|
|
|
|
buffer.length = 400;
|
|
|
|
tunRead(tunFD, cast(char*)buffer.ptr);
|
2021-07-18 17:46:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public void send(byte[] buffer)
|
|
|
|
{
|
2021-07-18 22:10:11 +01:00
|
|
|
sanityCheck();
|
|
|
|
|
2021-07-18 18:45:17 +01:00
|
|
|
tunWrite(tunFD, cast(char*)buffer.ptr, cast(int)buffer.length);
|
2021-07-18 17:46:08 +01:00
|
|
|
}
|
2021-07-18 18:26:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public final class TUNException : Exception
|
|
|
|
{
|
|
|
|
this(string msg)
|
|
|
|
{
|
|
|
|
super(msg);
|
|
|
|
}
|
2021-07-18 22:10:11 +01:00
|
|
|
}
|
|
|
|
|
2021-07-18 22:24:06 +01:00
|
|
|
public enum AdapterType : ushort
|
2021-07-18 22:10:11 +01:00
|
|
|
{
|
2021-07-18 22:24:06 +01:00
|
|
|
TUN = 1,
|
|
|
|
TAP = 0
|
2021-07-18 17:46:08 +01:00
|
|
|
}
|