netlink实例

/*sender.c   用户态程序*/

#include <sys/stat.h>

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>
#include <asm/types.h>
#include <linux/netlink.h>
#include <linux/socket.h>


#define MAX_PAYLOAD 1024 /* maximum payload size*/
struct sockaddr_nl src_addr, dest_addr;
struct nlmsghdr *nlh = NULL;
struct iovec iov;
int sock_fd;
struct msghdr msg;


int main(int argc, char* argv[])
{
sock_fd = socket(PF_NETLINK, SOCK_RAW, 17);
memset(&msg, 0, sizeof(msg));
memset(&src_addr, 0, sizeof(src_addr));
src_addr.nl_family = AF_NETLINK;
src_addr.nl_pid = getpid(); /* self pid */
src_addr.nl_groups = 0; /* not in mcast groups */
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; /* send to Linux Kernel */
dest_addr.nl_groups = 0; /* unicast */


nlh=(struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));
/* Fill the netlink message header */
nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
nlh->nlmsg_pid = getpid(); /* self pid */
nlh->nlmsg_flags = 0;
/* Fill in the netlink message payload */
strcpy(NLMSG_DATA(nlh), "Hello Kernel!");


iov.iov_base = (void *)nlh;
iov.iov_len = nlh->nlmsg_len;
msg.msg_name = (void *)&dest_addr;
msg.msg_namelen = sizeof(dest_addr);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
sendmsg(sock_fd, &msg, 0);
/* Read message from kernel */
memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
printf(" Waiting message. ...\n");
recvmsg(sock_fd, &msg, 0);
printf(" Received message payload: %s\n",NLMSG_DATA(nlh));
/* Close Netlink Socket */
close(sock_fd);
printf("%d\n", getpid());
return 0;

}


/*net_link.c  内核程序*/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <net/sock.h>
#include <net/netlink.h>


#define NETLINK_TEST 17


struct sock *nl_sk = NULL;
EXPORT_SYMBOL_GPL(nl_sk);


void nl_data_ready (struct sk_buff *__skb)
{
  struct sk_buff *skb;
  struct nlmsghdr *nlh;
  u32 pid;
  int rc;
  int len = NLMSG_SPACE(1200);
  char str[100];
  char reply[] = "Hello user!\n";
  printk("%s: data is ready to read.\n", __func__);
  skb = skb_get(__skb);


  if (skb->len >= NLMSG_SPACE(0)) {
    nlh = nlmsg_hdr(skb);
    printk("%s: recv %s.\n", __func__, (char *)NLMSG_DATA(nlh));
    memcpy(str,NLMSG_DATA(nlh), sizeof(str)); 
    pid = nlh->nlmsg_pid; /*pid of sending process */
    printk("%s: pid is %d\n", __func__, pid);
    kfree_skb(skb);


    skb = alloc_skb(len, GFP_ATOMIC);
    if (!skb){
      printk(KERN_ERR "%s: allocate failed.\n", __func__);
      return;
    }
    nlh = nlmsg_put(skb,0,0,0,1200,0);
    NETLINK_CB(skb).pid = 0; /* from kernel */


    memcpy(NLMSG_DATA(nlh), reply, sizeof(reply));
    printk("%s: going to send.\n", __func__);
    rc = netlink_unicast(nl_sk, skb, pid, MSG_DONTWAIT);
    if (rc < 0) {
      printk(KERN_ERR "%s: can not unicast skb (%d)\n", __func__, rc);
    }
    printk("%s: send is ok.\n", __func__);
  }
  return;
}


static int test_netlink(void) {
  nl_sk = netlink_kernel_create(&init_net, NETLINK_TEST, 0, nl_data_ready, NULL, THIS_MODULE);


  if (!nl_sk) {
    printk(KERN_ERR "%s: Cannot create netlink socket.\n", __func__);
    return -EIO;
  }
  printk("%s: create socket ok.\n", __func__);
  return 0;
}


int init_module()
{
  test_netlink();
  return 0;
}
void cleanup_module( )
{
  if (nl_sk != NULL){
    sock_release(nl_sk->sk_socket);
  }
  printk("%s: remove ok.\n", __func__);
}


MODULE_LICENSE("GPL");
MODULE_AUTHOR("Genjing");


//Makefile

MODULE_NAME :=net_link
obj-m :=$(MODULE_NAME).o
KERNELDIR :=/lib/modules/$(shell uname -r)/build
PWD :=$(shell pwd)
all:
$(MAKE) -C $(KERNELDIR) M=$(PWD)
gcc -o sender sender.c
clean:
rm -f *.ko *.o .*cmd  *.symvers *.order $(MODULE_NAME).mod.c sender
rm -rf .tmp_versions


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值