Используя Linux, как указать, на котором передаются данные интерфейса Ethernet

NullPointerException s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException. Они наиболее распространены, но другие способы перечислены на странице NullPointerException javadoc.

Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException, be:

public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}

В первой строке внутри main я явно устанавливаю ссылку Object obj равной null. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.

(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)

14
задан Skynet 26 January 2015 в 14:26
поделиться

1 ответ

Никакое предназначенное преступление, но ответ об использовании не связывает (), является довольно неправильным. свяжите (), будет управлять исходным IP-адресом, помещенным в пакетном заголовке IP. Это не управляет, какой интерфейс будет использоваться для отправки пакета: с таблицей маршрутизации ядра будут консультироваться для определения, какой интерфейс имеет самую низкую цену для достижения конкретного места назначения. (*see примечание)

Вместо этого необходимо использовать SO_BINDTODEVICE sockopt. Это делает две вещи:

  • Пакеты всегда будут выход от интерфейса, который Вы определили, независимо от того, что таблицы маршрутизации ядра говорит.
  • Только пакеты, прибывающие в указанный интерфейс, будут вручены сокету. Пакеты, прибывающие в другие интерфейсы, не будут.

, Если бы у Вас есть несколько интерфейсов, Вы хотите переключиться между, я предложил бы создать один сокет на интерфейс. Поскольку Вы также только получите пакеты к интерфейсу, с которым Вы связали, необходимо будет добавить все эти сокеты к Вашему 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");
}

(*note) Bind() к интерфейсному IP-адресу может привести к запутывающему, но тем не менее исправить поведение. Например, bind() к IP-адресу для eth1, но таблице маршрутизации при отсылке пакета eth0 тогда пакет появится на проводе eth0, но переносе исходного IP-адреса интерфейса eth1. Это странно, но позволяется, хотя пакеты, переданные обратно eth1 IP-адресу, были бы направлены назад к eth1. Можно протестировать это использование системы Linux с двумя IP интерфейсами. Я имею один и действительно тестировал его, и bind() не является эффективным при регулировании пакета физический интерфейс.

, Хотя технически позволено, в зависимости от топологии это не может, тем не менее, работать. Для расхолаживания распределенных атак "отказ в обслуживании", где взломщики используют подделанные адреса источника IP много маршрутизаторов теперь выполняют проверки Обратной передачи пути (RPF). Пакеты с исходным IP-адресом на "неправильном" пути могут быть отброшены.

18
ответ дан 1 December 2019 в 13:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: