#include "netlinkhandler.h" #include #include #include #include #include NetlinkHandler::NetlinkHandler(QObject *parent) : QObject(parent) {} NetlinkHandler::~NetlinkHandler() { closeSocket(); } bool NetlinkHandler::init(int protocol) { LOG_DEBUG("protoal is %d",protocol); if (!createSocket(protocol)) { emit errorOccurred("Failed to create netlink socket"); return false; } m_notifier = new QSocketNotifier(m_sock, QSocketNotifier::Read, this); connect(m_notifier, &QSocketNotifier::activated, this, &NetlinkHandler::onSocketReadyRead); return true; } bool NetlinkHandler::createSocket(int protocol) { m_sock = socket(AF_NETLINK, SOCK_RAW, protocol); if (m_sock < 0) return false; sockaddr_nl local = {}; local.nl_family = AF_NETLINK; local.nl_pid = getpid(); // 用户态PID local.nl_groups = 0; if (bind(m_sock, reinterpret_cast(&local), sizeof(local)) < 0) { close(m_sock); return false; } return true; } void NetlinkHandler::closeSocket() { if (m_sock >= 0) { ::close(m_sock); m_sock = -1; } } bool NetlinkHandler::sendMessage(const QByteArray &msg) { if (m_sock < 0) return false; struct nlmsghdr *nlh; struct sockaddr_nl kernel = {}; struct iovec iov; struct msghdr message = {}; char buffer[4096] = {}; nlh = reinterpret_cast(buffer); nlh->nlmsg_len = NLMSG_LENGTH(msg.size()); nlh->nlmsg_pid = getpid(); nlh->nlmsg_flags = 0; memcpy(NLMSG_DATA(nlh), msg.data(), msg.size()); kernel.nl_family = AF_NETLINK; iov.iov_base = nlh; iov.iov_len = nlh->nlmsg_len; message.msg_name = &kernel; message.msg_namelen = sizeof(kernel); message.msg_iov = &iov; message.msg_iovlen = 1; return sendmsg(m_sock, &message, 0) >= 0; } void NetlinkHandler::onSocketReadyRead() { char buffer[4096] = {}; int len = recv(m_sock, buffer, sizeof(buffer), 0); if (len < 0) { emit errorOccurred("recv failed"); return; } struct nlmsghdr *nlh = reinterpret_cast(buffer); if (NLMSG_OK(nlh, len)) { QByteArray data(reinterpret_cast(NLMSG_DATA(nlh)), nlh->nlmsg_len - NLMSG_HDRLEN); emit messageReceived(data); } }