RAW Socket - Ethertype и алгоритм получения - C - PullRequest
3 голосов
/ 12 марта 2012

Я работаю с необработанным сокетом на языке Си.Мне нужно отправить и получить необработанный пакет Ethernet.Пакет должен начинаться с заголовка IEEE 802.3:

MAC DST [0-5] - MAC SRC [6-11] - ETH TYPE [12-13]

Поймав пакеты с wireshark, я вижу следующую структуру:

MAC DST [0-5] - MAC SRC [6-11] - LENGTH [12-13] - TRAILER [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));
    ...
}

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

Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 13 марта 2012

Я нашел ответ на мой первый вопрос: я использую Ethertype == 0x0001 вместо EtherType> = 0x0600

http://www.cavebear.com/archive/cavebear/Ethernet/type.html

А как насчет второго вопроса? Что не так с моим кодом?

0 голосов
/ 03 октября 2013

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

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

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

...