国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Linux下C語言使用 netlink sockets與內(nèi)核模塊通信

這篇具有很好參考價值的文章主要介紹了Linux下C語言使用 netlink sockets與內(nèi)核模塊通信。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

netlink簡介

Netlink套接字是用以實現(xiàn)用戶進程與內(nèi)核進程通信的一種特殊的進程間通信(IPC) ,也是網(wǎng)絡(luò)應(yīng)用程序與內(nèi)核通信的最常用的接口。在Linux標(biāo)準(zhǔn)內(nèi)核中,系統(tǒng)默認(rèn)集成了很多netlink實例,比如日志上報、路由系統(tǒng)等,netlink消息是雙向的,應(yīng)用層可以發(fā)送消息到內(nèi)核,同時內(nèi)核也可以發(fā)送消息到應(yīng)用層進程,非常適合涉及到內(nèi)核信息采集的模塊。

與ioctl的區(qū)別

netlink采用sock方式實現(xiàn),而ioctl采用驅(qū)動注冊方式實現(xiàn)。netlink通常用于傳輸大量消息,而ioctl通常用于下發(fā)系統(tǒng)命令,不支持內(nèi)核主動發(fā)送消息到應(yīng)用層。
什么情況下用netlink?
在開發(fā)過程中,我們會面臨消息通信機制的選型,這和應(yīng)用層消息通信選型一樣,每個通信方式都有自己的優(yōu)缺點。采用netlink機制一般需要應(yīng)用層單獨起進程用于監(jiān)聽內(nèi)核發(fā)送上來的消息,開發(fā)工作量相對于ioctl較大,而ioctl主要用于驅(qū)動消息下發(fā),比如無線驅(qū)動的iwpriv命令實現(xiàn),就采用ioctl機制。

內(nèi)核模塊hello_kernel.c

#include <linux/module.h>
#include <net/sock.h> 
#include <linux/netlink.h>
#include <linux/skbuff.h> 
#define NETLINK_USER 31
 
struct sock *nl_sk = NULL;
 
static void hello_nl_recv_msg(struct sk_buff *skb)
{
 
    struct nlmsghdr *nlh;
    int pid;
    struct sk_buff *skb_out;
    int msg_size;
    char *msg = "Hello from kernel";
    int res;
 
    printk(KERN_INFO "Entering: %s\n", __FUNCTION__);
 
    msg_size = strlen(msg);
 
    nlh = (struct nlmsghdr *)skb->data;
    printk(KERN_INFO "Netlink received msg payload:%s\n", (char *)nlmsg_data(nlh));
    pid = nlh->nlmsg_pid; /*pid of sending process */
 
    skb_out = nlmsg_new(msg_size, 0);
    if (!skb_out) {
        printk(KERN_ERR "Failed to allocate new skb\n");
        return;
    }
 
    nlh = nlmsg_put(skb_out, 0, 0, NLMSG_DONE, msg_size, 0);
    NETLINK_CB(skb_out).dst_group = 0; /* not in mcast group */
    strncpy(nlmsg_data(nlh), msg, msg_size);
 
    res = nlmsg_unicast(nl_sk, skb_out, pid);
    if (res < 0)
        printk(KERN_INFO "Error while sending bak to user\n");
}
 
static int __init hello_init(void)
{
 
    printk("Entering: %s\n", __FUNCTION__);
    //nl_sk = netlink_kernel_create(&init_net, NETLINK_USER, 0, hello_nl_recv_msg, NULL, THIS_MODULE);
    struct netlink_kernel_cfg cfg = {
        .input = hello_nl_recv_msg,
    };
 
    nl_sk = netlink_kernel_create(&init_net, NETLINK_USER, &cfg);
    if (!nl_sk) {
        printk(KERN_ALERT "Error creating socket.\n");
        return -10;
    }
 
    return 0;
}
 
static void __exit hello_exit(void)
{
 
    printk(KERN_INFO "exiting hello module\n");
    netlink_kernel_release(nl_sk);
}
 
module_init(hello_init); 
module_exit(hello_exit);
MODULE_LICENSE("GPL");

