c - 使用适当的包装函数从 sk_buff 获取 pid
问题描述
这是从 Linux Kernel 中的 sk_buff 和 inode 获取 PID的后续问题,由于我无法在答案下发表评论,所以我在这里..
答案是skb->sk->socket->file->f_owner->pid
。
我之所以问是因为我有一种预感,即使用内核空间中的指针直接处理数据很容易出错。
我用谷歌搜索了这个,但没有发现任何有用的东西。
任何帮助或建议将不胜感激。
顺便说一句,内核版本是 4.4 或 3.10。基于最新内核头文件的解决方案也很好。
解决方案
由于我本周正在使用 5.10.28 和 Debian 11,这就是您得到的解决方案。:-@) /usr/include/linux/pid.h(或 debian/linux-headers/usr/src/linux-headers-5.10.28/include/linux/pid.h,如果你愿意)的这条评论告诉它比我一个人做得更好:
/*
* What is struct pid?
*
* A struct pid is the kernel's internal notion of a process identifier.
* It refers to individual tasks, process groups, and sessions. While
* there are processes attached to it the struct pid lives in a hash
* table, so it and then the processes that it refers to can be found
* quickly from the numeric pid value. The attached processes may be
* quickly accessed by following pointers from struct pid.
*
* Storing pid_t values in the kernel and referring to them later has a
* problem. The process originally with that pid may have exited and the
* pid allocator wrapped, and another process could have come along
* and been assigned that pid.
*
* Referring to user space processes by holding a reference to struct
* task_struct has a problem. When the user space process exits
* the now useless task_struct is still kept. A task_struct plus a
* stack consumes around 10K of low kernel memory. More precisely
* this is THREAD_SIZE + sizeof(struct task_struct). By comparison
* a struct pid is about 64 bytes.
*
* Holding a reference to struct pid solves both of these problems.
* It is small so holding a reference does not consume a lot of
* resources, and since a new struct pid is allocated when the numeric pid
* value is reused (when pids wrap around) we don't mistakenly refer to new
* processes.
*/
检查 pid.h 会显示一些对您有帮助的实用程序,如果您准备在内核空间中处理此问题(鉴于上面的黑暗警告,需要稍微了解命名空间等)。您的 sk_buff 包含一个指向struct pid的指针,而不仅仅是一个整数 pid,并且可能是一个用户空间进程,因为您在内核空间中,该进程现已消失。你最好的选择是这样的:
#include <pid.h>
struct pid *myspid;
pid_t mypid;
myspid = get_pid(skb->sk->socket->file->f_owner->pid);
if (myspid == NULL)
/* forget it */
mypid = pid_nr(myspid);
return mypid;
但肯定不止于此。只是让你进入球场。
推荐阅读
- python - 无法使用 Scrapy 从网页加载和抓取数据
- python - Python Wordpress_XMLRPC NewComment Auth
- php - 如何在 foreach 循环中更新多个字段记录?
- python - 如何从用户那里获取输入并根据输入调用函数?
- angular - 即使在导入 CalendarModule 后,“p-calendar”也不是已知元素错误
- tfs - TFS - 断开远程控制后部署组服务器脱机
- r - R ggplot构面查找贴标机
- amazon-redshift - Redshift中的Isdate函数
- javascript - 我的导航栏无法点击
- android - 是否可以以编程方式检查 Playstore 上可用的应用程序版本?