C: Linux Kernel - 如何在 struct ieee80211_mgmt 中使用 union 的变量字段数组 (u8 variable[0])?

标签 c linux-kernel device-driver

在文件 include/linux/ieee80211.h 中,我们有:

struct ieee80211_mgmt {
        ...
    union {
                ...
        struct {
           __le16 capab_info;
           __le16 listen_interval;
            /* followed by SSID and Supported rates */
            u8 variable[0];
        } __packed assoc_req;
                ...
    } u;
} __packed __aligned(2);

我需要修改这个结构中的一些字段。例如,要修改 capab_info,我会这样做:

...
struct ieee80211_mgmt *mgmt_hdr = skb->data;
mgmt_hdr->u.assoc_req.capab_info = 0xABCD;

但是如果我想修改/插入将定位在变量数组中某处的“SSID”字段,我不知道应该在哪里以及如何分配和修改它。

上面的代码我假设 skb->data 结构已经被 mac80211 模块分配,我想做的只是插入一个新字段(静态结构中没有列出)。

我没有在内核树上找到任何类似的代码作为示例。我很感激你能提供给我更好地理解它的任何观点。非常感谢!

最佳答案

允许结构将长度为零的数组作为其最终成员是 a GCC extension与标准 flexible array member 具有基本相同的语义.该成员可以通过名称和数组的元素类型访问,就像任何其他成员一样,并且您可以访问结构的实际分配大小允许的尽可能多的元素。例如,mgmt_hdr->u.assoc_req.variable[i] for i 在允许范围内。

当然,要知道您可以访问多少数据,您需要依赖某处存储的长度或依赖数据本身的某些特征,例如终止符/哨兵。如果您希望就地扩展数组,那么您可能会倒霉,如果您不知道分配了多少空间,那么您肯定是这样。在这种情况下,唯一可行的选择是将整个对象重新分配得更大,并将所有指向原始对象的指针替换为指向新对象的指针。如果您不能确定这样做,那么扩展数组不适合您,但如果您知道它的结束位置,您仍然可以修改现有内容。

关于C: Linux Kernel - 如何在 struct ieee80211_mgmt 中使用 union 的变量字段数组 (u8 variable[0])?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54525007/

相关文章:

c - mkfifo 的段错误

用递归比较2个数组(C语言)

C结构赋值使用memcpy

linux - 如何修改现有的 Linux 内核模块

c - file_operations.write 的返回值不受尊重

c - linux内核如何检查是否设置了粘滞位

c - LKM 崩溃取决于硬件?

macos - IO资源类

c++ - 从 C++ 应用程序重新启动 Windows 8.1 本地服务?

java - 笔记本电脑触摸板编程