红联Linux门户
Linux帮助

内核netlink编程,求帮助!

发布时间:2011-02-21 15:42:57来源:红联作者:maole123456
在网上搜了一些源码,make成功了,但是insmod的时候,死机,没反映,内核版本是2.6.18,一下是代码,望各位帮帮忙

////////////////////////////////////////////////////////////////////
net_link.c
///////////////////////////////////////////////////////////////////

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include


struct sock *nl_sk = NULL;

static void nl_data_ready (struct sock *sk, int len)
{
wake_up_interruptible(sk->sk_sleep);
}

int netlink_test()
{
struct sk_buff *skb = NULL;
struct nlmsghdr *nlh = NULL;

int err;
u32 pid;

//extern struct sock *netlink_kernel_create( int unit,
// unsigned int groups,
// void (*input)(struct sock *sk, int len),
// struct module *module);
nl_sk = netlink_kernel_create(28, 0, nl_data_ready, THIS_MODULE);

if (!nl_sk)
{
printk("Fail to create lc user event netlink socket.\n");
return 0;
}

/* wait for message coming down from user-space */

skb = skb_recv_datagram(nl_sk, 0, 0, &err);
nlh = (struct nlmsghdr *)skb->data;

printk("%s: received netlink message payload:%s ",__FUNCTION__,NLMSG_DATA(nlh));

pid = nlh->nlmsg_pid;
nlh->nlmsg_len = skb->len;

NETLINK_CB(skb).pid = 0;
NETLINK_CB(skb).dst_pid = pid;
NETLINK_CB(skb).dst_group = 1;
netlink_broadcast(nl_sk, skb, 0, 1, GFP_KERNEL);

return 1;
}

static int __init my_module_init(void)
{
printk( "Initializing Netlink Socket\n");
if( netlink_test())
{
printk( "Message has send\n");
}
else
{
printk("send error\n");
}

return 0;
}

static void __exit my_module_exit(void)
{
if(nl_sk)
{
sock_release(nl_sk->sk_socket);
printk( "Goodbye\n");
}
else
{
printk( "no sock,release error\n");
}
}

module_init(my_module_init);

module_exit(my_module_exit);

/////////////////////////////////////////////////////////////////////////////////
sender.c
////////////////////////////////////////////////////////////////////////////////
#include
#include
#include
#include
#include
#include
#include
#include

#define MAX_PAYLOAD 1024 /* maximum payload size*/

struct sockaddr_nl saddr, daddr;
struct msghdr msg;
struct nlmsghdr *nlh = NULL;
struct iovec iov;

int sd;

int main()
{
sd = socket(PF_NETLINK, SOCK_RAW,28);
if (sd == -1)
{
perror("socket error\n");
exit(1);
}
memset(&saddr, 0, sizeof(saddr));
memset(&daddr, 0, sizeof(daddr));

saddr.nl_family = AF_NETLINK;
saddr.nl_pid = getpid();
saddr.nl_groups = 1;

bind(sd, (struct sockaddr*)&saddr, sizeof(saddr));

daddr.nl_family = AF_NETLINK;
daddr.nl_pid = 0;
daddr.nl_groups = 1;

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), "crazysummers call kerbel!\n");
iov.iov_base = (void *)nlh;
iov.iov_len = nlh->nlmsg_len;
msg.msg_name = (void *)&daddr;
msg.msg_namelen = sizeof(daddr);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;

printf("Sent message to kernel\n");
sendmsg(sd, &msg, 0);
printf("Waiting for message from kernel\n");
memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
recvmsg(sd, &msg, 0);
printf(" Received message from kernel that send to it: %s \n", NLMSG_DATA(nlh));

close(sd);
}
文章评论

共有 2 条评论

  1. Qnoer 于 2011-02-21 16:14:58发表:

    不懂编程,帮你顶上

  2. maole123456 于 2011-02-21 15:44:38发表:

    补充 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 -fr *.ko *.o *.cmd sender $(MODULE_NAME).mod.c