Если под «перехватом» вы имели в виду прослушивание пакетов, то, что вы должны сделать, чтобы сделать это с WinPcap, это:
Найдите устройство, которое вы хотите использовать - См. Учебник WinPcap .
Откройте устройство, используя pcap_open
// Open the device
char errorBuffer[PCAP_ERRBUF_SIZE];
pcap_t *pcapDescriptor = pcap_open(source, // name of the device
snapshotLength, // portion of the packet to capture
// 65536 guarantees that the whole packet will be captured on all the link layers
attributes, // 0 for no flags, 1 for promiscuous
readTimeout, // read timeout
NULL, // authentication on the remote machine
errorBuffer); // error buffer
Используйте функцию, которая читает пакеты из дескриптора, например pcap_loop
int result = pcap_loop(pcapDescriptor, count, functionPointer, NULL);
Это будет цикл до тех пор, пока что-то не произойдет, или цикл не будет прерван с помощью вызова специального метода. Он будет вызывать functionPointer для каждого пакета.
В указанной функции реализуется нечто, анализирующее пакеты, оно должно выглядеть как pcap_handler
:
typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
const u_char *);
Теперь все, что вам осталось, - это проанализировать пакеты, в которых их буфер находится в const u_char*
, а их длина - в поле pcap_pkthdr
структура caplen
.
Предполагая, что у вас есть HTTP GET через TCP через IPv4 через Ethernet пакеты, вы можете:
- Пропустить 14 байтов заголовка Ethernet.
- Пропустить 20 байтов заголовка IPv4 (при условии, что вариантов IPv4 нет, если вы подозреваете, что варианты IPv4 возможны, вы можете прочитать 5-8 битов заголовка IPv4, умножить их на 4, и это будет число байтов занимает заголовок IPv4).
- Пропустить 20 байтов заголовка TCP (при условии, что нет опций TCP, если вы подозреваете, что опции TCP возможны, вы можете прочитать 96-99 бит заголовка TCP, умножив это на 4, и это будет число байтов, которые берет заголовок TCP).
Остальная часть пакета должна быть текстом HTTP. Текст между первым и вторым пробелом должен быть URI. Если он слишком длинный, вам может потребоваться выполнить реконструкцию TCP, но большинство URI достаточно малы, чтобы поместиться в один пакет.
ОБНОВЛЕНИЕ : В коде это будет выглядеть так (я написал без проверки):
int tcp_len, url_length;
uchar *url, *end_url, *final_url, *tcp_payload;
... /* code in http://www.winpcap.org/docs/docs_40_2/html/group__wpcap__tut6.html */
/* retireve the position of the tcp header */
ip_len = (ih->ver_ihl & 0xf) * 4;
/* retireve the position of the tcp payload */
tcp_len = (((uchar*)ih)[ip_len + 12] >> 4) * 4;
tcpPayload = (uchar*)ih + ip_len + tcp_len;
/* start of url - skip "GET " */
url = tcpPayload + 4;
/* length of url - lookfor space */
end_url = strchr((char*)url, ' ');
url_length = end_url - url;
/* copy the url to a null terminated c string */
final_url = (uchar*)malloc(url_length + 1);
strncpy((char*)final_url, (char*)url, url_length);
final_url[url_length] = '\0';
Вы также можете фильтровать только HTTP-трафик, используя создание и настройку BPF. См. Учебник по WinPcap . Вам, вероятно, следует использовать фильтр "tcp and dst port 80"
, который будет выдавать только запрос, который ваш компьютер отправляет на сервер.
Если вы не возражаете против использования C #, вы можете попробовать использовать Pcap.Net , который сделает все это для вас гораздо проще, включая разбор частей пакетов Ethernet, IPv4 и TCP .