用戶層~內(nèi)核層通信(netlink 內(nèi)核層)


layout: post
title: netlink通信機(jī)制-內(nèi)核層
date: 2018-08-02 02:01:33
categories: kernel
tags: kernel


內(nèi)核層

處理函數(shù)注冊

    struct netlink_kernel_cfg cfg = {
        .input = nl_data_ready, /* set recv callback */
    };

    nl_sk = netlink_kernel_create(&init_net, NETLINK_TEST, &cfg);

netlink_kernel_create 函數(shù)的使用具體跟內(nèi)核有關(guān)系,我這里是3.10的內(nèi)核秃症。

    //2.6版本的 
    netlink_kernel_create(&init_net, NETLINK_TEST, 0, NULL, kernel_receive, THIS_MODULE); 

    //3.8后版本
    netlink_kernel_create(&init_net, NETLINK_TEST, &cfg);

參數(shù)說明:

  1. 采用的固定的init_net,具體不知道為什么
  2. NETLINK_TEST 這個(gè)是netlink協(xié)議類型與用戶層的要相同
    int skfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_TEST);應(yīng)用層的代碼
    這個(gè)值取1~31
  3. cfg存放的是netlink內(nèi)核配置參數(shù)

接收數(shù)據(jù)

    //處理消息的函數(shù)绒瘦,這個(gè)根據(jù)內(nèi)核版本也有變動(dòng)义桂,老版本的好像是struct sock *skb 類型
    static void nl_data_ready(struct sk_buff *skb)

    //獲取netlink數(shù)據(jù)包中netlink header的起始地址篙贸。
    nlh = nlmsg_hdr(skb);

    //獲取struct nlmsghdr結(jié)構(gòu)的數(shù)據(jù)部分
    umsg = NLMSG_DATA(nlh);

發(fā)送數(shù)據(jù)

    struct sk_buff *skb;
    struct nlmsghdr *nlh;

    // 為新的 sk_buffer申請空間
    skb = nlmsg_new(slen, GFP_ATOMIC);

    //用nlmsg_put()來設(shè)置netlink消息頭部
    nlh = nlmsg_put(skb, 0, 0, NETLINK_TEST, slen, 0);

    //拷貝數(shù)據(jù)
    memcpy(nlmsg_data(nlh), message, slen);

    //通過netlink_unicast()將消息發(fā)送用戶空間由pid所指定了進(jìn)程號的進(jìn)程
    netlink_unicast(nl_sk, skb, pid, MSG_DONTWAIT);

源碼

/**
 *  @file:  ktest.c
 *  @brief: kernel example
 *  @author: lflish
 *  @date: 2018-8-1
 *  @email: hxy.gold@gmail.com
 *  kernel version: 3.10.0-862  
 **/

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

MODULE_LICENSE("GPL");
MODULE_AUTHOR("lflish");

#define MAX_MSGSIZE 125

#define NETLINK_TEST 30

struct sock *nl_sk = NULL;
//向用戶空間發(fā)送消息的接口
int sendnlmsg(char *message,int pid)
{
    struct sk_buff *skb;
    struct nlmsghdr *nlh;

    int slen = 0;

    if(!message || !nl_sk){
        return -1;
    }

    slen = strlen(message);

    // 為新的 sk_buffer申請空間
    skb = nlmsg_new(slen, GFP_ATOMIC);
    if(!skb){
        printk(KERN_ERR "my_net_link: alloc_skb Error./n");
        return -2;
    }

    //用nlmsg_put()來設(shè)置netlink消息頭部
    nlh = nlmsg_put(skb, 0, 0, NETLINK_TEST, slen, 0);
    if(nlh == NULL){
        printk("nlmsg_put failauer \n");
        nlmsg_free(skb);
        return -1;
    }

    memcpy(nlmsg_data(nlh), message, slen);

    //通過netlink_unicast()將消息發(fā)送用戶空間由pid所指定了進(jìn)程號的進(jìn)程
    netlink_unicast(nl_sk, skb, pid, MSG_DONTWAIT);
    printk("send OK!\n");

    return 0;
}

