Linux之NetLink学习笔记

news2024/9/21 20:23:09

1.NetLink机制

NetLink是一种基于应用层跟内核态的通信机制,其特点是一种异步全双工的通信方式,支持内核态主动发起通信的机制。该机制提供了一组特殊的API接口,用户态则通过socket API调用。内核发送的数据再应用层接收后会保存在接收进程socket的缓存中,再由接受进程处理。

2.NetLink通信示意图:

3.驱动文件ko文件的初始化与停止使用方式:

/* 模块入口函数 */
static int __init my_ko_init(void) {
    /**
        doing
    */
    printk("I am init self ko !!!");
    return 0;
}


/* 模块退出函数 */
static void __exit my_ko_exit(void) {
    // 注销netlink协议
    printk("I am exit self ko !!!");
    return;
}

module_init(my_ko_init)
module_exit(my_ko__exit)
MODULE_AUTHOR("my_self_ko");
MODULE_DESCRIPTION("self ko study");
MODULE_LICENSE("GPL");

 注:自定义的ko文件使用,按照如上图的模版标准来进行实现对应的功能,该模版是初始化跟退出还原方法,通过module_init,module_exit,两个函数进行插入加载跟卸载还原内核态信息(避免出现内核崩溃。

makefile:


obj-m += my_self_ko.o

all:
        make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) modules
clean:
        make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) clean

4.用户态创建NetLink套接字通信

4.1 netlink_kernel_create函数

用于创建一个内核态的netlink的socket服务。该函数对应的参数在不同的版本之间是不同的设定:

头文件:linux/netlink.h

 netlink_kernel_create(struct net *net, int unit, struct netlink_kernel_cfg *cfg)

a.   LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)的函数参数定义:

        netlink_kernel_create(NETLINK_SELF_MODULE,0,netlink_kernel_rcv,THIS_MODULE);

 b. KERNEL_VERSION(2,6,24)<  LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)

        netlink_kernel_create(&init_net, NETLINK_SELF_MODULE,0, netlink_kernel_rcv, NULL, THIS_MODULE);

 c. LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)

        struct netlink_kernel_cfg cfg = {

                .input = netlink_kernel_rcv,

        };

        netlink_kernel_create(&init_net, NETLINK_SELF_MODULE,0, &cfg);

以上为内核驱动ko文件内创建netlink的方法,netlink_kernel_rcv自定义的回调处理函数。

netlink_kernel_create函数:

        返回值: sock 对象指针.

        参数1: init_net,系统内部定义的类型,默认使用即可.

        参数2:自定义的通信消息类型,根据实际定义,但是避免跟系统冲以及不要超过系统范围。

        参数3:默认设置0

        参数4:设置系统消息回调函数,不同版本该接口有差异性,如上代码。

具体的方式通过客户端主动链接,双向通信。例如:

内核ko驱动代码:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/netlink.h>
#include <net/netlink.h>

#define NETLINK_TEST 17

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_TEST, 0, hello_nl_recv_msg, NULL, THIS_MODULE);
    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);

客户端:

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

#define NETLINK_TEST 17

struct sockaddr_nl src_addr, dest_addr;
struct nlmsghdr *nlh = NULL;
struct iovec iov;
struct msghdr msg;

int main()
{
    int sock_fd;
    sock_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_TEST);
    if(sock_fd < 0)
        return -1;

    memset(&src_addr, 0, sizeof(src_addr));
    src_addr.nl_family = AF_NETLINK;
    src_addr.nl_pid = getpid();

    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(1024));
    memset(nlh, 0, NLMSG_SPACE(1024));
    nlh->nlmsg_len = NLMSG_SPACE(1024);
    nlh->nlmsg_pid = getpid();
    nlh->nlmsg_flags = 0;

    strcpy(NLMSG_DATA(nlh), "Hello from user space!");

    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");

    memset(nlh, 0, NLMSG_SPACE(1024));
    recvmsg(sock_fd, &msg, 0);
    printf("Received message: %s\n", NLMSG_DATA(nlh));

    close(sock_fd);
    return 0;
}

 上述代码中自定义通信类型,不可以跟系统重复,否则会导致写入ko文件失败.如下:

 注:驱动文件ko插入内核NetLink启动失败导致内核ko驱动不可用:
 如调用失败,最可能原因,第二个参数NETLINK_TEST_MODULE错误,可能已经被系统占用。需  要重新更换该类型参数。可以通过: cat /proc/net/netlink 查看当前使用的内核类型,自我使用是 否跟内核冲突,修改即可。另外应用层也需同步修改NETLINK_TEST_MODULE   ,如下所示:

nlsock = netlink_kernel_create(&init_net, NETLINK_TEST_MODULE, &cfg);

注:自定义的文件,是不会主动从内核卸载的,当前系统使用的可以通过lsmod |grep 自定义ko文件名,查看当前的引用计数,只有当引用计数为0时,才可以卸载该驱动文件。可以使用rmmod 驱动文件名。

        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/547630.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MediaPipe虹膜检测:实时虹膜跟踪和深度估计

包括计算摄影(例如,人像模式和闪光反射)和增强现实效果(例如,虚拟化身)在内的大量实际应用都依赖于通过跟踪虹膜来估计眼睛位置。一旦获得了准确的光圈跟踪,我们就可以确定从相机到用户的公制距离,而无需使用专用的深度传感器。反过来,这可以改善各种用例,从计算摄影…

《Kali渗透基础》01. 介绍

kali渗透 1&#xff1a;渗透测试1.1&#xff1a;安全问题的根源1.2&#xff1a;安全目标1.3&#xff1a;渗透测试1.4&#xff1a;标准 2&#xff1a;Kali2.1&#xff1a;介绍2.2&#xff1a;策略2.3&#xff1a;安装 3&#xff1a;Kali 初步设置3.1&#xff1a;远程连接3.1.1&a…

深度学习之全过程搭建卷积神经网络(CNN)

大家好&#xff0c;我是带我去滑雪&#xff01; 本期将尝试使用CIFAR-10 数据集搭建卷积神经网络&#xff0c;该数据集由 10 个类别的 60000 张 32x32 彩色图像组成&#xff0c;每个类别有 6000 张图像。 下面开始全过程搭建CNN识别彩色图片&#xff1a; 目录 &#xff08;1&a…

【Linux】冯诺依曼与操作系统

目录 一、冯诺依曼结构体系1、冯诺依曼结构体系简介2、为什么要有内存呢&#xff1f; 二、操作系统1、操作系统如何对硬件进行管理&#xff1f;2、操作系统为什么要对软硬件进行管理&#xff1f; 一、冯诺依曼结构体系 1、冯诺依曼结构体系简介 在现实生活中&#xff0c;我们…

KEYSIGHT MSOS204A 2GHZ 4通道DSOS204A高清晰度示波器

KEYSIGHT是德DSOS204A/MSOS204A高清晰度示波器 附加功能&#xff1a; 2 GHz 带宽&#xff08;可升级&#xff09; 4 个模拟通道和 16 个数字通道 最大存储深度&#xff1a;800 Mpts&#xff08;2 通道&#xff09;&#xff0c;400 Mpts&#xff08;4 通道&#xff09; 最大…

菱形继承、菱形虚拟继承、以及菱形虚拟继承的模型结构内部。

1. 单继承&#xff1a;一个子类只有一个直接父类。 多继承&#xff1a;一个子类有两个或以上直接父类。 菱形继承&#xff1a;菱形继承是多继承的一种特殊情况。 下面是代码和对象模型结构&#xff0c;可以看出菱形结构存在哪些问题&#xff0c;如下&#xff1a; #define _CR…

学习经验分享【30】Pycharm插件chatgpt,用来辅助编写代码

在Pycharm中发现ChatGPT插件&#xff0c;很好用&#xff0c;免费安全&#xff0c;大家可以作为编代码的辅助工作&#xff0c;也可用来玩GPT的接口。具体方法如下 实现效果如下&#xff1a; 更多精彩内容敬请持续关注。如果本博文对你有帮助的话&#xff0c;欢迎点赞、评论区留言…

BUUCTF-一叶障目 解析

打开文件发现一张png图片&#xff0c;里面没有内容&#xff0c;使用tweakpng打开 tweakpng报错 &#xff0c;说明crc校验值对不上 有两种可能&#xff0c;一是crc值被修改&#xff0c;二是图片的宽高被修改&#xff08;在ctf中多半是后者&#xff09; 先尝试修改crc值为55900…

【王道·计算机网络】第五章 传输层

一、传输层概述 传输层为应用层提供通信服务&#xff0c;使用网络层服务传输层的功能&#xff1a; 提供进程和进程之间的逻辑通信&#xff08;网络层提供主机之间的逻辑通信&#xff09;复用&#xff08;发送发不同的应用进程&#xff09;和分用&#xff08;接收方正确的数据传…

【网络协议详解】——PPP协议(学习笔记)

