LINUX.ORG.RU

c socket broadcast в чем подвох?

 , ,


0

4

Здравствуйте, коллеги!

Есть код: https://github.com/pyang30/linux-udp-broadcast-example/blob/master/b_client.c

Компилится. Посылает…

Но только если IP получен!

Если IP не получен, то sendto возвращает -1.

Как сделать, что бы broadcast посылался вне зависимости получил данный компьютер ip или нет?

Т.е. как опычный dhcp client


HighMan

пнятненько

Anoxemian ★★★★★
()

Как сделать, что бы broadcast посылался вне зависимости получил данный компьютер ip или нет?

По-нормальному - никак. В пакете есть адрес откуда и адрес куда. Если по ненормальному, то это ручная генерация пакета и отправка его в сетевую карту на удачу. Будет работать до первого роутера, в одноранговой сети.

Т.е. как опычный dhcp client

DHCP клиент сначала прослушивает интерфейс на входящий броадкаст подсети, в которую посылает пакеты с настройкой DHCP сервер.

alex0x08 ★★★
()
Ответ на: комментарий от alex0x08

Прослушивание от отправки отличаешь?

Сначала dhcp client посылает broadcast на 255.255.255.255 поpt 67.

Если сетевое оборудование не зарубит broadcast, то его должны получить ВСЕ устройства локальной сети.

Дальше DHCP сервер… Точно не помню, но вроде, посылает так же broadcast в ответ, помещая в тело пакета mac клиента.

HighMan
() автор топика
Последнее исправление: HighMan (всего исправлений: 1)
Ответ на: комментарий от Anoxemian

man OSI, man socket, TCP/IP, UDP/IP, ARP, RAW. Все вкурить и будет щастье.

Думаешь, ты кажешься умным?

Разумеется, лучший ответ на любой вопрос: rtfm!

HighMan
() автор топика
Ответ на: комментарий от HighMan

По-английски читаешь?

I just had to face the same question myself, and after some research, I found the following on the RFC 2131, which describes the DHCP protocol, under section 1.6 Design Goals:

DHCP must provide service to existing BOOTP clients Also on the RFC 951, which describe the BOOTP protocol, we can find the following:

The UDP header contains source and destination port numbers. The BOOTP protocol uses two reserved port numbers, ‘BOOTP client’ (68) and ‘BOOTP server’ (67).

https://stackoverflow.com/questions/1790960/why-dhcp-client-listens-on-port-68

alex0x08 ★★★
()
Ответ на: комментарий от alex0x08

Да тут все более-менее ясно.

Я понять не могу, почему не посылается broadcast когда машина не получила IP?

HighMan
() автор топика
Ответ на: комментарий от HighMan

Посмотри вот этот и этот код:

 /* create socket for DHCP communications */
    dhcp_socket = create_dhcp_socket();

    /* get hardware address of client machine */
    get_hardware_address(dhcp_socket, network_interface_name);

    /* send DHCPDISCOVER packet */
    send_dhcp_discover(dhcp_socket);

    /* wait for a DHCPOFFER packet */
    get_dhcp_offer(dhcp_socket);

Видимо там и будет ответ на твой вопрос.

Кстати вот тут есть прикольный вариант на Bash как отправлять dhcp-discover, надо взять на вооружение.

alex0x08 ★★★
()
Ответ на: комментарий от HighMan

Нет ни одного интерфейса с флагами BROADCAST и UP? Что показывает ip link ls?

По идее 255.255.255.255 это линк-локал адрес, надо биндить сокет к интерфейсу с помощью SO_BINDTODEVICE. Когда есть несколько broadcast up интерфейсов то выбирается один случайным образом.

iliyap ★★★★★
()
Ответ на: комментарий от HighMan

В данном случае сокет нужно явно биндить к интерфейсу.

Если нет адреса, то посылать с флагом MSG_DONTROUTE

Да и ttl желательно установить в 1.

vel ★★★★★
()
Ответ на: комментарий от vel

через raw-сокет можно изображать новые протоколы на транспортном уровне (L4), а система уже автоматически оборачивает в IP (сетевой - L3):

Raw sockets allow new IPv4 protocols to be implemented in user space. A raw socket receives or sends the raw datagram not including link level headers.

или я что-то не понял?

ac130kz ★★
()
Ответ на: комментарий от ac130kz

понел ошибку, Baeldung как всегда четко пояснил. Тогда получается ОП просто не поменял код под SOCK_RAW, чтоб писать чисто L3 или L2.

ac130kz ★★
()
Ответ на: комментарий от vel

В данном случае сокет нужно явно биндить к интерфейсу.

Эврика!

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

Сегодня прибиндил:

setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &i, sizeof(int));
setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device) + 1);

Заработало! Остался лишь один момент: после перезагрузки компа интерфейсы находятся в DOWN. Попытки послать броадкаст через такой интерфейс, естественно, приводят к неудаче. Сначала нужно апнуть интерфейс.

Осталось разобраться как его програмно апнуть)

HighMan
() автор топика
Последнее исправление: HighMan (всего исправлений: 1)
Ответ на: комментарий от HighMan

Ещё можно через bpf слать и принимать, мне казалось dhcp-клиенты так и делают (заодно получают обход любых файрволлов, а вот с биндом как выше не уверен что обойдёт).

Осталось разобраться как его програмно апнуть)

ifconfig eth0 up или смотри в strace какие сисколлы он делает.

firkax ★★★★★
()
Ответ на: комментарий от HighMan

Поднять его просто ioctl SIOCSIFFLAGS IFF_UP

vel ★★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.