Аргумент sendto для сокета типа PF_PACKET

У меня есть требование использовать Berkeley Packet Filters в моей программе, для чего я узнал, что должен использовать сокет типа PF_PACKET. Я могу получать пакеты через мой фильтр, как и ожидалось. Я нахожусь в затруднительном положении, когда дело доходит до заполнения адреса сокета для отправки пакетов.

Я создал сокет следующим образом:

my_fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
....
memset(&socket_address, 0, sizeof (socket_address));
socket_address.sll_family = PF_PACKET;
socket_address.sll_ifindex = if_nametoindex("eth0");
socket_address.sll_protocol = htons(ETH_P_IP);

bind(ptr_simsw->gre_fd_pkt, (struct sockaddr *)&socket_address, sizeof(socket_address);
...
if (setsockopt (my_fd,  SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) < 0)
...

Я выбрал SOCK_DGRAM вместо SOCK_RAW, потому что моему приложению не требуется контроль над L2 в такой степени, я не хотел создавать заголовок Ethernet в программе, потому что IP-адрес назначения неоднократно меняется. Вот моя процедура отправки:

struct sockaddr_ll socket_address;
memset(&socket_address, 0, sizeof (socket_address));
socket_address.sll_family = PF_PACKET;
socket_address.sll_ifindex = if_nametoindex("eth0");
socket_address.sll_protocol = htons(ETH_P_IP);

if ((rval = sendto(my_fd, pkt_buf, IP_TOT_LEN, 0, (struct sockaddr *)&socket_address, sizeof(socket_address))) < 0) 
...

Проблема, которая возникает при этом, заключается в том, что адрес назначения в заголовках Ethernet остается 0, я думаю, потому что я не указал его в socket_address. Как правильно отправлять пакеты через сокет типа PF_PACKET без предоставления Ethernet dest? Насколько я понимаю, SOCK_DGRAM - путь для этого. Есть ли опция сокета и т. Д., С помощью которой ядро ​​может заполнить MAC?

0 ответов

Другие вопросы по тегам