2014-01-12 2 views
1

Я пишу программу на C, которая читает пакеты с использованием libpcap, а затем выводит информацию, такую ​​как адреса назначения и источника. Я новичок в сетевом программировании, поэтому я не могу понять выходное несоответствие, которое я получаю. Я всегда получаю правильный MAC-адрес назначения, но неверный адрес источника.Получение исходного MAC-адреса от ether_addr

Вот что ожидаемый результат должен быть:

Packet номер: 1 Packet Len: 42 Dest MAC: FF: FF: FF: FF: FF: FF MAC: 0: 2 : 2d: 90: 75: 89

Вот мой результат:

Packet Len: 42 Dest MAC: FF: FF: FF: FF: FF: FF MAC: 0: 0: c0: a8: 1: 1

Я знаю, что в сети Ethernet заголовка адрес источника непосредственно следует адрес получателя, поэтому я создал свою собственную-структуру, чтобы отразить это:

typedef struct __attribute__((__packed__)) EtherHeader { 
    const struct ether_addr destAddr[6]; 
    const struct ether_addr sourceAddr[6]; 
    uint8_t protocol; 
}EtherHeader; 

Вот отрывок из моего кода, который пытается получить адрес:

char *fileName = argv[1]; 
char errbuf[100]; 
const struct EtherHeader *eth; 

pcap_t *handle = pcap_open_offline(fileName, errbuf); 
struct pcap_pkthdr pktHdr = calloc(1, sizeof(struct pcap_pkthdr)); 
const u_char *nextPkt = pcap_next(handle, pktHdr); 
int packNum = 0; 

nextPkt = pcap_next(handle, pktHdr); 
printf("Packet number: %d Packet Len: %d\n", packNum, pktHdr->len); 
eth = (EtherHeader *)nextPkt; 
printf("Dest MAC: %s\n", ether_ntoa(eth->destAddr)); 
printf("Source MAC: %s\n", ether_ntoa(eth->sourceAddr)); 

Мне также необходимо определить, какой протокол содержит пакет. Как я могу добраться до сегмента пакета, который имеет это? Остальные два байта в заголовке?

Любые дополнительные вещи, за которые я должен следить, были бы весьма полезны.

+0

Обратите внимание, что на Linux 'структура ether_header' уже определена в'/usr/include/net/ethernet.h': 'struct ether_header { u_int8_t ether_dhost [ETH_ALEN];/* destination eth addr */ u_int8_t ether_shost [ETH_ALEN];/* source ether addr */ u_int16_t ether_type;/* поле идентификатора пакета */ } __attribute__ ((__packed __)); ' – Pierz

ответ

3

struct ether_addr уже определена как структура, содержащая 6 байт, так что вы должны заменить

const struct ether_addr destAddr[6]; 
const struct ether_addr sourceAddr[6]; 

по

const struct ether_addr destAddr; 
const struct ether_addr sourceAddr; 

Обратите внимание, что вам нужен адрес-оператора & при печати EtherNet адреса :

printf("Dest MAC: %s\n", ether_ntoa(&eth->destAddr)); 
printf("Source MAC: %s\n", ether_ntoa(&eth->sourceAddr)); 

(Что произошло в вашем случае, адрес получателя, что положить в destAddr[0], источника адрес в destAddr[1] и протокол в первые байты destAddr[2].)

+0

Спасибо, это сработало. В другом вопросе, для заголовков IP и TCP, как бы я изолировал только часть контрольной суммы? Первоначально я думал об использовании побитовых операций, но потом понял, что это будет означать смещение маски более чем на 32 бита, что, похоже, не разрешено в C. – PacSan

+0

@ user2259530: я не знаю, поэтому я бы предположил, что вы начинаете новый вопрос. - Если этот ответ решил вашу проблему, пожалуйста, подумайте о том, чтобы «принять» его, нажав на галочку. –

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