LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1308|回复: 12

请教unsigned char payload[0]有什么作用?

[复制链接]
发表于 2005-6-28 10:53:30 | 显示全部楼层 |阅读模式
[PHP]typedef struct ipq_packet_msg {
        unsigned long packet_id;        /* ID of queued packet */
        unsigned long mark;             /* Netfilter mark value */
        long timestamp_sec;             /* Packet arrival time (seconds) */
        long timestamp_usec;            /* Packet arrvial time (+useconds) */
        unsigned int hook;              /* Netfilter hook we rode in on */
        char indev_name[IFNAMSIZ];      /* Name of incoming interface */
        char outdev_name[IFNAMSIZ];     /* Name of outgoing interface */
        unsigned short hw_protocol;     /* Hardware protocol (network order) */
        unsigned short hw_type;         /* Hardware type */
        unsigned char hw_addrlen;       /* Hardware address length */
        unsigned char hw_addr[8];       /* Hardware address */
        size_t data_len;                /* Length of packet data */
        unsigned char payload[0];       /* Optional packet data */
} ipq_packet_msg_t;
[/PHP]

以上数据结构取自iptables的ip_queue的数据结构定义,文件在我的系统里是:/usr/include/linux/netfilter_ipv4/ip_queue.h,上面的包是来自内核的包,我想请教一下:最后一个成员unsigned char payload[0]的作用是什么?
发表于 2005-6-28 11:33:49 | 显示全部楼层
alignment, or reserved for future
回复 支持 反对

使用道具 举报

发表于 2005-6-28 11:42:05 | 显示全部楼层
用payload做载荷的指针?与data_len一起可以决定packet的长度
回复 支持 反对

使用道具 举报

发表于 2005-6-28 19:33:11 | 显示全部楼层
像 T  a[0];这样的东西,第一,可以自动申请到一块内存(sizeof(T)),第二,可以方便的使用
一个指针a.
// 说错了, 应该是T a[1]这样的用法

我猜这个域是用来判断ip包的负载类型并且引用负载数据, 比如一个包含了tcp数据的ip包
xxxxxxxxxxYzzzzzzzzzzzzzz
\-------------/ \----------------/
ip-header      ip-payload(tcp)
这样用payload[0]可以判断这个负载的类型, 而且可以用payload[1] ... payload[data_len]
引用tcp包, 中间不用为了一个char而跑到堆中单独分配一次内存, 又要释放.
回复 支持 反对

使用道具 举报

发表于 2005-6-28 22:15:59 | 显示全部楼层
payload的长度是多少,在定义这个结构的时候是不知道的;

程序当中可能有类似这样的语句,当知道了payload_size:
ipq_packet_msg_t *packet = malloc( sizeof(ipq_packet_msg_t) + payload_size);

然后payload就顺理成章的当数组用了,如 packet->payload
回复 支持 反对

使用道具 举报

发表于 2005-6-28 22:31:36 | 显示全部楼层
这是c99的功能,让变长结构使用起来方便一次。不过我还是坚持老式的写法:

  1. #ifndef offsetof
  2. # define offsetof(type, member)                ((size_t)&((type *)0)->member)
  3. #endif
  4. ...
  5. typedef struct ipq_packet_msg {
  6.         ...
  7.         unsigned char payload[1];       /* Optional packet data */
  8. } ipq_packet_msg_t;
  9. ...
  10. ipq_packet_msg_t *packet = malloc(offsetof(ipq_packet_msg_t) + payload_size);
复制代码

注意这时候最后一个是payload[1]。
回复 支持 反对

使用道具 举报

发表于 2005-6-28 22:34:01 | 显示全部楼层
如果不使用变长结构,则最后一个域必须是unsigned char *payload。这样,将增加一次malloc操作和平均3个指针的额外开消。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-6-29 14:00:34 | 显示全部楼层
多谢各位,我明白了它的作用了.

想继续请教Tetris:
((size_t)&((type *)0)->member)中,(type *)0->member指的是?

Post by Tetris
这是c99的功能,让变长结构使用起来方便一次。不过我还是坚持老式的写法:

  1. #ifndef offsetof
  2. # define offsetof(type, member)                ((size_t)&((type *)0)->member)
  3. #endif
  4. ...
  5. typedef struct ipq_packet_msg {
  6.         ...
  7.         unsigned char payload[1];       /* Optional packet data */
  8. } ipq_packet_msg_t;
  9. ...
  10. ipq_packet_msg_t *packet = malloc(offsetof(ipq_packet_msg_t) + payload_size);
复制代码

注意这时候最后一个是payload[1]。
回复 支持 反对

使用道具 举报

发表于 2005-6-29 14:23:53 | 显示全部楼层
取得偏移量。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-6-29 14:54:02 | 显示全部楼层
Post by gvim
取得偏移量。


基础不行,还是看不出来.多问几句.
(type *)0是什么意思?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表