Как получить необработанные пакеты уровня 2 в C / C ++? - PullRequest
10 голосов
/ 20 августа 2010

Как получить пакеты уровня 2 в POSIXy C ++? Пакеты имеют только MAC-адрес src и dst, тип / длину и данные, отформатированные пользователем. Это не 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

Ответы [ 5 ]

4 голосов
/ 20 августа 2010

Я думаю, что способ сделать это - написать собственную сетевую службу, которая связывается со слоем MUX в сетевом стеке VxWorks. Это достаточно хорошо задокументировано в Руководстве сетевого программиста VxWorks и кое-что, что я делал несколько раз.

Пользовательская сетевая служба может быть настроена на просмотр всех пакетов уровня 2, полученных на сетевом интерфейсе, с использованием типа службы MUX_PROTO_SNARF, как работает собственный протокол WDB Wind River, или пакетов с определенным типом протокола.

Также можно добавить интерфейс сокетов к вашей пользовательской сетевой службе, написав пользовательскую внутреннюю часть сокета, которая находится между сетевой службой и API сокетов. Это не требуется, если вы готовы выполнить обработку заявки в сетевой службе.

Вы не сказали, какую версию VxWorks вы используете, но я думаю, что вышеизложенное относится к VxWorks 5.5.x и 6.x

3 голосов
/ 20 августа 2010

Вы пытались установить протокол сокета на htons(ETH_P_ALL), как предписано в packet(7)?То, что вы делаете, не имеет ничего общего с IP (хотя IPPROTO_RAW может быть подстановочным знаком, не знаю)

1 голос
/ 20 августа 2010

Я думаю, что решить эту проблему будет сложнее, чем вы ожидаете. Учитывая, что это вообще не IP (или, по-видимому, любой другой протокол, который можно распознать), я не думаю, что вы сможете полностью решить свои проблемы с помощью кода уровня пользователя. В Linux, я думаю, вам нужно написать свой собственный драйвер интерфейса устройства (вероятно, с использованием NAPI). Заставить его работать в VxWorks почти наверняка будет нетривиально (больше похоже на полное переписывание с нуля, чем то, что большинство людей воспримут как порт).

0 голосов
/ 30 марта 2016

Сначала вам нужно указать протокол как ETH_P_ALL, чтобы ваш интерфейс получил весь пакет.Установите ваш сокет на случайный режим.Затем подключите сокет RAW к интерфейсу, прежде чем выполнять прием.

0 голосов
/ 20 августа 2010

Вы пытались подтвердить через Wireshark, что пакет действительно был отправлен с другого конца?

Кроме того, для отладки спросите ваших аппаратных парней, есть ли у них отладочный пин (вы можете подключить к логическому анализатору) что они могут утверждать, когда он получает пакет.Просто чтобы убедиться, что оборудование получает пакеты нормально.

...