static void nl_data_ready(struct sk_buff *skb)
{
    struct nlmsghdr *nlh = NULL;
    char *umsg = NULL;
    char kmsg[] = "hello users!!!";

    if(skb->len >= nlmsg_total_size(0))
    {   
        nlh = nlmsg_hdr(skb);
        umsg = NLMSG_DATA(nlh);
        if(umsg)
        {   
            printk("kernel recv from user: %s\n", umsg);
            sendnlmsg (kmsg, nlh->nlmsg_pid);
        }   
    }   
}

struct netlink_kernel_cfg cfg = {
    .input = nl_data_ready, /* set recv callback */
};

int myinit_module(void)
{
    printk("my netlink in\n");
    nl_sk = netlink_kernel_create(&init_net, NETLINK_TEST, &cfg);
    if(nl_sk == NULL)
        printk("kernel_create error\n");
    return 0;
}

void mycleanup_module(void)
{
    printk("my netlink out!\n");
    sock_release(nl_sk->sk_socket);
    netlink_kernel_release(nl_sk);
}

module_init(myinit_module);
module_exit(mycleanup_module);
MODULE_NAME :=ktest
obj-m :=$(MODULE_NAME).o

KERNELDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

all: user kernel

kernel:
    $(MAKE) -C $(KERNELDIR) M=$(PWD)

user: utest.c
    gcc utest.c -o utest

clean:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) clean
    rm -rf utest

以上是內(nèi)核的通信模型

git實(shí)例源碼

參考文檔

結(jié)構(gòu)君珠、宏等說明實(shí)例 https://www.cnblogs.com/wenqiang/p/6306727.html
rfc3549 https://tools.ietf.org/html/rfc3549
這哥們的不錯(cuò)肾筐,但是是低版本內(nèi)核 http://blog.chinaunix.net/uid-23069658-id-3405954.html
https://wenku.baidu.com/view/4d6af81da417866fb84a8eb5.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市缸剪,隨后出現(xiàn)的幾起案子吗铐,更是在濱河造成了極大的恐慌,老刑警劉巖杏节,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件唬渗,死亡現(xiàn)場離奇詭異,居然都是意外死亡奋渔,警方通過查閱死者的電腦和手機(jī)镊逝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來嫉鲸,“玉大人撑蒜,你說我怎么就攤上這事⌒” “怎么了座菠?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長藤树。 經(jīng)常有香客問我浴滴,道長,這世上最難降的妖魔是什么岁钓? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任升略,我火速辦了婚禮微王,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘品嚣。我一直安慰自己炕倘,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布腰根。 她就那樣靜靜地躺著激才,像睡著了一般。 火紅的嫁衣襯著肌膚如雪额嘿。 梳的紋絲不亂的頭發(fā)上瘸恼,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天,我揣著相機(jī)與錄音册养,去河邊找鬼东帅。 笑死,一個(gè)胖子當(dāng)著我的面吹牛球拦,可吹牛的內(nèi)容都是我干的靠闭。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼坎炼,長吁一口氣:“原來是場噩夢啊……” “哼愧膀!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起谣光,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤檩淋,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后萄金,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蟀悦,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年氧敢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了日戈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,834評論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡孙乖,死狀恐怖浙炼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情的圆,我是刑警寧澤鼓拧,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站越妈,受9級特大地震影響季俩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜梅掠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一酌住、第九天 我趴在偏房一處隱蔽的房頂上張望店归。 院中可真熱鬧,春花似錦酪我、人聲如沸消痛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽秩伞。三九已至,卻和暖如春欺矫,著一層夾襖步出監(jiān)牢的瞬間纱新,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工穆趴, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留脸爱,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓未妹,卻偏偏與公主長得像簿废,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子络它,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容