2013-07-31 2 views
0

Я читаю буфер из сокета (AF_PACKET, SOCK_DGRAM, htons (ETH_P_ARP)) со следующим кодом. Я использую структуру arp_frame для доступа к составным частям содержащегося ответа ARP. Inet_ntoa() возвращает правильный первый октет IP, но остальные октеты равны 0, производя 172.0.0.0.Почему этот код создает неполный IP-адрес?

Вопрос 1 почему это может случиться? Вопрос 2: как я могу напечатать r байтов буфера msg как hex в порядке байтов хоста для отладки пакета?

unsigned char msg[65535]; 
    struct ether_arp *arp_frame = (struct ether_arp *)msg; 

    while ((r = recv(sock, msg, sizeof(msg), 0))) { 
      // skip it's not an ARP REPLY 
      if (ntohs(arp_frame->arp_op) != ARPOP_REPLY) 
        continue; 

      for (i = 0; i < SONOS_PREFIX_NUM; i++) { 
        if (!memcmp(sonos_prefixes[i], arp_frame->arp_sha, 3)) { 
          struct in_addr addr; 
          addr.s_addr = *arp_frame->arp_spa; 

          printf("Blah: %lu\n", ntohl(*arp_frame->arp_spa)); 
          printf("Sonos found at %s\n", inet_ntoa(addr)); 
        } 
      } 
    } 

ответ

2

struct ether_arp выглядит следующим образом:

struct ether_arp { 
    struct arphdr ea_hdr;   /* fixed-size header */ 
    u_int8_t arp_sha[ETH_ALEN];  /* sender hardware address */ 
    u_int8_t arp_spa[4];   /* sender protocol address */ 
    u_int8_t arp_tha[ETH_ALEN];  /* target hardware address */ 
    u_int8_t arp_tpa[4];   /* target protocol address */ 
}; 

Имея это в виду, я думаю, что ваш addr.s_addr = *arp_frame->arp_spa; выглядит немного подозрительным. arp_frame->arp_spa дает u_int8_t[4], который затем разыменовывается как указатель. Думаю, memcpy() может быть более уместным.

+0

Bawls. Кажется, я полностью справился с неправильным руководством, так как сказал, что это u_long - http://www.propox.com/download/edunet_doc/all/html/structether__arp.html. Спасибо :) –

+0

Вероятно, это зависит от платформы ... В системах с большими байтами, где байтовый разворот не требуется, его удобно хранить в виде 32-битного целого числа, но в системах с маленькими концами я полагаю, что это будет зависят от реализации 'ntohl()' и друзей, которые выбрали разработчики ... Даже если это unsigned int/long, хотя, рассматривая его как указатель, это неправильно. – twalberg

0

Если вы считаете, что API сломан, распечатайте байты.

«Methinks, Brutus, вина не в звездах».

+0

Вы увидите, что я фильтрую, чтобы убедиться, что это ответы. Я должен также отметить, что это адрес источника, а не адрес назначения, и что код создает 172.0.0.0 для всех разобранных ARP-ответов. –

+0

Теперь, увидев правильный ответ, единственная часть этого полезного ответа - «Если вы считаете, что API сломан, распечатайте байты». – Joshua

Смежные вопросы