Отправить сырой arp ответный пакет в windows - PullRequest
0 голосов
/ 06 ноября 2019

В настоящее время я учусь использовать необработанные сокеты Windows.

Я создал необработанный кадр ответа arp (включает все заголовки (ethernet + arp заголовки)), и когда я отправляю его с помощью функции sendto, онзавершается с ошибкой и возвращает SOCKET_ERROR с кодом ошибки 10047.

Параметры, которые я использовал для создания сокета, были следующими:

socket s = socket(AF_INET,SOCK_RAW,IPPROTO_RAW);

, а также я изменил параметры сокета следующим образом:

int on=1;
setsockopt(s,IPPROTO_IP, 2,(char*)&on,sizeof(on));

(Кстати, '2' равно IP_HDRINCL, почему-то Visual Studio его не распознала ..)

Я пытаюсь отправить пакет следующим образом:

socketaddr sa = { 0 };
int SentBytesCount = sendto(s, (char*)&arp_raw_msg,sizeof(Arp_Frame),0,&sa,sizeof(sa));

Где Arp_Frame - это структура, которая включает заголовок ethernet + заголовок arp + 18 байт для заполнения.

После этого вызова я получаю, что SentBytesCount равно SOCKET_ERROR (-1), и пакет не являетсяотправлено.

Спасибо за помощь!

1 Ответ

0 голосов
/ 06 ноября 2019

Ошибка Winsock 10047: WSAEAFNOSUPPORT:

Семейство адресов не поддерживается семейством протоколов.

Использовался адрес, несовместимый с запрошенным протоколом. Все сокеты создаются со связанным семейством адресов (то есть AF_INET для интернет-протоколов) и общим типом протокола (то есть SOCK_STREAM). Эта ошибка возвращается, если в вызове socket явно запрашивается неверный протокол, или , если для сокета используется адрес неправильного семейства, например, в sendto.

Вы создали сокет AF_INET (IPv4), но не передаете sendto() действительный sockaddr_in, содержащий адрес и порт IPv4, отсюда и ошибка. Вместо этого вы передаете ему пустой socketaddr (что это?).

Любая структура sockaddr_..., которую вы используете с сокетом, должна соответствовать ожидаемому семейству адресов сокета, как установлено вызовом socket()(в вашем случае AF_INET, который использует sockaddr_in адреса).

sockaddr_in sa;
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = inet_addr("destination IP address");
sa.sin_port = htons(Destination port number);

int SentBytesCount = sendto(s, (char*)&arp_raw_msg, sizeof(Arp_Frame), 0, (struct sockaddr*)&sa, sizeof(sa));

Что касается IP_HDRINCL, то оно определено в ws2tcpip.h.

...