目录 &#x1f552; 1. 数据链路层协议概述&#x1f552; 2. PPP协议分析&#x1f558; 2.1 概述&#x1f558; 2.2 工作流程&#x1f558; 2.3 帧格式 &#x1f552; 3. LCP协议&#x1f558; 3.1 概述&#x1f558; 3.2 报文格式&#x1f558; 3.3 报文种类&#x1f564; 3.3…

3年经验,面试测试岗只会功能测试开口要求18K,令我陷入沉思

由于朋友临时有事&#xff0c; 所以今天我代替朋友进行一次面试&#xff0c;公司需要招聘一位自动化测试工程师&#xff0c;我以很认真负责的态度完成这个过程&#xff0c; 大概近30分钟。 主要是技术面试&#xff0c; 在近30分钟内&#xff0c; 我与被面试者是以交流学习的方式…

STM32F407+LWIP+DP83848以太网驱动移植

最近有个项目上需要用到网络功能&#xff0c;于是开始移植网络相关代码。在移植的过程中感觉好难&#xff0c;网上找各种资料都没有和自己项目符合的&#xff0c;移植废了废了好的大劲。不过现在回头看看&#xff0c;其实移植很简单&#xff0c;主要是当时刚开始接触网络&#…

【数据分享】2020年我国地级市医疗资源空间分布数据(Shp格式/Excel格式)

医疗资源的配置情况直接反映了一个城市的发展水平&#xff0c;医疗资源相关数据也是经常使用到的数据&#xff01; 我们发现学者刘海猛在科学数据银行&#xff08;ScienceDB&#xff09;平台上分享了2020年我国341个城市&#xff08;地区、州、盟&#xff09;的基础医疗资源数…

电脑安装软件时,如何避免捆绑安装?

在网络上非正规网站下载安装软件时&#xff0c;经常会遇到捆绑安装的情况。你明明下载了一个软件&#xff0c;电脑上却多出好几个。那么我们在安装软件时&#xff0c;如何才能避免捆绑安装呢&#xff1f; 什么是捆绑安装&#xff1f; 捆绑安装是指用户安装一个软件时&#xff…

Spring boot框架 JWT实现用户账户密码登录验证

目录 1、JWT定义 1、1 JWT工作流程 1、2 JWT优点 2、添加依赖项到pom.xml 3、创建用户实体类 4、实现认证服务 5、登录请求处理 6、生成JWT 1、JWT定义 JWT&#xff08;JSON Web Token&#xff09;是一种用于在网络应用间传递信息的安全传输方式。它是一种紧凑且自包含…

tolua源码分析(五)lua使用C#的enum

tolua源码分析&#xff08;五&#xff09;lua使用C#的enum 上一节我们讨论了C#类是如何注册到lua的过程&#xff0c;以及lua调用C#函数时底层所做的事情。在此基础之上&#xff0c;本节我们来看看C#的enum是如何注册到lua的&#xff0c;它和一般类的注册有哪些区别。 老规矩&a…

互联网医院资质代办|互联网医院牌照的申请流程

随着互联网技术的不断发展&#xff0c;互联网医疗已经逐渐成为人们关注的热点话题。而互联网医院作为互联网医疗的一种重要形式&#xff0c;也越来越受到社会各界的关注。若想开展互联网医院业务&#xff0c;则需要具备互联网医院牌照。那么互联网医院牌照的申请流程和需要的资…

算法——归并排序和计数排序

Ⅰ. 归并排序 1. 基本思想 归并排序&#xff08; MERGE-SORT &#xff09;是建立在归并操作上的一种有效的排序算法 , 该算法是采用分治法&#xff08; Divide and Conquer&#xff09;的一个非常典型的应用。将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff1b;…

Python爬虫| 一文掌握XPath

本文概要 本篇文章主要介绍利用Python爬虫爬取付费文章&#xff0c;适合练习爬虫基础同学&#xff0c;文中描述和代码示例很详细&#xff0c;干货满满&#xff0c;感兴趣的小伙伴快来一起学习吧&#xff01; &#x1f31f;&#x1f31f;&#x1f31f;个人简介&#x1f31f;&…

公司来了个00后,我愿称之为卷王之王,卷的让人崩溃...

前几天我们公司一下子来了几个新人&#xff0c;看样子好像都是一些00后&#xff0c;这些年轻人是真能熬啊&#xff0c;本来我们几个老油子都是每天稍微加会班就打算下班走了&#xff0c;这几个新人一直不走&#xff0c;搞得我们也不好提前走。 2023年春招已经过去了&#xff0…