数据包的类型转换如何填充网络结构的正确变量?

问题描述 投票:0回答:1

我目前正在与

libpcap
合作。当我输入“网络”结构(例如以太网)时,数据包 (
const unsigned char *
) 会填充结构 (1) 内的正确变量,这是怎么发生的?与跳过标头 (2) 时发生的过程相同吗?

//(1)
//Ethernet structure
typedef struct ethhdr{
        unsigned char dst_mac[6];
        unsigned char src_mac[6];
        unsigned short eth_type;
    }ethhdr_t;

... //inside the callback function
ethhdr_t *ethernet;
ethernet = (ethhdr_t *)(packet)



//(2)
//IP structure
typedef struct iphdr{
    unsigned char ip_vhl;
    unsigned char ip_tos;
    unsigned short ip_len;
    unsigned short ip_id;
    unsigned short ip_off;
#define IP_RF   0x8000
#define IP_DR   0x4000
#define IP_MF   0x2000
#define IP_OFFMASK  0x1fff
    unsigned char ip_ttl;
    unsigned char ip_p;
    unsigned short ip_sum;
    struct in_addr ip_src, ip_dst;
}iphdr_t;

... //inside the callback function
ethhdr_t *ethernet;
iphdr_t *ip;

ethernet = (ethhdr_t *)(packet)
ip = (iphdr_t *)(packet + 14) // + the size of the ethernet header
c networking casting libpcap
1个回答
0
投票
typedef struct ethhdr{
        unsigned char dst_mac[];
        unsigned char src_mac[];
        unsigned short eth_type;
    }ethhdr_t;

它不会编译,因为你只能有一个灵活的数组成员,并且它必须位于结构的末尾。如果您事先不知道数组的大小并且它“附加”到结构的末尾,则使用灵活的数组成员。

在这种情况下,您知道 MAC 地址的大小,即 6 个字节长。

typedef struct ethhdr{
        unsigned char dst_mac[6];
        unsigned char src_mac[6];
        unsigned short eth_type;
    }ethhdr_t;

我目前正在使用 libpcap。当我 类型转换“网络”结构,例如以太网,数据包 (const unsigned char *) 填充正确的变量 结构(1)?与跳过标头时发生的过程是否相同 (2)?

ethhdr_t *ethernet;
ethernet = (ethhdr_t *)(packet)

这是一个非常糟糕的代码,因为它可能会调用未定义的行为。潜在的问题有很多,主要有:

  1. 可能违反严格的别名规则。如果你指针 pune 类型,这个问题基本上无法解决
  2. 结构可能有填充。在非标准 C(编译器扩展、编译指示或属性)中,您可以打包结构。

解决方案之一是使用

union
memcpy
结构。

© www.soinside.com 2019 - 2024. All rights reserved.