func (d *afpacket) Read(to *ethernet.Frame) (err error) { to.Resize(d.ifce.MTU) for { *to = (*to)[:cap(*to)] var n int n, _, err = unix.Recvfrom(d.fd, []byte(*to), 0) if err != nil { return } *to = (*to)[:n] if !equalMAC(to.Source(), d.ifce.HardwareAddr) && (d.filter == nil || d.filter(*to)) { return } } }
func (d *bpfDev) Read(to *ethernet.Frame) (err error) { to.Resize(d.ifce.MTU) for { for d.p < d.n { hdr := (*bpfHdr)(unsafe.Pointer(&d.readBuf[d.p])) frameStart := d.p + int(hdr.hdrlen) n := int(hdr.caplen) *to = (*to)[:n] copy(*to, d.readBuf[frameStart:frameStart+n]) d.p += bpfWordalign(int(hdr.hdrlen) + int(hdr.caplen)) if !equalMAC(to.Source(), d.ifce.HardwareAddr) && (d.filter == nil || d.filter(*to)) { return } } d.n, err = d.fd.Read(d.readBuf) if err != nil { return } d.p = 0 } }
func TestReadFrame(t *testing.T) { var ( ifce *net.Interface err error d Dev ) if ifce, err = net.InterfaceByName(*dev); err != nil { t.Fatalf("getting interface error: %v", err) } d, err = NewDev(ifce, nil) if err != nil { t.Fatal(err) } var to ethernet.Frame for i := 0; i < 16; i++ { err = d.Read(&to) t.Logf("got frame: from %v to %v (ethertype %v): % x\n", to.Source(), to.Destination(), to.Ethertype(), to.Payload()) if err != nil { t.Fatal(err) } } err = d.Close() if err != nil { t.Fatal(err) } for i := 0; i < 1024; i++ { err = d.Read(&to) if err != nil { break } } if err == nil { t.Fatal("closed Dev can still read") } }