代码拉取完成,页面将自动刷新
#include <iostream>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/sock_diag.h>
#include <linux/unix_diag.h>
#define MAGIC_SEQ 123456
#define DIAG_REQUEST(_req, _r) \
struct { \
struct nlmsghdr nlh; \
_r; \
} _req = { \
.nlh = { \
.nlmsg_type = SOCK_DIAG_BY_FAMILY, \
.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST,\
.nlmsg_seq = MAGIC_SEQ, \
.nlmsg_len = sizeof(_req), \
}, \
}
static int send_query(int fd)
{
struct sockaddr_nl nladdr = {
.nl_family = AF_NETLINK
};
struct
{
struct nlmsghdr nlh;
struct unix_diag_req udr;
} req = {
.nlh = {
.nlmsg_len = sizeof(req),
.nlmsg_type = SOCK_DIAG_BY_FAMILY,
.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP
},
.udr = {
.sdiag_family = AF_UNIX,
// .udiag_states = -1,
.udiag_states = 1,
.udiag_show = UDIAG_SHOW_NAME | UDIAG_SHOW_PEER | UDIAG_SHOW_UID
}
};
struct iovec iov = {
.iov_base = &req,
.iov_len = sizeof(req)
};
struct msghdr msg = {
.msg_name = &nladdr,
.msg_namelen = sizeof(nladdr),
.msg_iov = &iov,
.msg_iovlen = 1
// .msg_iovlen = sizeof(iovec)
};
// if (sendmsg(fd, &msg, 0) < 0)
// {
// perror("sendmsg");
// return -1;
// }
for (;;)
{
if (sendmsg(fd, &msg, 0) < 0)
{
if (errno == EINTR)
continue;
perror("sendmsg");
return -1;
}
return 0;
}
}
static int print_diag(const struct unix_diag_msg* diag, unsigned int len)
{
if (len < NLMSG_LENGTH(sizeof(*diag)))
{
fputs("short response\n", stderr);
return -1;
}
if (diag->udiag_family != AF_UNIX)
{
fprintf(stderr, "unexpected family %u\n", diag->udiag_family);
return -1;
}
unsigned int rta_len = len - NLMSG_LENGTH(sizeof(*diag));
unsigned int peer = 0;
size_t path_len = 0;
char path[sizeof(((struct sockaddr_un*)0)->sun_path) + 1];
for (struct rtattr* attr = (struct rtattr*)(diag + 1);
RTA_OK(attr, rta_len); attr = RTA_NEXT(attr, rta_len))
{
switch (attr->rta_type)
{
case UNIX_DIAG_NAME:
if (!path_len)
{
path_len = RTA_PAYLOAD(attr);
if (path_len > sizeof(path) - 1)
path_len = sizeof(path) - 1;
memcpy(path, RTA_DATA(attr), path_len);
path[path_len] = '\0';
}
break;
case UNIX_DIAG_PEER:
if (RTA_PAYLOAD(attr) >= sizeof(peer))
peer = *(unsigned int*)RTA_DATA(attr);
break;
}
}
printf("inode=%u", diag->udiag_ino);
if (peer)
printf(", peer=%u", peer);
if (path_len)
printf(", name=%s%s", *path ? "" : "@",
*path ? path : path + 1);
putchar('\n');
return 0;
}
static int receive_responses(int fd)
{
long buf[8192 / sizeof(long)];
struct sockaddr_nl nladdr;
struct iovec iov = {
.iov_base = buf,
.iov_len = sizeof(buf)
};
int flags = 0;
for (;;)
{
struct msghdr msg = {
.msg_name = &nladdr,
.msg_namelen = sizeof(nladdr),
.msg_iov = &iov,
.msg_iovlen = 1
};
ssize_t ret = recvmsg(fd, &msg, flags);
if (ret < 0)
{
if (errno == EINTR)
continue;
perror("recvmsg");
return -1;
}
if (ret == 0)
return 0;
if (nladdr.nl_family != AF_NETLINK)
{
fputs("!AF_NETLINK\n", stderr);
return -1;
}
const struct nlmsghdr* h = (struct nlmsghdr*)buf;
if (!NLMSG_OK(h, ret))
{
fputs("!NLMSG_OK\n", stderr);
return -1;
}
for (; NLMSG_OK(h, ret); h = NLMSG_NEXT(h, ret))
{
if (h->nlmsg_type == NLMSG_DONE)
return 0;
if (h->nlmsg_type == NLMSG_ERROR)
{
const struct nlmsgerr* err = (struct nlmsgerr*)NLMSG_DATA(h);
if (h->nlmsg_len < NLMSG_LENGTH(sizeof(*err)))
{
fputs("NLMSG_ERROR\n", stderr);
}
else
{
errno = -err->error;
perror("NLMSG_ERROR");
}
return -1;
}
if (h->nlmsg_type != SOCK_DIAG_BY_FAMILY)
{
fprintf(stderr, "unexpected nlmsg_type %u\n",
(unsigned)h->nlmsg_type);
return -1;
}
if (print_diag((struct unix_diag_msg*)NLMSG_DATA(h), h->nlmsg_len))
return -1;
}
}
}
static int rtnl_open()
{
socklen_t addr_len;
int sndbuf = 32768;
int one = 1;
int rcvbuf = 1024 * 1024;
int fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_SOCK_DIAG);
if (fd < 0)
{
perror("Cannot open netlink socket");
return -1;
}
if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF,
&sndbuf, sizeof(sndbuf)) < 0)
{
perror("SO_SNDBUF");
return -1;
}
if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF,
&rcvbuf, sizeof(rcvbuf)) < 0)
{
perror("SO_RCVBUF");
return -1;
}
/* Older kernels may no support extended ACK reporting */
setsockopt(fd, SOL_NETLINK, NETLINK_EXT_ACK,
&one, sizeof(one));
struct sockaddr_nl src_addr;
memset(&src_addr, 0, sizeof(src_addr));
//src_address
src_addr.nl_family = AF_NETLINK;
src_addr.nl_pid = getpid(); // self pid
src_addr.nl_groups = 0; // multi cast
if (bind(fd, (struct sockaddr*)&src_addr, sizeof(src_addr)))
{
perror("Cannot bind netlink socket");
return -1;
}
if (getsockname(fd, (struct sockaddr*)&src_addr, &addr_len) < 0)
{
perror("Cannot getsockname");
return -1;
}
return fd;
}
int main(void)
{
int fd = rtnl_open();
// if (fd < 0)
// {
// perror("socket");
// return 1;
// }
//
// struct sockaddr_nl src_addr;
//
// memset(&src_addr, 0, sizeof(src_addr));
// //src_address
// src_addr.nl_family = AF_NETLINK;
// src_addr.nl_pid = getpid(); // self pid
// src_addr.nl_groups = 0; // multi cast
// bind(fd, (struct sockaddr*)&src_addr, sizeof(src_addr));
int ret = send_query(fd) || receive_responses(fd);
// send_query(fd);
//
// receive_responses(fd);
close(fd);
return ret;
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。