首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >为什么在使用netlink套接字与python用户通信时不能从内核模块获得消息响应?

为什么在使用netlink套接字与python用户通信时不能从内核模块获得消息响应?
EN

Stack Overflow用户
提问于 2021-07-13 19:15:28
回答 2查看 497关注 0票数 0

我使用netlink套接字与linux内核通信用户python代码,我可以从用户正确地发送消息到内核,但不能从内核获得响应。它显示:“向用户发送bak时出错。”在我的内核代码中

我尝试了所有的方法来获得响应消息:recvrecvfrom recvmsg,然后我的目的是解压它以获得具有以下格式的响应的有效负载: response_message = header +有效负载,但是用户总是无法获得响应。我在执行用户python代码时得到了这样的信息:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pid of sock : 1
seq number of sock : 0
pid of the message send to kernel:  1
seq number of the message send to kernel :  0
return of send  21
waiting for kernel ..

在内核端,当检查syslog文件时,我发现如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Jul 14 03:57:32 Bob kernel: [12381.663131] Kernel received :hello  id:XXXX!
Jul 14 03:57:32 Bob kernel: [12381.663132] python pid :1 XXXX
Jul 14 03:57:32 Bob kernel: [12381.663133] seq newsock : 0 id:XXXX!
Jul 14 03:57:32 Bob kernel: [12381.663134] Error while sending back to user  id:XXXX!

我想这个问题可能是由发送方和接收方的消息之间的seq号无效引起的,所以我尝试添加标志(NLM_F_REQUEST)并使用其他消息类型(MSG_SETCFG = 11,MSG_GETCFG =12),但没有工作。

熟悉netlink套接字的人能帮我找出谁来解决这个问题吗?

在这里,我的用户python代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import os
import socket
import struct
import ctypes


# types
NLMSG_NOOP = 1
NLMSG_ERROR = 2
NLMSG_DONE = 3
NLMSG_OVERRUN = 4
MSG_SETCFG = 11
MSG_GETCFG = 12
NLMSG_MIN_TYPE = 0x10

# flags
NLM_F_REQUEST = 1
NLM_F_MULTI = 2
NLM_F_ACK = 4
NLM_F_ECHO = 8



class Message:
    def __init__(self, msg_type, flags=0, seq=-1, payload=None):
        self.type = msg_type
        self.flags = flags
        self.seq = seq
        self.pid = 1
        payload = payload or []
        if isinstance(payload, list):
            contents = []
            for attr in payload:
                contents.append(attr._dump())
            self.payload = b''.join(contents)
        else:
            self.payload = payload

    def send(self, conn):
        if self.seq == -1:
            self.seq = conn.seq()

        self.pid = conn.pid
        length = len(self.payload)

        hdr = struct.pack("IHHII", length + 4 * 4, self.type,
                          self.flags, self.seq, self.pid)
        conn.send(hdr + bytes(self.payload, 'utf-8'))

 
class Connection(object):
    """
    Object representing Netlink socket connection to the kernel.
    """
    def __init__(self, nlservice=31, groups=0):
        # nlservice = Netlink IP service
        self.fd = socket.socket(socket.AF_NETLINK, socket.SOCK_RAW, nlservice)
        self.fd.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 65536)
        self.fd.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 65536)
        self.fd.bind((0, groups)) # pid=0 lets kernel assign socket PID
        self.pid, self.groups = self.fd.getsockname()
        self.pid = 1
        self._seq = 0
        
    def send(self, msg):
        if isinstance(msg, Message):
            if msg.seq == -1: 
                msg.seq = self.seq()
            #msg.seq = 1
            msg.pid = self.pid
            length = len(msg.payload)
            hdr = struct.pack("IHHII", length + 4 * 4, msg.type,
                          msg.flags, msg.seq, msg.pid) 
            msg = hdr + msg.payload.encode('utf-8')
            return self.fd.send(msg)
     
    def recve(self):
        #data, (nlpid, nlgrps) =  self.fd.recvfrom(16384)
        data = self.fd.recv(16384)
        msglen, msg_type, flags, seq, pid = struct.unpack("IHHII", data[:16])
        msg = Message(msg_type, flags, seq, data[16:])
        msg.pid = pid
        if msg_type == NLMSG_DONE:
           print("payload :", msg.payload)
           print("msg.pid :", msg.pid)
           print("msg.seq :", msg.seq)
        if msg.type == NLMSG_ERROR:
            errno = -struct.unpack("i", msg.payload[:4])[0]
            if errno != 0:
                err = OSError("Netlink error: %s (%d)" % (
                                                    os.strerror(errno), errno))
                err.errno = errno
                print("err :",err)
                raise err
        
        #return msg.payload 
         return msg 
        
    def seq(self):
        self._seq += 1
        return self._seq


