首先,你可以从my previous post中找到我的详细情况。
我在过去一天左右的时间里第一次尝试 netlink 套接字程序。
而且我不想让人觉得我没有从我在互联网上找到的其他人的示例代码中获得所有这些代码,因为我们都知道我就是这样做的。
但我一直在尝试对代码进行逆向工程(见结尾),经过数小时的调试,我终于成功编译了它。但是在尝试运行它之后,我收到消息“Segmentation Fault (Core Dumped)”。
现在我知道这个错误与尝试从无效的内存位置读取有关,但老实说我不理解我拼接在一起的一半代码所以如果有人能指出我哪里出错了我将不胜感激
如果您能解释一下我在一般情况下尝试通过 netlink 套接字发送消息时做对/做错的事情,我将非常感激。例如,我会将消息放在哪里?因为我真的不知道我现在会按原样发送什么消息。感谢您的帮助!
#include <sys/socket.h> /* socket definitions */
#include <sys/types.h> /* socket types */
#include <linux/netlink.h> /* netlink functions */
#include <sys/uio.h> /* scatter-gather definition for iovec */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/* Global constants */
#define ECHO_PORT (2002)
#define MAX_LINE (1000)
int socketHolder; // declare variable to hold Socket
// Set up configuration for destination which holds the socket to be used to communicate with the Kernel
struct sockaddr_nl dest; // declare variable to hold Socket Address
// Set up configuration for the netlink message header
struct nlmsghdr *netlinkHeader; // declare variable to hold message to be sent
// Set up configuration for the scatter-gather function for expediting writing to buffer
struct iovec iov;
// Set up configuration for the message header for simplifying message parameters to be sent
struct msghdr message;
int main()
{
memset(&dest, 0, sizeof(dest)); // set socket Address to all 0
dest.nl_family = AF_NETLINK; // set socket family to AF_NETLINK
dest.nl_pad = 0; // defaults to 0
dest.nl_pid = 0; // set address of netlink socket to 0 because we're going to the kernel
dest.nl_groups = 0; // set to 0 because we're doing unicast
netlinkHeader->nlmsg_pid = 0; // set sender port number to 0 because we're in kernel
iov.iov_base = (caddr_t)netlinkHeader; // set address of buffer
iov.iov_len = netlinkHeader->nlmsg_len; // set length of buffer
message.msg_name = (caddr_t) &dest; // set socket name
message.msg_namelen = sizeof(dest); // set length of name
message.msg_iov = &iov; // I have no idea what this is
message.msg_iovlen = 1; // number of iov blocks
message.msg_control = NULL; // ignore
message.msg_controllen = 0; // ignore
message.msg_flags = 0; //ignore
socketHolder = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC); // declare Socket and assign to holder variable
bind(socketHolder, (struct sockaddr *) &dest, sizeof(dest)); // bind the destination settings to socketHolder
int sender = sendmsg(socketHolder, &message, 0); // send the message
}
不幸的是,我对 netlink 不是很熟悉。但是你的错误(非常)可能在这里:
netlinkHeader->nlmsg_pid = 0; // set sender port number to 0 because we're in kernel
因为您从未初始化过 netlinkHeader
,即确保指针指向允许您读写的内存,所以这是未定义的行为。在实践中,它通常会导致段错误,因为您正在访问一些随机地址,并且您的操作系统会阻止您的进程破坏事物。
完全不确定为什么这是一个指针,您或许应该尝试使它成为 struct nlmsghdr
类型的实际实例,因为这听起来好像您想操纵地址。
此外,注释暗示代码取自内核代码,而您的代码不是内核代码,这可能暗示还有其他问题。
我是一名优秀的程序员,十分优秀!