аргумент sendto для сокета типа PF_PACKET - PullRequest
0 голосов
/ 11 октября 2018

У меня есть требование использовать 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?

...