Модераторы: xvr
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Принудительная отправка пакета, Как принудительно отправить пакет? 
V
    Опции темы
konshyn
Дата 13.2.2014, 11:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 295
Регистрация: 19.9.2013

Репутация: нет
Всего: нет



Привет!
Есть несколько интерфейсов. Хотя лушче на пальцах объясню.
Есть 1 сетевая карта, ее имя eth0;
На этой сетевой карте 3 vlan'a - eth0.102, eth0.103, eth0.104. У них ip-адреса: 192.168.2.11, 192.168.3.11, 192.168.4.11 соответственно. Шлюз у каждого свой: 192.168.2.1, 192.168.3.1, 192.168.4.1 соответственно
На коммутаторе стоит транковый порт, который видит эти 3 vlan'a + еще один - интернетовский.
по любому из этих vlan'oв можно выйти во внешнюю сеть (интернет), т.е. неважно куда будет default'ный маршрут: на 192.168.2.1, 192.168.3.1 или 192.168.4.1. Отправляться пакеты будут с соответствующего интерфейса eth0.102, eth0.103, eth0.104 - смотря, какой шлюз прописан.

Теперь вопрос: я хочу программным путем выбирать, с какого интерфейса отправить (очень желательно через socket(PF_INET,  SOCK_DGRAM, 0)) пакет. Через интерфейс, который прописан в default'ном маршруте, отправляется без проблем, а через любой другой wireshark ловит arp-запросы, но ответы не приходят и просто не хочет отправлять эти пакеты.

Что я для этого делаю:
Код

char name[] = "eth0.103";
sd = socket(PF_INET, SOCK_DGRAM,  0);
setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, name, strlen(name);
// дальше заполняю структуру struct sockaddr_in и отправляю пакет
sendto(...)


Как можно заставить систему отправлять с определнного интерфеса пакеты, независимо от того, знает он адресата или нет? Желательно программно. Не прописывая явно шлюзы.


--------------------
«Потому что ценность акта действия в этой стране возрастает в несколько раз».
PM MAIL Skype   Вверх
tzirechnoy
Дата 13.2.2014, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1173
Регистрация: 30.1.2009

Репутация: 3
Всего: 16



Цитата
Как можно заставить систему отправлять с определнного интерфеса пакеты, независимо от того, знает он адресата или нет?


А куда Вы собрались отправлять эти пакеты если адресат неизвестен?
PM MAIL   Вверх
konshyn
Дата 13.2.2014, 15:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 295
Регистрация: 19.9.2013

Репутация: нет
Всего: нет



Цитата(tzirechnoy @  13.2.2014,  15:00 Найти цитируемый пост)
А куда Вы собрались отправлять эти пакеты если адресат неизвестен?

Адресат известен. Linux'у просто не известен шлюз (он есть, но не хочется, чтобы о нем знали). Хочется, чтобы пакет просто вылетел из сетевой карты.

Что получается. У меня есть пакет. Я в структуре задаю адрес получателя, семейство и порт. Отправляю. Ядру нужно добавить заголовки. IP/UDP легко добавить на основе той информации, что я предоставил. Чтобы коммутатор не отбросил этот пакет, нужно в eth-заголовке в поле dest-addr подставить mac коммутатора. Для этого ядро отправляет arp-запрос, мол кто знает такого-то с таким-то IP (который я указал для функции sendto). Все это работает до момента с arp-запросом. Запрос отправляется с этого интерфеса, а ответ не приходит. Вообще не приходит, ни на какой интерфейс. 
Пингануть адрес с этого интерфейса тоже не получается. 

И как бы должно работать, но не работает. А в какую сторону смотреть не знаю. То ли реализовать это нужно по-другому, то ли схема, которую описал в первом сообщении, не такая. То ли вообще нельзя такое сделать, покрайне мере с udp-сокетом.

Это сообщение отредактировал(а) konshyn - 13.2.2014, 15:41


--------------------
«Потому что ценность акта действия в этой стране возрастает в несколько раз».
PM MAIL Skype   Вверх
feodorv
Дата 13.2.2014, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 1
Всего: 45



Цитата(konshyn @  13.2.2014,  12:47 Найти цитируемый пост)
setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, name, strlen(name);

