Pndpd/pndp/interface.go

85 lines
1.9 KiB
Go
Raw Normal View History

2021-12-27 07:58:10 -05:00
package pndp
import (
"golang.org/x/net/bpf"
"golang.org/x/sys/unix"
2022-01-04 17:37:52 -05:00
"net"
2021-12-27 07:58:10 -05:00
"syscall"
"unsafe"
)
// bpfFilter represents a classic BPF filter program that can be applied to a socket
type bpfFilter []bpf.Instruction
// ApplyTo applies the current filter onto the provided file descriptor
func (filter bpfFilter) ApplyTo(fd int) (err error) {
var assembled []bpf.RawInstruction
if assembled, err = bpf.Assemble(filter); err != nil {
return err
}
var program = unix.SockFprog{
Len: uint16(len(assembled)),
Filter: (*unix.SockFilter)(unsafe.Pointer(&assembled[0])),
}
var b = (*[unix.SizeofSockFprog]byte)(unsafe.Pointer(&program))[:unix.SizeofSockFprog]
if _, _, errno := syscall.Syscall6(syscall.SYS_SETSOCKOPT,
uintptr(fd), uintptr(syscall.SOL_SOCKET), uintptr(syscall.SO_ATTACH_FILTER),
uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), 0); errno != 0 {
return errno
}
return nil
}
type iflags struct {
name [syscall.IFNAMSIZ]byte
flags uint16
}
2022-01-04 15:48:28 -05:00
func setPromisc(fd int, iface string, enable bool) {
2022-01-04 17:37:52 -05:00
//TODO re-test ALLMULTI
2021-12-27 07:58:10 -05:00
var ifl iflags
copy(ifl.name[:], []byte(iface))
_, _, ep := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), syscall.SIOCGIFFLAGS, uintptr(unsafe.Pointer(&ifl)))
if ep != 0 {
panic(ep)
}
if enable {
2022-01-04 15:48:28 -05:00
ifl.flags |= uint16(syscall.IFF_PROMISC)
2021-12-27 07:58:10 -05:00
} else {
2022-01-04 15:48:28 -05:00
ifl.flags &^= uint16(syscall.IFF_PROMISC)
2021-12-27 07:58:10 -05:00
}
_, _, ep = syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), syscall.SIOCSIFFLAGS, uintptr(unsafe.Pointer(&ifl)))
if ep != 0 {
panic(ep)
}
2022-01-04 17:37:52 -05:00
// Also set Sockopt to promisc
intf, err := net.InterfaceByName(iface)
if err != nil {
panic(err.Error())
}
mreq := unix.PacketMreq{
Ifindex: int32(intf.Index),
Type: unix.PACKET_MR_PROMISC,
}
var opt int
if enable {
opt = unix.PACKET_ADD_MEMBERSHIP
} else {
opt = unix.PACKET_DROP_MEMBERSHIP
}
err = unix.SetsockoptPacketMreq(fd, unix.SOL_PACKET, opt, &mreq)
if err != nil {
panic(err)
}
2021-12-27 07:58:10 -05:00
}