mirror of
https://github.com/yggdrasil-network/water.git
synced 2025-05-20 00:45:09 +03:00
fake IFF_NO_PI on macOS (thanks @eliezedeck ) (#21)
This commit is contained in:
parent
3bfb4db1dd
commit
66c5b2f72c
2 changed files with 63 additions and 5 deletions
|
@ -147,8 +147,8 @@ $ ping 10.1.0.20
|
||||||
You'd see the ICMP packets printed out:
|
You'd see the ICMP packets printed out:
|
||||||
|
|
||||||
```
|
```
|
||||||
2016/10/23 20:21:53 Interface Name: utun2
|
2017/03/20 21:17:30 Interface Name: utun2
|
||||||
2016/10/23 20:22:40 Packet Received: 00 00 00 02 45 00 00 54 4a 2e 00 00 40 01 1c 5c 0a 01 00 0a 0a 01 00 14 08 00 31 51 f0 f9 00 00 58 0d 7e 80 00 03 14 21 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37
|
2017/03/20 21:17:40 Packet Received: 45 00 00 54 e9 1d 00 00 40 01 7d 6c 0a 01 00 0a 0a 01 00 14 08 00 ee 04 21 15 00 00 58 d0 a9 64 00 08 fb a5 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37
|
||||||
```
|
```
|
||||||
|
|
||||||
### TAP on Windows:
|
### TAP on Windows:
|
||||||
|
|
|
@ -5,7 +5,9 @@ package water
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
@ -112,12 +114,68 @@ func newTUN(string) (ifce *Interface, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Interface{
|
return &Interface{
|
||||||
isTAP: false,
|
isTAP: false,
|
||||||
name: string(ifName.name[:ifNameSize-1 /* -1 is for \0 */]),
|
name: string(ifName.name[:ifNameSize-1 /* -1 is for \0 */]),
|
||||||
ReadWriteCloser: os.NewFile(uintptr(fd), string(ifName.name[:])),
|
ReadWriteCloser: &tunReadCloser{
|
||||||
|
f: os.NewFile(uintptr(fd), string(ifName.name[:])),
|
||||||
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tunReadCloser is a hack to work around the first 4 bytes "packet
|
||||||
|
// information" because there doesn't seem to be an IFF_NO_PI for darwin.
|
||||||
|
type tunReadCloser struct {
|
||||||
|
f io.ReadWriteCloser
|
||||||
|
|
||||||
|
rMu sync.Mutex
|
||||||
|
rBuf []byte
|
||||||
|
|
||||||
|
wMu sync.Mutex
|
||||||
|
wBuf []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ io.ReadWriteCloser = (*tunReadCloser)(nil)
|
||||||
|
|
||||||
|
func (t *tunReadCloser) Read(to []byte) (int, error) {
|
||||||
|
t.rMu.Lock()
|
||||||
|
defer t.rMu.Unlock()
|
||||||
|
|
||||||
|
if cap(t.rBuf) < len(to)+4 {
|
||||||
|
t.rBuf = make([]byte, len(to)+4)
|
||||||
|
}
|
||||||
|
t.rBuf = t.rBuf[:len(to)+4]
|
||||||
|
|
||||||
|
n, err := t.f.Read(t.rBuf)
|
||||||
|
copy(to, t.rBuf[4:])
|
||||||
|
return n - 4, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *tunReadCloser) Write(from []byte) (int, error) {
|
||||||
|
t.wMu.Lock()
|
||||||
|
defer t.wMu.Unlock()
|
||||||
|
|
||||||
|
if cap(t.wBuf) < len(from)+4 {
|
||||||
|
t.wBuf = make([]byte, len(from)+4)
|
||||||
|
}
|
||||||
|
t.wBuf = t.wBuf[:len(from)+4]
|
||||||
|
|
||||||
|
t.wBuf[3] = 2 // Family: IP (2)
|
||||||
|
copy(t.wBuf[4:], from)
|
||||||
|
|
||||||
|
n, err := t.f.Write(t.wBuf)
|
||||||
|
return n - 4, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *tunReadCloser) Close() error {
|
||||||
|
// lock to make sure no read/write is in process.
|
||||||
|
t.rMu.Lock()
|
||||||
|
defer t.rMu.Unlock()
|
||||||
|
t.wMu.Lock()
|
||||||
|
defer t.wMu.Unlock()
|
||||||
|
|
||||||
|
return t.f.Close()
|
||||||
|
}
|
||||||
|
|
||||||
func newTAP(ifName string) (ifce *Interface, err error) {
|
func newTAP(ifName string) (ifce *Interface, err error) {
|
||||||
return nil, errors.New("tap interface not implemented on this platform")
|
return nil, errors.New("tap interface not implemented on this platform")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue