- fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
- if (fd < 0)
- return -errno;
-
- if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0) {
- r = -errno;
- goto finish;
- }
-
- memset(&req, 0, sizeof(req));
- req.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg));
- req.hdr.nlmsg_type = RTM_GETADDR;
- req.hdr.nlmsg_flags = NLM_F_REQUEST|NLM_F_DUMP|NLM_F_ACK;
- req.hdr.nlmsg_seq = seq;
- req.hdr.nlmsg_pid = 0;
-
- gen = NLMSG_DATA(&req.hdr);
- gen->rtgen_family = AF_UNSPEC;
-
- if (send(fd, &req, req.hdr.nlmsg_len, 0) < 0) {
- r = -errno;
- goto finish;
- }
-
- for (;;) {
- ssize_t bytes;
- struct msghdr msg;
- struct cmsghdr *cmsg;
- struct ucred *ucred;
- struct iovec iov;
- struct nlmsghdr *p;
- uint8_t cred_buffer[CMSG_SPACE(sizeof(struct ucred))];
- struct {
- struct nlmsghdr hdr;
- struct ifaddrmsg ifaddrmsg;
- uint8_t payload[16*1024];
- } resp;
-
- memset(&iov, 0, sizeof(iov));
- iov.iov_base = &resp;
- iov.iov_len = sizeof(resp);
-
- memset(&msg, 0, sizeof(msg));
- msg.msg_name = NULL;
- msg.msg_namelen = 0;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = cred_buffer;
- msg.msg_controllen = sizeof(cred_buffer);
- msg.msg_flags = 0;
-
- bytes = recvmsg(fd, &msg, 0);
- if (bytes < 0) {
- r = -errno;
- goto finish;
- }