LINUX.ORG.RU

Как получить все адреса?


0

0

Вопрос такой. Есть сервер. Надо получить адреса всех интерфейсов подрубленных к сети. экзэкать ifconfig а потом ловить и разгребать его вывод не подходит, так как пошловато выглядит. Может есть какая-нить функция?

★★★★

Так а что в них (в эти функции) передавать-то? Мне надо определить все ip-шники того сервера, на котором я запускаюсь. Символьного имени, типа www.server.com, он не имеет. :( А то все было бы проще.

Да и это вопрос добавочный. Мне потом надо будет сокет связать bind'ом с этим адресом, а затем вызывать connect() (НЕ listen()). Ну в общем, чтоб к какому-нить хосту конектится от определенного интерфейса. Какой порт мне надо будет передовать в bind в таком случае?

Dead ★★★★
() автор топика
Ответ на: комментарий от Die-Hard


Попробовал - ни хрена!
Только один интерфейс возвращают - правда, со всеми алиасами.

Die-Hard ★★★★★
()
Ответ на: комментарий от Dead

Dead (*) (2002-11-29 20:08:28.501):
> ...сокет связать bind'ом с этим адресом, а затем вызывать connect()
Не понял...
> ...к какому-нить хосту конектится от определенного интерфейса.
Ты IMHO чой-то путаешь.

connect() требует точного знания remote адреса: IPшник и порт.
Иначе, собственно, КУДА ты собрался коннектиться?

А bind() коннекту вообще не нужен, он его сам сделает.


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


Die-Hard (*) (2002-11-29 20:21:47.328):
>> ...сокет связать bind'ом с этим адресом, а затем вызывать connect()
>Не понял...
человек хочет сделать коннект с определенного адреса (source ip), правда насколько мне известно этот source_ip формируется исходя из маршрутизации, т.е. через какой интерфейс пройдет пакет на dest_ip.

>connect() требует точного знания remote адреса: IPшник и порт.
>Иначе, собственно, КУДА ты собрался коннектиться?

>А bind() коннекту вообще не нужен, он его сам сделает.
иногда нужен, если юзаешь UDP и хочешь принимать с того же сокета, который используется для connect()-а. удобно. иногда.

Гость

anonymous
()

во-первых: делаеть bind() на активном сокете следует в том случае если у тебя несколько сетевых интерфейсов и с более одного из них destination address достижим

во-вторых: если ты юзаешь UDP - то connect() такого сокета - это абсурд

2Dead - я так понимаю что у тебя следующая ситуация - есть сервер у которого два(или более) интерфейса в инет(или какую то другую сеть) и с обоих этих интефейсов виден dest addr(виден == достижим) и ты хочешь в зависимости от нагрузок на каждый из интефейсов использовать для коннекта менее загруженный? так? если так то придеться немного поразбираться с вещами разными если все серьезно, а если не очень то я бы сделал так .. берем соотношение ширин каналов - допустим 2/5 (1-й канал/2-й канал).. кидаем 7-ми гранный кубик - если выпадает 1 или 2 то используем 1-й канал иначе второй :)

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


во-первых: см. пункт о маршрутизации

во-вторых: connect() c UDP сокета можно использовать не только для того чтобы ввести лично в тебя в шок, но и для того чтобы использовать send() вместо sendto().

а дальше просто ТВ, первая лекция...


Гость.

anonymous
()

To Dead

2Dead:
Попробуй отпарсить вывод команды "cat /proc/net/route" или даже "route -n". Например:

[user /]# route -n
Kernel IP routing table
Destination Gateway  Genmask         Flags Metric Ref    Use Iface
10.0.0.1    0.0.0.0  255.255.255.255 UH    0      0        0 eth1
20.0.0.1    0.0.0.0  255.255.255.255 UH    0      0        0 eth0
10.0.0.0    0.0.0.0  255.255.255.0   U     0      0        0 eth1
20.0.0.0    0.0.0.0  255.255.255.0   U     0      0        0 eth0
127.0.0.0   0.0.0.0  255.0.0.0       U     0      0        0 lo
0.0.0.0     10.0.0.1 0.0.0.0         UG    0      0        0 eth1

строчки с Genmask 255.255.255.255 это нужные тебе адреса. Заодно узнаешь дефолт-интерфейс (0.0.0.0), поможет в случае если dest_addr не принадлежит локальным сетям.

Гость

anonymous
()

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: не знаю знаешь ли ты что значит слово "абсурд" но попробуй ответить на следующий
вопрос:
У моего холодильника есть функция подогрева продуктов но она не юзабельна
потомучто от этого продукты тухнут. Вопрос: является ли абсурдом то что у холодильники есть
такая функция?

PS: подумай хорошенько перед тем как отвечать

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


1. Пропиши нормальный роут для мультикаста
или заполни поле imr_interface структуры ip_mreq
или установи опцию IP_MULTICAST_IF на сокет (если ты сам отправляешь этот пакет).

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

P.S. <тот же>

Гость

anonymous
()

2lg

Ну допустим у нас есть интрефейсы. Так все таки можно биндом привязываться к интрефейсу и какой порт указывать в таком случае??? 0??? Или другой???

Dead ★★★★
() автор топика

Ребята! ну ведь есть в телнете опция -b

ну вот надо сделать что-то похожее

Dead ★★★★
() автор топика

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 ★★
()
Ответ на: комментарий от Dead

Никаких проблем:

