summaryrefslogtreecommitdiffhomepage
path: root/src/tun_linux.go
diff options
context:
space:
mode:
authorMathias Hall-Andersen <mathias@hall-andersen.dk>2017-12-04 21:39:06 +0100
committerMathias Hall-Andersen <mathias@hall-andersen.dk>2017-12-04 21:39:06 +0100
commit996c7c4d8aa11a73718e49b520d16bbf0630a3df (patch)
tree458d8349b53eb9b6a9f9d0fdd364a43ac10b96c5 /src/tun_linux.go
parent9fef0ca2fb26bfc15a5b25fdc4a03768fd6207b8 (diff)
Removed IFF_NO_PI from TUN linux
This change was needed for the Linux TUN status hack to work properly (not increment the error counter). This commit also updates the TUN interface to allow for the construction / removal of the TUN info headers in-place.
Diffstat (limited to 'src/tun_linux.go')
-rw-r--r--src/tun_linux.go36
1 files changed, 31 insertions, 5 deletions
diff --git a/src/tun_linux.go b/src/tun_linux.go
index 8a5d53b..daa2462 100644
--- a/src/tun_linux.go
+++ b/src/tun_linux.go
@@ -7,6 +7,7 @@ import (
"encoding/binary"
"errors"
"fmt"
+ "golang.org/x/net/ipv6"
"golang.org/x/sys/unix"
"net"
"os"
@@ -249,16 +250,41 @@ func (tun *NativeTun) MTU() (int, error) {
return int(val), nil
}
-func (tun *NativeTun) Write(d []byte) (int, error) {
- return tun.fd.Write(d)
+func (tun *NativeTun) Write(buff []byte, offset int) (int, error) {
+
+ // reserve space for header
+
+ buff = buff[offset-4:]
+
+ // add packet information header
+
+ buff[0] = 0x00
+ buff[1] = 0x00
+
+ if buff[4] == ipv6.Version<<4 {
+ buff[2] = 0x86
+ buff[3] = 0xdd
+ } else {
+ buff[2] = 0x08
+ buff[3] = 0x00
+ }
+
+ // write
+
+ return tun.fd.Write(buff)
}
-func (tun *NativeTun) Read(d []byte) (int, error) {
+func (tun *NativeTun) Read(buff []byte, offset int) (int, error) {
select {
case err := <-tun.errors:
return 0, err
default:
- return tun.fd.Read(d)
+ buff := buff[offset-4:]
+ n, err := tun.fd.Read(buff[:])
+ if n < 4 {
+ return 0, err
+ }
+ return n - 4, err
}
}
@@ -306,7 +332,7 @@ func CreateTUN(name string) (TUNDevice, error) {
// create new device
var ifr [IFReqSize]byte
- var flags uint16 = unix.IFF_TUN | unix.IFF_NO_PI
+ var flags uint16 = unix.IFF_TUN // | unix.IFF_NO_PI
nameBytes := []byte(name)
if len(nameBytes) >= unix.IFNAMSIZ {
return nil, errors.New("Interface name too long")