Câu trả lời ngắn: các gói được khai thác ở phần cuối của ngăn xếp mạng phần mềm (ví dụ: trong Linux).
Long trả lời với mã đào trong tcpdump, libpcap và Linux kernel 3.12:
Cả Wireshark và tcpdump sử dụng libpcap, ví dụ,
http://sources.debian.net/src/tcpdump/4.5.1-2/tcpdump.c#L1472
if (pcap_setfilter(pd, &fcode) < 0)
đó lần lượt cài đặt một gói lọc qua setfilter_op và activate_op. Có rất nhiều việc triển khai các hoạt động, và tôi nghĩ rằng trên Linux gần đây PF_PACKET
sẽ được sử dụng với 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 được thực hiện trong kernel, trong file net/packet/af_packet.c. Khởi của PF_SOCKET được thực hiện trong packet_do_bind
với register_prot_hook(sk)
chức năng (nếu thiết bị ở trạng thái UP), which callsdev_add_pack
từ net/core/dev.c để đăng ký móc:
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 }
Tôi nghĩ, xử lý pf_packet - các tpacket_rcv(...)
function - sẽ được đăng ký trong ptype_all .
Hooks, đăng ký tại ptype_all
đang kêu gọi các gói tin gửi đi từ dev_queue_xmit_nit
("Hỗ trợ thường xuyên. Gửi khung đi tới bất kỳ mạng hiện vòi sử dụng.") Với list_for_each_entry_rcu(ptype, &ptype_all, list) { ... deliver_skb ...} .. func
, deliver_skb gọi func đó là tpacket_rcv
cho libpcap.
dev_queue_xmit_nit được gọi từ dev_hard_start_xmit
(Line 2539 in net/core/dev.c) là AFAIK giai đoạn cuối cùng (cho gói đi) xử lý gói độc lập thiết bị trong ngăn xếp mạng Linux.
Lịch sử tương tự dành cho các gói gửi đến, ptype_all
móc được đăng ký được gọi từ __netif_receive_skb_core
với cùng một list_for_each_entry_rcu(ptype, &ptype_all, list) {.. deliver_skb..}
.__netif_receive_skb_core
được gọi từ __netif_receive_skb
vào đầu rất năng xử lý các gói tin đến
nền tảng Linux có mô tả tốt của chồng (http://www.linuxfoundation.org/collaborate/workgroups/networking/kernel_flow), bạn có thể nhìn thấy dev_hard_start_xmit
vào hình ảnh http://www.linuxfoundation.org/images/1/1c/Network_data_flow_through_kernel.png mạng (cảnh báo, nó là rất lớn) ở phía bên trái ngay dưới huyền thoại. Và netif_receive_skb
nằm bên trong hình vuông dưới cùng bên phải ("net/core/dev.c"), được cấp từ IRQ, sau đó là cuộc thăm dò NAPI hoặc netif_rx và thoát duy nhất từ đây là netif_receive_skb
.
Hình ảnh thậm chí còn hiển thị một trong hai móc pf_packet - hình vuông bên trái dưới chú giải ("net/packet/af_packet.c") - cho các gói đi.
Công cụ của bạn là gì? Làm thế nào nó kết nối với ngăn xếp mạng? Nếu bạn có thể định vị công cụ trong Network_data_flow picture, bạn sẽ nhận được câu trả lời. Ví dụ, Netfilter được nối (NF_HOOK
) chỉ trong ip_rcv
(đến) ip_output
(gửi đi cục bộ) và ip_forward
(gửi đi từ định tuyến) - chỉ sau netif_receive_skb
và ngay trước dev_queue_xmit
.
Trong khi đây là câu trả lời hoàn hảo cho câu hỏi cụ thể, các công cụ này thực sự nắm bắt được gói khi nó được gửi tới bộ điều hợp mạng, không phải khi nó đi vào dây. Điều này có nghĩa rằng tất cả mọi thứ bộ điều hợp mạng (mà trước đây chỉ là MAC FCS, nhưng bây giờ thường là IP/UDP/TCP checksum) không được chụp đúng cách. –
@Will Dean: Bộ điều hợp có thực sự sửa đổi IP và kiểm tra mức cao hơn không? Đó là một bất ngờ đối với tôi, bạn có một tham chiếu? –
@GregS - Biểu dữ liệu của Intel dành cho chip điều khiển Ethernet hiện đại sẽ cung cấp cho bạn tất cả các lỗi, nhưng nếu đó chỉ là vấn đề không tin tôi thì http://www.wireshark.org/faq.html#q11.1 nên đặt tâm trí của bạn thoải mái ... –