En Linux utiliza un receptáculo de PF_PACKET para leer datos de un dispositivo en bruto, tales como una interfaz de Ethernet se ejecuta en modo promiscuo:
s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))
Esto enviará copias de cada paquete recibido hasta el zócalo. Sin embargo, es bastante probable que en realidad no desee todos los paquetes. El kernel puede realizar un primer nivel de filtrado utilizando BPF, Berkeley Packet Filter. BPF es esencialmente una máquina virtual basado en la pila: se ocupa de un pequeño conjunto de instrucciones tales como:
ldh = load halfword (from packet)
jeq = jump if equal
ret = return with exit code
código de salida de BPF le dice al núcleo si se debe copiar el paquete a la toma o no. Es posible escribir programas BPF relativamente pequeños directamente, usando setsockopt (s, SOL_SOCKET, SO_ATTACH_FILTER,). (ADVERTENCIA: El núcleo toma una estructura sock_fprog, no una struct bpf_program, no las mezcle o su programa no funcionará en algunas plataformas).
Para cualquier cosa razonablemente compleja, realmente desea usar libpcap. BPF está limitado en lo que puede hacer, en particular en la cantidad de instrucciones que puede ejecutar por paquete. libpcap se encargará de dividir un filtro complejo en dos partes, con el kernel realizando un primer nivel de filtrado y el código de espacio de usuario más capaz que arroja los paquetes que en realidad no quería ver.
libpcap también abstrae la interfaz del kernel de su código de aplicación. Linux y BSD usan API similares, pero Solaris requiere DLPI y Windows usa algo más.
En Linux? Su publicación no indica el sistema operativo, pero ¿deberíamos suponer que con el uso de "raíz" quiere decir linux? – GEOCHET
sí, también lo hace la etiqueta supongo – jbleners