>>Не могу понять где искать lipq? или что это за проблема вообще???
>
>Проблема простая -- вы говорите программе слинковаться с библиотекой ipq (-lipq), но
>этой библиотеки нет в системе.
>
>>iptables установлен. libipq.h тожэ присутствует.
>
>Вы не указали дистрибутив. Смею предположить что вам нужен пакет libipq-devel Он
>у вас установлен? Скорее всего нет. Также можно посмотреть содержимое пакета,
>в котором содержится файл libipq.h -- возможно эта библиотека в нём,
>но расположена в нестандартном месте. В таком случае нужно указать этот
>каталог после ключа -L, если мне не изменяет память.
>
>>вот лог компиляции прграммы:
>>[root@z ~]# gcc dupkill.c -o dupkill -L -I -lipq
>>dupkill.c: In function 'die':
>>dupkill.c:30: warning: incompatible implicit declaration of built-in function 'exit'
>>/usr/bin/ld: cannot find -lipq
>>collect2: ld returned 1 exit status
>>make: *** [dupkill] Ошибка 1
>>[root@z ipt_dupkill]#
>
>Добавьте #include <stdlib.h> чтобы убрать warning. Также можно убрать ключи -L и -I -- в вашем случае, насколько понимаю, они бесполезны. (поправьте меня, если не прав)Я добавил #include <stdlib.h> предупреждение убралось, но вот как бороться с остальным???
тперь осталось(текст выводимый при компиляции):
gcc dupkill.c -o dupkill -L -I -lipq
/usr/bin/ld: cannot find -lipq
collect2: ld returned 1 exit status
make: *** [dupkill] Ошибка 1
[root@z ipt_dupkill]#
Приведу для более полной инфы исходник программы:
/*
* This code is GPL.
*/
#include <linux/netfilter.h>
#include <libipq/libipq.h>
#include <stdio.h>
#include <stdlib.h>
//Определяем размер буффера для чтения пакета
#define BUFSIZE 2048
//Интервал, в течение которого пакеты с одинкаовым crc признаются дублирующими
//(к нему прибавим еще макс. 1 секунду, так как мы меряем с точностью до секунды)
#define DROPTIME 1
//Размер таблицы 65536 - так как crc у нас 16 бит
//элемент таблицы - время прихода пакета в секундах
unsigned long timetable[0x10000];
//прототип ф-ции
unsigned short crc16(unsigned char *buf, int len);
//вспомогательная ф-ция для печати сообщения и освобождения ресурсов при ошибке
static void die(struct ipq_handle *h,char* msg)
{
//печать ошибки
ipq_perror(msg);
//освобождаем дескриптор выданный нам libipq
ipq_destroy_handle(h);
//выходим с кодом ошибки
exit(1);
}
int main(int argc, char **argv)
{
int status;
unsigned char buf[BUFSIZE];
struct ipq_handle *h;
unsigned short crc;
unsigned long time;
//инициализируем библиотеку libipq, она нам возвращает дескриптор для работы с ней
h = ipq_create_handle(0, PF_INET);
//завершаемся с ошибкой в случае неудачи инициализации
if (!h)
die(h,"ipq_create_handle");
//устанавливаем режим взаимодействия с библиотекой, запрашивая передачу полного
//пакета вместе с его содержимым, размером до BUFSIZE
status = ipq_set_mode(h, IPQ_COPY_PACKET, BUFSIZE);
if (status < 0)
die(h,"ipq_set_mode");
//начинаем цикл обработки
do{
//ждем сообщения из очереди ip_queue, читаем его в буфер
status = ipq_read(h, buf, BUFSIZE, 0);
if (status < 0)
die(h,"ipq_read");
//используем ф-цию ipq_message_type для определения типа пришедшего сообщения
//(определено 2 типа: ошибка или приход пакета
switch (ipq_message_type(buf)) {
case NLMSG_ERROR:
//при ошибке просто печатаем описывающий ее текст (получая его из соотв. ф-ции)
fprintf(stderr, "Received error message %d\n",
ipq_get_msgerr(buf));
break;
case IPQM_PACKET: {
//если к нам пришел пакет, получаем указатель на структуру, описывающую пакет
//и содержащую его данные
ipq_packet_msg_t *m = ipq_get_packet(buf);
//высчитываем контрольную сумму crc16 от содержимого пакета
crc = crc16(m->payload,m->data_len);
//в переменную time берем последнее время, в которое прошел пакет с таким crc
time = timetable[crc];
//пакеты, идущие от локального компьютера, имеют штамп времени 0, и мы их игнорируем
if(0 == m->timestamp_sec) {
//разрешить локальные пакеты:
status = ipq_set_verdict(h, m->packet_id,
NF_ACCEPT, 0, NULL);
}
//если время прохождения последнего пакета с данным crc отличается от времени прихода
//текущего пакета не более, чем на DROPTIME, признаем этот пакет дублированным.
else if( time >= m->timestamp_sec-DROPTIME ) {
//и ставим вердикт: отбросить пакет.
status = ipq_set_verdict(h, m->packet_id,
NF_DROP, 0, NULL);
}
else {
//если пакет не является дублированным,обновляем время прихода последнего пакета с данным crc.
timetable[crc] = m->timestamp_sec;
//и ставим вердикт: разрешить прохождение пакета.
status = ipq_set_verdict(h, m->packet_id,
NF_ACCEPT, 0, NULL);
}
//проверяем, не случилось ли ошибки при выставлении вердикта
if (status < 0)
die(h,"ipq_set_verdict");
break;
}
default:
//отмечаем неизвестные сообщения от библиотеки предупредительным сообщением
fprintf(stderr, "Unknown message type!\n");
break;
}
} while (1);
//освобождаем дескриптор выданный нам libipq
ipq_destroy_handle(h);
//завершаемся
return 0;
}
//Далее идет обыкновенная имплементация crc16, откопанная где-то в интеренете.
/* Table of CRCs of all 8-bit messages. */
unsigned long crc_table[256];
/* Flag: has the table been computed? Initially false. */
int crc_table_computed = 0;
/* Make the table for a fast CRC. */
void make_crc_table(void)
{
unsigned long c;
int n, k;
for (n = 0; n < 256; n++) {
c = (unsigned long) n;
for (k = 0; k < 8; k++) {
if (c & 1) {
c = 0xedb88320L ^ (c >> 1);
} else {
c = c >> 1;
}
}
crc_table[n] = c;
}
crc_table_computed = 1;
}
/*
Update a running crc with the bytes buf[0..len-1] and return
the updated crc. The crc should be initialized to zero. Pre- and
post-conditioning (one's complement) is performed within this
function so it shouldn't be done by the caller. Usage example:
unsigned long crc = 0L;
while (read_buffer(buffer, length) != EOF) {
crc = update_crc(crc, buffer, length);
}
if (crc != original_crc) error();
*/
unsigned long update_crc(unsigned long crc,
unsigned char *buf, int len)
{
unsigned long c = crc ^ 0xffffffffL;
int n;
if (!crc_table_computed)
make_crc_table();
for (n = 0; n < len; n++) {
c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
}
return c ^ 0xffffffffL;
}
/* Return the CRC of the bytes buf[0..len-1]. */
unsigned short crc16(unsigned char *buf, int len)
{
return (unsigned short)update_crc(0L, buf, len);
}