Как отправить пакет SOCK DGRAM с помощью пакета mmap, не беспокоясь о MAC-адресе?


Я хочу отправлять пакеты с помощью packet_mmap для получения высокой скорости передачи пакетов. Мне удалось отправить пакеты с помощью пакетного сокета в raw-режиме, для чего я создал L2, L3 и т. д. в буфере и отправил его с помощью

sendto(fd_socket, NULL, 0, 0, NULL, sizeof(struct sockaddr_ll));

Однако я не хочу беспокоиться о MAC-адресе назначения. Поэтому вместо этого я стал использовать Dgram. Если я хочу использовать sendto, есть аргумент для MAC-адреса назначения. Даже если это не то, что я хотел бы с точки зрения отсутствия беспокойства с помощью кэша arp и указанием MAC-адреса получателя:

sendto(fd_socket, NULL, 0, 0, (struct sockaddr *) ps_sockaddr, sizeof(struct sockaddr_ll));

Однако я обнаружил, что send также разрешено использовать с пакетным сокетом. http://man7.org/linux/man-pages/man7/packet.7.html Поэтому я заполнил буфер заголовком ip и так далее. В этом случае send возвращает ноль, так как ничего не найдено для отправки, что я ожидаю быть чем-то отличным от нуля, если есть ошибка с передачей пакета.

Есть ли способ использовать packet_mmap, не будучи обеспокоенным о Л2-адрес?

1 2

1 ответ:

Нет. Когда вы используете пакетный сокет в режиме SOCK_DGRAM, вам не нужно создавать заголовок L2, но вы все равно должны предоставить адрес L2, и тогда система построит заголовок для вас. (Таким образом, это будет иметь преимущество фактического построения L2-части пакета для вас, и вам не нужно будет указывать исходный MAC-адрес, но вам все равно нужно указать интерфейс, из которого вы хотите отправить пакет, и целевой MAC-адрес.)

Как система узнает, куда посылать пакет в противном случае? Я полагаю, что вы надеялись , что система посмотрит на IP-заголовок, который вы уже построили в буфере пакетов, а затем сделает выбор интерфейса и поиск ARP от вашего имени, но с помощью пакетного сокета вы обходите эту часть сетевого стека. (Кроме того, если IP-адрес не находится в локальной сети, потребуется этап маршрутизации-обычно просто найти шлюз по умолчанию и выполнить ARPing для его MAC-адреса.)

Теперь ты может получить большую часть того, что (я думаю) вы хотите с помощью сокета raw (http://man7.org/linux/man-pages/man7/raw.7.html в этом случае вы говорите ядру, что используете IP, но не полагаетесь на него для любого из более высоких уровней (> L3). И вы также можете построить свой собственный IP-заголовок в этом случае и иметь решение о маршрутизации, основанное на нем, используя опцию IP_HDRINCL.