Как определить, какой сетевой интерфейс (ip-адрес) будет использоваться для отправки пакета на определенный IP-адрес?

Я пишу стек SIP, и мне нужно вставить ip-адрес в сообщение. Этот адрес должен использоваться для отправки сообщения. Я знаю IP-адрес назначения и мне нужно определить сетевой адаптер (его адрес), который будет использоваться для отправки сообщения....


person rusbi    schedule 12.03.2010    source источник
comment
Какая ОС? Если вы подключены к нескольким сетевым адаптерам и не используете транспорт, такой как TCP/IP или UDP, которые поддерживают привязку к конкретным сетевым адаптерам перед отправкой данных, то нет надежного способа определить, какой именно сетевой адаптер будет использоваться, поскольку может использоваться более одного. быть подходящим в зависимости от маршрутов DNS и тому подобного. В Windows XP и более поздних версиях вы можете использовать GetBestInterfaceEx(), чтобы угадать, какая сетевая карта, скорее всего, будет использоваться.   -  person Remy Lebeau    schedule 13.03.2010
comment
этот ответ stackoverflow.com/a/29500867/121961 решает эту проблему для нескольких платформ   -  person Vargas    schedule 08.04.2015


Ответы (4)


Чтобы немного расширить комментарий Реми Лебо, GetBestInterfaceEx( ) — ваш лучший выбор, если вы используете Windows XP или новее. Это будет работать как для адресов IPv4, так и для IPv6.

GetBestInterface/GetBestInterfaceEx возвращает индекс (назовем его IDX) наиболее подходящего интерфейса для использования для связи с некоторым адресом.

Затем вы можете сопоставить этот индекс с локальным IP-адресом, получив сопоставление вашего интерфейса ‹-> IP-адреса с помощью GetIpAddrTable или GetAdaptersAddresses, если вы используете двойной стек (поддерживает как IPv6, так и IPv4).

Переберите эту таблицу и найдите интерфейс с dwIndex (или IfIndex, в случае GetAdaptersAddresses), соответствующим IDX.

person Frank Shearar    schedule 21.06.2010
comment
Если вам нужно, чтобы ваш код также работал в Linux, вы можете использовать мой ответ здесь: stackoverflow.com/questions/14398099 - person Vargas; 08.04.2016

Обычно лучше разрешить IP-адрес, с которым будет работать стек SIP, в качестве настраиваемой опции конфигурации. Это означает, что пользователю нужно будет установить параметр конфигурации, но, по крайней мере, ваш стек будет знать IP-адрес, на котором он работает.

Если это невозможно, вы можете использовать подход, заключающийся в отправке SIP-запроса на все IP-адреса с использованием фиктивного значения в заголовке Via, например 0.0.0.0, и установить интерфейс, на который вы получаете ответ, как интерфейс по умолчанию. Преимущество этого подхода также в том, что ответ SIP сообщит вам общедоступный IP-адрес, с которого был получен запрос, что может быть полезно, если ваш стек SIP находится за NAT.

person sipsorcery    schedule 13.03.2010
comment
Это все в порядке, и я использую вариант конфигурации для IP, но я хочу, чтобы стек работал, когда у меня есть два сетевых адаптера, подключенных к двум подсетям... Стек должен использовать определенный адрес в зависимости от подсети назначения.... - person rusbi; 14.03.2010
comment
Похоже, ваш вопрос больше похож на то, есть ли способ заставить ОС сообщить вам, какой IP-адрес она отправит с IP-адреса назначения abcd. Я бы порекомендовал задать это в отдельном вопросе, но, насколько я знаю, ответ - Windows и Linux не предоставляют для этого вызова, кроме анализа вывода команд route и ifconfig и выполнения сопоставления подсети sime неуклюже. - person sipsorcery; 14.03.2010

По TCP, я думаю, вы можете получить адрес локальной стороны сокета после connect(). Я не знаю, верно ли то же самое для UDP (подозреваю, что нет), но, возможно, стоит попробовать.

person tc.    schedule 21.06.2010

Сокет позволит вам выполнить привязку к локальной конечной точке перед вызовом соединения (как UDP, так и TCP).

Все в порядке, если вы знаете порт. Однако, если вы хотите, чтобы порт был эфемерным (например, какой-то случайный номер порта), вы должны придумать свой собственный алгоритм для этого и надежный код для обработки случаев, когда порт используется исключительно другим приложением.

person jnielsen    schedule 21.09.2010