in netlink.go [162:200]
func (c *NetlinkClient) Receive(nonBlocking bool, p NetlinkParser) ([]syscall.NetlinkMessage, error) {
var flags int
if nonBlocking {
flags |= syscall.MSG_DONTWAIT
}
// XXX (akroh): A possible enhancement is to use the MSG_PEEK flag to
// check the message size and increase the buffer size to handle it all.
nr, from, err := syscall.Recvfrom(c.fd, c.readBuf, flags)
if err != nil {
// EAGAIN or EWOULDBLOCK will be returned for non-blocking reads where
// the read would normally have blocked.
return nil, err
}
if nr < syscall.NLMSG_HDRLEN {
return nil, fmt.Errorf("not enough bytes (%v) received to form a netlink header", nr)
}
fromNetlink, ok := from.(*syscall.SockaddrNetlink)
if !ok || fromNetlink.Pid != 0 {
// Spoofed packet received on audit netlink socket.
return nil, errors.New("message received was not from the kernel")
}
buf := c.readBuf[:nr]
// Dump raw data for inspection purposes.
if c.respWriter != nil {
if _, err = c.respWriter.Write(buf); err != nil {
return nil, err
}
}
msgs, err := p(buf)
if err != nil {
return nil, fmt.Errorf("failed to parse netlink messages (bytes_received=%v): %w", nr, err)
}
return msgs, nil
}