mirror of
https://github.com/soypat/lneto.git
synced 2026-08-31 20:09:05 +00:00
add ARP; add tap internal calls; more lneto2 additions
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
//go:build linux && !baremetal
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/netip"
|
||||
"os"
|
||||
"os/exec"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type Tap struct {
|
||||
fd int
|
||||
name string
|
||||
}
|
||||
|
||||
func NewTap(name string, ip netip.Prefix) (*Tap, error) {
|
||||
if len(name) >= syscall.IFNAMSIZ {
|
||||
return nil, errors.New("name too large")
|
||||
}
|
||||
fd, err := syscall.Open("/dev/net/tun", os.O_RDWR, 0777)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open tun device: %w", err)
|
||||
}
|
||||
|
||||
var ifr [syscall.IFNAMSIZ + 64]byte // extra space for compatibility
|
||||
|
||||
// Set the name; it will be zero-padded automatically.
|
||||
copy(ifr[:syscall.IFNAMSIZ-1], name)
|
||||
|
||||
// Set the flags (starting at offset IFNAMSIZ).
|
||||
flags := uint16(syscall.IFF_TAP | syscall.IFF_NO_PI)
|
||||
*(*uint16)(unsafe.Pointer(&ifr[syscall.IFNAMSIZ])) = flags
|
||||
// Issue the ioctl to create the interface.
|
||||
_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TUNSETIFF), uintptr(unsafe.Pointer(&ifr[0])))
|
||||
if errno != 0 {
|
||||
return nil, fmt.Errorf("creating tap interface: %w", errno)
|
||||
}
|
||||
if ip.IsValid() {
|
||||
// Optionally, bring the interface up and assign an IP address.
|
||||
// You can do this using the 'ip' command for simplicity.
|
||||
err = exec.Command("ip", "link", "set", "dev", name, "up").Run()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to set ip link: %w", err)
|
||||
}
|
||||
|
||||
err = exec.Command("ip", "addr", "add", ip.String(), "dev", name).Run()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to assign IP address: %w", err)
|
||||
}
|
||||
}
|
||||
return &Tap{fd: fd, name: name}, nil
|
||||
}
|
||||
|
||||
func (tap *Tap) Read(b []byte) (int, error) {
|
||||
return syscall.Read(tap.fd, b)
|
||||
}
|
||||
|
||||
func (tap *Tap) Write(b []byte) (int, error) {
|
||||
return syscall.Write(tap.fd, b)
|
||||
}
|
||||
|
||||
func (tap *Tap) Close() error {
|
||||
return syscall.Close(tap.fd)
|
||||
}
|
||||
Reference in New Issue
Block a user