在c中构建vlan头
我需要建立一个vlan头。 我有构建eh头(struct-ether\u头)的代码,它工作正常在c中构建vlan头,c,network-programming,ethernet,C,Network Programming,Ethernet,我需要建立一个vlan头。 我有构建eh头(struct-ether\u头)的代码,它工作正常 /* Ethernet header */ memcpy(eh->ether_shost,src_mac_.data(), 6); memcpy(eh->ether_dhost,socketAddress.sll_addr , 6); /* Ethertype field */ eh->ether_type = htons(ETH_P_IP); 我没有找到vlan_eth_头的结
/* Ethernet header */
memcpy(eh->ether_shost,src_mac_.data(), 6);
memcpy(eh->ether_dhost,socketAddress.sll_addr , 6);
/* Ethertype field */
eh->ether_type = htons(ETH_P_IP);
我没有找到vlan_eth_头的结构,所以我创建了自己的结构,并按如下方式填充它:
struct vlan_ethhdr {
u_int8_t ether_dhost[ETH_ALEN]; /* destination eth addr */
u_int8_t ether_shost[ETH_ALEN]; /* source ether addr */
u_int16_t h_vlan_proto;
u_int16_t h_vlan_TCI;
u_int16_t ether_type;
};
/* Ethernet header */
memcpy(eh->ether_shost,src_mac_.data(), 6);
memcpy(eh->ether_dhost,socketAddress.sll_addr , 6);
eh->h_vlan_proto = htons(0x8100);
eh->h_vlan_TCI = htons(VLAN_ID);
/* Ethertype field */
eh->ether_type = htons(ETH_P_IP);
看来我做错了。
看起来Wireshak甚至没有识别出这个数据包(旧代码发送tcp数据包并正确发送)。
有什么建议吗?您确定您的结构包装正确吗?默认情况下,编译器会添加一些填充。它很容易被禁用 例如,对于GCC:
#pragma pack(push)
#pragma pack(0)
struct vlan_ethhdr {
u_int8_t ether_dhost[ETH_ALEN]; /* destination eth addr */
u_int8_t ether_shost[ETH_ALEN]; /* source ether addr */
u_int16_t h_vlan_proto;
u_int16_t h_vlan_TCI;
u_int16_t ether_type;
};
#pragma pack(pop)
- DstMAC[6字节]
- SrcMAC[6字节]
- 类型[2字节]
- 0x8100
- VLAN标记[4字节]
- 优先级[0..2位]
- 0
- CFI[3位]
- 0
- ID[4..15位]
- 以太网类型[16..31]
- 0x0800(IP)
首先,您应该通过在byte[]缓冲区中创建一些测试数据包来避免任何结构填充问题,这样您就可以确保所有内容都正确无误。然后,您可以放心地调试您的结构和htons字节顺序,因为您知道正确的值应该是什么。我构造VLAN的代码是正确的。起初它对我不起作用,因为我忘了把包的大小改大。
请注意,TCI不仅包括优先级和CFI。在我的例子中,它们都是零,所以我不需要对TCI使用掩码和填充。802.1Q 4字节VLAN标记通常被认为是
0x8100+pri+cfi+VLAN
wireshark将vlan标记描述为
pri+cfi+vlan+etype
(不包括8100,但包括数据有效负载的etype)的方式有些独特。但是,无论哪种方式,总的数据包格式和长度都是正确的 我基于linux中的struct eth_头。现在我看到有一个区别,它们有}属性}((压缩));我没有抄。这可能是原因吗?你可以在下面的链接中看到,它的defined without pack with and not pack都是相同的大小(18个额外的4字节)@user1495181如果你对它的确切大小有疑问,你可以在你的结构上做一个sizeof()。你猜我应该如何设置vlan id?我看到了这个引用,但不知道它是否正确。我将按照您的建议尝试使用字节。打印十六进制(或从wireshark复制),包括IP标头的位置,这样可以很容易地看到错误所在。