| 2009年5月16日
内核版本: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$
关注「黑光技术」,关注大数据+微服务