10

POSIXy C ++でレイヤー2パケットを受信するにはどうすればよいですか?パケットには、srcおよびdst MACアドレス、タイプ/長さ、およびカスタム形式のデータのみが含まれます。それらはTCPでもUDPでもIPでもIGMPでもARPでも何でもありません-それらはハードウェアの人たちによって私に与えられた自家製のフォーマットです。

socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)はそのから戻ることはありませんrecvfrom()

うまく送信できますが、ネットワークスタックでどのようなオプションを使用しても受信できません。

(プラットフォームはVxWorksですが、POSIXやLinuxなどを翻訳できます...)

受信コード(現在の化身):

 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
4

5 に答える 5

4

これを行う方法は、VxWorks ネットワーク スタックの MUX レイヤーにバインドする独自のネットワーク サービスを作成することだと思います。これは、VxWorks Network Programmer's Guide にかなり詳しく記載されており、私が何度も行ってきたことです。

カスタム ネットワーク サービスは、MUX_PROTO_SNARF サービス タイプ (Wind River 独自の WDB プロトコルの動作方法) を使用して、ネットワーク インターフェイスで受信したすべてのレイヤー 2 パケット、または特定のプロトコル タイプのパケットを表示するように構成できます。

ネットワーク サービスとソケット API の間にカスタム ソケット バックエンドを作成することで、カスタム ネットワーク サービスにソケット インターフェイスを追加することもできます。Network Service でアプリケーション処理を行う場合、これは必要ありません。

使用している VxWorks のバージョンについては言及されていませんが、上記は VxWorks 5.5.x および 6.x に当てはまると思います。

于 2010-08-20T09:14:20.223 に答える
3

htons(ETH_P_ALL)で規定されているように、ソケット プロトコルを に設定してみましたpacket(7)か? あなたがしていることはIPとはあまり関係がありません(IPPROTO_RAWワイルドカード値かもしれませんが、わかりません)

于 2010-08-19T22:46:31.873 に答える
1

これは予想以上に解決が難しい問題だと思います。それがまったく IP ではない (または明らかに他のプロトコルが認識できる) ことを考えると、ユーザーレベルのコードだけで問題を完全に解決できるとは思えません。Linux では、独自のデバイスに依存しないインターフェイスドライバーを作成する必要があると思います(おそらく を使用NAPI)。VxWorks で動作させることは、ほぼ確実に簡単なことではありません (ほとんどの人が移植と考えるよりも、ゼロから完全に書き直したようなものです)。

于 2010-08-19T23:05:09.003 に答える
0

最初に、インターフェイスがすべてのパケットを取得できるように、プロトコルを ETH_P_ALL として指定する必要があります。ソケットを無差別モードに設定します。次に、受信を実行する前に、RAW ソケットをインターフェイスにバインドします。

于 2016-03-30T15:11:19.493 に答える
0

パケットが実際に相手側から送信されたことを Wireshark 経由で確認してみましたか?

また、デバッグのために、ハードウェア担当者に、パケットを受信したときにアサートできるデバッグ ピン (ロジック アナライザーに接続できます) があるかどうか尋ねてください。ハードウェアがパケットを正常に取得していることを確認するだけです。

于 2010-08-19T23:47:28.667 に答える