sock = Connection()

var = 'hello'
msg1 = Message(3,0,-1,var) 
print("pid of sock :", sock.pid)
print ("seq number of sock :",sock._seq)

#res1 = msg1.send(sock)
res1 = sock.send(msg1)
print("pid of the message send to kernel: ", msg1.pid)
print("seq number of the message send to kernel : ", msg1.seq)

print("return of send ", res1)

while 1:
   print("waiting for kernel ..")
   #msgreply = sock.fd.recvmsg(16384)
   res2 = sock.recve()
   print("return of recive ", res2)

下面是我的内核代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <linux/module.h>
#include <net/mptcp.h>


/********Test deb***********/

#include <linux/module.h>  
#include <linux/kernel.h>  
#include <linux/init.h>  
#include <net/sock.h>  
#include <linux/socket.h>  
#include <linux/net.h>  
#include <asm/types.h>  
#include <linux/netlink.h>  
#include <linux/netlink.h>  
#include <linux/skbuff.h> 
#include <linux/inetdevice.h>
#include <linux/uio.h>
/****** other lib for other test github ******/
#include <linux/gfp.h>
#include <linux/kprobes.h>
#include <linux/ptrace.h>
#include <linux/time.h>
#include <net/net_namespace.h>


#define NETLINK_USER 31

#define MSG_SETCFG      0x11

#define MSG_GETCFG      0x12

//#define NETLINK_USERROCK 31

struct sock *nl_sk = NULL;


static void hello_nl_recv_msg(struct sk_buff *skb) {

struct nlmsghdr *nlh;
int pid, seq;
struct sk_buff *skb_out;
int msg_size;
char *msg="Helloo";
char *msgg;
int res;
char *recive;

//printk(KERN_DEBUG "KERNEL MODE id:XXXX!\n");
printk(KERN_INFO "Entering: %s  id:XXXX!\n", __FUNCTION__);
msg_size = strlen(msg);

////recive ////

nlh=(struct nlmsghdr*)skb->data;
//nlh = nlmsg_hdr(skb);
msgg=(char *)NLMSG_DATA(nlh);

printk(KERN_INFO "Kernel received :%s  id:XXXX!\n",msgg);

pid = nlh->nlmsg_pid; //pid of sending process /
//pid = 1; //just set it to 1 like we did in python
printk(KERN_INFO "python pid :%d XXXX", pid);

////////end recive /


///////sending message /

skb_out = nlmsg_new(msg_size,0);

if(!skb_out) {
    printk(KERN_ERR "Failed to allocate new skb  id:XXXX!\n");
    return;
}

//nlh = nlmsg_put(skb, 0, 1, NLMSG_DONE, msg_size + 1, 0);
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);

seq = nlh->nlmsg_seq;
printk(KERN_INFO "seq newsock : %d id:XXXX!\n", seq);

if(!nlmsg_data(nlh)) {
    printk(KERN_ERR "Failed to copy the message skbout id:XXXX!\n");
    return;
}
   
//printk(KERN_INFO "copied message :" , nlmsg_data(nlh));
//changed pid to 0
res=nlmsg_unicast(nl_sk,skb_out, pid);

if(res<0)
    printk(KERN_INFO "Error while sending back to user  id:XXXX!\n");

/////end send /

}


