如何接收C/C+中的原始第2层数据包+;? 如何在PosixC++中接收第2层数据包?数据包只有src和dst MAC地址、类型/长度和自定义格式的数据。它们不是TCP或UDP或IP或IGMP或ARP或其他任何东西——它们是硬件人员给我的一种自制格式

如何接收C/C+中的原始第2层数据包+;? 如何在PosixC++中接收第2层数据包?数据包只有src和dst MAC地址、类型/长度和自定义格式的数据。它们不是TCP或UDP或IP或IGMP或ARP或其他任何东西——它们是硬件人员给我的一种自制格式,c++,c,sockets,posix,vxworks,C++,C,Sockets,Posix,Vxworks,我的套接字(AF\u数据包、SOCK\u RAW、IPPROTO\u RAW)从不从其recvfrom()返回 我可以很好地发送,但无论我在网络堆栈中抛出什么选项,我都无法接收 (平台是VxWorks,但我可以翻译POSIX或Linux或任何东西…) 接收代码(当前化身): ints; 如果((s=套接字(AF_数据包、SOCK_原始、IPPROTO_原始)),它应该是您的自定义协议的以太网(802.3)协议ID,以网络字节顺序。也许开始阅读手册页并检查你猜到的任何参数。所有这些都在FPGA内部

我的
套接字(AF\u数据包、SOCK\u RAW、IPPROTO\u RAW)
从不从其
recvfrom()返回

我可以很好地发送,但无论我在网络堆栈中抛出什么选项,我都无法接收

(平台是VxWorks,但我可以翻译POSIX或Linux或任何东西…)

接收代码(当前化身):

ints;
如果((s=套接字(AF_数据包、SOCK_原始、IPPROTO_原始))<0){
printf(“套接字创建错误”);
返回-1;
}
结构ifrequ ifr;
strncpy(_ifr.ifr_名称,“lltemac0”,strlen(“lltemac0”));
ioctl(s、IP_SIOCGIFINDEX和ifr);
结构sockaddr\u ll\u sockAttrib;
memset(&_sockAttrib,0,sizeof(_sockAttrib));
_sockAttrib.sll_len=sizeof(_sockAttrib);
_sockAttrib.sll_family=AF_数据包;
_sockAttrib.sll_协议=IFT_以太;
_sockAttrib.sll_iIndex=_ifr.ifr_iIndex;
_sockAttrib.sll_hatype=0xFFFF;
_sockAttrib.sll\u pkttype=数据包\u主机;
_sockAttrib.sll_halen=6;
_sockAttrib.sll_addr[0]=0x00;
_sockAttrib.sll_addr[1]=0x02;
_sockAttrib.sll_addr[2]=0x03;
_sockAttrib.sll_addr[3]=0x12;
_sockAttrib.sll_addr[4]=0x34;
_sockAttrib.sll_addr[5]=0x56;
int _sockAttrib=sizeof(_sockAttrib);
字符包[64];
memset(packet,0,sizeof(packet));
如果(recvfrom,(char*)数据包,sizeof(数据包),0,
(结构sockaddr*)和&u sockAttrib和&u sockAttribLen)<0)
{
printf(“数据包接收错误”);
}
//代码永远不会到达这里

您是否尝试过按照
数据包(7)
中的规定将套接字协议设置为
htons(ETH\u p\u ALL)
?您所做的与IP没有多大关系(尽管
IPPROTO_RAW
可能是一些通配符值,不知道)

我认为这将是一个比您预期的更难解决的问题。考虑到它根本不是IP(或者任何其他协议都可以识别),我认为您无法完全用用户级代码解决您的问题。在Linux上,我认为您需要编写自己的驱动程序(可能使用)。让它在VxWorks下工作几乎肯定是不平凡的(更像是从头开始的完全重写,而不是大多数人认为的端口)。

您是否尝试过通过Wireshark确认数据包实际上是从另一端发送的


此外,对于调试,请询问硬件人员是否有调试pin(您可以连接到逻辑分析器),当它接收到数据包时,他们可以断言该pin。只是为了确保硬件能够很好地获取数据包。

我认为这样做的方法是编写自己的网络服务,绑定到VxWorks网络堆栈中的MUX层。这在VxWorks网络程序员指南中有很好的记录,我已经做过很多次了

自定义网络服务可配置为使用MUX_PROTO_SNARF服务类型(Wind River自己的WDB协议的工作方式)查看网络接口上接收的所有第2层数据包,或查看具有特定协议类型的数据包

通过编写位于网络服务和套接字API之间的自定义套接字后端,还可以向自定义网络服务添加套接字接口。如果您愿意在网络服务中进行应用程序处理,则不需要这样做


您还没有说您使用的是哪个版本的VxWorks,但我认为以上内容适用于VxWorks 5.5.x和6.x。首先,您需要将协议指定为ETH_p_ALL,以便您的接口获得所有数据包。将您的套接字设置为混杂模式。然后在执行接收之前将原始套接字绑定到接口。

我很高兴您标记了此POSIX,祝您在Windoze上尝试此操作好运;)只是一个NITPoice:POSIX没有定义C++绑定,只有C正确答案-传递给<代码> SoCK()的协议<代码>不应该是代码> IPTrimeWRAW < /C>,它应该是您的自定义协议的以太网(802.3)协议ID,以网络字节顺序。也许开始阅读手册页并检查你猜到的任何参数。所有这些都在FPGA内部,所以不能被切分。HW说它有效,所以我现在不得不同意。谢谢。我采用了延迟路由,只是在数据包进入网络堆栈之前从Xilinx代码中复制了数据包。你的方式将是。。。不懒惰,不落后于计划方式…:)
 int s;

 if ((s = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) < 0) {
  printf("socket create error.");
      return -1;
 }

   struct ifreq          _ifr;   
   strncpy(_ifr.ifr_name, "lltemac0", strlen("lltemac0"));
   ioctl(s, IP_SIOCGIFINDEX, &_ifr);

   struct sockaddr_ll _sockAttrib;
   memset(&_sockAttrib, 0, sizeof(_sockAttrib));
   _sockAttrib.sll_len      = sizeof(_sockAttrib);
   _sockAttrib.sll_family   = AF_PACKET;
   _sockAttrib.sll_protocol = IFT_ETHER;
   _sockAttrib.sll_ifindex  = _ifr.ifr_ifindex;
   _sockAttrib.sll_hatype   = 0xFFFF;
   _sockAttrib.sll_pkttype  = PACKET_HOST;
   _sockAttrib.sll_halen    = 6;
   _sockAttrib.sll_addr[0]  = 0x00;
   _sockAttrib.sll_addr[1]  = 0x02;
   _sockAttrib.sll_addr[2]  = 0x03;
   _sockAttrib.sll_addr[3]  = 0x12;
   _sockAttrib.sll_addr[4]  = 0x34;
   _sockAttrib.sll_addr[5]  = 0x56;
   int _sockAttribLen = sizeof(_sockAttrib);


 char packet[64];
 memset(packet, 0, sizeof(packet));

   if (recvfrom(s, (char *)packet, sizeof(packet), 0,
                (struct sockaddr *)&_sockAttrib, &_sockAttribLen) < 0)
   {
      printf("packet receive error.");
   }

   // code never reaches here