Если я правильно понял проблему, нужен простой bind() на сокет с номером порта 0 и IP адресом желаемого интерфейса.


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
konshyn
Дата 13.2.2014, 18:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 295
Регистрация: 19.9.2013

Репутация: нет
Всего: нет



Цитата(feodorv @  13.2.2014,  16:30 Найти цитируемый пост)
Если я правильно понял проблему, нужен простой bind() на сокет с номером порта 0 и IP адресом желаемого интерфейса. 

А в чем разница для linux'a в данном случае? Сегодня уже нет возможности проверить.


--------------------
«Потому что ценность акта действия в этой стране возрастает в несколько раз».
PM MAIL Skype   Вверх
tzirechnoy
Дата 14.2.2014, 19:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1173
Регистрация: 30.1.2009

Репутация: 3
Всего: 16



Цитата
На коммутаторе стоит транковый порт, который видит эти 3 vlan'a + еще один - интернетовский.


Вероятно, на L3 коммутаторе, который, по сути, ужэ работает роутером.

Цитата
Теперь вопрос: я хочу программным путем выбирать, с какого интерфейса отправить (очень желательно через socket(PF_INET,  SOCK_DGRAM, 0)) пакет. 


Вообще, это делается через bind() и задание адреса.
И source-based routing -- админом хоста.

Код
ip route add table 15000 default via 192.168.4.1
ip rule add from 192.168.4.11 lookup 15000



Цитата
Все это работает до момента с arp-запросом. Запрос отправляется с этого интерфеса, а ответ не приходит.


Если ответ не приходит от роутера -- то и смотреть надо конфиг роутера.

Ну, или забить на arp и воспользоваться статикой. Впрочем, это вряд ли поможэт, учитывая, что роутер не считает арп своим -- так что и src адрес вряд ли сочтёт. Хотя можэт и сочтёт, но мне в любом случае лень выпытывать из Вас, какие ещё  тривиальные ошыбки Вы допустили.

В общем, не занимайтесь фигнёй, SO_BINDTODEVICE -- это очень частная отладочная опцыя, по-моему локально-линуксовая, совсем не универсальная и работающая только от рута.
PM MAIL   Вверх
konshyn
  Дата 18.2.2014, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 295
Регистрация: 19.9.2013

Репутация: нет
Всего: нет



Цитата(feodorv @  13.2.2014,  16:30 Найти цитируемый пост)
Если я правильно понял проблему, нужен простой bind() на сокет с номером порта 0 и IP адресом желаемого интерфейса. 


Цитата(tzirechnoy @  14.2.2014,  19:07 Найти цитируемый пост)

Вообще, это делается через bind() и задание адреса.
И source-based routing -- админом хоста.


Да, вы правы.


Цитата(tzirechnoy @  14.2.2014,  19:07 Найти цитируемый пост)
Если ответ не приходит от роутера -- то и смотреть надо конфиг роутера.

Ну, или забить на arp и воспользоваться статикой. Впрочем, это вряд ли поможэт, учитывая, что роутер не считает арп своим -- так что и src адрес вряд ли сочтёт. Хотя можэт и сочтёт, но мне в любом случае лень выпытывать из Вас, какие ещё  тривиальные ошыбки Вы допустили.

В общем, не занимайтесь фигнёй, SO_BINDTODEVICE -- это очень частная отладочная опцыя, по-моему локально-линуксовая, совсем не универсальная и работающая только от рута. 

Проблема была именно в SO_BINDTODEVICE. Грубо говоря, приязывалось к физическому устройству, а на логические (ВЛАНы) не выдавала ошибку, но почему-то не отправлялось.
bind() выручил, и там неважно уже, пакетные сокеты, или обычные датаграммные.

но все намного проще делается через libpcap и libnet (особенно последние версии, там все есть, что нужно. для меня smile). не понимаю, чего так долго откладывал его изучение..

tzirechnoy, feodorv, Спасибо за объяснения

Это сообщение отредактировал(а) konshyn - 18.2.2014, 16:11


--------------------
«Потому что ценность акта действия в этой стране возрастает в несколько раз».
PM MAIL Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Программирование под Unix/Linux"
xvr
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой "Код".
  • Вопросы мобильной разработки тут
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr.

 
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема »


 




[ Время генерации скрипта: 0.0703 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.