2

我需要建立一个 vlan 标头。我有构建 eh 标头(结构 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 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数据包并正确发送它们)。有什么建议吗?

4

4 回答 4

1

http://wiki.wireshark.org/VLAN

  • DstMAC [6 字节]
  • SrcMAC [6 字节]
  • 类型 [2 字节]
    • 0x8100
  • VLANTag [4 字节]
    • 优先级 [0..2 位]
      • 0
    • CFI [3 位]
      • 0
    • ID [4..15 位]
    • 以太网类型 [16..31]
      • 0x0800 (IP)

我的猜测是您没有正确设置 VLAN_ID。

首先,您应该通过在 byte[] 缓冲区中创建一些测试数据包来避免任何结构填充问题,这样您就可以确保一切正确。然后您可以放心地调试您的结构和 htons 字节排序,因为您知道正确的值应该是什么。

于 2012-10-31T19:52:24.580 回答
1

我构建 VLAN 的代码是正确的。它最初对我不起作用,因为我现在忘记将数据包的大小更改为更大。请注意,TCI 不仅是 VID,它还包含优先级和 CFI。在我的情况下,它们都为零,所以我不需要为 TCI 使用掩码和填充。

于 2012-11-01T08:51:58.900 回答
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)
于 2012-10-31T19:27:18.947 回答
0

802.1Q 4字节的VLAN标签一般被认为是0x8100+pri+cfi+vlan. 将 vlan 标签描述为(不包括 8100,但包括数据有效负载的 etype)
的 wireshark 方式有些独特。 但是,无论哪种方式,整体数据包格式和长度都是正确的。pri+cfi+vlan+etype

于 2012-11-03T10:56:20.553 回答