in sys/linux/inetdiag.go [139:198]
func NetlinkInetDiagWithBuf(request syscall.NetlinkMessage, readBuf []byte, resp io.Writer) ([]*InetDiagMsg, error) {
s, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_INET_DIAG)
if err != nil {
return nil, err
}
defer syscall.Close(s)
lsa := &syscall.SockaddrNetlink{Family: syscall.AF_NETLINK}
if err := syscall.Sendto(s, serialize(request), 0, lsa); err != nil {
return nil, err
}
if len(readBuf) == 0 {
// Default size used in libnl.
readBuf = make([]byte, os.Getpagesize())
}
var inetDiagMsgs []*InetDiagMsg
done:
for {
buf := readBuf
nr, _, err := syscall.Recvfrom(s, buf, 0)
if err != nil {
return nil, err
}
if nr < syscall.NLMSG_HDRLEN {
return nil, syscall.EINVAL
}
buf = buf[:nr]
// Dump raw data for inspection purposes.
if resp != nil {
if _, err := resp.Write(buf); err != nil {
return nil, err
}
}
msgs, err := syscall.ParseNetlinkMessage(buf)
if err != nil {
return nil, err
}
for _, m := range msgs {
if m.Header.Type == syscall.NLMSG_DONE {
break done
}
if m.Header.Type == syscall.NLMSG_ERROR {
return nil, ParseNetlinkError(m.Data)
}
inetDiagMsg, err := ParseInetDiagMsg(m.Data)
if err != nil {
return nil, err
}
inetDiagMsgs = append(inetDiagMsgs, inetDiagMsg)
}
}
return inetDiagMsgs, nil
}