是否可以在 Linux 中接收原始以太网帧而不指定接口?
Is it possible to receive raw ethernet frames in Linux without specifying an interface?
我正在使用 mdlayhers (golang) 库来处理原始以太网帧,以便在网络设备上接收和处理 LLDP 数据包。我想监控大量接口(最多 128 个)的 LLDP 帧。
在Linux我don't believe it's required指定一个接口来捕获设备数据,但我可能是错的。是否可以通过例如绑定到 AF_PACKET
来跨所有接口接收原始以太网帧? IE。有没有办法在 raw.ListenPacket
中指定一个通配符接口,或者我最好为每个接口创建一个新的 goroutine?
是的,你可以。我相信这就是您要找的:
package main
import (
"fmt"
"net"
"os"
"syscall"
)
func main() {
fd, err := syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, int(htons(syscall.ETH_P_ALL)))
if err != nil {
fmt.Fprintf(os.Stderr, "syscall socket: %s", err.Error())
os.Exit(1)
}
// Make a 32KB buffer
buf := make([]byte, 1<<16)
for {
len, sockaddr, err := syscall.Recvfrom(fd, buf, 0)
if err != nil {
fmt.Fprintf(os.Stderr, "syscall recvfrom: %s", err.Error())
os.Exit(1)
}
if llsa, ok := sockaddr.(*syscall.SockaddrLinklayer); ok {
inter, err := net.InterfaceByIndex(llsa.Ifindex)
if err != nil {
fmt.Fprintf(os.Stderr, "interface from ifindex: %s", err.Error())
os.Exit(1)
}
fmt.Print(inter.Name + ": ")
}
fmt.Printf("% X\n", buf[:len])
}
}
// htons converts a short (uint16) from host-to-network byte order.
func htons(i uint16) uint16 {
return (i<<8)&0xff00 | i>>8
}
我正在使用 mdlayhers (golang) 库来处理原始以太网帧,以便在网络设备上接收和处理 LLDP 数据包。我想监控大量接口(最多 128 个)的 LLDP 帧。
在Linux我don't believe it's required指定一个接口来捕获设备数据,但我可能是错的。是否可以通过例如绑定到 AF_PACKET
来跨所有接口接收原始以太网帧? IE。有没有办法在 raw.ListenPacket
中指定一个通配符接口,或者我最好为每个接口创建一个新的 goroutine?
是的,你可以。我相信这就是您要找的:
package main
import (
"fmt"
"net"
"os"
"syscall"
)
func main() {
fd, err := syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, int(htons(syscall.ETH_P_ALL)))
if err != nil {
fmt.Fprintf(os.Stderr, "syscall socket: %s", err.Error())
os.Exit(1)
}
// Make a 32KB buffer
buf := make([]byte, 1<<16)
for {
len, sockaddr, err := syscall.Recvfrom(fd, buf, 0)
if err != nil {
fmt.Fprintf(os.Stderr, "syscall recvfrom: %s", err.Error())
os.Exit(1)
}
if llsa, ok := sockaddr.(*syscall.SockaddrLinklayer); ok {
inter, err := net.InterfaceByIndex(llsa.Ifindex)
if err != nil {
fmt.Fprintf(os.Stderr, "interface from ifindex: %s", err.Error())
os.Exit(1)
}
fmt.Print(inter.Name + ": ")
}
fmt.Printf("% X\n", buf[:len])
}
}
// htons converts a short (uint16) from host-to-network byte order.
func htons(i uint16) uint16 {
return (i<<8)&0xff00 | i>>8
}