netlink socket(linux内核模块与用户态之间通信实例)

本文通过一个编程实例来更深入地了解netlink。

1.1        实现内容

1.          功能

Ø  实现一个并发的echo服务器程序,它(接收端)将接收到字符串进行转换处理后,返回给发送端;允许有多个发送端同时存在;

Ø  字符串的处理包括:直接返回、全部转换为大写、全部转换为小写;处理方式应可以配置,配置方式包括全局(缺省)及每“发送-接收对(xmit/recv peer)”的。配置转换时,不应该影响正在处理的字符串;

Ø  为模拟处理过程的延时,接收端中每个字符转换添加200ms的延迟;

Ø  接收端中需统计其处理字符的数量,并且给外部提供命令形式的查询手段;

Ø  具备必要的例外处理,如内存不足等、client未关闭链接即意外退出等;  

1.2        验收成果

1.        程序结构(应用专业方向)

Ø  以有链接的client-server方式实现echo程序  

Ø  存在多个client,client与server在同一个系统中,它们之间采用domain socket或netlink socket相连;client之间没有关联

Ø  client是一个程序的多个实例,而server只允许运行一个实例  

2.        程序结构(内核专业方向)

Ø  内核模块作为接收端(服务器),而发送端(客户端)是用户空间的应用程序;

Ø  内核模块可动态加载与卸载 

Ø  驱动相关组:

·          创建虚拟字符型设备,用于接受来自客户端的字符

·          使用ioctl控制接口来配置echo处理方式,ioctl的cmd自定义;

·          并发使用驱动的多实例来模拟;

Ø  非驱动相关组:

·          创建内核线程,作为内核中的server,用于,通信可采用netlink socket或其它可用的方式;

·          使用netlink接口来配置echo处理转换方式;


用户态netlink socket源码

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

#define NETLINK_TEST    17
#define MSG_LEN         125
#define BUF_LEN         125 
#define TIME            210

int skfd;
struct sockaddr_nl local;
struct sockaddr_nl dest;
struct nlmsghdr *message;

struct msg_to_kernel
{
    struct nlmsghdr hdr;
    char data[MSG_LEN];
};
struct u_packet_info
{
    struct nlmsghdr hdr;
    char msg[MSG_LEN];
};

static void sig_pipe(int sign)
{
    printf("Catch a SIGPIPE signal\n");
    close(skfd);
    kill(local.nl_pid,SIGUSR1);
    exit(-1);
}

int init_netlink(void)
{
    //char *send_data = "aaaaaaaaaaaaBBBBBBBBBBBBBBBBBBaaaaaaaaaaaaaaaaBBBBBBBBBBBB11111112222";
    char send_data[BUF_LEN];
    message = (struct nlmsghdr *)malloc(1);       
    skfd = socket(PF_NETLINK, SOCK_RAW, NETLINK_TEST);
    
    if(skfd < 0){
        printf("can not create a netlink socket\n");
        return -1;
    }    
    
    memset(&local, 0, sizeof(local));
    local.nl_family = AF_NETLINK;
    local.nl_pid = getpid();    
    local.nl_groups = 0;
    if(bind(skfd, (struct sockaddr *)&local, sizeof(local)) != 0){
        printf("bind() error\n");
        return -1;
    }
    memset(&dest, 0, sizeof(dest));
    dest.nl_family = AF_NETLINK;
    dest.nl_pid = 0;
    dest.nl_groups = 0;

    memset(message, '\0', sizeof(struct nlmsghdr));
    message->nlmsg_len = NLMSG_SPACE(MSG_LEN);
    message->nlmsg_flags = 0;
    message->nlmsg_type = 0;
    message->nlmsg_seq = 0;
    message->nlmsg_pid = local.nl_pid;    
    
    while(1) {
        printf("input  the  data: ");
        fgets(send_data, MSG_LEN, stdin);
        if(0 == (strlen(send_data)-1)) 
            continue;
        else
            break;
    }
    memcpy(NLMS

  • 8
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值