dnstt_exporter/internal/dnstt/capture_linux.go

51 lines
1.1 KiB
Go
Raw Normal View History

2026-05-05 13:43:02 +02:00
//go:build linux
package dnstt
import (
"fmt"
"syscall"
)
// OpenRawSocket creates an AF_PACKET raw socket for sniffing IPv4 packets.
func OpenRawSocket() (int, error) {
fd, err := syscall.Socket(syscall.AF_PACKET, syscall.SOCK_DGRAM, int(htons(syscall.ETH_P_IP)))
if err != nil {
return -1, fmt.Errorf("open raw socket: %w", err)
}
tv := syscall.Timeval{Sec: 0, Usec: 500000}
_ = syscall.SetsockoptTimeval(fd, syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, &tv)
return fd, nil
}
// CaptureLoop records matching packets until stop is closed.
func CaptureLoop(fd int, port int, collector *Collector, stop <-chan struct{}) {
buf := make([]byte, 65535)
for {
select {
case <-stop:
return
default:
}
n, _, err := syscall.Recvfrom(fd, buf, 0)
if err != nil {
if err == syscall.EAGAIN || err == syscall.EWOULDBLOCK || err == syscall.EINTR {
continue
}
return
}
ProcessIPv4Packet(buf[:n], port, collector)
}
}
// CloseRawSocket closes a socket opened by OpenRawSocket.
func CloseRawSocket(fd int) error {
return syscall.Close(fd)
}
func htons(v uint16) uint16 {
return (v << 8) | (v >> 8)
}