Broadcast IPv6
От: dosik Россия www.dosik.ru
Дата: 20.09.15 05:57
Оценка:
Пока в академических целях решил попробовать. Чую не уйти мне от этого.
Компилим и запускаем следующий код:
    WSADATA wsaData{};
    WSAStartup(MAKEWORD(2, 2), &wsaData);

    SOCKET DHCPSock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
    if (DHCPSock == INVALID_SOCKET)
        return WSAGetLastError();

    sockaddr_in6 recvaddr{};
    recvaddr.sin6_family = AF_INET6;
    recvaddr.sin6_port = htons(547);
    recvaddr.sin6_addr = in6addr_any;
    int err = bind(DHCPSock, (const SOCKADDR*)&recvaddr, (int)sizeof(recvaddr));

    char recvbuf[1024]{};
    err = recv(DHCPSock, reinterpret_cast<char*>(&recvbuf), sizeof(recvbuf), 0);

Но не ловятся бродкасты и все тут.
Wireshark показывает, что движуха есть и пакетики на ff02::1:2 приходят.
Пробовал задавать адаптер в лоб:
    recvaddr.sin6_addr.u = {0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xf1, 0x24, 0x38, 0xb4, 0xaf, 0x17, 0x80};

Эффект тот же.
Что я делаю не так?
Re: Broadcast IPv6
От: VTT http://vtt.to
Дата: 20.09.15 07:09
Оценка: +3
Здравствуйте, dosik, Вы писали:

D>Что я делаю не так?


В IPv6 нет broadcast, есть только multicast. Чтобы их получать надо подписаться на соответствующую рассылку через setsockopt c IPV6_ADD_MEMBERSHIP.
B да, проверяйте коды ошибки, возвращаемые bind и прочими функциями. И винигрет с reinterpret_cast и c-style cast тоже не есть хорошо.
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.
Re[2]: Broadcast IPv6
От: dosik Россия www.dosik.ru
Дата: 20.09.15 12:50
Оценка:
Здравствуйте, VTT, Вы писали:

VTT>Здравствуйте, dosik, Вы писали:


D>>Что я делаю не так?


VTT>В IPv6 нет broadcast, есть только multicast. Чтобы их получать надо подписаться на соответствующую рассылку через setsockopt c IPV6_ADD_MEMBERSHIP.

Не хотит получать. Делаю вот так:
    WSADATA wsaData{};
    if (int wsaerr = WSAStartup(MAKEWORD(2, 2), &wsaData))
        return wsaerr;

    SOCKET DHCPSock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
    if (DHCPSock == INVALID_SOCKET)
        return WSAGetLastError();

    sockaddr_in6 recvaddr{};
    recvaddr.sin6_family = AF_INET6;
    recvaddr.sin6_port = htons(547);
    inet_pton(AF_INET6, "fe80::20f1:2438:b4af:1780", &recvaddr.sin6_addr);
    if (int err = bind(DHCPSock, reinterpret_cast<const sockaddr*>(&recvaddr), sizeof(recvaddr)))
        return WSAGetLastError();

    ipv6_mreq maddr{};
    inet_pton(AF_INET6, "ff02::1:2", &maddr.ipv6mr_multiaddr);
    if (int err = setsockopt(DHCPSock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, reinterpret_cast<char*>(&maddr), sizeof(maddr)))
        return WSAGetLastError();

    char recvbuf[1024]{};
    sockaddr_in6 srcaddr{};
    int fromlen = sizeof(srcaddr);
    recvfrom(DHCPSock, reinterpret_cast<char*>(&recvbuf), sizeof(recvbuf), 0, reinterpret_cast<sockaddr*>(&srcaddr), &fromlen);


Может что-то еще упустил?

VTT>B да, проверяйте коды ошибки, возвращаемые bind и прочими функциями. И винигрет с reinterpret_cast и c-style cast тоже не есть хорошо.

Нет ни чего более постоянного — чем временное, еще и выдранное из различных "углов"
Re[3]: Broadcast IPv6
От: VTT http://vtt.to
Дата: 20.09.15 13:26
Оценка:
Здравствуйте, dosik, Вы писали:

D>Может что-то еще упустил?


В ipv6_mreq есть еще второе поле которое надо инициализировать в ANY аддресс.
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.
Re[4]: Broadcast IPv6
От: dosik Россия www.dosik.ru
Дата: 20.09.15 17:00
Оценка:
Здравствуйте, VTT, Вы писали:

VTT>В ipv6_mreq есть еще второе поле которое надо инициализировать в ANY аддресс.

Оно и так нулевое.
ipv6_mreq maddr{};

Поля инициализируются значениями по умолчанию — нулями.
Потом я забиваю туда адрес.
Или ANY — это не ноль?
Re[5]: Broadcast IPv6
От: VTT http://vtt.to
Дата: 20.09.15 19:20
Оценка:
Здравствуйте, dosik, Вы писали:

Эм, это я малость ввел в заблуждение, там второе поле — индекс интерфейса и 0 — это интерфейс для мультикаста по-умолчанию.
Может у вас надо слушать не интерфейс по умолчанию?
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.
Re[6]: Broadcast IPv6
От: dosik Россия www.dosik.ru
Дата: 21.09.15 04:06
Оценка:
Здравствуйте, VTT, Вы писали:

VTT>Может у вас надо слушать не интерфейс по умолчанию?

Все верно. При чем MSDN рекомендует использовать GetAdaptersAddresses для получения индекса необходимого адаптера.
Пока не могу понять только одного: для всех без исключения адаптеров FirstUnicastAddress она возвращает "fe80::0", не смотря на то, что система назначила этому адаптеру адрес "fe80::20f1:2438:b4af:1780", и как их идентифицировать по IP пока не знаю.

По названию определил индекс, поставил в .ipv6mr_interface, пакетики побежали. Спасибо!
Re[7]: Broadcast IPv6
От: Mr.Delphist  
Дата: 11.12.15 14:53
Оценка:
Здравствуйте, dosik, Вы писали:

D>Пока не могу понять только одного: для всех без исключения адаптеров FirstUnicastAddress она возвращает "fe80::0", не смотря на то, что система назначила этому адаптеру адрес "fe80::20f1:2438:b4af:1780", и как их идентифицировать по IP пока не знаю.


Дело в том, что одному адаптеру может соответствовать несколько адресов, особенно в IPv6. Система просто вернула Вам первый их них (что и означает название FirstUnicastAddress), надо перебирать все, если ищете известный IP. Насколько помню, "fe80::0" — немаршрутизируемый локальный адрес сетевухи, по аналогии с 169.254.0.0/16

D>По названию определил индекс, поставил в .ipv6mr_interface, пакетики побежали. Спасибо!


Кстати, да — может потребоваться SetSockOption(IP_PROTO, IP_MULTICAST_IF) для выбранного адаптера, иначе ОС будет считать, что подписка на мультикаст уже есть другим адаптером, поэтому "нечего пакеты зазря всем раздавать" и будет кормить лишь дефолтного адаптера с наивысшей метрикой (а это может оказаться VPN, хе-хе).
http://windowsasusual.blogspot.ru/2013/01/socket-option-multicast-interface.html
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.