Как отправить пакет 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 ответ:
Нет. Когда вы используете пакетный сокет в режиме
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
.