s=socket(...)
bind(s,...) // какие нужны sourse ip, port
connect(s, //  какие нужны destination ip, port

Могу прислать кусок кода (пример коннекта к 80 порту, проверял как-то ipchains).

anonymous
()

hey Dead: -b как в телнете сделать? какие проблемы?
...
  u_int32_t baddr;
  struct sockaddr_in sa;
...
   while ((ch = getopt(ac, av, "b:")) != -1)
      switch (ch) {
        case 'b':
           baddr = inet_addr(optind);
           break;
...
 bzero(&sa, sizeof(sa));
 ...
 sa.sin_addr.s_addr = baddr;
 ...
 connect(fd, (struct sockaddr*)&sa, ..);
      

lg ★★
()

Ну в принципе это я и сделал. :) Значит порт нулевой должен быть. Спасибо.

Dead ★★★★
() автор топика

Еще раз большое спасибо всем отвечавшим!

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


in reply...:
На счет сорс роутинга в твоем посте вроде ясно написано, а вот с обычным - приведи вывод команды route. _Посмотрим_.

И еще, что для тебя изменит мой ответ? Это имеет какое-то отношение к использованию/не использованию bind()?

Гость.

P.S. На счет примера из telnet-а, там точно все в порядке? Вызов connect() приведет к бинду на указанный в параметре -b адресу?

anonymous
()

1) мой route table:
[lg@lg:p1][~/prog/lisp]$ netstat -rn
Routing tables

Internet:
Destination Gateway Flags Refs Use Netif Expire
10/24 tun0 USc 0 0 tun0 =>
10.1/24 tun1 USc 0 0 tun1 =>
192.168.1/24 fxp0 USc 2 0 fxp0 =>
192.168.2/24 fxp1 USc 0 0 fxp1 =>

[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 протокол для передачи данных поэтому
ты по идеи должен ответить на вопрос про яму.

2PS: извиняюсь - забыл перед connect() написать err = bind(fd, (struct sockadr*)&sa, sizeof(sa)); ...

lg ★★
()

Я протестирую все и сюда напишу обязательно.

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


1. На твоей машине - не знаю. На моей, вне зависимости от соурс-роутов этот пакет уйдет на def_gw через def_iface.

2. Чесслово не понял. Давай еще раз и по-русски:
На счет необходимости делать bind() и connect() на UDP-сокет: необходимость ненулевая.

На счет того что изменит мой ответ - имелось ввиду мое первое сообщение, я написал что src_addr выбирается в соответствии с маршрутизацией. _Выбирается_. Т.е. когда не биндишь, а просто делаешь sendto(). С bind-ом вроде разобрались - работает.

P.S. Если внимательно этот код прочтешь, то увидишь что еще кое-что забыл... впрочем я уже придираюсь. Хотя кусок кода забавный даже с твоим дополнением.

anonymous
()

хехе .. как известно 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) реализации сокетов?

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


>>насчет UDP - зачем ты хочешь делать bind() - затем что тебе
>>короче(удобнее) писать send() вместо sendto(определяя dst_add)
bind() определяет src_addr, а не dst. скорее ты хотел написать connect(), хотя как знать.

>>смысл сводится к тому что использовать UDP в _реальных_ целях
>>целесообразно только как нессущий протокол для единовременных
>>сообщений .. но зачем тебе тогда использоать bind() который
>>схавает лишнее время
учту твое мнение здесь, и, забегая вперед верну твой же совет
абстрагироваться. Ростов-Москва не ед. путь и Инет это не вся
сеть.

From Гость: Могу, правда тебя первого бы не устроил абстрактный ответ на счет правил обзора "рутинг таблиц". Лично я не уверен что он (такой ответ) вообще существует.

Гость.

anonymous
()

да - вместо bind() я конечно же хотел написать connect() - сами понимаете - пятница, жена в больнице, один дома, жрать нечего, пива дохрена - вобщем реально ошибся

связь Таганрог-Ростов-Москва гораздо лучще чем допустин Осло-Москва-Ульяновск или Москва-Екатеринбург-Омск - вобщем Российсий инет не в кольце достаточно стрёмная вещь для UDP.

рутинг супер вещь - я даже видел(жена писала) реализацию управления рутингом нейросетью с web мордой.

lg ★★
()

Ок. Мне пора. WBR, Гость.

anonymous
()

Ребята. У мне не UDP, а обычный TCP Просто надо коннектится от определенного интерфейса И ВСЕ Зачем это надо? Задача просто очень специфическая.

Dead ★★★★
() автор топика

2lg :"хехе .. как известно source routing забавная вещь - поразному везде реализированная .. не обязательно что source routing приминияется перед статическим(прописанным) роутингом или правилами динамического роутинга .. может даже такое происходить что у тебя сначала проходят правила source_addr/port routing ..сокет биндиться на какой то адрес и после него проходит packet len routing(или мало ли еще чего) и адрес перебиндивается на другой .. здесь наварачивать можно до безпредела."

Ты прав!!!! На практике так и оказалось. На некоторых серверах пашет, на некоторых нет. Действительно забавная штука получается.

Dead ★★★★
() автор топика

собственно как получить все интерфейсы
man ioctl
но так как толкового описания ioctl нигде нету
то можно подробнее смотреть в dhcpd
там прямо коментарий в исходнике
вот тут мы получаем все интерфейсы сервера.

Aleks_IZA
()

по моему это не портабельно - хотя под FreeBSD и Linux должно прокатить ..

lg ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.