内核部分
#include <net/genetlink.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
int ctl_test_function(struct sk_buff *skb, struct genl_info *info)
{
printk("get process pid=%d cmd=%d pid=%d type=%d\n",info->snd_pid,info->genlhdr->cmd,info->nlhdr->nlmsg_pid,info->nlhdr->nlmsg_type);
return 0;
}
struct genl_family test_ctl = {
.id=1023, //消息类型
.name="testnet",
.version=0x02,
};
struct genl_ops test_ctl_ops={
.cmd = 100,//自己先设置一个命令
.doit = ctl_test_function,
};
static int __init testnlk_init(void)
{
if(genl_register_family(&test_ctl) != 0)
{
printk("register faimly error\n");
return -1;
}
if(genl_register_ops(&test_ctl,&test_ctl_ops) != 0)
{
printk("Register ops error\n");
goto out;
}
return 0;
out:
genl_unregister_family(&test_ctl);
return 0;
}
static void __exit testnlk_exit(void)
{
genl_unregister_ops(&test_ctl,&test_ctl_ops);
genl_unregister_family(&test_ctl);
}
module_init(testnlk_init);
module_exit(testnlk_exit);
MODULE_LICENSE("GPL");
应用部分
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/genetlink.h>
//先只传递消息头没有载荷数据
struct mymsg{
struct nlmsghdr nhdr;
struct genlmsghdr genhdr;
};
int main(int argc,char *argv[])
{
int skfd;
struct sockaddr_nl addr={0};
struct mymsg msg={0};
int ret;
skfd = socket(AF_NETLINK,SOCK_RAW,NETLINK_GENERIC);
if(skfd < 0)
{
printf("socket error\n");
return -1;
}
addr.nl_family = AF_NETLINK;
addr.nl_pid = getpid();
if(bind(skfd,(struct sockaddr *)&addr,sizeof(addr)) < 0 )
{
printf("Bind error\n");
goto out;
}
//设置消息头
msg.nhdr.nlmsg_type = 1023; //消息类型
msg.nhdr.nlmsg_pid = getpid();
msg.nhdr.nlmsg_flags = NLM_F_REQUEST;
msg.nhdr.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN); //nlmsghdr头长 + gennlmsg头长
msg.genhdr.cmd = 100; //命令字
msg.genhdr.version = 0x02;
//发送信息到内核
addr.nl_family = AF_NETLINK;
addr.nl_pid = 0;
ret = sendto(skfd,(char*)&msg,msg.nhdr.nlmsg_len,0,(struct sockaddr *)&addr,sizeof(addr));
if(ret <= 0)
{
printf("send error\n");
}
out:
close(skfd);
return 0;
}