應(yīng)用層代碼hello.c

#include <linux/netlink.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
 
#define NETLINK_USER 31
 
#define MAX_PAYLOAD 1024 /* maximum payload size*/
struct sockaddr_nl src_addr, dest_addr;
struct nlmsghdr *nlh = NULL;
struct iovec iov;
int sock_fd;
struct msghdr msg;
 
int main()
{
    sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_USER);
    if (sock_fd < 0)
        return -1;
 
    memset(&src_addr, 0, sizeof(src_addr));
    src_addr.nl_family = AF_NETLINK;
    src_addr.nl_pid = getpid(); /* self pid */
 
    bind(sock_fd, (struct sockaddr *)&src_addr, sizeof(src_addr));
 
    memset(&dest_addr, 0, sizeof(dest_addr));
    dest_addr.nl_family = AF_NETLINK;
    dest_addr.nl_pid = 0; /* For Linux Kernel */
    dest_addr.nl_groups = 0; /* unicast */
 
    nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));
    memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
    nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
    nlh->nlmsg_pid = getpid();
    nlh->nlmsg_flags = 0;
 
    strcpy(NLMSG_DATA(nlh), "Hello");
 
    iov.iov_base = (void *)nlh;
    iov.iov_len = nlh->nlmsg_len;
    msg.msg_name = (void *)&dest_addr;
    msg.msg_namelen = sizeof(dest_addr);
    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;
 
    printf("Sending message to kernel\n");
    sendmsg(sock_fd, &msg, 0);
    printf("Waiting for message from kernel\n");
 
    /* Read message from kernel */
    recvmsg(sock_fd, &msg, 0);
    printf("Received message payload: %s\n", NLMSG_DATA(nlh));
    close(sock_fd);
 
    return 0;
}

?Makefile

bin=hello
obj-m = hello_kernel.o
KVERSION = $(shell uname -r)
all:$(bin)
	make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
bin:
	gcc hello.c -o hello
clean:
	make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean
	rm -rf hello.o hello

Makefile問題記錄一下

chat:KVERSION?=?$(shell?uname?-r)去掉shell有什么區(qū)別?

在Makefile中,`$(shell?...)`是一個用于執(zhí)行命令并獲取其輸出的內(nèi)置函數(shù)。在你提到的語句中,`$(shell?uname?-r)`用于執(zhí)行`uname?-r`命令來獲取當(dāng)前Linux內(nèi)核的版本,并將結(jié)果賦值給`KVERSION`變量。如果你去掉`shell`,那么整個語句就會變成:
KVERSION?=?uname?-r
這將不再是一個命令執(zhí)行語句,而是一個簡單的變量賦值語句。這意味著`KVERSION`的值將直接設(shè)置為字符串`"uname?-r"`,而不是執(zhí)行`uname?-r`命令并獲取其輸出。
因此,區(qū)別在于:
-?`KVERSION?=?$(shell?uname?-r)`:這會執(zhí)行`uname?-r`命令,獲取內(nèi)核版本,并將結(jié)果作為字符串賦值給`KVERSION`變量。
-?`KVERSION?=?uname?-r`:這只是將字符串`"uname?-r"`賦值給`KVERSION`變量,不會執(zhí)行命令或獲取內(nèi)核版本。
如果你想要將內(nèi)核版本賦值給`KVERSION`變量,你應(yīng)該使用`$(shell?...)`來執(zhí)行命令。否則,你將只是將命令字符串本身賦值給變量,而不會獲取命令的輸出。

make? -C什么意思?

