在c中构建vlan标头

时间:2012-10-31 19:23:09

标签: c network-programming ethernet

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

4 个答案:

答案 0 :(得分:1)

http://wiki.wireshark.org/VLAN

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

我的猜测是你没有正确设置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)有点独特。
但是,整个数据包格式和长度都是正确的。