Создаем продвинутый боевой софт! Иван Скляров Хакер, номер #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-адрес. |