Вопрос такой. Есть сервер. Надо получить адреса всех интерфейсов подрубленных к сети. экзэкать ifconfig а потом ловить и разгребать его вывод не подходит, так как пошловато выглядит. Может есть какая-нить функция?
Так а что в них (в эти функции) передавать-то? Мне надо определить все ip-шники того сервера, на котором я запускаюсь. Символьного имени, типа www.server.com, он не имеет. :( А то все было бы проще.
Да и это вопрос добавочный. Мне потом надо будет сокет связать bind'ом с этим адресом, а затем вызывать connect() (НЕ listen()). Ну в общем, чтоб к какому-нить хосту конектится от определенного интерфейса. Какой порт мне надо будет передовать в bind в таком случае?
Dead (*) (2002-11-29 20:08:28.501):
> ...сокет связать bind'ом с этим адресом, а затем вызывать connect()
Не понял...
> ...к какому-нить хосту конектится от определенного интерфейса.
Ты IMHO чой-то путаешь.
connect() требует точного знания remote адреса: IPшник и порт.
Иначе, собственно, КУДА ты собрался коннектиться?
А bind() коннекту вообще не нужен, он его сам сделает.
Die-Hard (*) (2002-11-29 20:21:47.328):
>> ...сокет связать bind'ом с этим адресом, а затем вызывать connect()
>Не понял...
человек хочет сделать коннект с определенного адреса (source ip), правда насколько мне известно этот source_ip формируется исходя из маршрутизации, т.е. через какой интерфейс пройдет пакет на dest_ip.
>connect() требует точного знания remote адреса: IPшник и порт.
>Иначе, собственно, КУДА ты собрался коннектиться?
>А bind() коннекту вообще не нужен, он его сам сделает.
иногда нужен, если юзаешь UDP и хочешь принимать с того же сокета, который используется для connect()-а. удобно. иногда.
во-первых: делаеть bind() на активном сокете следует в том случае если у тебя несколько сетевых интерфейсов и с более одного из них destination address достижим
во-вторых: если ты юзаешь UDP - то connect() такого сокета - это абсурд
2Dead - я так понимаю что у тебя следующая ситуация - есть сервер у которого два(или более) интерфейса в инет(или какую то другую сеть) и с обоих этих интефейсов виден dest addr(виден == достижим) и ты хочешь в зависимости от нагрузок на каждый из интефейсов использовать для коннекта менее загруженный? так? если так то придеться немного поразбираться с вещами разными если все серьезно, а если не очень то я бы сделал так .. берем соотношение ширин каналов - допустим 2/5 (1-й канал/2-й канал).. кидаем 7-ми гранный кубик - если выпадает 1 или 2 то используем 1-й канал иначе второй :)
во-вторых: connect() c UDP сокета можно использовать не только для того чтобы ввести лично в тебя в шок, но и для того чтобы использовать send() вместо sendto().
2Гость:
про маршрутизацию .. ответь на такой вопрос:
есть два интерфейса: i1, i2 у i1 IP-адрес 10.0.0.1/24 у i2 - 10.1.0.1/24
на машине следующая таблица маршрутизации:
default 0
if src_addr == 10.0.0.1 gtw = 10.0.0.33 (source routing)
if src_addr == 10.1.0.1 gtw = 10.1.0.33 (source routing)
if dst_net == 10/24 gtw = i1
if dst_net == 10.1/24 gtw = i2
как ты думаешь с какого интефейса пойдет пакет на dst_addr == 224.0.0.1 ?
про UDP: не знаю знаешь ли ты что значит слово "абсурд" но попробуй ответить на следующий
вопрос:
У моего холодильника есть функция подогрева продуктов но она не юзабельна
потомучто от этого продукты тухнут. Вопрос: является ли абсурдом то что у холодильники есть
такая функция?
1. Пропиши нормальный роут для мультикаста
или заполни поле imr_interface структуры ip_mreq
или установи опцию IP_MULTICAST_IF на сокет (если ты сам отправляешь этот пакет).
2. По этому вопросу я уже высказался ранее, добавить мне нечего.
in reply to Гость:
1) не понял про что ты говоришь, но я знаю откуда ты это взял :). ну ладно - если тебя смущает 224.0.0.1 - возмем 223.0.0.1 - вопрос остается открытым - с какого интефейса?
2) ладно - Зачем ты используешь UDP - для передачи данных? для передачи единновременных сообщений?
попробуй еще один вопрос древних времен - какой глубины надо вырыть яму чтобы в ней поместилсь палка длиной 6 метров?
2Dead:
вообще общепринятое соглашение порты
0-1024 - привилегированные - то есть их испльзуют процессы от root
1024-4|5XXX - общего пользования
... - для особых служб (типа nat, int proxying)
если _ты сделаешь_ bind() с подачей 0 в sin_port то "скорее всего" тебе присвоят
один из свободных портов из диапазона 1024-4|5XXX(возможно иначе если ты root) или если все порты заняты - ошибку (типа address already in use)
[lg@lg:p1][~/prog/lisp]$ root ipfw show
00100 168934 1349094 fwd 10.0.0.33 ip from 10.0.0.1 to not 10/24
00200 43908 908992 fwd 10.1.0.33 ip from 10.1.0.1 to not 10.1/24
...
65535 3377 1317430 allow ip from any to any
2) конечно изменит - ты я думаю изпользуешь UDP протокол для передачи данных поэтому
ты по идеи должен ответить на вопрос про яму.
1. На твоей машине - не знаю. На моей, вне зависимости от соурс-роутов этот пакет уйдет на def_gw через def_iface.
2. Чесслово не понял. Давай еще раз и по-русски:
На счет необходимости делать bind() и connect() на UDP-сокет: необходимость ненулевая.
На счет того что изменит мой ответ - имелось ввиду мое первое сообщение, я написал что src_addr выбирается в соответствии с маршрутизацией. _Выбирается_. Т.е. когда не биндишь, а просто делаешь sendto(). С bind-ом вроде разобрались - работает.
P.S. Если внимательно этот код прочтешь, то увидишь что еще кое-что забыл... впрочем я уже придираюсь. Хотя кусок кода забавный даже с твоим дополнением.
хехе .. как известно source routing забавная вещь - поразному везде реализированная .. не обязательно что source routing приминияется перед статическим(прописанным) роутингом или правилами динамического роутинга .. может даже такое происходить что у тебя сначала проходят правила source_addr/port routing ..сокет биндиться на какой то адрес и после него проходит packet len routing(или мало ли еще чего) и адрес перебиндивается на другой .. здесь наварачивать можно до безпредела.
насчет UDP - зачем ты хочешь делать bind() - затем что тебе короче(удобнее) писать send() вместо sendto(определяя dst_add) - почему тееб это удобнее - скорее всего потомучто ты делаешь много таких send() вызовов и не хочешь тратить время заполняя какие-то структуры (типа ОС это сделает быстрее), но почему тебе надо делать много вызовов send() наверное ты решил передать какие то данные другой стороне - например статистику по покупкам в Таганрогских интернет-магазинах - как известно из Таганрога нет прямого канал в Москву и передача данных Москва-Таганрог происходит через каналы Таганрог-Ростов-Москва - по статистике канала Ростов-Москва 13% пакетов теряется .. поэтому передача данных по UDP от Таганрога до Москвы будет надежным лишь на 90% то есть это означает что ты можешь где-то проколосться в статистике для финансвых планирователей .. возможно что это может прокатить в некоторых случаях, но в большинстве грамотный финансовый планорователь всю вину свалит на некорректную передачу данных ..
смысл сводится к тому что использовать UDP в _реальных_ целях целесообразно только как нессущий протокол для единовременных сообщений .. но зачем тебе тогда использоать bind() который схавает лишнее время
2Гость: ты вообще можешь абстрагироваться от своей машины? у людей другие ОС - другие реализации TCP/IP стеков .. другие правила обзора рутинг таблиц - другие(не BSD) реализации сокетов?
>>насчет UDP - зачем ты хочешь делать bind() - затем что тебе
>>короче(удобнее) писать send() вместо sendto(определяя dst_add)
bind() определяет src_addr, а не dst. скорее ты хотел написать connect(), хотя как знать.
>>смысл сводится к тому что использовать UDP в _реальных_ целях
>>целесообразно только как нессущий протокол для единовременных
>>сообщений .. но зачем тебе тогда использоать bind() который
>>схавает лишнее время
учту твое мнение здесь, и, забегая вперед верну твой же совет
абстрагироваться. Ростов-Москва не ед. путь и Инет это не вся
сеть.
From Гость: Могу, правда тебя первого бы не устроил абстрактный ответ на счет правил обзора "рутинг таблиц". Лично я не уверен что он (такой ответ) вообще существует.
да - вместо bind() я конечно же хотел написать connect() - сами понимаете - пятница, жена в больнице, один дома, жрать нечего, пива дохрена - вобщем реально ошибся
связь Таганрог-Ростов-Москва гораздо лучще чем допустин Осло-Москва-Ульяновск или Москва-Екатеринбург-Омск - вобщем Российсий инет не в кольце достаточно стрёмная вещь для UDP.
рутинг супер вещь - я даже видел(жена писала) реализацию управления рутингом нейросетью с web мордой.
2lg :"хехе .. как известно source routing забавная вещь - поразному везде реализированная .. не обязательно что source routing приминияется перед статическим(прописанным) роутингом или правилами динамического роутинга .. может даже такое происходить что у тебя сначала проходят правила source_addr/port routing ..сокет биндиться на какой то адрес и после него проходит packet len routing(или мало ли еще чего) и адрес перебиндивается на другой .. здесь наварачивать можно до безпредела."
Ты прав!!!! На практике так и оказалось. На некоторых серверах пашет, на некоторых нет. Действительно забавная штука получается.
собственно как получить все интерфейсы
man ioctl
но так как толкового описания ioctl нигде нету
то можно подробнее смотреть в dhcpd
там прямо коментарий в исходнике
вот тут мы получаем все интерфейсы сервера.