c - C: Linux Kernel - 如何在 struct ieee80211_mgmt 中使用 union 的变量字段数组(u8 变量 [0])?
问题描述
在文件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 模块分配,我想做的只是插入一个新字段(静态结构中没有列出)。
我没有在内核树上找到任何类似的代码用作示例。我很感激你能提供给我的任何观点,以便更好地理解它。非常感谢!
解决方案
允许结构将长度为零的数组作为其最终成员是GCC 扩展,其语义与标准灵活数组成员基本相同。该成员可以通过名称和数组的元素类型访问,就像其他任何元素一样,您可以访问结构的实际分配大小允许的尽可能多的元素。例如,mgmt_hdr->u.assoc_req.variable[i]
在i
允许的范围内。
当然,要知道您可以访问多少数据,您需要依赖某处存储的长度或依赖数据本身的某些特征,例如终止符/哨兵。如果您希望就地扩展阵列,那么您可能不走运,如果您不知道分配了多少空间,那么您肯定是。在这种情况下,您唯一可行的选择是重新分配更大的整个对象,并将所有指向原始对象的指针替换为指向新对象的指针。如果您不能确定这样做,那么扩展数组不是您的选择,但如果您知道它在哪里结束,您仍然可以修改现有内容。
推荐阅读
- python - Python Port Scanner 显示不存在主机上的开放端口
- python - python 在使用 Sql Server 的 fast_executemany 作为 TRUE 时崩溃
- python - OpenCV如何从噪声和误报中清除轮廓
- graphql - GraphQL Nexus - 添加自定义标量类型
- swift - 如何在运行时使用可达性检查 Internet 连接的网络连接更改?
- node.js - 错误:模块版本不匹配 - 未删除 node_modules
- swift - 在闭包内调用闭包
- django - Django 单元测试因 CIText 和 Sqlite 而失败
- c# - 如何检查进程是否因服务而死亡
- spring-boot - 将变量从 VueJS 传递到另一个应用程序的控制器