Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #96, ДЕКАБРЬ 2006 г.

Создаем продвинутый боевой софт!

Иван Скляров

Хакер, номер #096, стр. 096-080-3


}

Здесь открывается интерфейс, имя которого указано в dev, и говорится, сколько байт пакета захватывать (значение BUFSIZ определено в pcap.h). Сетевой интерфейс переключается в неразборчивый режим. Также отмечается, что данные будут читаться до тех пор, пока не произойдет ошибка.

Создание фильтра

Для включения фильтра в программу существуют две основные функции: pcap_compile() и pcap_setfilter(). Выражение для фильтра хранится в обыкновенной строке (массиве символов). Синтаксис таких выражений полностью соответствует тому синтаксису, который используется утилитой tcpdump. Перед тем как применить фильтр, его нужно «скомпилировать». Это делает функция pcap_compile(). Ее прототип выглядит следующим образом:

int pcap_compile(pcap_t *p, struct bpf_program *fp, char *str, int optimize, bpf_u_int32 netmask)

Первый аргумент — это дескриптор открытой сессии. Второй аргумент — указатель на область в памяти, где будет храниться «скомпилированная» версия нашего фильтра. Далее идет само выражение фильтра в виде обычной строки. Следующий параметр определяет, нужно ли оптимизировать наше выражение (0 — нет, 1 — да). Последний параметр — маска сети, к которой применяется наш фильтр. Функция возвращает –1 в случае ошибки, все другие значения говорят об успешном завершении.

После того как выражение «скомпилировано», его нужно применить, что осуществляется с помощью функции pcap_setfilter(). Ее прототип выглядит так:

int pcap_setfilter(pcap_t *p, struct bpf_program *fp)

Первый аргумент — это дескриптор открытой сессии, второй - указатель на «скомпилированную» версию выражения для фильтра (как правило, второй аргумент функции pcap_compile()).

Демонстрационный фрагмент кода

#include <pcap.h>

...

pcap_t *handle; /* дескриптор сессии */

char dev[] = "eth0"; /* сетевой интерфейс, на котором будем слушать */

char errbuf[PCAP_ERRBUF_SIZE]; /* буфер под описание ошибки */

struct bpf_program filter; /* скомпилированное выражение для фильтра */

сhar filter_app[] = "udp dst port 53"; /* выражение для фильтра */

bpf_u_int32 mask; /* сетевая маска нашего интерфейса */

bpf_u_int32 net; /* IP-адрес нашего интерфейса */

pcap_lookupnet(dev, &net, &mask, errbuf);

if (dev == NULL) {

fprintf(stderr, "%s", errbuf);

exit(-1);

}

handle = pcap_open_live(dev, BUFSIZ, 1, 0, errbuf);

if (handle == NULL) {

fprintf(stderr, "%s", errbuf);

exit(-1);

}

if (pcap_compile(handle, &filter, filter_app, 0, mask) == -1) {

fprintf(stderr, "%s", pcap_geterr(handle));

exit(-1);

}

if (pcap_setfilter(handle, &filter) == -1) {

fprintf(stderr, "%s", pcap_geterr(handle));

exit (-1);

}

Эта программа подготавливает перехватчик UDP-пакетов, идущих на 53-й порт.

Пример содержит две функции, которые мы еще не рассматривали: pcap_lookupnet() и pcap_geterr().

Первая функция необходима для определения маски сети, которую затем нужно подставить в последний параметр функции pcap_compile(). Прототип функции:

int pcap_lookupnet(const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp, char *errbuf)

Хотя нам требуется только маска сети, но для полноты картины мы также определяем IP-адрес.

Назад на стр. 096-080-2  Содержание  Вперед на стр. 096-080-4