В Linux используется сокет PF_PACKET для чтения данных из исходного устройства, такие как сетевой интерфейс работает в смешанном режиме:
s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))
Это будет посылать копии каждого пакета, принятые до вашего гнезда. Вполне вероятно, что вам действительно не нужен каждый пакет. Ядро может выполнять первый уровень фильтрации с использованием BPF, Berkeley Packet Filter. BPF по существу стек на основе виртуальной машины: он обрабатывает небольшой набор команд, таких как:
ldh = load halfword (from packet)
jeq = jump if equal
ret = return with exit code
код выхода БНФ сообщает ядру ли скопировать пакет в сокет или нет. Можно писать относительно небольшие программы BPF напрямую, используя setsockopt (s, SOL_SOCKET, SO_ATTACH_FILTER). (ПРЕДУПРЕЖДЕНИЕ: Ядро принимает struct sock_fprog, а не struct bpf_program, не смешивает их, или ваша программа не будет работать на некоторых платформах).
Для чего-либо достаточно сложного, вы действительно хотите использовать libpcap. BPF ограничен тем, что он может сделать, в частности, количеством инструкций, которые он может выполнить для каждого пакета. libpcap позаботится о том, чтобы разбивать сложный фильтр на две части, причем ядро выполняет первый уровень фильтрации, а более удобный код пространства пользователя выводит пакеты, которые он фактически не хочет видеть.
libpcap также абстрагирует интерфейс ядра вне вашего кода приложения. Linux и BSD используют аналогичные API, но Solaris требует, чтобы DLPI и Windows использовали что-то еще.
В Linux? Ваше сообщение не указывает на ОС, но следует ли предположить, что вы используете «root», то есть Linux? – GEOCHET 2008-09-22 13:19:47
yep, так что тег я думаю – jbleners 2008-09-22 13:27:30