Я пишу стек SIP, и мне нужно вставить ip-адрес в сообщение. Этот адрес должен использоваться для отправки сообщения. Я знаю IP-адрес назначения и мне нужно определить сетевой адаптер (его адрес), который будет использоваться для отправки сообщения....
Как определить, какой сетевой интерфейс (ip-адрес) будет использоваться для отправки пакета на определенный IP-адрес?
Ответы (4)
Чтобы немного расширить комментарий Реми Лебо, GetBestInterfaceEx( ) — ваш лучший выбор, если вы используете Windows XP или новее. Это будет работать как для адресов IPv4, так и для IPv6.
GetBestInterface/GetBestInterfaceEx возвращает индекс (назовем его IDX) наиболее подходящего интерфейса для использования для связи с некоторым адресом.
Затем вы можете сопоставить этот индекс с локальным IP-адресом, получив сопоставление вашего интерфейса ‹-> IP-адреса с помощью GetIpAddrTable или GetAdaptersAddresses, если вы используете двойной стек (поддерживает как IPv6, так и IPv4).
Переберите эту таблицу и найдите интерфейс с dwIndex (или IfIndex, в случае GetAdaptersAddresses), соответствующим IDX.
Обычно лучше разрешить IP-адрес, с которым будет работать стек SIP, в качестве настраиваемой опции конфигурации. Это означает, что пользователю нужно будет установить параметр конфигурации, но, по крайней мере, ваш стек будет знать IP-адрес, на котором он работает.
Если это невозможно, вы можете использовать подход, заключающийся в отправке SIP-запроса на все IP-адреса с использованием фиктивного значения в заголовке Via, например 0.0.0.0, и установить интерфейс, на который вы получаете ответ, как интерфейс по умолчанию. Преимущество этого подхода также в том, что ответ SIP сообщит вам общедоступный IP-адрес, с которого был получен запрос, что может быть полезно, если ваш стек SIP находится за NAT.
По TCP, я думаю, вы можете получить адрес локальной стороны сокета после connect(). Я не знаю, верно ли то же самое для UDP (подозреваю, что нет), но, возможно, стоит попробовать.
Сокет позволит вам выполнить привязку к локальной конечной точке перед вызовом соединения (как UDP, так и TCP).
Все в порядке, если вы знаете порт. Однако, если вы хотите, чтобы порт был эфемерным (например, какой-то случайный номер порта), вы должны придумать свой собственный алгоритм для этого и надежный код для обработки случаев, когда порт используется исключительно другим приложением.