内核版本:2.6.26
内核态程序:knetlink.c
- /*
- * Copyright (c) 2009-~ Helight.Xu
- *
- * This source code is released for free distribution under the terms of the
- * GNU General Public License
- *
- * Author: Helight.Xu<Helight.Xu@gmail.com>
- * Created Time: Sat 16 May 2009 04:20:14 PM CST
- * File Name: knetlink.c
- *
- * Description:
- */
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/init.h>
- #include <net/sock.h>
- #include <asm/types.h>
- #include <linux/netlink.h>
- #include <linux/skbuff.h>
- #define NETLINK_XUX 21 /* testing */
- #define VFW_GROUP 1
- #define MSG_SIZE NLMSG_SPACE(2048)
- static struct sock *xux_sock;
- struct netlink_data{
- struct nlmsghdr msg;
- char data[1024];
- };
- static void test_link(struct sk_buff *skb)
- {
- struct nlmsghdr *nlh;
- u32 rlen;
- void *data;
- while (skb->len >= NLMSG_SPACE(0)) {
- nlh = nlmsg_hdr(skb);
- if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
- return;
- rlen = NLMSG_ALIGN(nlh->nlmsg_len);
- if (rlen > skb->len)
- rlen = skb->len;
- data = NLMSG_DATA(nlh);
- printk("link:%s", (char *)data);
- netlink_ack(skb, nlh, 0);
- skb_pull(skb, rlen);
- }
- }
- int __init init_link(void)
- {
- xux_sock = netlink_kernel_create(&init_net, NETLINK_XUX, 0,
- test_link, NULL, THIS_MODULE);
- if (!xux_sock){
- printk("cannot initialize netlink socket");
- return -1;
- } else
- xux_sock->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT;
- printk("Init OK!\n");
- return 0;
- }
- void __exit exit_link(void)
- {
- netlink_kernel_release(xux_sock);
- printk(": Release OK!\n");
- return;
- }
- MODULE_AUTHOR("Helight.Xu");
- MODULE_LICENSE("Dual BSD/GPL");
- module_init(init_link);
- module_exit(exit_link);
用户态程序:unetlink.c
- /*
- * Copyright (c) 2009-~ Helight.Xu
- *
- * This source code is released for free distribution under the terms of the
- * GNU General Public License
- *
- * Author: Helight.Xu<Helight.Xu@gmail.com>
- * Created Time: Sat 16 May 2009 04:20:14 PM CST
- * File Name: unetlink.c
- *
- * Description:
- */
- #include <stdio.h>
- #include <string.h>
- #include <unistd.h>
- #include <string.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <time.h>
- #include <sys/poll.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <linux/netlink.h>
- #define NETLINK_XUX 21 /* testing */
- #define VFW_GROUP 1
- struct netlink_data{
- struct nlmsghdr msg;
- char data[1024];
- };
- int link_open(void);
- int main(int args, char *argv[])
- {
- struct netlink_data nldata;
- struct nlmsghdr *msg = &nldata.msg;
- int retval;
- struct sockaddr_nl addr;
- char *data = "hello world!\0";
- int size = strlen(data);
- int fd = link_open();
- memset(&nldata, '\0', sizeof(nldata));
- msg->nlmsg_len = NLMSG_SPACE(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));
- printf("hello:%02x len: %d data:%s\n",
- NLMSG_DATA(msg),
- sizeof(NLMSG_DATA(msg)),
- NLMSG_DATA(msg));
- close(fd);
- return 0;
- }
- int link_open(void)
- {
- int saved_errno;
- int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_XUX);
- if (fd < 0) {
- saved_errno = errno;
- if (errno == EINVAL || errno == EPROTONOSUPPORT ||
- errno == EAFNOSUPPORT)
- printf("Error - audit support not in kernel");
- else
- printf("Error opening audit netlink socket (%s)",
- strerror(errno));
- errno = saved_errno;
- return fd;
- }
- if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
- saved_errno = errno;
- close(fd);
- printf("Error setting audit netlink socket CLOEXEC flag (%s)",
- strerror(errno));
- errno = saved_errno;
- return -1;
- }
- return fd;
- }
测试结果:
xux@zhwen:~/netdev$ sudo insmod knetlink.ko
xux@zhwen:~/netdev$ ./unetlink
[ 2373.160357] Init OK!
[ 2378.000012] link:hello world!
xux@zhwen:~/netdev$