`make?-C`?是?`make`?命令的一個選項,用于指定?`make`?命令應(yīng)該在哪個目錄下執(zhí)行。
語法為:
make?-C?<目錄>
其中?`<目錄>`?是你希望?`make`?命令執(zhí)行的目錄的路徑。
這個選項通常用于在項目的子目錄中執(zhí)行?`make`?命令,以便構(gòu)建子項目或依賴于其他目錄中的代碼的項目。這對于在大型項目中管理多個模塊或組件的構(gòu)建過程非常有用,因為你可以在每個子目錄中維護一個獨立的?`Makefile`?文件,并使用?`-C`?選項來指定要構(gòu)建的子目錄。
例如,如果你有一個名為?`subproject`?的子目錄,并在該目錄中有一個名為?`Makefile`?的構(gòu)建文件,你可以使用以下命令在?`subproject`?目錄中執(zhí)行?`make`:
make?-C?subproject
這將導(dǎo)致?`make`?命令在?`subproject`?目錄中查找并執(zhí)行?`Makefile`?文件,執(zhí)行與該子項目相關(guān)的構(gòu)建任務(wù)。

運行結(jié)果:

應(yīng)用層

Linux下C語言使用 netlink sockets與內(nèi)核模塊通信,linux,c語言,網(wǎng)絡(luò)

內(nèi)核,先加載.ko,運行hello之后,用dmesg就可查看收到的消息

Linux下C語言使用 netlink sockets與內(nèi)核模塊通信,linux,c語言,網(wǎng)絡(luò)

代碼來源:

Linux下C語言如何使用 netlink sockets與內(nèi)核模塊通信?_c語言nlmsghdr的使用_wellnw的博客-CSDN博客文章來源地址http://www.zghlxwxcb.cn/news/detail-732775.html

到了這里,關(guān)于Linux下C語言使用 netlink sockets與內(nèi)核模塊通信的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Linux網(wǎng)絡(luò)編程:socket、客戶端服務(wù)器端使用socket通信(TCP)

    Linux網(wǎng)絡(luò)編程:socket、客戶端服務(wù)器端使用socket通信(TCP)

    socket(套接字),用于網(wǎng)絡(luò)中不同主機間進程的通信。 socket是一個偽文件,包含讀緩沖區(qū)、寫緩沖區(qū)。 socket必須成對出現(xiàn)。 socket可以建立主機進程間的通信,但需要協(xié)議(IPV4、IPV6等)、port端口、IP地址。 ??????? ?(1)創(chuàng)建流式socket套接字。 ? ? ? ? ? ? ? ? a)此s

    2024年02月11日
    瀏覽(33)
  • 【Linux驅(qū)動】內(nèi)核模塊編譯 —— make modules 的使用(單模塊編譯、多模塊編譯)

    編譯驅(qū)動一般采用的是將驅(qū)動編譯成模塊(.ko 文件),然后加載到內(nèi)核,這其中就用到了 make modules 命令。 目錄 一、單模塊編譯 1、一個 c 文件編譯成一個 ko 文件 2、多個文件編譯成一個 ko 文件 二、多模塊編譯(多文件多模塊) 下面是最簡易的單文件單模塊編譯,假設(shè)我們

    2024年02月10日
    瀏覽(90)
  • 【嵌入式Linux】編譯應(yīng)用和ko內(nèi)核模塊Makefile使用記錄

    【嵌入式Linux】編譯應(yīng)用和ko內(nèi)核模塊Makefile使用記錄

    在Makefile中,變量的賦值可以使用以下幾種方式: = :最基本的賦值符號,表示簡單的延遲展開(lazy expansion)方式。變量的值將會在使用變量的時候進行展開。 := :立即展開(immediate expansion)的賦值方式。變量的值在賦值的時候立即展開,并且在后續(xù)的使用中不再改變。

    2024年02月08日
    瀏覽(24)
  • 【Shell 命令集合 系統(tǒng)設(shè)置 】Linux 加載和卸載內(nèi)核模塊 modprobe命令 使用指南

    【Shell 命令集合 系統(tǒng)設(shè)置 】Linux 加載和卸載內(nèi)核模塊 modprobe命令 使用指南

    Shell 命令專欄:Linux Shell 命令全解析 modprobe命令是Linux系統(tǒng)中用于加載和卸載內(nèi)核模塊的工具。內(nèi)核模塊是一種可以動態(tài)加載到內(nèi)核中的代碼,它們可以擴展內(nèi)核的功能,添加新的驅(qū)動程序或功能。 modprobe命令的主要作用有以下幾個方面: 加載內(nèi)核模塊:modprobe命令可以根據(jù)

    2024年02月04日
    瀏覽(122)
  • 【Shell 命令集合 系統(tǒng)設(shè)置 】?Linux 向內(nèi)核中加載指定的模塊 insmod命令 使用指南

    【Shell 命令集合 系統(tǒng)設(shè)置 】?Linux 向內(nèi)核中加載指定的模塊 insmod命令 使用指南

    Shell 命令專欄:Linux Shell 命令全解析 insmod命令是Linux系統(tǒng)中的一個命令,用于向內(nèi)核中加載指定的模塊。它的作用是將指定的模塊文件加載到內(nèi)核中,使得系統(tǒng)可以使用該模塊提供的功能。 模塊是一種可以動態(tài)加載到內(nèi)核中的代碼,它可以擴展內(nèi)核的功能。在Linux系統(tǒng)中,模

    2024年02月07日
    瀏覽(28)
  • Linux內(nèi)核學(xué)習(xí)(十三)—— 設(shè)備與模塊(基于Linux 2.6內(nèi)核)

    目錄 一、設(shè)備類型 二、模塊 構(gòu)建模塊 安裝模塊 載入模塊 在 Linux 以及 Unix 系統(tǒng)中,設(shè)備被分為以下三種類型: 塊設(shè)備(blkdev) :以塊為尋址單位,塊的大小隨設(shè)備的不同而變化;塊設(shè)備通常支持重定位(seeking)操作,也就是對數(shù)據(jù)的隨機訪問。如硬盤、藍(lán)光光碟和 Flas

    2024年02月11日
    瀏覽(90)
  • Linux——socket網(wǎng)絡(luò)通信

    Linux——socket網(wǎng)絡(luò)通信

    Socket套接字 由遠(yuǎn)景研究規(guī)劃局(Advanced Research Projects Agency, ARPA)資助加里福尼亞大學(xué)伯克利分校的一個研究組研發(fā)。其目的是將 TCP/IP 協(xié)議相關(guān)軟件移植到UNIX類系統(tǒng)中。設(shè)計者開發(fā)了一個接口,以便應(yīng)用程序能簡單地調(diào)用該接口通信。這個接口不斷完善,最終形成了 Socket套

    2024年02月11日
    瀏覽(26)
  • 【Socket】Linux下UDP Socket的基本流程以及connect、bind函數(shù)的使用(C語言實現(xiàn))

    Socket的原意是“插座”,在計算機通信領(lǐng)域,socket 被翻譯為“套接字”。 Socket通信主要有兩個類型:TCP、UDP。 TCP通信,是一個有序的、可靠的、面向連接的通信方式。用數(shù)據(jù)流的方式傳遞信息。 UDP通信,是無連接的、不保證有序到達的、但具有較好的實時性、能夠高速傳輸

    2024年02月13日
    瀏覽(28)
  • Linux系統(tǒng)編程,socket通信編程。

    管道,共享內(nèi)存,消息隊列。 跨機器通信,在網(wǎng)絡(luò)上傳遞數(shù)據(jù),通過socket套接字來實現(xiàn)。 頭文件,#include sys/types.h,#include sys/socket.h int socket(int domain, int type, int protocol); domain,協(xié)議族,type。類型,protocol,使用的特定的協(xié)議 返回值,0,成功,-1,失敗, 在一個監(jiān)聽socket上接

    2024年02月07日
    瀏覽(25)
  • Linux驅(qū)動開發(fā)——內(nèi)核模塊

    Linux驅(qū)動開發(fā)——內(nèi)核模塊

    目錄 內(nèi)核模塊的由來 第一個內(nèi)核模塊程序? 內(nèi)核模塊工具? 將多個源文件編譯生成一個內(nèi)核模塊? 內(nèi)核模塊參數(shù) 內(nèi)核模塊依賴 關(guān)于內(nèi)核模塊的進一步討論? 習(xí)題 最近一直在玩那些其它的技術(shù),眼看快暑假了,我決定夯實一下我的驅(qū)動方面的技能,迎接我的實習(xí),找了一本

    2024年02月04日
    瀏覽(100)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包