static int __init hello_init(void) {

printk("Entering: %s id:XXXX!\n",__FUNCTION__);
//This is for 3.6 kernels and above.
struct netlink_kernel_cfg cfg = {
    .input = hello_nl_recv_msg,
};

nl_sk = netlink_kernel_create(&init_net, NETLINK_USER, &cfg);
//nl_sk = netlink_kernel_create(&init_net, NETLINK_USER, 0, hello_nl_recv_msg,NULL,THIS_MODULE);
if(!nl_sk)
{
    printk(KERN_ALERT "Error creating socket.  id:XXXX!\n");
    return -10;

}

return 0;
}

static void __exit hello_exit(void) {

printk(KERN_INFO "exiting hello module  id:XXXX!\n");
netlink_kernel_release(nl_sk);
}

module_init(hello_init); module_exit(hello_exit);

MODULE_LICENSE("GPL");
EN

回答 2

Stack Overflow用户

发布于 2021-07-13 21:23:51

内核模块中需要注意的两件事

  1. 行的目的是什么"if(!nlmsg_data(nlh))“,因为我们已经关联了有效载荷
  2. (什么是nlmsg_unicast的返回值),因为它会让我们知道为什么返回错误

票数 0
EN

Stack Overflow用户

发布于 2021-12-08 16:07:51

我使用Netlink并在将self.pid = 1更改为self.pid = os.getpid()之后,使用自己的内核模块尝试了python代码。

我能够从内核模块得到响应。当设置为1时,内核模块给出错误-111的问题也是一样的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68371581

复制
相关文章
linux netlink套接字学习资料
http://blog.csdn.net/unbutun/article/details/3394061
全栈程序员站长
2022/07/10
1.1K0
python UDP套接字通信
UDPserver.py 1 import socket 2 #导入套接字模块 3 4 s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) 5 # - socket.AF_INET:IPV4 6 # - socket.STREAM:TCP 7 # - socket.DGRAM:UDP 8 9 s.bind(('',25555)) 10 #绑定套接字有效地址和端口 11 #''空位任何地址 本地的127.0.0.1 和局域网还有自己真实
py3study
2020/01/19
1.5K0
Linux用户空间与内核空间通信(Netlink通信机制)
Netlink是linux提供的用于内核和用户态进程之间的通信方式。但是注意虽然Netlink主要用于用户空间和内核空间的通信,但是也能用于用户空间的两个进程通信。只是进程间通信有其他很多方式,一般不用Netlink。除非需要用到Netlink的广播特性时。
嵌入式Linux内核
2022/10/25
4.9K2
Linux用户空间与内核空间通信(Netlink通信机制)
Python与套接字
服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客 户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时 客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应 数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束
星陨1357
2023/03/14
2.4K0
Python与套接字
socket:Python网络通信套接字
socket库提供了一个底层C API,可以使用BSD套接字接口实现网络通信。它包括socket类,用于处理具体的数据通道,还包括用来完成网络相关任务的函数,如将一个服务器名转换为一个地址以及格式化数据以便在网络上发送。
luckpunk
2023/09/29
2540
socket:Python网络通信套接字
Socket套接字通信原理
       Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议.
