1

我有一个像这样的C结构......

struct icmp_prefixopt {
    u_int8_t        icmpopt_type;
    u_int8_t        icmpopt_len;
    u_int8_t        prefixlen;
    u_int8_t        lflag:1;
    u_int8_t        aflag:1;
    u_int8_t        reserved:6;

};

我在同一个模块中为这样的成员提供了价值-

   popt= (struct icmp_prefixopt *)
                    malloc(sizeof(struct icmp_prefixopt));

  popt->icmpopt_type = 3;
  popt->icmpopt_len = 4;
  popt->prefixlen = (u_int8_t)strtoul(arg, (char **)NULL, 0);

     arg = index(arg, '+');
            if (arg) {
                    ++arg;
                    popt->lflag = ((u_int8_t)strtoul(arg, (char **)NULL, 0))&1;
            }


     arg = index(arg, '+');
            if (arg) {
                    ++arg;
                    popt->aflag = ((u_int8_t)strtoul(arg, (char **)NULL, 0))&1;
            }


     arg = index(arg, '+');
            if (arg) {
                    ++arg;
                 popt->reserved = 32;  //((u_int8_t)strtoul(arg, (char **)NULL, 0))<<2;
            }

其中 arg 是传递给此模块的命令行参数。

现在以十六进制格式查看结构执行后的内容->

  03 04 20 81

   icmpopt_type: seems fine
   icmpopt_len: seems fine
   prefixlen: seems fine

但是在它们的构成字节中,其他 3 个字段的位看起来是相反的

  lflag:1; aflag:1; reserved:6

所以它应该是 -10100000=A0但实际上他们是=>81=10000001

这给我带来了很多问题......

  1. 与小端/大端有什么关系?

  2. 如果是,那么 8 位的 htonl 和 htons 等功能的对应物是什么。

  3. 如果不是,可能是什么问题,或者我完全误解了什么?

  4. 什么是最好的方法?要修改结构本身内这些字段的顺序,
    还是应用一些位运算符并在此处本身移位?

在命令行提供的输入 -

    32+1+0+32 

最后的 32 在这里没有用,因为我在模块本身中修复了 32 以进行测试。虽然我的实际目的也需要考虑这个领域。

请尽快用任何替代方法帮助我。

提前谢谢。

编辑:

在此处输入图像描述

这是我需要创建的实际结构,并且随着创建,需要为用户提供通过 GUI 为所有字段指定值的规定。(现在只能通过 linux 命令行)。

我想我现在已经把问题说得更清楚了,但如果需要任何进一步的信息,我很乐意补充。

4

1 回答 1

5

编译器如何选择打包位域完全取决于实现。它不一定与字节顺序有关。

htnol(和类似的)不适用于位域。如果您需要有保证的订单,那么您需要自己手动打包uint8_t。例如:

struct icmp_prefixopt {
    u_int8_t        icmpopt_type;
    u_int8_t        icmpopt_len;
    u_int8_t        prefixlen;
    u_int8_t        stuff;
}

...

popt->stuff = (lflag << 7) | (aflag << 6);

当然,在实践中,您应该使用 sensible #defines 而不是幻数(对于 6 和 7)。您可能会决定将其包装在一堆 setter 和 getter 函数中。

于 2013-01-15T22:39:37.020 回答