Support nopi mode

This commit is contained in:
Jason A. Donenfeld 2018-02-28 12:40:56 +01:00
parent 09de7d1342
commit fd248c6cb1

View file

@ -27,6 +27,7 @@ type NativeTun struct {
name string // name of interface name string // name of interface
errors chan error // async error handling errors chan error // async error handling
events chan TUNEvent // device related events events chan TUNEvent // device related events
nopi bool // the device was pased IFF_NO_PI
} }
func toRTMGRP(sc uint) uint { func toRTMGRP(sc uint) uint {
@ -242,21 +243,25 @@ func (tun *NativeTun) MTU() (int, error) {
func (tun *NativeTun) Write(buff []byte, offset int) (int, error) { func (tun *NativeTun) Write(buff []byte, offset int) (int, error) {
// reserve space for header if tun.nopi {
buff = buff[offset:]
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 { } else {
buff[2] = 0x08 // reserve space for header
buff[3] = 0x00
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 // write
@ -269,12 +274,16 @@ func (tun *NativeTun) Read(buff []byte, offset int) (int, error) {
case err := <-tun.errors: case err := <-tun.errors:
return 0, err return 0, err
default: default:
buff := buff[offset-4:] if tun.nopi {
n, err := tun.fd.Read(buff[:]) return tun.fd.Read(buff[offset:])
if n < 4 { } else {
return 0, err buff := buff[offset-4:]
n, err := tun.fd.Read(buff[:])
if n < 4 {
return 0, err
}
return n - 4, err
} }
return n - 4, err
} }
} }
@ -292,6 +301,7 @@ func CreateTUNFromFile(name string, fd *os.File) (TUNDevice, error) {
name: name, name: name,
events: make(chan TUNEvent, 5), events: make(chan TUNEvent, 5),
errors: make(chan error, 5), errors: make(chan error, 5),
nopi: false,
} }
// start event listener // start event listener
@ -349,6 +359,7 @@ func CreateTUN(name string) (TUNDevice, error) {
name: newName, name: newName,
events: make(chan TUNEvent, 5), events: make(chan TUNEvent, 5),
errors: make(chan error, 5), errors: make(chan error, 5),
nopi: false,
} }
// start event listener // start event listener