我需要构建一个vlan标头。 我有构建eh头的代码(struct ether_header),它工作正常。
/* 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_header的struct,所以我自己创建并填充它:
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数据包并将它们发送正确)。 有什么建议吗?
答案 0 :(得分:1)
http://wiki.wireshark.org/VLAN
我的猜测是你没有正确设置VLAN_ID。
首先,您应该通过在byte []缓冲区中创建一些测试数据包来避免任何结构填充问题,这样您就可以确保一切正确。然后,您可以放心地调试结构和htons字节顺序,因为您知道正确的值应该是什么。
答案 1 :(得分:1)
构建VLAN的代码是正确的。它首先为我工作,因为我忘了改变数据包的大小现在更大。 注意TCI不仅仅是VID的优先级和CFI。在我的情况下,它们都为零,所以我不需要为TCI使用掩码和填充。
答案 2 :(得分:0)
您确定您的结构是否妥善包装?编译器默认添加一些填充。它很容易被禁用。
例如,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)
答案 3 :(得分:0)
802.1Q 4字节VLAN标记通常被视为0x8100+pri+cfi+vlan
的形式
wireshark将vlan标签描述为pri+cfi+vlan+etype
的方式(不包括8100,但包括数据有效负载的etype)有点独特。
但是,整个数据包格式和长度都是正确的。