Перехват / перенаправление пакетов TCP SYN в программу C++ в Linux
Я пытаюсь найти самый простой способ перехвата пакетов TCP SYN, отправленных моим компьютером, в программе на C++. Я знаю несколько вариантов. Можно было бы отслеживать весь трафик и просто выборочно работать с пакетами SYN, ничего не делая с остальными. Другой вариант, с которым я столкнулся, заключался в использовании утилиты фильтрации пакетов, которая будет пересылать SYN-пакеты в мою программу. Кто-то предложил мне использовать для этого же netfilter .
Мне было интересно, есть ли другие варианты или мне стоит копаться в netfilter. Кроме того, были бы полезны любые указания о том, как это сделать с помощью netfilter.
РЕДАКТИРОВАТЬ: я хочу перехватить SYN-пакет и, возможно, потребуется его изменить (перенаправить в другое место назначения, изменить порт назначения и т. Д.), Прежде чем повторно вводить его обратно в сеть.
Изменить: я смог сделать это, используя комбинацию iptables и libnetfilter_queue. Я использовал ipfilter для перенаправления всех пакетов TCP SYN в определенную очередь (это была простая команда).
Затем в программе на C я смог использовать API libnetfilter_queue для доступа к пакетам в очереди, проанализировать их и повторно отправить обратно в сеть.
Ответов (2)2
Если вы просто хотите видеть пакеты, используйте libpcap
фильтрацию пакетов - это будет работать практически с любым вариантом UNIX.
Если вы хотите каким-то образом перехватить и переписать пакеты, предоставьте дополнительную информацию о том, что вы пытаетесь сделать, и что должно произойти с пакетами впоследствии.
Как вы предполагаете, это может быть приложение для netfilter и его модуля очереди , хотя для этого требуется ядро 2.6.14 или новее:
Основные особенности
- получение пакетов в очереди от подсистемы ядра nfnetlink_queue
- вынесение вердиктов и / или повторное внедрение измененных пакетов в подсистему ядра nfnetlink_queue
Вы можете использовать сырые сокеты или, например, библиотеку pcap. С помощью pcap вы настраиваете фильтр и захватываете интересный трафик:
#include <pcap.h>
...
pcap_t* reader_handle;
char errbuf[PCAP_ERRBUF_SIZE];
if ( (reader_handle = pcap_open_live(device_string, capture_size, 0, timeout, errbuf) ) == NULL)
{
//ooops
}
struct bpf_program fp;
if (pcap_compile(reader_handle, &fp, filter_string, 1, 0) == -1)
{
//ooops, cleanup
}
if (pcap_setfilter(reader_handle, &fp) == -1)
{
//ooops, cleanup
}
pcap_freecode(&fp);
А потом просто захватываешь, есть несколько разных способов, например:
pcap_pkthdr* header;
u_char* pkt_data;
const int status = pcap_next_ex(reader_handle, &header, &pkt_data);
// Check the status
После окончания захвата:
pcap_close(reader_handle);
Вам нужны привилегии, чтобы играть с необработанными сокетами. Приведенный выше пример можно красиво обернуть на C++.