10
votes

Comment puis-je recevoir des paquets de couche 2 crus en C / C ++?

Comment recevoir des paquets de couche 2 dans Posixy C ++? Les paquets n'ont que SRC et DST Adresse MAC, type / longueur et données formatées personnalisées. Ils ne sont pas TCP ou UDP ou IP ou IGMP ou ARP ou autre - ils sont un format brassé à la maison qui m'a été donné par les gars du matériel.

My Socket (AF_PACKET, SOCK_RAW, IPProto_raw) Code > ne revient jamais de son recvfrom () code>. p>

Je peux envoyer une amende, je ne peux tout simplement pas recevoir quelles que soient les options que j'envoie à la pile de réseau. P> (la plate-forme est VXWorks, mais je peux traduire POSIX ou Linux ou autre ...) P>

Code de réception (Incarnation actuelle): P>

 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


3 commentaires

Je suis content que vous ayez marqué ce posx, bonne chance à essayer de le faire sur Windoze;)


Stackoverflow.com/Questtions/1829187/udp-sockets-in-c Stackoverflow.com/questions/1795874/ ...


Juste un Nitpick: Posix ne définit pas les liaisons C ++, seulement C.


5 Réponses :


3
votes

Avez-vous essayé de définir le protocole de socket vers HTONS (Eth_P_All) comme indiqué dans paquet (7) ? Ce que vous faites n'a pas beaucoup à faire avec IP (bien que ipproto_raw peut être une valeur générique, Dunno)


2 commentaires

Réponse correcte - le protocole transmis à socket () ne doit pas être ipproto_raw , il devrait s'agir de l'ID de protocole Ethernet (802.3) pour votre protocole personnalisé, dans le réseau d'octrois ordre.


Commencez peut-être à lire des pages d'homme et à vérifier les arguments que vous avez deviné.



1
votes

Je pense que cela va être un problème un peu plus difficile à résoudre que prévu. Étant donné que ce n'est pas une adresse IP du tout (ou apparemment à tout autre protocole, rien ne reconnaîtra), je ne pense pas que vous puissiez résoudre votre problème entièrement avec le code de niveau utilisateur. Sur Linux, je pense que vous auriez besoin d'écrire votre propre Interface agnostique de périphérique pilote (probablement en utilisant NAPI < / a>). L'obtenir au travail sous Vxworks sera presque certainement non trivial (plus comme une réécriture complète de la terre de la base que la plupart des gens penseraient comme un port).


0 commentaires

0
votes

Avez-vous essayé de confirmer via Wireshark qu'un paquet a été envoyé de l'autre extrémité?

Aussi, pour le débogage, demandez à vos gars de votre matériel s'ils ont une broche de débogage (vous pouvez vous attacher à un analyseur logique) qu'ils peuvent affirmer lorsqu'il reçoit un paquet. Juste pour vous assurer que le matériel consiste à obtenir les paquets bien.


1 commentaires

Tout est à l'intérieur d'une FPGA, de sorte qu'il ne peut pas être projeté. HW dit que ça fonctionne, je dois donc y aller avec ça pour l'instant.



4
votes

Je pense que la manière de le faire consiste à écrire votre propre service réseau qui se lie à la couche MUX de la pile réseau VXWorks. Ceci est raisonnablement bien documenté dans le Guide du programmeur de réseau VXWorks et quelque chose que j'ai fait plusieurs fois.

Un service réseau personnalisé peut être configuré pour voir tous les paquets de couche 2 reçus sur une interface réseau à l'aide du type de service MUX_Proto_Snarf, ce qui permet de fonctionner par le protocole WDB de Wind River ou des paquets avec un type de protocole spécifique.

Il est également possible d'ajouter une interface de socket à votre service réseau personnalisé en écrivant un back-end de socket personnalisé situé entre le service réseau et l'API de socket. Ceci n'est pas nécessaire si vous êtes heureux de traiter le traitement de la demande dans le service réseau.

Vous n'avez pas dit quelle version de VXWorks que vous utilisez, mais je pense que le ci-dessus contient pour VXWorks 5.5.x et 6.x


1 commentaires

Merci. Je suis allé la route paresseuse et je viens de copier le paquet du code Xilinx avant d'entrer dans la pile de réseau. Votre chemin serait le ... pas paresseux, pas derrière le calendrier ... :)



0
votes

Tout d'abord, vous devez spécifier le protocole comme éth_p_all afin que votre interface obtient tout le paquet. Définissez votre prise pour être en mode promiscuous. Ensuite, liez votre prise brute à une interface avant d'effectuer une réception.


0 commentaires