Без обид, но ответ об использовании bind() совершенно неверен. bind() будет управлять исходным IP-адресом, помещенным в IP-заголовок пакета. Он не контролирует, какой интерфейс будет использоваться для отправки пакета: будет проведена консультация с таблицей маршрутизации ядра, чтобы определить, какой интерфейс имеет наименьшую стоимость для достижения определенного пункта назначения. (*смотрите примечание)
Instead, you should use an SO_BINDTODEVICE
sockopt. This does two things:
- Пакеты всегда будут выходить из указанного вами интерфейса, независимо от того, что говорят таблицы маршрутизации ядра.
- В сокет будут передаваться только пакеты, поступающие на указанный интерфейс. Пакеты, поступающие на другие интерфейсы, не будут.
Если у вас есть несколько интерфейсов, между которыми вы хотите переключаться, я бы предложил создать по одному сокету для каждого интерфейса. Поскольку вы также будете получать пакеты только на интерфейс, к которому вы привязаны, вам нужно будет добавить все эти сокеты к вашему 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-адресом на «неправильном» пути могут быть отброшены.
person
DGentry
schedule
06.10.2008