summaryrefslogtreecommitdiffhomepage
path: root/test/packetimpact/testbench/rawsockets.go
diff options
context:
space:
mode:
Diffstat (limited to 'test/packetimpact/testbench/rawsockets.go')
-rw-r--r--test/packetimpact/testbench/rawsockets.go33
1 files changed, 26 insertions, 7 deletions
diff --git a/test/packetimpact/testbench/rawsockets.go b/test/packetimpact/testbench/rawsockets.go
index 193bb2dc8..1ac96626a 100644
--- a/test/packetimpact/testbench/rawsockets.go
+++ b/test/packetimpact/testbench/rawsockets.go
@@ -38,13 +38,27 @@ func htons(x uint16) uint16 {
}
// NewSniffer creates a Sniffer connected to *device.
-func NewSniffer(t *testing.T) (Sniffer, error) {
+func (n *DUTTestNet) NewSniffer(t *testing.T) (Sniffer, error) {
t.Helper()
+ ifInfo, err := net.InterfaceByName(n.LocalDevName)
+ if err != nil {
+ return Sniffer{}, err
+ }
+
+ var haddr [8]byte
+ copy(haddr[:], ifInfo.HardwareAddr)
+ sa := unix.SockaddrLinklayer{
+ Protocol: htons(unix.ETH_P_ALL),
+ Ifindex: ifInfo.Index,
+ }
snifferFd, err := unix.Socket(unix.AF_PACKET, unix.SOCK_RAW, int(htons(unix.ETH_P_ALL)))
if err != nil {
return Sniffer{}, err
}
+ if err := unix.Bind(snifferFd, &sa); err != nil {
+ return Sniffer{}, err
+ }
if err := unix.SetsockoptInt(snifferFd, unix.SOL_SOCKET, unix.SO_RCVBUFFORCE, 1); err != nil {
t.Fatalf("can't set sockopt SO_RCVBUFFORCE to 1: %s", err)
}
@@ -60,7 +74,8 @@ func NewSniffer(t *testing.T) (Sniffer, error) {
// packet too large for the buffer arrives, the test will get a fatal error.
const maxReadSize int = 65536
-// Recv tries to read one frame until the timeout is up.
+// Recv tries to read one frame until the timeout is up. If the timeout given
+// is 0, then no read attempt will be made.
func (s *Sniffer) Recv(t *testing.T, timeout time.Duration) []byte {
t.Helper()
@@ -73,9 +88,13 @@ func (s *Sniffer) Recv(t *testing.T, timeout time.Duration) []byte {
whole, frac := math.Modf(timeout.Seconds())
tv := unix.Timeval{
Sec: int64(whole),
- Usec: int64(frac * float64(time.Microsecond/time.Second)),
+ Usec: int64(frac * float64(time.Second/time.Microsecond)),
+ }
+ // The following should never happen, but having this guard here is better
+ // than blocking indefinitely in the future.
+ if tv.Sec == 0 && tv.Usec == 0 {
+ t.Fatal("setting SO_RCVTIMEO to 0 means blocking indefinitely")
}
-
if err := unix.SetsockoptTimeval(s.fd, unix.SOL_SOCKET, unix.SO_RCVTIMEO, &tv); err != nil {
t.Fatalf("can't setsockopt SO_RCVTIMEO: %s", err)
}
@@ -136,10 +155,10 @@ type Injector struct {
}
// NewInjector creates a new injector on *device.
-func NewInjector(t *testing.T) (Injector, error) {
+func (n *DUTTestNet) NewInjector(t *testing.T) (Injector, error) {
t.Helper()
- ifInfo, err := net.InterfaceByName(LocalDevice)
+ ifInfo, err := net.InterfaceByName(n.LocalDevName)
if err != nil {
return Injector{}, err
}
@@ -147,7 +166,7 @@ func NewInjector(t *testing.T) (Injector, error) {
var haddr [8]byte
copy(haddr[:], ifInfo.HardwareAddr)
sa := unix.SockaddrLinklayer{
- Protocol: unix.ETH_P_IP,
+ Protocol: htons(unix.ETH_P_IP),
Ifindex: ifInfo.Index,
Halen: uint8(len(ifInfo.HardwareAddr)),
Addr: haddr,