业余草
2019/01/21
8920
Socket套接字通信原理
ipset如何与netfilter内核模块进行通信
最近需要使用ipset,iptables,和netfilter,所以把三者的源代码看大概阅读了一遍。
全栈程序员站长
2022/11/08
1.4K0
ipset如何与netfilter内核模块进行通信
【Python】Python 网络编程 ( Socket 套接字简介 | Socket 套接字使用步骤 | Socket 套接字服务端与客户端开发 )
Socket 套接字 是一种 进程之间的 通信机制 , 通过套接字可以在 不同的进程之间 进行数据交换 ;
韩曙亮
2023/10/11
4950
【Python】Python 网络编程 ( Socket 套接字简介 | Socket 套接字使用步骤 | Socket 套接字服务端与客户端开发 )
Python套接字
Python只支持AF_UNIX(基于文件)、AF_NETLINK(使用标准的BSD套接字接口进行用户级别和内核级别代码之间的IPC)、AF_TIPC(透明的进程间通信)、AF_INET(基于网络)家族。
用户4845306
2019/03/14
1.6K0
14.10 Socket 套接字选择通信
对于网络通信中的服务端来说,显然不可能是一对一的,我们所希望的是服务端启用一份则可以选择性的与特定一个客户端通信,而当不需要与客户端通信时,则只需要将该套接字挂到链表中存储并等待后续操作,套接字服务端通过多线程实现存储套接字和选择通信,可以提高服务端的并发性能,使其能够同时处理多个客户端的请求。在实际应用场景中,这种技术被广泛应用于网络编程、互联网应用等领域。
微软技术分享
2023/10/18
2400
14.10 Socket 套接字选择通信
Windows 网络通信套接字技术
TCP/IP协议实际上就是在物理网上的一组完整的网络协议。其中TCP是提供传输 层服务,而IP则是提供网络层服务。TCP/IP协议包括如下协议,其结构如图所示。
全栈程序员站长
2022/09/23
7960
Windows 网络通信套接字技术
反弹shell-逃逸基于execve的命令监控(上)
本篇聊一聊 新的主题:《反弹shell-逃逸基于execve的命令监控》,打算写一个专题,预估可以写三篇,内容确实有点多,也是最近研究了一些有意思的东西,想给大家分享一下。喜欢的话,请大家一定点在看,并分享出去,算是对我原创最大的支持了。
七夜安全博客
2019/12/26
3.2K0
反弹shell-逃逸基于execve的命令监控(上)
网络安全自学篇(十四)| Python攻防之基础常识、正则表达式、Web编程和套接字通信(一)
免责声明:本公众号发布的文章均转载自互联网或经作者投稿授权的原创,文末已注明出处,其内容和图片版权归原网站或作者本人所有,并不代表安全+的观点,若有无意侵权或转载不当之处请联系我们处理,谢谢合作!
天钧
2020/03/26
2.3K0
网络安全自学篇(十四)| Python攻防之基础常识、正则表达式、Web编程和套接字通信(一)
通过netfilter使用get/setsockopt实现用户态与内核模块之间的通信
本文讲述通过netfilter和get/setsockopt实现用户态与内核态之间的通信。首先介绍相关背景,然后给出代码示例。重点在于介绍通过netfilter的钩子机制实现用户态设置和获取socket选项,从而完成用户态与内核态之间的通信。
雷大亨
2018/01/01
2.9K0
Linux进程通信之Unix套接字(二)
执行服务端代码php demo29.php,通过ls命令可以看到已经生成文件,并且通过file命令可以看到生成的文件是一个socket文件,通过pstree -ap 查看启动的进程id,通过strace命令监控服务端进程
北溟有鱼QAQ
2021/12/14
1.8K0
Linux进程通信之Unix套接字(二)
完美解决Python套接字编程时TCP断包与粘包问题
首先,来看一个代码,使用TCP协议,发送端发送一句话,接收端接收并显示,运行完全正常。
Python小屋屋主
2020/04/15
2.1K0
完美解决Python套接字编程时TCP断包与粘包问题
Linux进程通信之Unix套接字(一)
当然PHP中还封装了其他两种类型的协议,不常用(SOCK_SEQPACKET 提供一个顺序化的、可靠的、全双工的、面向连接的、固定最大长度的数据通信;数据端通过接收每一个数据段来读取整个数据包和SOCK_RDM 提供一个可靠的数据层,但不保证到达顺序。一般的操作系统都未实现此功能。)
北溟有鱼QAQ
2021/12/12
2.8K0
Linux进程通信之Unix套接字(一)
C/C++ 套接字通信类的封装
在掌握了基于 TCP 的套接字通信流程之后,为了方便使用,提高编码效率,可以对通信操作进行封装,本着有浅入深的原则,先基于 C 语言进行面向过程的函数封装,然后再基于 C++ 进行面向对象的类封装。
C语言与CPP编程
2021/12/09
2K0
并发篇-python套接字
在介绍下 IP地址 和 端口号 每台电脑连接网络都会有IP地址 需要记住:127.0.0.1 localhost 是本机地址 端口号 需要注意:一台主机有0~65535个端口号 端口是用来区分应
小团子
2019/07/18
4760
并发篇-python套接字
点击加载更多

相似问题

如何使用netlink套接字与内核模块通信?

412

如何使用netlink套接字进行内核-用户空间通信

22

Python -套接字通信,多条消息

11

Netlink套接字

23

用户空间netlink套接字从内核空间接收空消息

24
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文