1,內核態代碼
#include <linux/module.h>
#include <linux/netlink.h>
#include <net/sock.h>#define NETLINK_TEST 31
struct sock *nl_sk = NULL;
static void nl_recv_msg(struct sk_buff *skb) {
??? struct nlmsghdr *nlh;
??? int pid;
??? char *msg;
?? ?
??? nlh = (struct nlmsghdr*)skb->data;
??? pid = nlh->nlmsg_pid; // 獲取發送者的 PID
??? msg = nlh->nlmsg_data;??? printk(KERN_INFO "Received message: %s from pid: %d\n", msg, pid);
??? // 回復用戶空間
??? nlh->nlmsg_pid = 0; // 目標為用戶空間
??? nlh->nlmsg_type = NLMSG_DONE; // 消息類型
??? strcpy(nlh->nlmsg_data, "Hello from Kernel");
?? ?
??? netlink_unicast(nl_sk, skb, pid, MSG_DONTWAIT);
}static int __init hello_init(void) {
??? struct netlink_kernel_cfg cfg = {
??????? .input = nl_recv_msg,
??? };??? nl_sk = netlink_kernel_create(&init_net, NETLINK_TEST, &cfg);
??? if (!nl_sk) {
??????? printk(KERN_ALERT "Error creating netlink socket.\n");
??????? return -ENOMEM;
??? }
??? printk(KERN_INFO "Netlink module initialized.\n");
??? return 0;
}static void __exit hello_exit(void) {
??? netlink_kernel_release(nl_sk);
??? printk(KERN_INFO "Netlink module exited.\n");
}module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
運行insmod hello.ko
3,用戶態代碼
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <linux/netlink.h>#define NETLINK_TEST 31
int main() {
??? struct sockaddr_nl src_addr, dest_addr;
??? struct nlmsghdr *nlh = NULL;
??? int sock_fd, msg_size;
??? char *msg = "Hello from User";??? sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_TEST);
??? if (sock_fd < 0) {
??????? perror("socket");
??????? return -1;
??? }??? memset(&src_addr, 0, sizeof(src_addr));
??? src_addr.nl_family = AF_NETLINK;
??? src_addr.nl_pid = getpid(); // 用于識別??? bind(sock_fd, (struct sockaddr *)&src_addr, sizeof(src_addr));
??? memset(&dest_addr, 0, sizeof(dest_addr));
??? dest_addr.nl_family = AF_NETLINK;
??? dest_addr.nl_pid = 0; // 目標為內核
??? dest_addr.nl_groups = 0;??? nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(1024));
??? nlh->nlmsg_len = NLMSG_LENGTH(strlen(msg) + 1);
??? nlh->nlmsg_pid = getpid();
??? nlh->nlmsg_flags = 0;
??? strcpy(NLMSG_DATA(nlh), msg);??? msg_size = sendto(sock_fd, nlh, nlh->nlmsg_len, 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
??? if (msg_size < 0) {
??????? perror("sendto");
??????? return -1;
??? }??? // 接收內核的回復
??? recv(sock_fd, nlh, NLMSG_BUFFER_SIZE, 0);
??? printf("Received from kernel: %s\n", (char *)NLMSG_DATA(nlh));??? close(sock_fd);
??? return 0;
}
gcc main.c -o main
?