संक्षिप्त उत्तर: सॉफ़्टवेयर नेटवर्क स्टैक (जैसे लिनक्स में) के अंत में पैकेट टैप किए जाते हैं। कोड tcpdump, libpcap और लिनक्स कर्नेल 3.12 में खुदाई के साथ
लांग जवाब:
दोनों Wireshark और tcpdump उदाहरण के लिए, libpcap का उपयोग करता है,
http://sources.debian.net/src/tcpdump/4.5.1-2/tcpdump.c#L1472
if (pcap_setfilter(pd, &fcode) < 0)
जो बारी में एक पैकेट स्थापित setfilter_op और activate_op के माध्यम से फ़िल्टर करें। इन आपरेशनों के कार्यान्वयन की बहुत हैं, और मुझे लगता है कि हाल ही में लिनक्स पर PF_PACKET
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, कर्नेल में कार्यान्वित किया जाता है फ़ाइल net/packet/af_packet.c में। PF_SOCKET का प्रारंभ, register_prot_hook(sk)
समारोह के साथ packet_do_bind
में किया जाता है (यदि डिवाइस उत्तर प्रदेश राज्य में है) which callsnet/core/dev.c से dev_add_pack
हुक रजिस्टर करने के लिए:
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 }
मुझे लगता है, pf_packet हैंडलर - tpacket_rcv(...)
function - ptype_all में पंजीकृत किया जाएगा ।
हुक्स, ptype_all
में पंजीकृत ("दिनचर्या का समर्थन करें। निवर्तमान फ्रेम भेजता करने के लिए किसी भी नेटवर्क का उपयोग वर्तमान में टैप करता।") dev_queue_xmit_nit
से बाहर जाने वाले पैकेट के लिए कहा जाता है list_for_each_entry_rcu(ptype, &ptype_all, list) { ... deliver_skb ...} .. func
साथ, deliver_skb समारोह जो libpcap के लिए tpacket_rcv
है कहता है।
dev_queue_xmit_nit dev_hard_start_xmit
(Line 2539 in net/core/dev.c) से कहा जाता है जो लिनक्स नेटवर्किंग स्टैक में डिवाइस-स्वतंत्र पैकेट हैंडलिंग के अंतिम चरण (आउटगोइंग पैकेट के लिए) AFAIK है।
वही इतिहास इनकमिंग पैकेट्स के लिए है, ptype_all
- से पंजीकृत हुक को list_for_each_entry_rcu(ptype, &ptype_all, list) {.. deliver_skb..}
के साथ बुलाया जाता है।__netif_receive_skb_core
आने वाले पैकेट
से निपटने के बहुत शुरुआत में
__netif_receive_skb
से कहा जाता है
लिनक्स नींव बस के नीचे बाईं ओर नेटवर्किंग स्टैक (http://www.linuxfoundation.org/collaborate/workgroups/networking/kernel_flow), तो आप छवि http://www.linuxfoundation.org/images/1/1c/Network_data_flow_through_kernel.png पर dev_hard_start_xmit
देख सकते हैं की अच्छा वर्णन (चेतावनी, यह बहुत बड़ा है) है कथा। और netif_receive_skb
दाएं निचले वर्ग ("नेट/कोर/dev.c") के अंदर है, जिसे आईआरक्यू, फिर एनएपीआई पोल या नेटिफ_आरएक्स से खिलाया जाता है और यहां से केवल एक ही निकास netif_receive_skb
है।
तस्वीर दो पीएफ_पैकेट हुकों में से एक को दिखाती है - आउटगोइंग पैकेट के लिए किंवदंती ("नेट/पैकेट/af_packet.c") के नीचे बाएंतम वर्ग।
आपका उपकरण क्या है? यह नेटवर्किंग स्टैक से कैसे जुड़ता है? यदि आप Network_data_flow picture में टूल का पता लगा सकते हैं, तो आपको जवाब मिल जाएगा। उदाहरण के लिए, नेटफिल्टर है शौकीन (NF_HOOK
) ip_rcv
केवल में (आवक) ip_output
(स्थानीय जावक) और ip_forward
(मार्ग से बाहर जाने वाले) - netif_receive_skb
के तुरंत बाद और dev_queue_xmit
बस से पहले।
हालांकि यह विशिष्ट प्रश्न के लिए एक बिल्कुल अच्छा जवाब है, लेकिन ये उपकरण वास्तव में पैकेट को कैप्चर करते हैं क्योंकि यह नेटवर्क एडाप्टर को वितरित किया जाता है, न कि यह तार पर जाता है। इसका मतलब यह है कि नेटवर्क एडाप्टर जो कुछ भी करता है (जो केवल मैक एफसीएस होता था, लेकिन अब आमतौर पर आईपी/यूडीपी/टीसीपी चेकसम भी होता है) ठीक से कब्जा नहीं किया जाता है। –
@ विल डीन: क्या एडेप्टर वास्तव में आईपी और उच्च स्तरीय चेकसम को संशोधित करते हैं? यह मेरे लिए एक आश्चर्य है, क्या आपके पास कोई संदर्भ है? –
@ ग्रेग्स - एक आधुनिक ईथरनेट नियंत्रक चिप के लिए एक इंटेल डेटाशीट आपको सभी गोर देगा, लेकिन अगर यह सिर्फ मुझे विश्वास करने का मामला नहीं है, तो http://www.wireshark.org/faq.html#q11.1 चाहिए अपने दिमाग को आसानी से सेट करें ... –