2012-03-12 2 views
3

Я работаю с сырым сокетом на языке C. Мне нужно отправить и получить необработанный пакет ethernet. пакет должен начинаться с заголовка IEEE 802.3:RAW Socket - алгоритм Ethertype и получения - C

MAC DST [0-5] - MAC-SRC [6-11] - ETH, ТИП [12-13]

Ловля пакетов с WIRESHARK I см следующую структуру:

MAC-DST [0-5] - MAC-SRC [6-11] - ДЛИНА [12-13] - ТРЕЙЛЕР [14-58] -....

Это мой код:

... 
sraw = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_802_3)); 
... 
retVal = setsockopt(sraw, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)); 
... 
val = 3; 
retVal = setsockopt(sraw, SOL_SOCKET, SO_PRIORITY, &val, sizeof (val)); 
... 
memcpy(ptr_eth_header->DstMac, dst_mac, 6); 
memcpy(ptr_eth_header->SrcMac, src_mac, 6); 
ptr_eth_header->Type = htons(ETH_P_802_3); 
memcpy(buffer + ETHHDR_SIZE, data, 60); 
... 
sockaddr.sll_family = htons(PF_PACKET); 
sockaddr.sll_protocol = htons(ETH_P_802_3); 
sockaddr.sll_ifindex = ifr.ifr_ifru.ifru_ivalue; 
sockaddr.sll_halen = 6; 
memcpy(&(sockaddr.sll_addr), dst_mac, 6); 
... 
bytes = sendto(sraw, buffer, sizeof(buffer), 0, (struct sockaddr *) &(sockaddr), sizeof (struct sockaddr_ll)); 

Это просто проблема «проводов»? Есть идеи?

Моя вторая проблема заключается в получении необработанных сообщений. Процесс застревает на recvfrom.

Это мой код:

sraw = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_802_3)); 
... 
retVal = setsockopt(sraw, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)); 
... 
val = 3; 
retVal = setsockopt(sraw, SOL_SOCKET, SO_PRIORITY, &val, sizeof (val)); 
... 
val = CLIENT_PACKET_SIZE; 
retVal = setsockopt(sraw, SOL_SOCKET, SO_RCVBUF, &val, sizeof (val)); 

sockaddr.sll_family = htons(PF_PACKET); 
sockaddr.sll_ifindex = ifr.ifr_ifindex; 
sockaddr.sll_protocol = htons(ETH_P_802_3); 

buffer = malloc(CLIENT_PACKET_SIZE * sizeof(char)); 
while (count < PACKET_COUNT) { 
    bytes = recvfrom(sraw, buffer, CLIENT_PACKET_SIZE, 0, (struct sockaddr *)&sockaddr, (socklen_t*)sizeof(sockaddr)); 
    ... 
} 

Не могли бы вы мне помочь?

Заранее благодарен!

+0

Является ли ваша структура заголовка упакованной? Что такое 'sizeof (buffer)'? –

+1

Да, это так. 'typedef struct { char DstMac [6]; char SrcMac [6]; short int Тип; } HEADER; ' ' sizeof (buffer) 'is is 64. – Simone

+0

Вы можете проверить, что пакет отправлен/принят сетевым адаптером, используя Wireshark независимо от вашей программы? – Ioan

ответ

0

Ответ на одно слово для вашего вопроса сложно. Но если вы спросите меня, почему recvfrom может застрять, с вашим кодом, я бы сказал, что вы не можете получать какой-либо пакет, удовлетворяющий вашему фильтру. Вы уверены, что передаете значение ifindex в ожидаемом формате? Я вижу, что вы передаете ifindex sockaddr.sll_ifindex = ifr.ifr_ifru.ifru_ivalue; как это в sendto.

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

Кроме того, для вашего сценария я бы предложил использовать неблокирующий сокет вместо блокировки. Вызовите recvfrom только тогда, когда вы знаете, что есть пакеты, ожидающие чтения.