В Linux вы используете сокет PF_PACKET для чтения данных с необработанного устройства, такого как интерфейс Ethernet, работающий в случайном режиме:
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 сообщает ядру, копировать ли пакет в сокет или нет. Можно написать относительно небольшие программы BPF напрямую, используя setsockopt (s, SOL_SOCKET, SO_ATTACH_FILTER,). (ВНИМАНИЕ: Ядро принимает struct sock_fprog, а не struct bpf_program, не путайте их, иначе ваша программа не будет работать на некоторых платформах).
Для чего-то достаточно сложного, вы действительно хотите использовать libpcap. BPF ограничен в том, что он может делать, в частности, в количестве команд, которые он может выполнять для каждого пакета. libpcap позаботится о разбиении сложного фильтра на две части, при этом ядро выполнит первый уровень фильтрации, а более мощный код пользовательского пространства отбросит пакеты, которые он фактически не хотел видеть.
libpcap также абстрагирует интерфейс ядра от кода вашего приложения. Linux и BSD используют схожие API, но Solaris требует DLPI, а Windows использует что-то другое.