Используйте libpcap
, pcap_inject () , в частности.
Вы не можете использовать socket()
, также используя IPPROTO_RAW
, потому что L2 (eth) и L3 (ip) также будут подделаны стеком IP ОС в этом случае.
Вам необходимо внедрить пакет прямо в сетевую карту. Если вы хотите, чтобы он был доставлен на IP-адрес, отличный от исходного, вам необходимо «отредактировать» содержимое пакета.
Пример вставлен отсюда: http://www.microhowto.info/howto/send_an_arbitrary_ethernet_frame_using_libpcap.html
char pcap_errbuf[PCAP_ERRBUF_SIZE];
pcap_errbuf[0]='\0';
pcap_t* pcap=pcap_open_live(if_name,65536,0,0,pcap_errbuf);
if (pcap_errbuf[0]!='\0') {
fprintf(stderr,"%s",pcap_errbuf);
}
if (!pcap) {
exit(1);
}
if (pcap_inject(pcap, <PACKET_DATA> , <PACKET_SIZE> )==-1) {
pcap_perror(pcap,0);
pcap_close(pcap);
exit(1);
}
pcap_close(pcap)
Если вы не хотите редактировать IP-адрес, пакет сможет достичь другого конца провода, только если у вас нет коммутаторов / маршрутизаторов между двумя узлами.
В качестве альтернативы ОП предлагает использовать туннель. Это на самом деле работает (я проверял это с tcpreplay
) - вы можете использовать туннель GRE, который на самом деле может также транспортировать Ethernet-трафик.
На двух узлах вы можете установить туннель gretap . Я использовал эти команды:
на хосте A (его IP-адрес 192.168.1.211):
ip link add gretap1 type gretap local 192.168.1.211 remote 192.168.1.64
ip link set gretap1 up
на хосте B (его IP-адрес 192.168.1.64):
ip link add gretap1 type gretap local 192.168.1.64 remote 192.168.1.211
ip link set gretap1 up
На этом этапе можно использовать туннель L2 GRE и позволить ему транспортировать ETH-трафик с использованием интерфейсов gretap1. На одном узле я ввел трафик в туннель с помощью команды:
tcpreplay -i gretap1 test.pcap
и другой узел подтвердил, что трафик был передан, перехватив его через интерфейс gretap1 с помощью wireshark или tcpdump.
К сожалению, есть проблема с этой настройкой: MTU туннеля меньше, чем MTU сети, поэтому не гарантируется, что вы можете воспроизвести все пакеты.