mirror of https://github.com/deavmi/libtun.git
Compare commits
17 Commits
57
README.md
57
README.md
|
@ -1,4 +1,61 @@
|
|||
libtun
|
||||
======
|
||||
|
||||
![](branding/logo.png)
|
||||
|
||||
TUN/TAP adapter for D-based applications
|
||||
|
||||
## Usage
|
||||
|
||||
First add it to your dub-based project via:
|
||||
|
||||
```
|
||||
dub add libtun
|
||||
```
|
||||
|
||||
### `Adapter`
|
||||
|
||||
The `Adapter` class provides you with all you need to get started. One can construct a new adapter as follows:
|
||||
|
||||
```d
|
||||
import libtun.adapter;
|
||||
|
||||
void main()
|
||||
{
|
||||
try
|
||||
{
|
||||
TUNAdapter tun = new TUNAdapter("interface0", AdapterType.TUN);
|
||||
}
|
||||
catch(TUNException)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Reading and writing is easy:
|
||||
|
||||
```d
|
||||
byte[] data;
|
||||
|
||||
try
|
||||
{
|
||||
tun.receive(data);
|
||||
tun.write([65,66,66,65]);
|
||||
}
|
||||
catch(TUNException)
|
||||
{
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
There are two types of adapters:
|
||||
|
||||
1. `AdapterType.TUN`
|
||||
* This is for creating a TUN device
|
||||
2. `AdapterType.TAP`
|
||||
* This is for creating a TAP device
|
||||
|
||||
## License
|
||||
|
||||
LGPLv3
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 5.1 KiB |
Binary file not shown.
6
dub.json
6
dub.json
|
@ -4,9 +4,7 @@
|
|||
],
|
||||
"copyright": "Copyright © 2021, Tristan B. Kildaire",
|
||||
"description": "TUN adapter for D",
|
||||
"license": "GPLv3",
|
||||
"license": "LGPL-3.0",
|
||||
"name": "libtun",
|
||||
"targetType": "library",
|
||||
"preBuildCommands": ["gcc ~/.dub/packages/libtun-0.0.7/libtun/source/libtun/tunctl.c -o ~/.dub/packages/libtun-0.0.7/libtun/source/tunctl.o -c"],
|
||||
"lflags": ["~/.dub/packages/libtun-0.0.7/libtun/source/tunctl.o"]
|
||||
"targetType": "library"
|
||||
}
|
11
notes.md
11
notes.md
|
@ -10,4 +10,13 @@ It appears you canot use PEEK on fd's that are not sockets.
|
|||
Regardless of whether they implement queuoing or not, it would be nice
|
||||
if that was allowed. And if tuntap did it. THEN I could make a system
|
||||
that doesn't allocate something huge and THEN I could go ahead
|
||||
and also PEEK read.
|
||||
and also PEEK read.
|
||||
|
||||
|
||||
## TODO
|
||||
|
||||
- [ ] Adapter settings
|
||||
- [ ] `up`/`down` interface
|
||||
- [ ] Set address on interface
|
||||
- [ ] For source address selection
|
||||
- [ ] For possible automatic route addition
|
|
@ -1,20 +1,8 @@
|
|||
module libtun.adapter;
|
||||
|
||||
extern (C) int ioctl(int fd, ulong request, void* data);
|
||||
extern (C) int open(char* path, int flags);
|
||||
import libtun.tunctl;
|
||||
|
||||
import core.stdc.stdio;
|
||||
|
||||
|
||||
/**
|
||||
* TUN maintenance routines in `tunctl.c`
|
||||
*/
|
||||
extern (C) int createTun(char* interfaceName, int iffFlags);
|
||||
extern (C) int destroyTun(int fd);
|
||||
extern (C) int tunWrite(int fd, char* data, int length);
|
||||
extern (C) int tunRead(int fd, char* data, int amount);
|
||||
|
||||
public class TUNAdapter
|
||||
public class Adapter
|
||||
{
|
||||
/* Tunnel device descriptor */
|
||||
private int tunFD;
|
||||
|
@ -24,17 +12,26 @@ public class TUNAdapter
|
|||
private byte[] scratch;
|
||||
|
||||
|
||||
/**
|
||||
* Instantiates a new Adapter with the given interface name
|
||||
* and optionally you can specifiy the adapter type (default
|
||||
* is TAP)
|
||||
*
|
||||
* Params:
|
||||
* interfaceName = the name of the interface to create
|
||||
* adapterType = The AdapterType to use
|
||||
*/
|
||||
this(string interfaceName, AdapterType adapterType = AdapterType.TAP)
|
||||
{
|
||||
init(interfaceName);
|
||||
init(interfaceName, adapterType);
|
||||
}
|
||||
|
||||
private void init(string interfaceName)
|
||||
private void init(string interfaceName, AdapterType adapterType)
|
||||
{
|
||||
tunFD = createTun(cast(char*)interfaceName, 4096|2);
|
||||
tunFD = createTun(cast(char*)interfaceName, 4096|adapterType);
|
||||
if(tunFD < 0)
|
||||
{
|
||||
throw new TUNException("Error creating tun device");
|
||||
throw new AdapterException("Error creating tun device");
|
||||
}
|
||||
|
||||
/* TODO: Get device MTU and add functions for setting it */
|
||||
|
@ -46,10 +43,21 @@ public class TUNAdapter
|
|||
{
|
||||
if(isClosed)
|
||||
{
|
||||
throw new TUNException("Cannot operate on closed tunnel device");
|
||||
throw new AdapterException("Cannot operate on closed tunnel device");
|
||||
}
|
||||
}
|
||||
|
||||
public void setAddress()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the adapter
|
||||
*
|
||||
* Throws:
|
||||
* TUNException if the operation failed
|
||||
*/
|
||||
public void close()
|
||||
{
|
||||
sanityCheck();
|
||||
|
@ -58,7 +66,15 @@ public class TUNAdapter
|
|||
destroyTun(tunFD);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Blocks to receive into the buffer
|
||||
*
|
||||
* Params:
|
||||
* buffer = The buffer variable to write the received
|
||||
* data into
|
||||
* Throws:
|
||||
* TUNException if the read failed
|
||||
*/
|
||||
public void receive(ref byte[] buffer)
|
||||
{
|
||||
sanityCheck();
|
||||
|
@ -79,7 +95,7 @@ public class TUNAdapter
|
|||
|
||||
if(status < 0)
|
||||
{
|
||||
throw new TUNException("Read failed");
|
||||
throw new AdapterException("Read failed");
|
||||
}
|
||||
else if(status == 0)
|
||||
{
|
||||
|
@ -90,17 +106,16 @@ public class TUNAdapter
|
|||
/* Copy the data into their buffer (and of correct length) */
|
||||
buffer = scratch[0..status].dup;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the provided data
|
||||
*
|
||||
* Params:
|
||||
* buffer = The data to send
|
||||
* Throws:
|
||||
* TUNException if an error occurs
|
||||
*/
|
||||
public void send(byte[] buffer)
|
||||
{
|
||||
sanityCheck();
|
||||
|
@ -120,7 +135,7 @@ public class TUNAdapter
|
|||
|
||||
}
|
||||
|
||||
public final class TUNException : Exception
|
||||
public final class AdapterException : Exception
|
||||
{
|
||||
this(string msg)
|
||||
{
|
||||
|
@ -128,8 +143,8 @@ public final class TUNException : Exception
|
|||
}
|
||||
}
|
||||
|
||||
public enum AdapterType : ushort
|
||||
public enum AdapterType : byte
|
||||
{
|
||||
TUN = 1,
|
||||
TAP = 0
|
||||
TAP = 2
|
||||
}
|
|
@ -8,7 +8,7 @@ import core.thread;
|
|||
void main()
|
||||
{
|
||||
writeln("Edit source/app.d to start your project.");
|
||||
TUNAdapter adapter = new TUNAdapter("testInterface0");
|
||||
Adapter adapter = new Adapter("testInterface0");
|
||||
|
||||
while(true)
|
||||
{
|
||||
|
|
|
@ -20,11 +20,20 @@
|
|||
#include<string.h>
|
||||
#include<sys/ioctl.h>
|
||||
#include<unistd.h>
|
||||
#include<stdint.h>
|
||||
|
||||
int createTun(char* interfaceName, int iffFlags)
|
||||
/* TODO: Update types here using stdint */
|
||||
//TODO: We could possibly use directly
|
||||
uint32_t createTun(char* interfaceName, int32_t iffFlags)
|
||||
{
|
||||
/* TODO: Add all required error checking */
|
||||
int tunFD = open("/dev/net/tun", O_RDWR);
|
||||
int32_t tunFD = open("/dev/net/tun", O_RDWR);
|
||||
|
||||
/* If error */
|
||||
if(tunFD < 0)
|
||||
{
|
||||
return tunFD;
|
||||
}
|
||||
|
||||
/* TUN properties */
|
||||
struct ifreq interfaceReqData;
|
||||
|
@ -38,22 +47,24 @@ int createTun(char* interfaceName, int iffFlags)
|
|||
strcpy(interfaceReqData.ifr_name, interfaceName);
|
||||
|
||||
/* Attempt to bring up the tun device node */
|
||||
int tunStatus = ioctl(tunFD, TUNSETIFF, &interfaceReqData);
|
||||
int32_t tunStatus = ioctl(tunFD, TUNSETIFF, &interfaceReqData);
|
||||
|
||||
if(tunStatus < 0)
|
||||
{
|
||||
tunFD = tunStatus;
|
||||
tunFD = tunStatus;
|
||||
}
|
||||
|
||||
return tunFD;
|
||||
}
|
||||
|
||||
int destroyTun(int fd)
|
||||
//TOOD: Maybe use directly
|
||||
uint32_t destroyTun(uint32_t fd)
|
||||
{
|
||||
return close(fd);
|
||||
}
|
||||
|
||||
int tunWrite(int fd, char* data, int length)
|
||||
//TODO: Maybe use directly
|
||||
uint32_t tunWrite(uint32_t fd, char* data, int length)
|
||||
{
|
||||
write(fd, data, length);
|
||||
}
|
||||
|
@ -64,7 +75,11 @@ int tunWrite(int fd, char* data, int length)
|
|||
*
|
||||
* (FIXME: For now we just read 20 bytes)
|
||||
*/
|
||||
int tunRead(int fd, char* data, int amount)
|
||||
//TODO: Maybe use directly
|
||||
uint32_t tunRead(uint32_t fd, char* data, int amount)
|
||||
{
|
||||
return read(fd, data, amount);
|
||||
}
|
||||
|
||||
|
||||
// uint32_t tunSet()
|
Loading…
Reference in New Issue