Перехват / перенаправление пакетов TCP SYN в программу C++ в Linux

Я пытаюсь найти самый простой способ перехвата пакетов TCP SYN, отправленных моим компьютером, в программе на C++. Я знаю несколько вариантов. Можно было бы отслеживать весь трафик и просто выборочно работать с пакетами SYN, ничего не делая с остальными. Другой вариант, с которым я столкнулся, заключался в использовании утилиты фильтрации пакетов, которая будет пересылать SYN-пакеты в мою программу. Кто-то предложил мне использовать для этого же netfilter .

Мне было интересно, есть ли другие варианты или мне стоит копаться в netfilter. Кроме того, были бы полезны любые указания о том, как это сделать с помощью netfilter.

РЕДАКТИРОВАТЬ: я хочу перехватить SYN-пакет и, возможно, потребуется его изменить (перенаправить в другое место назначения, изменить порт назначения и т. Д.), Прежде чем повторно вводить его обратно в сеть.

Изменить: я смог сделать это, используя комбинацию iptables и libnetfilter_queue. Я использовал ipfilter для перенаправления всех пакетов TCP SYN в определенную очередь (это была простая команда).
Затем в программе на C я смог использовать API libnetfilter_queue для доступа к пакетам в очереди, проанализировать их и повторно отправить обратно в сеть.

Ответов (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++.