Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在c中构建vlan头_C_Network Programming_Ethernet - Fatal编程技术网

在c中构建vlan头

在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_头的结

我需要建立一个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_头的结构,所以我创建了自己的结构,并按如下方式填充它:

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)
我猜你没有正确设置VLAN\u ID


首先,您应该通过在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标头的位置,这样可以很容易地看到错误所在。