linux netlink通信

(1)加入自己的NETLINK通信端口

     在/usr/include/linux/netlink.h 中加入 NETLINK_TEST 20

2)用户层代码

#include <stdio.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <arpa/inet.h>

#include <string.h>

#include <linux/netlink.h>

#define NETLINK_TEST           20

  

struct netlink_data{ 

        struct nlmsghdr msg; 

        char data[1024]; 

}; 

  

int main() 

        struct netlink_data nldata; 

        struct nlmsghdr *msg = &nldata.msg; 

        int retval; 

        struct sockaddr_nl addr; 

        char *data = "hello world!\0"; 

        int size = strlen(data); 

        //创建socket

        int fd = socket(PF_NETLINK,SOCK_RAW,NETLINK_TEST); 

        if(fd<0)

        {

            printf("socket error");

            return 0;

        }

        //设置netlink消息头部信息

        memset(&nldata, '\0', sizeof(nldata)); 

        msg->nlmsg_len = NLMSG_LENGTH(size); //表示数据长度size+消息头部长度

        msg->nlmsg_type = 0; 

        msg->nlmsg_flags = 0; 

        msg->nlmsg_seq = 0; 

        //设置接收信息的地址

        addr.nl_family = AF_NETLINK; 

        addr.nl_pid = 0; 

        addr.nl_groups = 0; 

        //拷贝信息到消息头后面

        memcpy(NLMSG_DATA(msg), data, size); 

        //发送消息

        retval = sendto(fd, &nldata, msg->nlmsg_len, 0, 

                        (struct sockaddr*)&addr, sizeof(addr)); 

  

        close(fd); 

        return 0; 

(3)内核层代码

#include <linux/module.h>

#include <linux/init.h>

#include <net/sock.h>

#include <linux/netlink.h>

#include <linux/inet.h>

#include <linux/skbuff.h>

#define NETLINK_TEST 20

struct sock *nl_sk = NULL;

void test(struct sk_buff *__skb)

{

      struct sk_buff *skb;

      struct nlmsghdr *nlh;

      //获取对skb的引用指针

      skb=skb_get(__skb);

      if(skb->len<NLMSG_SPACE(0))

      {

           goto free;

      }

      nlh=(struct nlmsghdr *)skb->data;

      printk("msg:%s\n",(char *)NLMSG_DATA(nlh));

free:

      kfree_skb(skb);

}

static int __init netlink_init(void)

{

     //创建内核sock

     nl_sk=netlink_kernel_create(&init_net,NETLINK_TEST,0,test,NULL,THIS_MODULE);

     if(!nl_sk)

     {

         printk("netlink:can not create");

         return 0;

     }

     else

     {

      printk("netlink:create success!");

        return 1;

     }

}

static void __exit netlink_exit(void)

{

     if(nl_sk)

     {

           //回收内核sock

           netlink_kernel_release(nl_sk);

     }

}

MODULE_LICENSE("GPL");

module_init(netlink_init);

module_exit(netlink_exit);

(4)常用结构

struct sockaddr_nl

{

        sa_family_t     nl_family;      /* AF_NETLINK   */

        unsigned short  nl_pad;         /* zero         */

        __u32           nl_pid;         /* port ID      */

        __u32           nl_groups;      /* multicast groups mask */

};

struct nlmsghdr

{

        __u32           nlmsg_len;      /* Length of message including header */

        __u16           nlmsg_type;     /* Message content */

        __u16           nlmsg_flags;    /* Additional flags */

        __u32           nlmsg_seq;      /* Sequence number */

        __u32           nlmsg_pid;      /* Sending process port ID */

};

(5)nlmsghdr常用宏

#define NLMSG_HDRLEN  ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr)))//获取头部大小

#define NLMSG_LENGTH(len) ((len)+NLMSG_ALIGN(NLMSG_HDRLEN))//获取头部+信息大小

#define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len)) //获取分配空间大小

#define NLMSG_DATA(nlh)  ((void*)(((char*)nlh) + NLMSG_LENGTH(0))) //获取数据开始位置

<!--EndFragment-->
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值