Ответ 1
Не указано преступление, но ответ об использовании bind() совершенно неверен. bind() будет управлять исходным IP-адресом, помещенным в заголовок IP-пакета. Он не контролирует, какой интерфейс будет использоваться для отправки пакета. Будет проконсультирована таблица маршрутизации ядра, чтобы определить, какой интерфейс имеет самую низкую стоимость для достижения определенного адресата. (* см. примечание)
Вместо этого вы должны использовать sockopt SO_BINDTODEVICE
. Это делает две вещи:
- Пакеты всегда будут выводиться из указанного вами интерфейса, независимо от того, что говорят таблицы маршрутизации ядра.
- Только пакеты, поступающие на указанный интерфейс, будут переданы в сокет. Пакеты, поступающие на другие интерфейсы, не будут.
Если у вас есть несколько интерфейсов, которые вы хотите переключить, я бы предложил создать один сокет для каждого интерфейса. Поскольку вы также будете получать пакеты только к интерфейсу, к которому вы привязались, вам нужно будет добавить все эти сокеты в ваш select()
/poll()
/все, что вы используете.
#include <net/if.h>
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, "eth1", sizeof(ifr.ifr_name));
if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE,
(void *)&ifr, sizeof(ifr)) < 0) {
perror("SO_BINDTODEVICE failed");
}
(* примечание)
Bind()
к IP-адресу интерфейса может привести к запутанному, но, тем не менее, правильному поведению. Например, если вы Bind()
на IP-адрес eth1, но таблица маршрутизации отправляет пакет eth0, тогда пакет появится на проводнике eth0, но будет иметь IP-адрес источника интерфейса eth1. Это странно, но разрешено, хотя пакеты, отправленные обратно на IP-адрес eth1, будут перенаправлены на eth1. Вы можете протестировать это с помощью Linux-системы с двумя iP-интерфейсами. У меня есть один, и я проверил его, а Bind()
неэффективно управляет пакетом из физического интерфейса.
Хотя технически разрешено, в зависимости от топологии это тем не менее не работает. Чтобы ослабить распределенные атаки на отказ в обслуживании, когда злоумышленники используют поддельные IP-адреса, многие маршрутизаторы теперь выполняют проверки обратного пути (RPF). Пакеты с исходным IP-адресом на "неправильном" пути могут быть удалены.