Respuesta corta: los paquetes se conectan al final de la pila de la red del software (por ejemplo, en Linux).
Respuesta larga con el código de la excavación en tcpdump, libpcap y el kernel Linux 3.12:
Tanto Wireshark y tcpdump utiliza libpcap, por ejemplo,
http://sources.debian.net/src/tcpdump/4.5.1-2/tcpdump.c#L1472
if (pcap_setfilter(pd, &fcode) < 0)
que a su vez instalar un paquete filtrar a través de setfilter_op y activate_op. Hay muchas implementaciones de estas operaciones, y creo que en Linux reciente PF_PACKET
se utilizará con pcap_activate_linux
libpcap-1.5.3-2/pcap-linux.c#L1287:
/*
* Current Linux kernels use the protocol family PF_PACKET to
* allow direct access to all packets on the network while
* older kernels had a special socket type SOCK_PACKET to
* implement this feature.
* While this old implementation is kind of obsolete we need
* to be compatible with older kernels for a while so we are
* trying both methods with the newer method preferred.
*/
status = activate_new(handle);
...
activate_new(pcap_t *handle)
...
/*
* Open a socket with protocol family packet. If the
* "any" device was specified, we open a SOCK_DGRAM
* socket for the cooked interface, otherwise we first
* try a SOCK_RAW socket for the raw interface.
*/
sock_fd = is_any_device ?
socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)) :
socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
PF_PACKET se implementa en el kernel, en el archivo net/packet/af_packet.c. Inicialización de PF_SOCKET se realiza en packet_do_bind
con register_prot_hook(sk)
función (si el dispositivo se encuentra en estado UP), which callsdev_add_pack
de net/core/dev.c para registrar el gancho:
370 /**
371 * dev_add_pack - add packet handler
372 * @pt: packet type declaration
373 *
374 * Add a protocol handler to the networking stack. The passed &packet_type
375 * is linked into kernel lists and may not be freed until it has been
376 * removed from the kernel lists.
377 *
378 * This call does not sleep therefore it can not
379 * guarantee all CPU's that are in middle of receiving packets
380 * will see the new packet type (until the next received packet).
381 */
382
383 void dev_add_pack(struct packet_type *pt)
384 {
385 struct list_head *head = ptype_head(pt);
386
387 spin_lock(&ptype_lock);
388 list_add_rcu(&pt->list, head);
389 spin_unlock(&ptype_lock);
390 }
creo, manejador PF_PACKET - la tpacket_rcv(...)
function - se registrará en ptype_all .
ganchos, registradas en ptype_all
son llamados para los paquetes salientes de dev_queue_xmit_nit
("Apoyo a la rutina. Envía tramas salientes a cualquier red grifos actualmente en uso.") Con list_for_each_entry_rcu(ptype, &ptype_all, list) { ... deliver_skb ...} .. func
, deliver_skb llama a la func que es tpacket_rcv
para libpcap.
dev_queue_xmit_nit se llama desde dev_hard_start_xmit
(Line 2539 in net/core/dev.c) que es AFAIK la última etapa (para paquetes salientes) de manejo de paquetes independiente del dispositivo en la pila de red de Linux.
El mismo historial corresponde a los paquetes entrantes, ptype_all
-los enganches registrados se llaman desde __netif_receive_skb_core
con el mismo list_for_each_entry_rcu(ptype, &ptype_all, list) {.. deliver_skb..}
.__netif_receive_skb_core
se llama desde __netif_receive_skb
en el comienzo mismo de manejo de paquetes entrantes
Linux fundación tiene buena descripción de pila de red (http://www.linuxfoundation.org/collaborate/workgroups/networking/kernel_flow), se puede ver dev_hard_start_xmit
en la imagen http://www.linuxfoundation.org/images/1/1c/Network_data_flow_through_kernel.png (advertencia, que es enorme) en el lado izquierdo justo debajo de la leyenda. Y netif_receive_skb
se encuentra dentro del cuadro inferior derecho ("net/core/dev.c"), que se alimenta desde IRQ, luego NAPI poll o netif_rx y la única salida desde aquí es netif_receive_skb
.
La imagen muestra incluso uno de los dos ganchos pf_packet: el cuadrado situado más a la izquierda debajo de la leyenda ("net/packet/af_packet.c") para los paquetes salientes.
¿Cuál es su herramienta? ¿Cómo se conecta a la pila de redes? Si puede ubicar la herramienta en el Network_data_flow picture, obtendrá la respuesta. Por ejemplo, Netfilter está enganchado (NF_HOOK
) solo en ip_rcv
(entrante) ip_output
(local de salida) y ip_forward
(saliente de la ruta) - justo después de netif_receive_skb
y justo antes de dev_queue_xmit
.
Si bien esta es una respuesta perfectamente buena para la pregunta específica, estas herramientas capturan el paquete tal como se lo entrega al adaptador de red, no a medida que pasa al cable. Esto significa que todo lo que hace el adaptador de red (que solía ser solo MAC FCS, pero ahora también suele ser sumas de verificación IP/UDP/TCP) no se captura correctamente. –
@Will Dean: ¿Los adaptadores realmente modifican las sumas de comprobación de IP y de nivel superior? Eso es una sorpresa para mí, ¿tiene alguna referencia? –
@GregS: una hoja de datos de Intel para un chip controlador Ethernet moderno te daría toda la sangre derramada, pero si solo es cuestión de no creerme, entonces http://www.wireshark.org/faq.html#q11.1 debería pon tu mente a gusto ... –